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

洱海月 v0-07-0300 封包解析:ID 027 CGPlayerShopAcquireShopList(玩家商店列表请求)

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

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

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

×

CGPlayerShopAcquireShopList 是当前 Temp_Release_v0-07-0300 中用于请求玩家商店列表的空包协议。当前 Game.exe 可以明确确认这条请求包没有包体字段;Lua 服务端收到后,会直接返回 GCPlayerShopAcquireShopList(578) 店铺列表数据。

包信息

项目 内容
封包 ID 27
包名 CGPlayerShopAcquireShopList
对应回包 GCPlayerShopAcquireShopList(578)
作用 请求当前玩家商店列表

当前 Game.exe 的虚函数结论为:

CGPlayerShopAcquireShopList
GetPacketID()   = 0x1405EFE80 -> 27;
GetPacketSize() = 0x14046FDC0 -> 0;
Read            = 0x1400BFC70;
Write           = 0x1400BFC70;
Execute thunk   = 0x1405FDBD0 -> 0x140328DE0;

包体结构

当前 Game.exe 中这是一条空包,请求体长度为 0。

偏移 长度 字段 类型 含义
- 0 (无) - 当前请求包无包体字段

当前实际行为

  • 当前 Game.exe 明确保留了 CGPlayerShopAcquireShopList,并将其定义为空包。
  • Lua 消息服收到这条请求后,会转发到场景服的 char_player_shop_acquire_shop_list。
  • 当前场景服不会读取任何请求字段,而是直接组装 GCPlayerShopAcquireShopList 回包。
  • 该回包在当前请求链路中包含:
    • npc_id = define.INVAILD_ID
    • com_factor = playershopmanager:get_com_factor()
    • shop_infos = playershopmanager:get_shop_infos({ human = human })
  • 因此当前这条请求的真实效果是:向客户端回发“当前所有已挂牌玩家店铺列表”。
  • playershopmanager:get_shop_infos() 在当前实现里会遍历全部 player_shops,只保留 is_listed_player_shop(shop) 的店铺。
  • 如果传入当前玩家对象,还会先同步该玩家的收藏店铺状态,再写入每个店铺条目的 is_in_favor。
  • 同一条 GCPlayerShopAcquireShopList 回包还会被 NPC 脚本层复用:
    • DispatchPlayerShopList() 会下发 npc_id = targetId 的普通店铺列表
    • DispatchPlayerShopSaleOutList() 会下发售出店铺列表,并额外设置 unknow = 1
  • 从当前 Game.exe 可确认 GCPlayerShopAcquireShopList 的长度公式是 13 + shop_num * 256,说明每个 shop_info 条目在协议层是固定 256 字节块。

服务端落点

  • 协议定义:/home/ubuntu/Game2/services/game/packet.lua
  • 请求入口:/home/ubuntu/Game2/services/msgagent.lua
  • 场景处理:/home/ubuntu/Game2/services/scene/scenecore.lua
  • 列表组装:/home/ubuntu/Game2/lualib/playershopmanager.lua
  • NPC 脚本复用:/home/ubuntu/Game2/lualib/script_base.lua

关键代码

当前 Game.exe 请求包结构

__int64 sub_1400BFC70()
{
  return 1;
}

当前 Lua 请求入口

function request:CGPlayerShopAcquireShopList()
    skynet.call(my_scene, "lua", "char_player_shop_acquire_shop_list", my_obj_id, self)
end

当前 Lua 场景处理

function scenecore:char_player_shop_acquire_shop_list(who, psa)
    local obj_me = self.objs[who]
    send_player_shop_acquire_shop_list(self, obj_me)
end

当前 Lua 回包组装

local function send_player_shop_acquire_shop_list(scene, human)
    local msg = packet_def.GCPlayerShopAcquireShopList.new()
    msg.npc_id = define.INVAILD_ID
    msg.com_factor = playershopmanager:get_com_factor()
    msg.shop_infos = playershopmanager:get_shop_infos({ human = human })
    scene:send2client(human, msg)
end

当前 Lua 店铺信息来源

function playershopmanager:get_shop_infos(opts)
    opts = opts or {}
    local human = opts.human
    if human then
        ...
        human:update_favorite_shop_guids(valid_shop_guids)
    end
    local shop_infos = {}
    for i, shop in ipairs(self.player_shops) do
        if is_listed_player_shop(shop)
            and (not opts.only_on_sale or shop:get_status() == shop.STATUS.STATUS_PLAYER_SHOP_ON_SALE) then
            table.insert(shop_infos, build_shop_info(shop, i, opts.sale_out_list, human))
        end
    end
    return shop_infos
end

结论

  1. CGPlayerShopAcquireShopList 的封包 ID 是 27,当前 Game.exe 中固定长度为 0,属于空包请求。
  2. 当前 Lua 服务端不会从请求体读取任何参数,而是直接进入玩家商店列表回包流程。
  3. 这条请求的主回包是 GCPlayerShopAcquireShopList(578),当前请求链路下会返回全量已挂牌店铺列表、当前商会系数和收藏状态。
  4. 当前 GCPlayerShopAcquireShopList 在协议层是动态长度包,长度公式为 13 + shop_num * 256。
  5. 因此这条包应归类为玩家商店列表刷新请求,而不是携带筛选条件的业务参数包。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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