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

洱海月 v0-07-0300 封包解析:ID 210 CGAskItemInfo(查询背包物品详情)

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

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

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

×

CGAskItemInfo 是客户端向游戏服请求某个背包格详细物品信息的定长请求包。

当前版本里,这条包结构非常简单,只有一个背包格索引和一个请求回显标识。服务端收到后会从角色道具背包中取出对应格子的物品原始数据,并通过 GCItemInfo 回传。

包信息

项目 内容
封包 ID 210
包名 CGAskItemInfo
方向 CG 客户端 -> 游戏服
包长 6
当前 Lua 协议定义 /home/ubuntu/Game2/services/game/packet.lua
当前服务端入口 /home/ubuntu/Game2/services/msgagent.lua
当前场景处理 /home/ubuntu/Game2/services/scene/scenecore.lua 的 ask_item_info()
主要作用 请求查询指定背包格物品详情,并等待 GCItemInfo 回包

当前 Game.exe 可直接确认:

GetPacketID()   = 210;
GetPacketSize() = 6;
Read()          = sub_1405C2170;
Write()         = sub_1405C21C0;
Execute()       = sub_140328170;

包体结构

偏移 长度 字段 类型 含义
0x00 0x02 bagIndex uint16 当前角色道具背包格索引
0x02 0x04 askid uint32 请求回显标识,服务端会原样回填到 GCItemInfo.askid

总长度固定为:

2 + 4 = 6

当前实际行为 / 模式说明

  • 当前 Lua 服务端收到 CGAskItemInfo 后,会直接把请求转交场景层 ask_item_info() 处理。
  • 场景层会先创建一条 GCItemInfo 回包,并把请求里的:
    • askid
    • bagIndex

原样带回响应。

  • 随后服务端调用:
obj:get_prop_bag():get_item(bag_index)

从当前角色的道具背包中读取该格物品。

  • 如果该格没有物品,当前实现会构造一个空 item_cls.new() 占位数据,并把 GCItemInfo.unknow_1 置为 define.INVAILD_ID,表示该格为空。
  • 如果该格存在物品,则回包中会带上 copy_item_raw_data_with_lock_state(item) 的完整道具原始数据。
  • 这条包本身不负责修改物品状态,只负责查询并回传详情。

因此,CGAskItemInfo 在当前版本里的实际定位,就是“客户端查询背包格物品信息”的轻量请求包。

服务端落点

  • 协议定义:
    • /home/ubuntu/Game2/services/game/packet.lua
  • 请求入口:
    • /home/ubuntu/Game2/services/msgagent.lua
  • 场景处理:
    • /home/ubuntu/Game2/services/scene/scenecore.lua

当前 Lua 转发关系非常直接:

function request:CGAskItemInfo()
    skynet.call(my_scene, "lua", "ask_item_info", my_obj_id, self)
end

场景层核心处理如下:

function scenecore:ask_item_info(whos, ask)
    local ret = packet_def.GCItemInfo.new()
    ret.askid = ask.askid
    ret.bagIndex = ask.bagIndex
    ret.unknow_1 = 0
    ret.unknow_2 = 0

    local obj = self.objs[whos]
    obj:refresh_locked_item_unlock_state(false)

    local item = obj:get_prop_bag():get_item(ask.bagIndex) or item_cls.new()
    local raw_data = obj:copy_item_raw_data_with_lock_state(item)
    ret.item = raw_data

    if item:get_index() == define.INVAILD_ID then
        ret.unknow_1 = define.INVAILD_ID
    end

    self:send2client(obj, ret)
end

关键代码

当前 Lua 协议定义

packet.CGAskItemInfo = {
    xy_id = packet.XYID_CG_ASK_ITEM_INFO,
    ctor = function(self) end,
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.bagIndex = stream:readushort()
        self.askid = stream:readuint()
    end,
    bos = function(self)
        local stream = bostream.new()
        stream:writeushort(self.bagIndex)
        stream:writeuint(self.askid)
        return stream:get()
    end
}

当前 Game.exe 关键结论

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

Read(stream) {
    read_u16(bagIndex);
    read_u32(askid);
    return 1;
}

Write(stream) {
    write_u16(bagIndex);
    write_u32(askid);
    return 1;
}

GetPacketSize() {
    return 6;
}

Execute() {
    return 2;
}

其中 Read() 在当前 Game.exe 里对应两次固定长度读取:

read(stream, this + 0x18, 2);
read(stream, this + 0x1C, 4);

这与当前 Lua 的 ushort + uint32 完全对齐。

结论

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

  1. 这是一条固定长度 6 字节的客户端请求包。
  2. 包体只有两个字段:
    • bagIndex
    • askid
  3. bagIndex 用于定位当前角色道具背包中的目标格子。
  4. askid 是请求回显标识,服务端会原样带回到 GCItemInfo.askid,用于客户端侧做请求响应对应。
  5. 当前真实业务处理在 scenecore:ask_item_info(),作用是查询背包格物品详情,不负责消耗、移动或修改物品。
  6. 当前 Game.exe 与当前 Lua 对这条包的结构判断完全一致,不需要借助旧 Server 作为结论依据。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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