CGOpenItemBox 是旧版客户端里用于打开地面物品箱并请求箱内物品列表的请求包。当前 Game.exe 与 Lua 服务端都能确认,这条包只携带一个目标物品箱对象 ID。
包信息
| 项目 |
内容 |
| 封包 ID |
52 |
| 包名 |
CGOpenItemBox |
| 相关回包 |
GCBoxItemList |
| 相关回包 ID |
163 |
| 作用 |
按对象 ID 请求服务端返回指定物品箱当前的物品列表 |
包体结构
当前 Game.exe 与 Lua 协议定义都能确认,这条包固定为 4 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x04 |
m_objID |
uint32 |
目标物品箱对象 ID |
当前 Game.exe 的 GetPacketSize() 返回固定值:
4
当前实际行为 / 模式说明
- 当前
Game.exe 中,CGOpenItemBox::GetPacketID() 返回 52,GetPacketSize() 返回 4。
- 当前
Game.exe 的 Read() / Write() 都只处理一个 uint32 m_objID。
- 当前
Game.exe 的 Execute() 对客户端侧是空处理,直接返回 2。
- 当前 Lua 请求入口
request:CGOpenItemBox() 会把整包转发到场景服 char_open_box_item()。
- 场景服按
m_objID 从当前场景对象表中查找目标对象,并要求目标类型必须是 itembox。
- 命中目标后,服务端会遍历物品箱容器,把当前物品列表组装成
GCBoxItemList(163) 回给客户端。
- 当前
GCBoxItemList 的返回内容包括:
m_objID
size
item_box_type
item_list
- 当前物品箱容器初始化容量为
10,GCBoxItemList 的协议层也会把 size 限制在 10 以内。
- 这条包只负责“打开并查看箱内列表”,实际拾取物品走另一条请求,结果由
GCPickResult(558) 返回。
- 当前
CGOpenItemBox 处理本身不修改物品箱的 open_flag,它只按对象 ID 读取当前箱内内容。
- 掉落箱的可见性由物品箱对象自身控制,当前实现只允许拥有者或无归属箱子对外可见。
服务端落点
- 协议定义:
/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/itembox.lua
关键代码
当前 Lua 协议定义
packet.CGOpenItemBox = {
xy_id = packet.XYID_CG_OPEN_ITEM_BOX,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.m_objID = stream:readuint()
end,
bos = function(self)
local stream = bostream.new()
stream:writeuint(self.m_objID)
return stream:get()
end
}
当前 Lua 请求入口
function request:CGOpenItemBox()
skynet.call(my_scene, "lua", "char_open_box_item", my_obj_id, self)
end
当前 Lua 场景处理
function scenecore:char_open_box_item(me, box_item)
local obj_box = self.objs[box_item.m_objID]
if obj_box then
assert(obj_box:get_obj_type() == "itembox", box_item.m_objID)
local msg = packet_def.GCBoxItemList.new()
local container = obj_box:get_container()
local list = {}
local item_list = container:get_item_data()
for i = 0, container:get_size() do
local item = item_list[i]
if item then
table.insert(list, item:copy_raw_data())
end
end
msg.m_objID = box_item.m_objID
msg.size = #list
msg.item_list = list
msg.item_box_type = obj_box:get_item_box_type()
self:send2client(me, msg)
end
end
当前 Game.exe 的读写与执行结论
GetPacketID() = 52;
GetPacketSize() = 4;
Read(stream) {
read_u32(m_objID);
}
Write(stream) {
write_u32(m_objID);
}
Execute() {
return 2;
}
结论
这条包在当前旧版项目里要记住六点:
CGOpenItemBox 的封包 ID 是 52。
- 它是固定
4 字节结构,只包含一个 uint32 m_objID。
- 这条包的作用是按对象 ID 请求查看指定物品箱当前的物品列表。
- 服务端命中目标后,会返回
GCBoxItemList(163),其中包含箱子对象 ID、箱子类型和当前物品列表。
- 当前物品箱容器最大容量是
10,返回列表也按 10 个槽位上限处理。
- 这条包本身不负责拾取物品,真正的取走流程由后续拾取请求和
GCPickResult(558) 处理。
|