包信息
| 项目 |
值 |
| PacketID |
455 |
| 方向 |
Server -> Client |
| 长度 |
12 |
| 作用 |
返回一次心法学习后的当前金钱、当前经验、心法 ID 和当前等级,同时用于服务端批量同步心法等级 |
包体结构
| 偏移 |
长度 |
字段 |
类型 |
含义 |
| 0x00 |
0x04 |
current_money |
uint32 |
当前剩余金钱 |
| 0x04 |
0x04 |
current_exp |
uint32 |
当前剩余经验 |
| 0x08 |
0x02 |
xinfa_id |
uint16 |
本次返回的心法 ID |
| 0x0A |
0x02 |
current_level |
uint16 |
该心法当前等级 |
当前实际行为 / 模式说明
- 客户端发起
CGAskStudyXinfa 后,msgagent.lua 会先核对客户端提交的 now_level 是否等于角色当前心法等级,不一致直接提示“非法请求”并终止。
- 场景服
char_study_xinfa 会按 xinfa_study_speed_v1[level + 1] 读取下一等级所需经验和金钱,再决定是否升级成功。
- 这个包没有单独的结果码。当前实现里,升级成功时返回
current_level = 请求等级 + 1,同时 current_money / current_exp 变为扣费后的最新值;条件不足时仍会回包,但 current_level 保持原值,金钱和经验也保持不变。
- 如果配置缺失导致
cost_exp 或 cost_money 无法取得,服务端只弹提示,不发送 GCStudyXinfa。
human:up_xinfa_level(level) 会遍历角色已有心法并逐本发送 GCStudyXinfa,用于批量提升或同步心法等级。
- 当前
Game.exe 的执行函数直接取 xinfa_id + current_level 更新客户端本地心法数据,并触发两次界面刷新通知;前面的金钱和经验字段仍保留在包体中。
服务端落点
/home/ubuntu/Game2/services/game/packet.lua
/home/ubuntu/Game2/services/msgagent.lua
/home/ubuntu/Game2/services/scene/scenecore.lua
/home/ubuntu/Game2/services/scene/obj/human.lua
关键代码
-- /home/ubuntu/Game2/services/game/packet.lua
self.current_money = stream:readuint()
self.current_exp = stream:readuint()
self.xinfa_id = stream:readushort()
self.current_level = stream:readushort()
-- /home/ubuntu/Game2/services/msgagent.lua
function request:CGAskStudyXinfa()
local xinfa = skynet.call(my_scene, "lua", "call_human_function", my_obj_id, "get_xinfa", self.xinfa)
if xinfa.m_nXinFaLevel ~= self.now_level then
ma_func:notify_tips("非法请求")
return
end
skynet.call(my_scene, "lua", "char_study_xinfa", my_obj_id, self)
end
-- /home/ubuntu/Game2/services/scene/scenecore.lua
msg.current_exp = my_exp
msg.current_money = my_money
msg.current_level = req.now_level
msg.xinfa_id = req.xinfa
if my_exp >= cost_exp and obj_me:check_money_with_priority(cost_money) then
msg.current_level = req.now_level + 1
obj_me:set_exp(my_exp - cost_exp)
obj_me:cost_money_with_priority(cost_money, "心法学习")
obj_me:study_xinfa(req.xinfa, msg.current_level)
msg.current_exp = obj_me:get_exp()
msg.current_money = obj_me:get_money()
end
-- /home/ubuntu/Game2/services/scene/obj/human.lua
local msg = packet_def.GCStudyXinfa.new()
msg.current_exp = self:get_attrib("exp")
msg.current_money = self:get_attrib("money")
msg.current_level = level
msg.xinfa_id = xinfa.m_nXinFaID
self:get_scene():send2client(self, msg)
// Game.exe
GetPacketID() = 455;
GetPacketSize() = 12;
Read() : read(a1 + 24, 4); read(a1 + 28, 4); read(a1 + 32, 2); read(a1 + 34, 2);
Write() : write(a1 + 24, 4); write(a1 + 28, 4); write(a1 + 32, 2); write(a1 + 34, 2);
Execute(): update_xinfa(xinfa_id, current_level); post_refresh(\"93;0\"); notify(150); notify(22);
结论
GCStudyXinfa 是当前版本的心法学习结果回包,固定长度 12 字节,按“当前金钱、当前经验、心法 ID、当前等级”的顺序返回结果。当前 Lua 用它同时覆盖手动学习心法回包和批量同步心法等级两条发送链,是否升级成功需要通过 current_level 是否增长以及资源数值是否发生变化来判断。