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 对应物品,并校验它确实是珍兽装备。
- 如果目标珍兽不存在、处于锁定/交易状态,或者目标就是当前出战珍兽,当前实现都会直接拒绝后续处理。
- 当前场景服不会直接使用客户端上传的
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,不需要继续保留成不明确字段名。