GCAuctionBoxList 是元宝市场“我的寄售盒”回包。客户端发出空包 CGAuctionBoxList(85) 后,msgagent 会立即向 .Ybexchange 拉取当前角色的寄售盒数据,并把道具寄售栏与珍兽寄售栏一起打包回客户端。
包信息
| 项目 |
内容 |
| 封包 ID |
816 |
| 包名 |
GCAuctionBoxList |
| 方向 |
GC 游戏服 -> 客户端 |
| 包长 |
变长 |
| 对应请求 |
CGAuctionBoxList(85) |
| 当前 Lua 协议定义 |
/home/ubuntu/Game2/services/game/packet.lua |
| 当前 Lua 发送落点 |
/home/ubuntu/Game2/services/msgagent.lua |
| 作用 |
返回当前角色的元宝市场寄售盒快照 |
当前 Game.exe 可确认,这条包的长度按实际存在的栏位动态累加:
packet_size = 2 + Σ(每个存在栏位的固定头 48 字节 + 详情区长度)
包体结构
包头
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x02 |
slot_mask |
uint16 |
15 个寄售栏位的存在位图;位 1..10 表示道具栏,位 11..15 表示珍兽栏 |
每个存在栏位的固定头
| 偏移 |
长度 |
字段 |
类型 |
含义 |
+0x00 |
0x04 |
id |
int32 |
寄售记录 ID |
+0x04 |
0x01 |
status_code |
int8 |
寄售状态码;现役 Lua 明确按 on_sale/off/buyed 写 1/2/3 |
+0x05 |
0x01 |
slot_index |
int8 |
当前寄售栏位号 |
+0x06 |
0x04 |
on_sale_date |
uint32 |
上架时间 |
+0x0A |
0x04 |
total_price |
int32 |
寄售总价 |
+0x0E |
0x1E |
seller_name |
char[30] |
卖家名,当前 Lua 发送前按 GBK 定长写入 |
+0x2C |
0x04 |
seller_guid |
int32 |
卖家角色 GUID |
详情区
| 条件 |
结构 |
栏位 1..10 |
固定头后接 ItemInfo |
栏位 11..15 |
固定头后接 GCDetailAttrib_Pet |
当前实际行为
- 当前
Game.exe 的 Read() / Write() 先处理 slot_mask,再按位图顺序依次解析 15 个寄售栏位。
- 当前 Lua
bis() 和 bos() 与这一结构完全一致:
1..10 按道具寄售栏处理;
11..15 按珍兽寄售栏处理。
- 现役发送链很直接:
request:CGAuctionBoxList() 调用 send_auction_box_list()
send_auction_box_list() 通过 .Ybexchange:get_box_list(guid) 拉取寄售盒
- 然后构造
GCAuctionBoxList 并发送给客户端
- 当前 Lua 发送时,状态码已可以明确命名为
status_code:
on_sale -> 1
off -> 2
buyed -> 3
- 其他未知状态回退为
0
- 当前 Lua 发送时,第二个单字节字段写的是当前栏位号,因此可以明确命名为
slot_index。
seller_name 与 seller_guid 在当前结构里既出现在道具寄售栏,也出现在珍兽寄售栏。
- 当前发送链还会把
.Ybexchange 返回值缓存到 auction_box_list,供后续领取元宝、取回寄售物等请求复用。
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 请求入口与发送:
/home/ubuntu/Game2/services/msgagent.lua
- 上游数据源:
.Ybexchange 服务的 get_box_list
关键代码
当前 Lua 协议定义
packet.GCAuctionBoxList = {
xy_id = packet.XYID_GC_AUCTION_BOX_LIST,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.flag = stream:readushort()
for i = 1, 10 do
local bit = (0x1 << (i - 1))
if (bit & self.flag) == bit then
local merchandise = {}
merchandise.id = stream:readint()
merchandise.unknow_1 = stream:readchar()
merchandise.unknow_2 = stream:readchar()
merchandise.on_sale_date = stream:readuint()
merchandise.total_price = stream:readint()
merchandise.seller_name = stream:read(0x1E)
merchandise.seller_guid = stream:readint()
merchandise.item = packet.ItemInfo.new()
merchandise.item:bis(stream)
self.merchandise_list[i] = merchandise
end
end
for i = 11, 15 do
...
end
end
}
当前 Lua 发送状态与栏位号
if merchadise.status == "on_sale" then
stream:writechar(merchadise.unknow_1 or 1)
elseif merchadise.status == "off" then
stream:writechar(merchadise.unknow_1 or 2)
elseif merchadise.status == "buyed" then
stream:writechar(merchadise.unknow_1 or 3)
else
stream:writechar(merchadise.unknow_1 or 0)
end
stream:writechar(i)
当前 Lua 请求入口
local function send_auction_box_list()
local my_guid = ma_func:get_guid()
local merchadise_list = skynet.call(".Ybexchange", "lua", "get_box_list", my_guid)
local msg = packet_def.GCAuctionBoxList.new()
msg.merchadise_list = merchadise_list
auction_box_list = merchadise_list
Net:send(msg)
end
function request:CGAuctionBoxList()
send_auction_box_list()
end
结论
GCAuctionBoxList(816) 是当前元宝市场寄售盒的现役变长回包,结构已经可以明确写成:
slot_mask
- 每个存在栏位的固定头
id + status_code + slot_index + on_sale_date + total_price + seller_name + seller_guid
- 后接
ItemInfo 或 GCDetailAttrib_Pet
其中最关键的命名收敛点有两个:
- 原 Lua 里的
unknow_1 可以明确解释为 status_code。
- 原 Lua 里的
unknow_2 可以明确解释为 slot_index。
|