[Parity][net-world][S1][R] 0x0D 被解成"停止移动",丢掉了 mode 代码:其他玩家死亡、受击、格挡全部看不到,自己的 DT 也永远不播(#548 只修了一半) #567

Closed
opened 2026-10-02 11:42:39 +00:00 by troytt · 0 comments
Owner

1.13c 客户端保真度审计立项(基准快照:7bd1090 / main @ 77a20c7)

证据标记说明:V-data = 1.13c MPQ 数据表 (.txt / animdata.d2 / .tbl / pal.pl2);V-src = D2MOO 逆向源码;V-bin = 1.13c DLL 反汇编;K = 1.13c 公认行为。

来源审计项:net-world#6 — [S1][R] F6 0x0D 被解成"停止移动",丢掉了 mode 代码:其他玩家死亡、受击、格挡全部看不到,自己的 DT 也永远不播(#548 只修了一半)

  • 位置:src/netproto/d2gs/s2c/movement.ts:41-59(byte 6 的 mode 代码和 byte 12 的生命百分比都直接丢弃,输出 UnitMove mode:'stop');src/client/session/online-session.ts:1597-1598(selfMode = isSelfDead ? (selfUnit?.mode === 0 ? 0 : 17) : ...);src/client/world/client-world.ts:1848、1947(把 PlrMode 16 = S4 当成死亡态)
  • 原版:D2MOO PlrMsg.cpp:85-107 的 stru_6FD30708(按 PlrMode 下标):DT → 0x0D 代码 0x08;GH → 0x0D 代码 0x06;BL → 0x0D 代码 0x12;DD → 0x0D 代码 0x09;NU/TN → 0x0D 代码 0x07。sub_6FC82010(PlrMsg.cpp:172-176,GH/BL/DD)和 sub_6FC820C0(178-191,DT)对所有客户端都发,包括本人;sub_6FC821C0(NU/TN,193-200)不发给本人。包结构见 D2PacketDef.h:653:byte 0x0C 是 UNITS_GetCurrentLifePercentage(玩家为 0..100)(V-src)。plrmode.txt #16 = S4(V-data)。
  • 实测:别的玩家收到 0x0D 代码 8 或 9 → mode 1、lifePct 128(死人画成站着);自己收到 0x0D 代码 8 → mode 1,isSelfDead=false。
  • 影响:别的玩家死了还站着、没有倒地和尸体,受击和格挡动作也不播;自己死亡只能等 0x95 life=0 才直接跳到 DD,没有 DT 倒地过程(全仓库没有任何地方产生玩家 mode 0)。另外 S4 被当成死亡态,S4 期间(如 Left Hand Throw)收到的移动包不再改 mode。
  • 建议:netproto 把 0x0D 解成 UnitMode{code→PlrMode 映射, hitClass, lifePct(0..100)};客户端按 DT → DD 播放;死亡判定只认 0/17,去掉 16。
  • 已有 issue:#548(部分:12 → 17 已修,DT 与其他玩家死亡仍缺)
> **1.13c 客户端保真度审计立项**(基准快照:`7bd1090` / `main @ 77a20c7`) > 证据标记说明:`V-data` = 1.13c MPQ 数据表 (`.txt` / `animdata.d2` / `.tbl` / `pal.pl2`);`V-src` = D2MOO 逆向源码;`V-bin` = 1.13c DLL 反汇编;`K` = 1.13c 公认行为。 ### 来源审计项:`net-world#6` — [S1][R] F6 0x0D 被解成"停止移动",丢掉了 mode 代码:其他玩家死亡、受击、格挡全部看不到,自己的 DT 也永远不播(#548 只修了一半) - 位置:`src/netproto/d2gs/s2c/movement.ts:41-59`(byte 6 的 mode 代码和 byte 12 的生命百分比都直接丢弃,输出 `UnitMove mode:'stop'`);`src/client/session/online-session.ts:1597-1598`(`selfMode = isSelfDead ? (selfUnit?.mode === 0 ? 0 : 17) : ...`);`src/client/world/client-world.ts:1848`、`1947`(把 PlrMode 16 = S4 当成死亡态) - 原版:D2MOO `PlrMsg.cpp:85-107` 的 `stru_6FD30708`(按 PlrMode 下标):DT → 0x0D 代码 0x08;GH → 0x0D 代码 0x06;BL → 0x0D 代码 0x12;DD → 0x0D 代码 0x09;NU/TN → 0x0D 代码 0x07。`sub_6FC82010`(`PlrMsg.cpp:172-176`,GH/BL/DD)和 `sub_6FC820C0`(`178-191`,DT)对所有客户端都发,**包括本人**;`sub_6FC821C0`(NU/TN,`193-200`)不发给本人。包结构见 `D2PacketDef.h:653`:byte 0x0C 是 `UNITS_GetCurrentLifePercentage`(玩家为 0..100)(V-src)。`plrmode.txt` #16 = S4(V-data)。 - 实测:别的玩家收到 0x0D 代码 8 或 9 → mode 1、lifePct 128(死人画成站着);自己收到 0x0D 代码 8 → mode 1,`isSelfDead=false`。 - 影响:别的玩家死了还站着、没有倒地和尸体,受击和格挡动作也不播;自己死亡只能等 0x95 life=0 才直接跳到 DD,没有 DT 倒地过程(全仓库没有任何地方产生玩家 mode 0)。另外 S4 被当成死亡态,S4 期间(如 Left Hand Throw)收到的移动包不再改 mode。 - 建议:netproto 把 0x0D 解成 `UnitMode{code→PlrMode 映射, hitClass, lifePct(0..100)}`;客户端按 DT → DD 播放;死亡判定只认 0/17,去掉 16。 - 已有 issue:#548(部分:12 → 17 已修,DT 与其他玩家死亡仍缺)
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#567
No description provided.