问题现象
玩家不是“英雄归来”状态,重新登录游戏后,右上快捷入口仍显示“英雄归来”图标。
客户端显示效果类似:
点击打开英雄归来礼馈界面,领取英雄归来礼馈。
涉及文件
服务端:
tlbb/services/scripts/event/huodong/heros_returns.lua
客户端只作为参考,不修改:
客户端/Interface/PlayerQuicklyEnter/PlayerQuicklyEnter.lua
客户端/Config/PlayerQuicklyEnterHide.txt
原因分析
客户端快捷入口中,“英雄归来”的入口 ID 是 3。
PlayerQuicklyEnterHide.txt 中该入口默认处于可显示状态。
也就是说,如果服务端不主动刷新运行态显隐,客户端会默认显示这个图标。
英雄归来图标最终应该由服务端主动下发快捷入口状态控制:
GCQuickEnterPoint(type=0, id=3, value=0/1)
其中:
type=0 表示控制按钮显隐
id=3 表示英雄归来快捷入口
value=0 表示隐藏
value=1 表示显示
另外要注意 Lua 的布尔语义:
0
在 Lua 中也是真值。
所以不能写成:
show and 1 or 0
如果调用方传入 0,结果仍会变成 1,导致本来想隐藏,实际却发成显示。
最终修复方案
只使用 GCQuickEnterPoint 控制快捷入口,不再走 UI_COMMAND 80811000 兼容链路,也不使用 skynet.timeout 延迟补发。
在 heros_returns.lua 中增加快捷入口常量:
heros_returns.QUICK_ENTER_ID = 3
heros_returns.QUICK_ENTER_TYPE_BUTTON = 0
增加布尔归一化函数:
local function normalize_ui_bool(value)
return value == true or tonumber(value) == 1
end
修改 SendQuickEnter:
function heros_returns:SendQuickEnter(selfId, show)
local flag = normalize_ui_bool(show) and 1 or 0
self:DispatchQuickEnterPoint(selfId, self.QUICK_ENTER_TYPE_BUTTON, self.QUICK_ENTER_ID, flag)
end
调用处统一传布尔值。
隐藏:
self:SendQuickEnter(selfId, false)
显示:
self:SendQuickEnter(selfId, true)
不要再写:
self:SendQuickEnter(selfId, 0)
self:SendQuickEnter(selfId, 1)
登录逻辑示例
非回归玩家登录时隐藏入口:
if (self:GetLevel(selfId) or 0) < self.MIN_LEVEL then
self:SendQuickEnter(selfId, false)
return
end
活动已激活时显示入口:
if self:IsActive(selfId) then
self:UpdateLoginDay(selfId)
self:EnsureImpact(selfId)
self:SendQuickEnter(selfId, true)
self:SendRedPoint(selfId)
return
end
不满足回归条件时隐藏入口:
self:SendQuickEnter(selfId, false)
GM 关闭活动时也要隐藏入口:
self:CancelImpact(selfId)
self:SendQuickEnter(selfId, false)
验证方式
语法检查:
luac -p tlbb/services/scripts/event/huodong/heros_returns.lua
Git 空白检查:
git diff --check
服内测试:
- 热重载
808110 脚本。
- 使用非英雄归来状态角色重新登录。
- 确认右上“英雄归来”快捷入口不显示。
- 使用满足英雄归来条件或 GM 激活的角色登录。
- 确认右上“英雄归来”快捷入口正常显示。
最终效果
非英雄归来状态玩家:
右上英雄归来图标不显示
英雄归来状态玩家:
右上英雄归来图标正常显示
该修复只修改服务端,不需要修改客户端。