一、线上事故:发奖直接 getplayerbyname(名字) 不判空,离线队员返回 nil 后照样进 setplayvar,attempt to index a nil value 炸了整轮结算,500 人份奖励卡发。
二、底层原理:名字转对象是查询不是保证:不在线即返回 nil;先转对象、判 nil、离线走补发队列,三步固定节奏——对象有效性在服务端永远要主动验证。
三、正确代码:
错误写法。示例代码如下:
local function give(actorName, exp)
local a = getplayerbyname(actorName)
setplayvar(a, "EXP_ADD", exp) -- 离线时a为nil,直接炸
end
正确写法。示例代码如下:
local offline = {}
local function give(actorName, exp)
local a = getplayerbyname(actorName)
if not a then
offline[#offline + 1] = {name = actorName, exp = exp}
return -- 离线入补发队列
end
setplayvar(a, "EXP_ADD", exp)
end
local function reissue()
for i, r in ipairs(offline) do give(r.name, r.exp) end
offline = {}
end
sendmsg(actor, 1, "沙巴克结算完成,离线 " .. #offline .. " 人待补")
四、引擎验证:500 人结算含 60 人离线:裸发版卡死 1 次全停;判空版 440 人即时到账,60 人上线补发 100% 达账。
五、FAQ:问:离线补发存哪?答:setsysvarex 落库更稳,重启不丢,在线表只是快路径。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏】 一、业务场景 帮会成员各自打怪缺乏交流,武艺高低无从比较。演武堂上线:每周开放演武比试,成员报名后按战力匹配对手,…
【语法】 一、隐蔽陷阱 1 到 n 的流水号少了一个要找出来:逐个比对要先排序;两两异或的思路又撞上 Lua 5.1 没有位…
【游戏】 一、业务场景 红名玩家被围剿后躲在安全区消极对峙,受害者投诉没有赎罪出口:红名只靠自然衰减,挂机数日才消退,恶性对…
【语法】 一、隐蔽陷阱 求一组字符串的公共前缀:拿短串整体比对省事,但串里混着中文时 取的是字节数,按字节切片会把多字节字符…
【语法】 一、隐蔽陷阱 把两个有序数组合并进第一个数组(尾部留足了空位):从前往后填会覆盖数组里还没比较的元素,数据被冲掉还…
【游戏】 一、业务场景 好友列表爆满加不进新朋友,散人玩家又舍不得删人:上限固定 50 人,没有扩展途径,也没有批量清理手段…