This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/pkg/protocol/methods/extraction_methods4229938.go
T

92 lines
5.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package methods
//
// 搜打撤(ExtractionShooter / 不要抬头!)在 4229938 上的 wire 契约。
// 两份依据,冲突时以第一条为准:
// 1. 客户端 RPCDeserializeAuto.lua 的 reader 本体 —— Reader[297] 物品基类 / Reader[1050]
// 容器元素 / Reader[530] 容器;这三个是逐字节抄下来的。
// 2. 捐赠端 handoff AI_HANDOFF不要抬头2.md §6。
// ⛑ 四条都要照做(写错一条整包报废):
// - complex 嵌套 = 1 字节 marker:null 写 0x00,有值写该契约的 TypeMark。
// 多态靠 marker 区分 —— 物品基类 1、容器元素 2。
// - 字典 = marker + Int32 count(默认就是 Int32,别改成 7bit)。
// - 列表 = marker + 7bit(count+1);空列表 = FF 01,不是 FF 00。
// - ⛑⛑ 顶层推送契约一律 Inline = true:每条 midToReader 都是
// reader.ReadUInt32(reader) / ReadUInt64 直接开局,不读 root 标记。
// 唯一例外是 67410186 的返回值 —— 它写的是 Base.ReadComplex(reader, Auto.Reader[530])
// ⇒ 那一处的 ExtractionShooterContainerInfo 必须带那个 FF(它是 complex 目标)。
// 「搜打撤的物品为什么不能用错的 TypeMark」:Auto.Dispatch[297] 按 marker 跳表,
// 写成 0xFF 会落到 undefined 分支,客户端整包 deserialize failed。
//
//
// 背包里的物品(Reader[297] 的派生类 ExtractionShooterBagItemInfo)。
// 与物品基类唯一的区别是 complex marker —— 背包/容器内通行的是 1,不是 0xFF。
//
//
// 容器里的物品(Reader[1050] = Concrete[297][2])—— 在基类前面多了一个
// Pid2SearchFinishTimeDict。
// 这个字典是搜索动画的开关:空字典 = 未搜索 = 客户端把图标藏起来。
// 而且时间戳必须是未来的 —— 客户端 StartSearchStateTracker 里
// waitSeconds < 0 会被钳成 0,过去时间戳 ⇒ wait(0) 空转、动画播不出来。
//
//
// 容器内容(Reader[530])。CfgId 必须是配置表里的容器行 id —— 客户端拿它取容量和图标,
// 填 0 会得到「格子正确但整箱空」。
//
// ------------------------------------------------------------------ push
// SyncExtractionShooterContainerInfo(68820459) —— 容器内容的推送形态。
//
// SyncExtractionShooterSetItemInfo(64091558) —— 单件进包。
// ⛑ 物品必须包成复杂值且 marker=1(ExtractionShooterBagItemInfo)。
//
//
// SyncExtractionShooterChangeBagCapacity(64119720) —— 扩容后的真实格数。
// ⛑ 列表是 [x, y] 两个 i32,不是「每格写一个 1」。写成后者客户端会把容量读成
// 「宽 = 格子数、高 = 1」,面板排布全错。
//
// SyncExtractionShooterClearBag(64282046) —— 整包重推前先清空。
// SyncExtractionShooterSortBagResult(64226140) —— 排序后的整包。
// SyncExtractionShooterBagExpansionUnlocked(64359472)。
// SyncExtractionShooterTokenCount(64840255)。
// SyncExtractionShooterEvacuationPlayerState(64763956) —— 裸 u8。
// ------------------------------------------------------------------ settlement
//
// 单个角色(spirit)的战斗数据统计(Auto.Reader[1334])。
// 我们只有出场那一条、而且恒发空表,所以这里不填字段 —— 一旦填错字段布局,
// 客户端会在幽灵数据上做算术然后把整棵 UI 树崩掉(参考 handoff §11 第 4 条)。
// 什么时候要真数据:按抓包样本逐个字段补,不要对着 dump.cs 的空壳猜。
//
//
// 结算主体(Auto.Reader[474]):
// u32 EnterRaidTime + f64 BattleTime + list7<complex[1334]> + u32 ElementEffectCount。
// 这是 complex 目标(SyncRaidSettlement 里写的是 ReadComplex),
// 所以它必须带 marker(默认 0xFF),与顶层那些 Inline 契约相反。
//
// ------------------------------------------------------------------ requests
//
// 搜打撤的客户端 → 服务端请求体。
// ⛑️⛑️ 每个契约都必须是 [UxContract(Inline = true)]:C2S 请求体是「裸标量」,
// 客户端 SerializerHelper.*_Serializer 只挨个 WritePrimitive,不写对象标记。
// 漏了 Inline 会让 UxSerializer.Deserialize 先吃掉一个字节当标记(期望 0xFF),
// 于是 8 字节的实例 id 被读成「标记 + 只剩 7 字节」⇒ 越界抛异常 ⇒
// TryGetArgs 把这个异常 catch 掉并返回 false(见 UxRpcMessage.TryGetArgs)
// ⇒ 处理器拿到全默认值:容器实例 id 恒为 0、全世界共用一份快照。
// ⛑️ 字段顺序就是线上顺序,不要按"看起来合理"调整:顺序取自
// ClientToGameDelegate.lua / ClientToGameSceneDelegate.lua 的 *_Serializer。
// 本版的所有字段顺序都是捐赠端 实机暴露后订正过的(handoff §14.8)——
// 第一版移植时按"常见布局"猜的槽位那两条是错的:
// · ShiftContainerItemToSlot 只有 5 个字段、没有 isRotated,
// 第 4 个是槽位组包 id(99952004)、第 5 个是槽位下标;
// · ShiftSlotItemToContainer 是 bag 在前,u64 container 在第三个。
// 这两处写错的表现是「容器里的东西搬不出来 / 装备永远落到错误格」。
//
// ShiftItem(63749738, 25B):六种右键动作全走这一条,区别只是 destBag。
// RaidSplitItem(67597775, 25B):bag | container(u64) | x | y | count | isRotated。
//
// SyncRaidSettlement(68995324) —— 副本结算。
// ⛑ 线格式 u64 instance + bool isWin + complex[474] + u32 closeTime,
// 零战斗数据时恒 32 字节(handoff §6.7),这就是笔算校验:
// 8 + 1 + (FF 1 + u32 4 + f64 8 + 空 list7 2 + u32 4) + 4 = 32。
// 改动这个结构后如果字节数变了,一定是 dosing 错了地方(多半是把 complex 写成 Inline)。
//