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

洱海月 v0-07-0300 封包解析:ID 491 CGPetUseEquip(给珍兽穿装备)

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

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

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

×

CGPetUseEquip 是旧版客户端里用于把人物背包中的珍兽装备穿到指定珍兽身上的请求包。

当前版本里,这条包的关键输入是“背包格索引 + 珍兽 GUID”;客户端还会附带一个目标珍兽装备栏位,但场景服不会直接信任该值,而是按装备自身配置重新计算最终穿戴位置。

包信息

项目 内容
封包 ID 491
包名 CGPetUseEquip
方向 CG 客户端 -> 场景服
固定包长 10
直接回包 GCPetUseEquipResult
回包 ID 528
主要作用 请求把人物背包中的指定珍兽装备穿到目标珍兽身上
当前 Lua 入口 request:CGPetUseEquip()
当前场景服处理 scenecore:char_use_pet_equip()

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

GetPacketID() = 491;
GetPacketSize() = 10;

包体结构

这条包是固定长度包,结构为 uint8 + uint8 + PetGUID(8)。

偏移 长度 字段 类型 含义
0x00 0x01 bag_index uint8 人物背包中的珍兽装备格索引
0x01 0x01 equip_point uint8 客户端请求穿入的珍兽装备栏位
0x02 0x04 pet_guid_high uint32 珍兽 GUID 高 32 位
0x06 0x04 pet_guid_low uint32 珍兽 GUID 低 32 位

当前实际行为 / 模式说明

  • 当前 Lua 请求入口是 request:CGPetUseEquip(),随后转到场景服 scenecore:char_use_pet_equip()。
  • 场景服实际强依赖的输入是:
    • bag_index
    • pet_guid
  • 场景服会先从人物背包取出 bag_index 对应物品,并校验它确实是珍兽装备。
  • 如果目标珍兽不存在、处于锁定/交易状态,或者目标就是当前出战珍兽,当前实现都会直接拒绝后续处理。
  • 当前场景服不会直接使用客户端上传的 equip_point 作为最终落点,而是读取装备配置里的 equip_point 重新计算真正的珍兽装备栏位。
  • 只要计算出的栏位位于 define.PET_EQUIP.PEQUIP_CAP ~ define.PET_EQUIP.PEQUIP_SOUL 范围内,场景服就会把这件装备交换到对应珍兽装备容器位置。
  • 成功后返回 GCPetUseEquipResult,其中 equip_point 和 bag_index 都以服务端最终结果回填。
  • 当前客户端发送辅助函数里,equip_point == 5 会额外检查角色等级是否达到 85 级;这对应 define.PET_EQUIP.PEQUIP_SOUL 的魂器栏位。

服务端落点

这条包在当前项目里的关键位置如下:

  • 协议定义:
    • /home/ubuntu/Game2/services/game/packet.lua
  • 请求入口:
    • /home/ubuntu/Game2/services/msgagent.lua
  • 场景服处理:
    • /home/ubuntu/Game2/services/scene/scenecore.lua
  • 珍兽装备栏位常量:
    • /home/ubuntu/Game2/lualib/define.lua

关键代码

当前 Lua 协议定义

packet.CGPetUseEquip = {
    xy_id = packet.XYID_CG_PET_USE_EQUIP,
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.bag_index = stream:readuchar()
        self.equip_point = stream:readuchar()
        self.pet_guid = packet.PetGUID.new()
        self.pet_guid:bis(stream)
    end
}

当前 Lua 请求入口

function request:CGPetUseEquip()
    skynet.call(my_scene, "lua", "char_use_pet_equip", my_obj_id, self)
end

当前场景服处理

function scenecore:char_use_pet_equip(who, use)
    local bag_pos = use.bag_index
    local guid = pet_guid.new()
    guid:set(use.pet_guid.m_uHighSection, use.pet_guid.m_uLowSection)

    local bag_container = obj:get_prop_bag_container()
    local pet_equip = bag_container:get_item(bag_pos)
    if not pet_equip or not pet_equip:is_pet_equip() then
        return
    end

    local dest_index = pet_equip:get_base_config().equip_point
    if not dest_index
    or dest_index < define.PET_EQUIP.PEQUIP_CAP
    or dest_index > define.PET_EQUIP.PEQUIP_SOUL then
        return
    end

    local pet_equip_container = pet_detail:get_equip_container()
    local isok = item_operator:exchange_item(bag_container, bag_pos, pet_equip_container, dest_index)
end

当前客户端关键结论

Game.exe 的 CGPetUseEquip::Read/Write 明确表明这条包的顺序是两个 1 字节字段后接 8 字节 PetGUID:

read(a1 + 24, 1);
read(a1 + 25, 1);
read(a1 + 26, 8);

进一步结合客户端发送辅助函数可以确认:

  • 第 1 个字节对应背包格索引
  • 第 2 个字节对应目标珍兽装备栏位

其中发送前还有一条明显的客户端限制:

if (a3 == 5 && level < 85)

这说明第 2 个参数对应 PEQUIP_SOUL = 5 的魂器栏位请求。

结论

CGPetUseEquip 在当前旧版项目中的最终语义已经可以明确确定:

  • bag_index 是人物背包中的珍兽装备来源格
  • equip_point 是客户端请求的目标珍兽装备栏位
  • pet_guid 是目标珍兽 GUID

其中真正决定最终穿戴到哪个栏位的,是服务端读取装备配置后计算出来的 equip_point,不是客户端上传值本身。

因此,这条包里原先常见的 from / to 命名可以直接收敛为 bag_index / equip_point,不需要继续保留成不明确字段名。

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

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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