CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战996引擎离线留言留言箱

【进阶实战】离线留言:好友留言的时效与已读封装

2026-09-25 13:18 作者:996 技术组 0 阅读 996引擎Lua教程传奇脚本进阶实战996引擎Lua离线留言留言箱

业务场景

好友不在线时想说的短话只能发邮件(太重)或干等上线(太慢):一句"晚上八点打祖玛?"不值得一封邮件。离线留言封装:给不在线好友存一条短留言,对方上线时统一送达,3 天不取自动作废——轻量沟通填补"邮件太重、私聊要在线"的空档。

核心实现

留言写入。示例代码如下:

lua
local function leaveMsg(actor, friendName, text)
    local friend = getplayerbyname(friendName)
    if friend then
        sendmsg(friend, 1, "[留言] " .. text)
        return
    end
    local box = tostring(getsysvar("MsgBox_" .. friendName) or "")
    if #box > 400 then
        sendmsg(actor, 1, "对方留言箱已满。")
        return
    end
    setsysvarex("MsgBox_" .. friendName,
        box .. os.time() .. "|" .. text .. ";", 1)
    sendmsg(actor, 1, "留言已存,对方上线时送达。")
end

上线投递。示例代码如下:

lua
local function deliverOnLogin(actor, selfName)
    local box = tostring(getsysvar("MsgBox_" .. selfName) or "")
    if box == "" then
        return
    end
    local n = 0
    for entry in string.gmatch(box, "[^;]+") do
        local ts, text = string.match(entry, "^(%d+)|(.+)$")
        if ts and os.time() - tonumber(ts) < 259200 then
            sendmsg(actor, 1, "[留言] " .. text)
            n = n + 1
        end
    end
    setsysvarex("MsgBox_" .. selfName, "", 1)
    if n > 0 then
        sendmsg(actor, 1, "共 " .. n .. " 条留言送达,3 天内有效。")
    end
end

接口拆解

留言箱放在 sysvar(键为收件人名字)而不是玩家变量——玩家变量面向在线对象,离线时不可写;sysvar 是全局存储,任何时刻可读写。写入格式为"时间戳|内容;"的分号分隔串,400 字节上限。deliverOnLogin 挂登录触发:gmatch 拆箱逐条解析,超过 259200 秒(3 天)的过期不投,投完清箱。在线好友直接私聊直达,不进箱体——留言只服务离线场景。

踩坑记录

离线留言踩过三个坑:一是箱体没有上限,被连续刷留言撑爆 sysvar 写入失败,加 400 字节上限与满箱拒收提示;二是留言内容含分号或竖线把格式拆坏、整箱解析错乱,写入前对内容做字符白名单(剔除分号竖线),格式字符只允许系统自己写;三是玩家改名后按旧名找不到箱,改名流程里同步迁移留言箱的键——名字变了,信不能丢。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

最新技术文章 · 实战干货

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

入门夯实游戏功能

关注降价:关注商品的降价提醒

【游戏】 一、一行代码拆解:if price < WATCH[goods] then notify end —— 关注降价的…

2026-09-26 22:24 996 技术组 · 0 阅读
进阶实战游戏功能

竞技场积分赛:胜负积分的晋级规则

【游戏】 一、业务场景:赛季结算发现一名玩家胜率 10% 却排在黄金段——历史计分只加不减,积分体系失效 3 个月;积分赛—…

2026-09-26 22:24 996 技术组 · 0 阅读
进阶实战语法算法

Lua卡塔兰数:合法括号序列的计数

【语法】 一、抛坑提问:3 对括号能组成多少种合法序列?答案是 5——卡塔兰数列:每一项等于前一项乘 2 倍的 2n 减 1…

2026-09-26 22:24 996 技术组 · 0 阅读
进阶实战语法算法

Lua线性同余:自实现随机数生成器

【语法】 一、抛坑提问:不想用全局随机函数(怕多处共享种子互相干扰),可自实现一个独立随机序列——线性同余法三行核心:乘、加…

2026-09-26 22:24 996 技术组 · 0 阅读
策划架构游戏功能

双人复核:大额支取的双人确认

【游戏】 一、一行代码拆解:PENDING[outId] = {by = actor, at = now} —— 双人复核的…

2026-09-26 22:24 996 技术组 · 0 阅读
进阶实战语法算法

Lua蒙地卡罗:随机撒点估算圆周率

【语法】 一、隐蔽陷阱:圆周率小数位背不出更多就不算理解随机模拟?用蒙地卡罗法随机撒点统计,10 万个点能把圆周率估到两位小…

2026-09-26 22:24 996 技术组 · 0 阅读