找回密码
 registerss
搜索

洱海月 v0-07-0300 封包解析:ID 291 CGDiscardItem(丢弃道具请求)

[复制链接]
Waylee 发表于 2026-4-13 15:04 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

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

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

×

CGDiscardItem 是客户端向游戏服提交“丢弃指定格子道具”的固定长度请求包。

当前版本里,这条包的结构很简单,只带两个字节:目标格索引和来源类型。真正的可丢弃判断、锁定判断、交易冲突处理以及最终删除动作,都由服务端在收到请求后完成,并通过 GCDiscardItemResult 返回结果。

包信息

项目 内容
封包 ID 291
包名 CGDiscardItem
方向 CG 客户端 -> 游戏服
包长 2
当前 Lua 协议定义 /home/ubuntu/Game2/services/game/packet.lua
当前服务端入口 /home/ubuntu/Game2/services/msgagent.lua
当前场景处理 /home/ubuntu/Game2/services/scene/scenecore.lua 的 char_discard_item()
主要作用 请求丢弃指定来源中的一件道具

当前 Game.exe 可直接确认:

GetPacketID()   = 291;
GetPacketSize() = 2;
Read()          = sub_1405C54F0;
Write()         = sub_1405C5540;
Execute()       = sub_1403281A0;

包体结构

偏移 长度 字段 类型 含义
0x00 0x01 bag_index uint8 要丢弃的目标格索引
0x01 0x01 opt uint8 来源类型,当前 Lua 定义中 0=FromBag、1=FromBank

当前 Lua 中的来源枚举为:

OPT = {
    FromBag  = 0,
    FromBank = 1,
}

当前实际行为 / 模式说明

这条包虽然定义了 FromBag 和 FromBank 两种来源,但当前场景层只实际处理:

  • FromBag = 0

也就是“从角色道具背包丢弃”。

当前 msgagent 收到请求后,会先检查:

  • 小额密码是否已经解锁

如果未解锁,会直接回操作错误,不进入场景层。

进入 scenecore:char_discard_item() 后,当前实际流程如下:

  1. 仅当 discard.opt == packet_def.CGDiscardItem.OPT.FromBag 时继续处理
  2. 刷新锁定道具状态
  3. 从角色道具背包 prop_bag_container 取出 discard.bag_index 对应物品
  4. 如果物品正参与交易,会先取消交易,再重新取物品
  5. 如果物品已锁定,则直接提示“该道具已锁定,无法丢弃”
  6. 如果物品规则不允许丢弃,则提示“xxx不能丢弃”
  7. 只有在物品满足 IRL_DISCARD 规则时,才调用 erase_item_by_bag_index() 真正删除
  8. 最后通过 GCDiscardItemResult 回传处理结果

当前版本里的结果码定义为:

define.DISCARDITEM_RESULT = {
    DISCARDITEM_SUCCESS = 0,
    DISCARDITEM_FAIL = 1,
}

因此,这条包的重点不是包体复杂,而是服务端会对“是否真的允许丢弃”做完整校验。

服务端落点

  • 协议定义:
    • /home/ubuntu/Game2/services/game/packet.lua
  • 请求入口:
    • /home/ubuntu/Game2/services/msgagent.lua
  • 场景处理:
    • /home/ubuntu/Game2/services/scene/scenecore.lua
  • 相关结果回包:
    • /home/ubuntu/Game2/services/game/packet.lua 中的 GCDiscardItemResult

当前 msgagent 入口逻辑如下:

function request:CGDiscardItem()
    if not ma_func:is_minor_password_is_unlock() then
        ma_func:send_operate_result_msg(define.OPERATE_RESULT.OR_NEED_UNLOCKMINORPASSWORD)
        return
    end
    skynet.call(my_scene, "lua", "char_discard_item", my_obj_id, self)
end

当前场景层核心处理如下:

function scenecore:char_discard_item(who, discard)
    local obj = self.objs[who]
    if not obj then
        return
    end
    if discard.opt == packet_def.CGDiscardItem.OPT.FromBag then
        obj:refresh_locked_item_unlock_state(false)
        local container = obj:get_prop_bag_container()
        local item = container:get_item(discard.bag_index)
        if item then
            -- 交易冲突、锁定、规则校验
            -- 满足 IRL_DISCARD 才真正删除
            -- 最终回发 GCDiscardItemResult
        end
    end
end

关键代码

当前 Lua 协议定义

packet.CGDiscardItem = {
    xy_id = packet.XYID_CG_DISCARD_ITEM,
    OPT = {
        FromBag  = 0,
        FromBank = 1,
    },
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.bag_index = stream:readuchar()
        self.opt = stream:readuchar()
    end
}

当前结果回包

当前 GCDiscardItemResult 结构为:

偏移 长度 字段 类型 含义
0x00 0x01 result uint8 丢弃结果码,0=成功、1=失败
0x01 0x01 bag_index uint8 原背包格索引
0x02 0x01 opt uint8 来源类型
0x03 0x04 item_index int32 被处理物品的物品表索引

这说明客户端最终展示结果时,不只是看成功失败,还会同步知道“哪一格、哪一种来源、哪一个物品索引”被处理。

当前 Game.exe 关键结论

当前客户端包类的读写顺序与 Lua 完全一致:

Read(stream) {
    read_u8(bag_index);
    read_u8(opt);
    return 1;
}

Write(stream) {
    write_u8(bag_index);
    write_u8(opt);
    return 1;
}

GetPacketSize() {
    return 2;
}

Execute() {
    return 2;
}

其中 Read() 在当前 Game.exe 里对应两次 1 字节读取,顺序就是:

read(stream, this + 0x19, 1);
read(stream, this + 0x18, 1);

结合当前 Lua 定义,可以明确还原成:

bag_index:uint8;
opt:uint8;

结论

CGDiscardItem 在当前 Temp_Release_v0-07-0300 里的最终结论可以直接收敛为:

  1. 这是一条固定长度 2 字节的客户端请求包。
  2. 包体字段只有:
    • bag_index
    • opt
  3. 当前协议枚举里虽然保留了 FromBag 与 FromBank,但当前场景层只真实处理 FromBag。
  4. 服务端会在真正删除前执行交易冲突、锁定状态和道具规则校验,不满足条件时不会删除。
  5. 最终处理结果通过 GCDiscardItemResult 回包返回。
  6. 当前 Game.exe 与当前 Lua 对这条包的结构判断完全一致,不需要借助旧 Server 才能确定包体。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

GMT+8, 2026-10-24 13:57 , Processed in 0.025830 second(s), 27 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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