找回密码
 registerss
搜索
查看: 25|回复: 0

洱海月 v0-07-0300 封包解析:ID 875 GCSecKillRemoveItem(扫荡掉落项处理结果)

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:603
  • 打卡月天数:1
  • 打卡总奖励:600
  • 最近打卡:2026-10-03 06:32:28
Waylee 发表于 2026-4-15 13:15 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?registerss

×

GCSecKillRemoveItem 是当前扫荡结果页处理中实际在用的结果回包。场景服在处理 CGSecKillRemoveItem(874) 后,每成功移除或领取一个条目,就会立刻回一条 GCSecKillRemoveItem 给客户端。

这条包本身非常短,Game.exe 与当前 Lua 都确认它是固定 2 字节结构,只回显“是否丢弃”和“条目索引”两个字段。

包信息

项目 内容
封包 ID 875
包名 GCSecKillRemoveItem
方向 GC 服务端 -> 客户端
固定包长 2
当前 Lua 协议定义 已定义
当前 Lua 发送入口 human:remove_sec_kill_item()
关联请求 CGSecKillRemoveItem(874)
主要作用 回报某个扫荡结果条目已被丢弃或已被领取并移除

当前 Game.exe 的虚函数结论为:

GCSecKillRemoveItem
GetPacketID()   = 875;
GetPacketSize() = 2;
Read            = 0x1405C2E10;
Write           = 0x1405C7850;
Execute thunk   = 0x140617480 -> sub_140090630;

包体结构

偏移 长度 字段 类型 含义
0x00 0x01 is_discard uint8 1 表示丢弃路径;0 表示领取/保留路径
0x01 0x01 index uint8 被处理的扫荡结果条目索引

当前 Game.exe 与 Lua 的读写都一致:

Read(stream) {
    read_u8(is_discard);
    read_u8(index);
}

Write(stream) {
    write_u8(is_discard);
    write_u8(index);
}

当前实际行为

当前 Lua 的完整处理链是:

  1. 客户端发送 CGSecKillRemoveItem,包体为 is_discard + is_all + index。
  2. /home/ubuntu/Game2/services/msgagent.lua 转发到 char_sec_kill_remove_item。
  3. 场景服按请求分三种路径处理:
    • is_discard == 1:倒序丢弃全部条目
    • is_discard == 0 && is_all == 1:检查背包空间后,逐项创建进背包并移除
    • is_discard == 0 && is_all == 0:按 index 只处理单条
  4. 每成功处理一条,human:remove_sec_kill_item() 都会发送一条 GCSecKillRemoveItem。

客户端 Execute() 的本地行为也很直接:

  • is_discard == 1 时,进入“全部丢弃/清空”路径。
  • 否则按 index 删除对应条目。
  • 随后刷新本地扫荡结果页并触发事件 813。

因此,这条回包不是“整个扫荡页的最终结果包”,而是逐条反馈包。无论是批量丢弃还是批量领取,客户端都是靠多条 GCSecKillRemoveItem 把列表逐项删干净。

服务端落点

当前项目里与这条回包相关的落点如下:

  • 协议定义:
    • /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

关键代码

当前 Lua 回包发送

function human:remove_sec_kill_item(index, is_discard)
    local item_list = self.dungeonsweep.sec_kill_data.item_list or {}
    for i, item in ipairs(item_list) do
        if item.index == index then
            table.remove(item_list, i)
        end
    end
    local msg = packet_def.GCSecKillRemoveItem.new()
    msg.is_discard = is_discard
    msg.index = index
    self:get_scene():send2client(self, msg)
end

当前 Game.exe 的执行关键点

Execute() {
    if (is_discard == 1)
        clear_or_discard_path();
    else
        remove_item_by_index(index);

    refresh_ui();
    fire_event(813);
    return 2;
}

结论

GCSecKillRemoveItem 的结论可以直接收敛为:

  1. 这条包固定只有 2 字节,结构为 is_discard + index。
  2. 它是当前扫荡结果处理链的现役逐条反馈包。
  3. 当前 Lua 不管是批量丢弃还是批量领取,最终都会拆成多条 GCSecKillRemoveItem 逐项回给客户端。
  4. 客户端收到后只负责按标记移除条目并刷新扫荡结果界面。

因此,这条包应归类为“当前版本实际在用的扫荡掉落项逐条处理结果回包”。

您需要登录后才可以回帖 登录 | registerss

本版积分规则

QQ|手机版|雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 )|天天打卡

GMT+8, 2026-10-4 11:26 , Processed in 0.063966 second(s), 26 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表