diff --git a/TankiOffline/app/src/jsMain/kotlin/App/Main.kt b/TankiOffline/app/src/jsMain/kotlin/App/Main.kt index b6eecc1..4542125 100644 --- a/TankiOffline/app/src/jsMain/kotlin/App/Main.kt +++ b/TankiOffline/app/src/jsMain/kotlin/App/Main.kt @@ -191,7 +191,14 @@ object Replay { T.Pings++ continue } - val R = SpaceFrame.DecodeBody(Body, DownlinkRegistry.ByMethodId, Aliases) + val R = try { + SpaceFrame.DecodeBody(Body, DownlinkRegistry.ByMethodId, Aliases) + } catch (E: Throwable) { + // 单帧异常(如 nullmap 位不足)只记一条错误,不中断整轮回放 + T.Errors++ + println(" ⚠ $Path:${E.message}") + continue + } T.Records += R.Records.size T.Short += R.ShortCommandCount T.Unknown += R.UnknownMethodIds.size diff --git a/TankiOffline/net/src/jsMain/kotlin/Net/Wire/ModelCodec.kt b/TankiOffline/net/src/jsMain/kotlin/Net/Wire/ModelCodec.kt index 35ed80d..69b9417 100644 --- a/TankiOffline/net/src/jsMain/kotlin/Net/Wire/ModelCodec.kt +++ b/TankiOffline/net/src/jsMain/kotlin/Net/Wire/ModelCodec.kt @@ -4,9 +4,9 @@ // · 必填字段:直接读写 // · opt :先从 nullmap 取 1 位(1=null,0=有值),有值才读写 T // · list/map:varint 个数 + 逐项 -// · enum:按 i32 处理。真正的 EnumCodecInfo(module_24635 的 vn → Kt)读 0 字节, -// 但字段表里的 enum<...> 是提取器从 Wt(...) 工厂抽出来的(Wt 为「varint 计数 + 元素」的数组型 codec), -// 回放实测按 i32 与原始字节吻合,改成 0 会让记录回编码变短 +// · enum:按 i32 处理。源码上 EnumCodecInfo(module_24635 的 vn → Kt)读写都是空实现, +// 但整套改成 0 字节会让回放退化(railgun-battle 多 8 条错 + 回编码不一致 + nullmap 位不足), +// 说明表里标成 enum<...> 的字段还有别的东西没建模,宽度不能单独改 // · string/bytes:varint 长度 + 原始字节 // · Vector3:3 × f32 package Net.Wire diff --git a/TankiOffline/tools/GenerateProtocol.py b/TankiOffline/tools/GenerateProtocol.py index 3f27583..881b01c 100644 --- a/TankiOffline/tools/GenerateProtocol.py +++ b/TankiOffline/tools/GenerateProtocol.py @@ -162,10 +162,10 @@ def DecodeExpr(Node) -> str: if Kind == "map": return "Wire.ReadMap(R, { " + DecodeExpr(Node[1]) + " }, { " + DecodeExpr(Node[2]) + " })" if Kind == "enum": - # 实测口径:这里按 i32 读。注意真正的 EnumCodecInfo(module_24635 的 vn → Kt)是 0 字节, - # 但字段表里的 enum<...> 是提取器从 Wt(...) 工厂抽出来的(Wt 是「varint 计数 + 元素」的数组型 - # codec,与 ListCodecInfo 同形),语义还没定死;回放证明按 i32 与原始字节吻合, - # 改成 0 字节会立刻造成记录回编码变短(railgun-battle/s2c_0541)。 + # 实测口径:按 i32 读。源码上 EnumCodecInfo(module_24635 的 vn → Kt)读写都是空实现, + # 但把它改成 0 字节后回放立刻退化(railgun-battle 多出 8 条错、出现回编码不一致、 + # 并在 space-3074457345817190050 触发“nullmap 位不足”), + # 说明现有字段表里标成 enum<...> 的字段还有别的东西没建模,宽度不能单独改。 return "R.ReadInt()" if Kind == "model": return Node[1] + "Codec.Decode(R, N)"