CGAuctionSell 是客户端向元宝市场提交上架请求的封包,用于把珍兽或道具放入寄售栏并指定售价。当前 Game.exe 能确认,这是一条在 type = 1 或 type = 2 时固定 15 字节的 Client -> Server 协议;当前 Lua 服务端会继续做价格、交易限制、寄售栏容量与对象可操作性校验。
包信息
| 项目 |
内容 |
| 封包 ID |
87 |
| 包名 |
CGAuctionSell |
| 方向 |
Client -> Server |
| 对应回包 |
GCAuctionChangeStatus、GCAuctionError、GCAuctionBoxList |
| 作用 |
提交元宝市场上架请求,携带商品类型、目标 GUID、来源槽位和售价 |
包体结构
当前有效类型下固定长度 15 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
type |
uint8 |
商品类型;当前 1=珍兽,2=道具/装备 |
0x01 |
0x08 |
target_guid |
bytes[8] |
目标对象 GUID;type=1 时按 PetGUID 解析,type=2 时按 ItemGUID 解析 |
0x09 |
0x01 |
source_index |
uint8 |
来源槽位;当前客户端道具上架路径会写入物品栏索引,珍兽上架路径固定写 255 |
0x0A |
0x01 |
reserved_flag |
int8 |
保留字节;当前客户端上架发送函数固定写 -1 |
0x0B |
0x04 |
price |
uint32 |
上架售价,单位为元宝 |
当前实际行为
- 当前
Game.exe 中,CGAuctionSell::GetPacketID() 返回 87。
- 当前
Game.exe 中,CGAuctionSell::GetPacketSize() 会先检查 type:
type = 1 时返回 15
type = 2 时返回 15
- 其他值返回
0
- 当前
Game.exe 的 Read() 顺序可以明确确认:
- 先读
type
- 再按
type 分支读取 PetGUID 或 ItemGUID
- 再读
source_index
- 再读
reserved_flag
- 最后读
price
- 当前客户端存在两条明确的发包入口:
Auction::PacketSend_SellPet(param1, param2, param3)
Auction::PacketSend_SellItem(param1, param2, param3)
- 从当前
Game.exe 的发包构造可以确认:
- 珍兽上架时,包内
type = 1
- 道具上架时,包内
type = 2
- 道具上架路径会把第一个参数写入
source_index
- 两条路径都会把
reserved_flag 固定写成 -1
- 当前 Lua 协议定义也已直接使用
source_index 与 reserved_flag 两个明确字段,不再保留 pos 与 unknow_2 的兼容别名。
- 当前 Lua 服务端入口
request:CGAuctionSell() 收包后,会先做基础校验:
- 二级密码是否已解锁
- 账号是否被限制交易
- 售价是否位于允许区间
- 对应类型寄售栏是否已满
- 当前场景服会继续做对象级校验:
type = 1 时检查宠物是否存在、是否可操作、是否带装备
type = 2 时检查道具是否存在、是否可操作、是否为绑定物品
- 之后按售价计算上架手续费,并尝试先扣物、再扣手续费、再写入
.Ybexchange
- 上架成功后,当前服务端会发送:
GCAuctionChangeStatus
GCAuctionBoxList
- 如果寄售栏已满,当前服务端会直接返回
GCAuctionError.SELL_LIST_FULL;其他失败路径则多为提示消息或回滚处理。
- 当前 Lua 主链并没有使用
source_index 与 reserved_flag 参与服务端校验,真正作为上架对象依据的是 GUID 字段。
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 登录服消息入口:
/home/ubuntu/Game2/services/msgagent.lua
- 场景服上架前校验、扣物与回滚:
/home/ubuntu/Game2/services/scene/scenecore.lua
- 元宝市场价格校验与手续费计算:
/home/ubuntu/Game2/lualib/ybmarket_helper.lua
关键代码
当前 Lua 协议解析
packet.CGAuctionSell = {
xy_id = packet.XYID_CG_AUCTION_SELL,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.type = stream:readuchar()
if self.type == 1 then
self.pet_guid = packet.PetGUID.new()
self.pet_guid:bis(stream)
elseif self.type == 2 then
self.item_guid = packet.ItemGUID.new()
self.item_guid:bis(stream)
end
self.source_index = stream:readuchar()
self.reserved_flag = stream:readchar()
self.price = stream:readuint()
end
}
当前 Lua 上架处理入口
function request:CGAuctionSell()
if not ma_func:is_minor_password_is_unlock() then
ma_func:send_operate_result_msg(define.OPERATE_RESULT.OR_NEED_UNLOCKMINORPASSWORD)
return
end
if ma_func:check_right_limit_exchange() then
ma_func:notify_tips("账号限制交易,请联系客服处理")
return
end
local ok, err_msg = ybmarket_helper.validate_price(self.price)
if not ok then
ma_func:notify_tips(err_msg)
return
end
local is_full = skynet.call(".Ybexchange", "lua", "before_sell_check_is_full", my_guid, self.type)
if is_full then
local msg = packet_def.GCAuctionError.new()
msg.result = msg.ERR_CODE.SELL_LIST_FULL
Net:send(msg)
return
end
local item, item_name, take_level = skynet.call(my_scene, "lua", "auction_sell_before_check", my_obj_id, self)
...
end
当前 Game.exe 结论
GetPacketID() = 87;
GetPacketSize() {
if (type == 1) return 15;
if (type == 2) return 15;
return 0;
}
Read(stream) {
read_u8(type);
if (type == 1) {
read_bytes(pet_guid, 8);
} else if (type == 2) {
read_bytes(item_guid, 8);
}
read_u8(source_index);
read_i8(reserved_flag);
read_u32(price);
}
PacketSend_SellPet(index, price, confirm) {
if (confirm == 1) {
packet.type = 1;
packet.pet_guid = GetPetGuidByIndex(index);
packet.source_index = 255;
packet.reserved_flag = -1;
packet.price = price;
SendPacket(packet);
}
}
PacketSend_SellItem(index, price, confirm) {
if (confirm == 1) {
packet.type = 2;
packet.item_guid = GetItemGuidByIndex(index);
packet.source_index = index;
packet.reserved_flag = -1;
packet.price = price;
SendPacket(packet);
}
}
结论
CGAuctionSell 是当前元宝市场的上架请求包,合法类型下总长固定 15 字节。它的核心字段只有四类:商品类型、目标 GUID、来源槽位、售价。当前 Game.exe 已经能明确确认 type = 1 为珍兽、type = 2 为道具/装备;而当前 Lua 服务端真正依赖的是 GUID 与 price,source_index 和 reserved_flag 在现有主链里并不参与上架判定。上架成功后,服务端会同步寄售状态变化并刷新寄售栏列表。
|