86 lines
6.2 KiB
Go
86 lines
6.2 KiB
Go
package methods
|
||
|
||
// Destructible / discard / hangup wire contracts (fresh unhandled-log batch).
|
||
// Client invoke: AskNotifyDestructibleHits (67043150).
|
||
// Client invoke: AskOperateDestructibleObject (67351604).
|
||
// Client notify: AskMoveDestructibleObjects (67341910).
|
||
// WriteDestructibleBrokenInfo order.
|
||
// Client notify: AskBreakDestructibleObjects (67891964).
|
||
// Client notify: AskReadWeaponRedDots (67449888).
|
||
// Client invoke: AskDiscardWeaponByInstanceId (67892019).
|
||
// Client notify: AskDiscardWeapon (67155190).
|
||
// Client notify: AskBreakSkillTimeCurve (67425306).
|
||
// ---------------------------------------------------------------------------------------
|
||
// 第三批轻量回执的返回契约(2026-09-27,见 GameRouter.MiscAcks.cs 第三批注释)。
|
||
//
|
||
// 三个返回体的 wire 布局**全部以客户端 `RPCDeserializeAuto.lua` 的返回值 reader 为准**,
|
||
// 不再照 dump.cs 猜(`dump.cs` 只给字段声明,不给 inline / 7Bit / presence 这些编码细节):
|
||
//
|
||
// | 方法 | lua 返回 reader | 编码结论 |
|
||
// |---|---|---|
|
||
// | `AskTimePanelInfo`(63323227) | `Base.ReadStruct(reader, Auto.Reader[612])` (RPCDeserializeAuto.lua:10868) | **struct = 无顶层 presence 字节** ⇒ `Inline = true` |
|
||
// | `GetUploadObjectUrl`(63757076) | `Base.ReadComplex(reader, Auto.Reader[588])` (:12156) | complex = 顶层 0xFF ⇒ 默认(非 inline) |
|
||
// | `AskItemDestructibleCreate`(67362514) | `reader.ReadUInt64(reader)` (:15250) | 裸 u64,8 字节 LE,无标记 ⇒ 不需要契约 |
|
||
//
|
||
// `Auto.Reader[612]`(= `TimePanelInfo`,dump.cs:1744419 struct)体内只有一个字段:
|
||
// `obj.PersonalTimeSettings = Base.ReadList7Bit(reader, ReadComplex(Auto.Reader[1290]))`
|
||
//
|
||
// ⛑⛑ **`Auto.Reader[1290]`(PersonalTimeSetting)不是空类** —— dump.cs:1751813 把它显示成
|
||
// `public class PersonalTimeSetting {}`(字段被 dumper 丢了),但 lua 的 reader(:34623)明明有
|
||
// `Label(string) / Hour(u32) / Minute(u32)` 三个字段。仓库里 **`TimeWeatherMethods4229938.cs:60`
|
||
// 的 `PersonalTimeSetting4229938` 就是对的**(`ChangePersonalTimeSetting` 已经在用它)。
|
||
// ⇒ 这里**不重新定义**,直接复用那一个;本轮只回空列表,元素一个字节都不用写,
|
||
// 所以字段差异不影响 wire,但注释别再写「空类」。
|
||
//
|
||
// ⛑ 空列表的 wire = `FF 01`:首字节 0xFF 是集合 presence(0x00 才是 null),
|
||
// 第二字节是 **Int7 计数带 +1 偏置**(0 项 ⇒ 写 1)。见 UxWriter.Int7 / UxContract.WriteList。
|
||
// 对照物:`GameRouter.NpcInvite.cs` 的 `UxNullListBody = { 0x00 }` 是「null 列表」,
|
||
// 这里要的是「空列表」(Lua 里 `{}` 是真值,`nil` 不是),两者别混。
|
||
// ---------------------------------------------------------------------------------------
|
||
// AskTimePanelInfo 的返回体:TimePanelInfo(struct,无顶层标记)+ 一个 7Bit 列表。
|
||
//
|
||
// GetUploadObjectUrl 的返回体:UploadObjectUrl(dump.cs:1753916,complex)。
|
||
// 字段顺序严格按 `Auto.Reader[588]`:Url(string) → ExpireTimeStamp(u32) → ObjectKey(string)。
|
||
//
|
||
// ---------------------------------------------------------------------------------------
|
||
// 第五批:B 组 5 条「要真返回值」的契约(2026-09-27 23:4x,见 GameRouter.MiscAcks.cs 第五批)。
|
||
//
|
||
// 同样以 `RPCDeserializeAuto.lua` 的返回值 reader 为准(硬规则 209):
|
||
//
|
||
// | 方法 | id | reader | 编码 |
|
||
// |---|---|---|---|
|
||
// | `AskPutMapPinFar` | 63522219 | `Base.ReadStruct(Reader[625])` | struct **无标记**;`PinData{u64 Id, UXVector3 PinPos}`,PinPos 也是 struct(3×f32,无标记) |
|
||
// | `GetCharacterRandomDialog` | 63175540 | `reader.ReadUInt32()` | 裸 u32,无标记 ⇒ 不需要契约 |
|
||
// | `StartWorldLifeGame` | 67864009 | `reader.ReadUInt64()` | 裸 u64,无标记 ⇒ 不需要契约 |
|
||
// | `AskBasketballOperatorAction` | 67028937 | `reader.ReadUInt64()` | 裸 u64,无标记 ⇒ 不需要契约 |
|
||
// | `AskWushuTournamentSeasonData` | 63308286 | `Base.ReadComplex(Reader[611])` | complex 顶层 `FF`;`Rounds` 是 `ReadList7Bit(ReadComplex(Reader[1664]))` |
|
||
//
|
||
// ⛑ **空列表也要占 2 字节**(`FF 01` = presence + 偏置 Int7 计数 0+1),所以字段必须存在,
|
||
// 不能因为"反正没数据"就把 `Rounds` / `OpponentBestStars` 省掉。
|
||
// ---------------------------------------------------------------------------------------
|
||
// AskPutMapPinFar 的返回体:PinData(struct,无顶层标记)+ 内嵌 UXVector3(也是 struct)。
|
||
//
|
||
// AskWushuTournamentSeasonData 的返回体:WushuTournamentSeasonClientInfo(complex,顶层 0xFF)。
|
||
// 字段顺序严格按 `Auto.Reader[611]`。
|
||
//
|
||
// `Auto.Reader[1664]`(一轮战绩)。本轮只回空列表,元素一个字节都不写。
|
||
// `Auto.Reader[1663]`(对手星数)。
|
||
// ---------------------------------------------------------------------------------------
|
||
// 第六批:`AskMultiverseStatus`(63799383) 的返回体(2026-09-29,见 GameRouter.MiscAcks.cs 第六批)。
|
||
//
|
||
// lua 返回 reader = `Base.ReadComplex(reader, Auto.Reader[288])`(RPCDeserializeAuto.lua:12296)
|
||
// ⇒ **complex,顶层 0xFF 存在标记**(非 inline)。`Auto.Reader[288]` 字段顺序(:33636):
|
||
// MultiverseStatusDict = ReadDict(u32 → byte) ⇒ presence + **Int32** 计数(不是 Int7)
|
||
// ShowLastMutiId = u32
|
||
// MainPageTabStatusDict = ReadDict(u32 → byte)
|
||
// ActivityStatusDict = ReadDict(u32 → byte)
|
||
// CurMutiPanelId = u32
|
||
//
|
||
// ⛑ `ReadDict` 的计数是 `reader.ReadInt32`(RPCDeserializeBase.lua:162),**没有** Int7 的 +1 偏置
|
||
// ⇒ 这里必须用 `UxCountEncoding.Int32`,写成 Int7 会多读一个字节、把后面的 u32 带偏。
|
||
// ⛑ 本服没有多世界(Multiverse)数据 ⇒ 三个字典全回**空字典**。空字典也占 5 字节(`FF` + Int32 计数 0),
|
||
// 所以字段一个都不能省。整帧实测 24B(`_ux_wire_check` PASS):
|
||
// `FF` + (`FF00000000`) + `00000000` + (`FF00000000`) + (`FF00000000`) + `00000000`。
|
||
// ---------------------------------------------------------------------------------------
|
||
// AskMultiverseStatus 的返回体:MultiverseStatusInfo(complex,顶层 0xFF)。
|