GCBankSwapItem 是当前版本用于通知客户端“钱庄格位发生交换”的结果包。当前 Lua 服务端会在银行内两个格子直接交换位置时发送它;如果只是同类可叠加物品发生合并,则不会发送这条包,而是改走单格刷新或全量刷新。
当前 Game.exe 与当前 Lua 服务端都能确认,这条包固定携带 4 个 uint8 字段:from_bag、to_bag、from_index、to_index。其中当前 Lua 主链实际发送时,from_bag / to_bag 基本都是 2 -> 2,表示钱庄内部换位。
包信息
| 项目 |
内容 |
| 封包 ID |
99 |
| 包名 |
GCBankSwapItem |
| 方向 |
GC 服务端 -> 客户端 |
| 固定包长 |
4 |
| 对应请求 |
CGBankSwapItem |
| 主要作用 |
通知客户端钱庄格位之间发生交换 |
当前 Game.exe 的虚函数结论为:
GetPacketID() = 99;
GetPacketSize() = 4;
包体结构
按当前 Game.exe 与当前 Lua 服务端现状,这条包固定为 4 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
from_bag |
uint8 |
来源容器类型 |
0x01 |
0x01 |
to_bag |
uint8 |
目标容器类型 |
0x02 |
0x01 |
from_index |
uint8 |
来源格索引 |
0x03 |
0x01 |
to_index |
uint8 |
目标格索引 |
当前实际行为 / 模式说明
- 当前 Lua 请求入口
request:CGBankSwapItem() 会把请求转到场景服 char_bank_swap_item()。
- 当前场景服处理固定取的是钱庄容器
bank_bag_container,也就是这条回包在当前 Lua 主链里实际用于“钱庄内部换位”。
- 当
from_index 与 to_index 上都是同类、可叠加、未锁定且绑定状态一致的道具时:
- 服务端优先执行堆叠合并
- 不发送
GCBankSwapItem
- 改走
char_bank_item_info() 或 char_bank_acquire_list() 刷新,避免客户端先做视觉交换再纠正产生闪烁
- 当不是堆叠合并,而是真正的格位交换时:
- 服务端调用
item_operator:exchange_item(...)
- 然后发送
GCBankSwapItem
- 当前普通银行换位路径里,
from_bag 和 to_bag 直接沿用客户端请求值
- 当前银行整理
char_bank_pack_up() 的第一阶段,也会连续发送多条 GCBankSwapItem
- 并且这里会明确写死
from_bag = 2、to_bag = 2
- 说明当前 Lua 现役主链确实把
2 当作钱庄容器
- 当前客户端
Game.exe 的 handler 还能区分多种容器组合:
1 -> 2:背包到钱庄
2 -> 1:钱庄到背包
2 -> 2:钱庄内部换位
- 但按当前 Lua 现状,跨容器存入 / 取出分别主要走的是
GCBankAddItem 和 GCBankRemoveItem,GCBankSwapItem 的主用场景仍是钱庄内部换位通知。
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 请求入口:
/home/ubuntu/Game2/services/msgagent.lua
- 场景处理:
/home/ubuntu/Game2/services/scene/scenecore.lua
- 银行整理复用发送点:
/home/ubuntu/Game2/services/scene/scenecore.lua
关键代码
当前 Lua 协议定义
packet.GCBankSwapItem = {
xy_id = packet.XYID_GC_BANK_SWAP_ITEM,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.from_bag = stream:readuchar()
self.to_bag = stream:readuchar()
self.from_index = stream:readuchar()
self.to_index = stream:readuchar()
end,
bos = function(self)
local stream = bostream.new()
stream:writeuchar(self.from_bag)
stream:writeuchar(self.to_bag)
stream:writeuchar(self.from_index)
stream:writeuchar(self.to_index)
return stream:get()
end
}
当前 Lua 银行内交换发送
function scenecore:char_bank_swap_item(who, swap)
local human = self.objs[who]
local bank_bag_container = human:get_bank_bag_container()
local from_index = swap.from_index
local to_index = swap.to_index
...
item_operator:exchange_item(bank_bag_container, from_index, bank_bag_container, to_index)
local msg = packet_def.GCBankSwapItem.new()
msg.from_bag = swap.from_bag
msg.to_bag = swap.to_bag
msg.from_index = from_index
msg.to_index = to_index
self:send2client(human, msg)
end
当前 Lua 银行整理阶段复用发送
for i = 1, pack_up.size do
local from_index = froms[i]
local to_index = tos[i]
item_operator:exchange_item(bank_bag_container, from_index, bank_bag_container, to_index)
local swap = packet_def.GCBankSwapItem.new()
swap.from_bag = 2
swap.to_bag = 2
swap.from_index = from_index
swap.to_index = to_index
self:send2client(human, swap)
end
当前 Game.exe 的读写与执行结论
GetPacketID() = 99;
GetPacketSize() = 4;
Read(stream) {
read_u8(from_bag);
read_u8(to_bag);
read_u8(from_index);
read_u8(to_index);
}
Write(stream) {
write_u8(from_bag);
write_u8(to_bag);
write_u8(from_index);
write_u8(to_index);
}
Execute() {
return 2;
}
当前客户端 handler 侧的容器组合含义
当前 Game.exe 的 GCBankSwapItem handler 可以区分以下组合:
from_bag = 1, to_bag = 2 -> 背包到钱庄
from_bag = 2, to_bag = 1 -> 钱庄到背包
from_bag = 2, to_bag = 2 -> 钱庄内部换位
这说明字段本身是通用“容器 + 格位”通知结构,但当前 Lua 主链实际发得最多的是 2 -> 2。
结论
GCBankSwapItem 的封包 ID 是 99,固定长度 4 字节。
- 包体结构已经可以明确确定为
from_bag + to_bag + from_index + to_index。
- 当前 Lua 现役主链中,这条包主要用于钱庄内部格位交换通知。
- 同类可叠加道具发生合并时,服务端不会发送这条包,而是直接刷新格子或全量刷新钱庄列表。
- 当前客户端仍保留更通用的容器解释能力,但按当前 Lua 现状,跨容器存取主要由
GCBankAddItem / GCBankRemoveItem 负责。