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

洱海月 v0-07-0300 封包解析:ID 087 CGAuctionSell(元宝市场上架请求)

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

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

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

×

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 在现有主链里并不参与上架判定。上架成功后,服务端会同步寄售状态变化并刷新寄售栏列表。

您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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