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

洱海月 v0-07-0300 封包解析:ID 054 CGAuctionSearch(元宝市场搜索)

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

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

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

×

CGAuctionSearch 是客户端向元宝交易市场提交搜索条件的请求包,用于分页查询寄售中的珍兽、道具或装备。

包信息

项目 内容
封包 ID 054
包名 CGAuctionSearch
方向 客户端 -> 游戏服
长度 变长
对应回包 GCAuctionSearch
回包 ID 704
作用 按类型、分类、排序、关键字和页码查询元宝市场列表

包体结构

当前 Game.exe 的 GetPacketSize() 返回 name_len + 12,Lua 协议定义也按同样顺序解析。

偏移 长度 字段 类型 含义
0x00 0x01 type int8 搜索大类;当前服务端直接拿它匹配 ybmarket.type
0x01 0x04 sub_type uint32 分类筛选编码,当前会拆成三级子类条件
0x05 0x01 order uint8 排序方式
0x06 0x04 name_len uint32 关键字字节长度
0x0A name_len name char[name_len] 搜索关键字,当前 Lua 按 GBK 转 UTF-8
0x0A + name_len 0x02 page int16 页码,当前每页固定 10 条

总长度:

12 + name_len 字节

当前实际行为

  • Game.exe 中 sub_1405EC2D0() 直接返回 54,sub_140202700() 返回 name_len + 12,可确认当前客户端类的包 ID 与变长公式。
  • Game.exe 中 sub_1405C76A0() 依次读取 1 + 4 + 1 + 4 + name_len + 2 字节,与 Lua 的 type / sub_type / order / name / page 完全一致。
  • 当前 Lua 入口 request:CGAuctionSearch() 直接把整包转发给 .Ybexchange:search(self),然后立即构造 GCAuctionSearch 回包。
  • 当前搜索默认条件是 { type = request.type, status = "on_sale" }。
  • 当 request.name ~= "" 时,搜索条件会被改写成 { item_name = { $regex = request.name }, status = "on_sale" },原本的 type 过滤会被覆盖掉。
  • 当前 sub_type 会被拆成三段:first = sub_type // 10000、second = (sub_type % 10000) // 100、last = sub_type % 100;每段只要不是 0 或 1,就会附加到 query_tbl["sub_type.1/2/3"]。
  • 当前排序值只有 4 种显式分支:
    • 1:价格从低到高
    • 2:价格从高到低
    • 3:名称从小到大
    • 4:名称从大到小
  • 当前页码直接参与 skip = (request.page - 1) * 10 计算,没有在服务端做范围钳制。
  • 当前回包 GCAuctionSearch 会写回 msg.type = self.type、msg.order = self.order、msg.cur_page_num = self.page,但 msg.sub_type 被硬编码成 117,并不会回传请求里的真实 sub_type。
  • 当前 GCAuctionSearch.bos() 里,type == 1 走珍兽详情序列化,其他类型统一走 ItemInfo 序列化。因此从当前服务端逻辑推断,type = 1 对应珍兽,非 1 对应物品/装备。

服务端落点

  • 协议定义:/home/ubuntu/Game2/services/game/packet.lua
  • 请求入口:/home/ubuntu/Game2/services/msgagent.lua
  • 交易市场服务入口:/home/ubuntu/Game2/services/ybexchange/ybexchange.lua
  • 交易市场搜索逻辑:/home/ubuntu/Game2/services/ybexchange/ybexchange_core.lua

关键代码

客户端 Game.exe 关键方法:

__int64 sub_1405EC2D0()
{
  return 54;
}

__int64 __fastcall sub_140202700(__int64 a1)
{
  return *(unsigned int *)(a1 + 36) + 12LL;
}

__int64 __fastcall sub_1405C76A0(__int64 a1, __int64 a2)
{
  sub_1403F9B00(a2, (char *)(a1 + 24), 1u);
  sub_1403F9B00(a2, (char *)(a1 + 28), 4u);
  sub_1403F9B00(a2, (char *)(a1 + 32), 1u);
  sub_1403F9B00(a2, (char *)(a1 + 36), 4u);
  sub_1403F9B00(a2, (char *)(a1 + 40), *(_DWORD *)(a1 + 36));
  sub_1403F9B00(a2, (char *)(a1 + 104), 2u);
  return 1;
}

当前 Lua 协议与请求入口:

packet.CGAuctionSearch = {
    xy_id = packet.XYID_CG_AUCTION_SEARCH,
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.type = stream:readchar()
        self.sub_type = stream:readuint()
        self.order = stream:readuchar()
        local len = stream:readuint()
        self.name = stream:read(len)
        self.name = gbk.toutf8(self.name)
        self.page = stream:readshort()
    end
}

function request:CGAuctionSearch()
    local result = skynet.call(".Ybexchange", "lua", "search", self)
    local msg = packet_def.GCAuctionSearch.new()
    msg.type = self.type
    msg.sub_type = 117
    msg.order = self.order
    msg.cur_page_num = self.page
    msg.page_total = result.page_total
    msg.merchandise_list = result.merchandise_list
    Net:send(msg)
end

当前交易市场搜索逻辑:

function ybexchange_core:search(request)
    local query_tbl = {type = request.type, status = "on_sale"}
    if request.name ~= "" then
        query_tbl = {["item_name"] = {["$regex"] = request.name}, status = "on_sale"}
    end
    self:trans_search_sub_type(request, query_tbl)

    if request.order == 1 then
        sorter = {["price"] = 1}
    elseif request.order == 2 then
        sorter = {["price"] = -1}
    elseif request.order == 3 then
        sorter = {["item_name"] = 1}
    elseif request.order == 4 then
        sorter = {["item_name"] = -1}
    end

    local skip = (request.page - 1) * 10
    ...
end

结论

CGAuctionSearch 是当前元宝市场的变长搜索请求包,结构稳定为 type + sub_type + order + name_len + name + page,总长公式为 12 + name_len。

当前版本最需要记住的不是字段名本身,而是三条实际行为:

  • name 非空时会覆盖默认的 type 条件,搜索会退化成“按名称 + 状态 + 子类”的组合查询。
  • sub_type 在服务端被拆成三级分类条件,而回包阶段却被硬编码成 117,不会原样带回。
  • page 和 order 当前都直接信任客户端输入,服务端只按固定每页 10 条做分页计算。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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