[Parity][net-world][S1][R] 0x8E / 0x74(尸体归属)被当成"自己死了",活着时也会弹出死亡遮罩并拦截全部点击;对其他玩家则改写组队/敌对状态 #564

Closed
opened 2026-10-02 11:42:34 +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#3 — [S1][R] F3 0x8E / 0x74(尸体归属)被当成"自己死了",活着时也会弹出死亡遮罩并拦截全部点击;对其他玩家则改写组队/敌对状态

  • 位置:netproto 把两者都解成 Party relation:src/netproto/d2gs/s2c/party.ts:84-97、181-194;src/client/world/client-world.ts:2258-2274(rawRel === 1 && rawUnitId === this.selfId → _isSelfDead = true),以及 2249-2256(CorpseAssign 类型同理);其他玩家走 2276-2312:rawOtherId !== undefined && rawRel === 1 → lootPermit = true、hostile = false
  • 原版:0x8E/0x74 的含义是"玩家 X 的尸体单位 = Y"。D2Game 在以下时刻发 assign=1:复活时在死亡点生成尸体(PlrModes.cpp:497-512 生成独立的 pDeadBody,648 发 0x8E,此时本人已经复活);带着存档尸体进游戏(PlrSave.cpp:1653、PlrSave2.cpp:1201);尸体进入视野(SUnitMsg.cpp:140-145 发 0x74)。尸体被捡回时发 assign=0(PlrModes.cpp:728)(V-src)。也就是说,收到"自己的尸体"恰恰说明本人是活着的。
  • 实测:自己存活时 apply 8E 01 <self=1> <corpse=77>,isSelfDead 变 true;收到 LifeMana(life>0) 后变回 false;再 apply 0x74(自己的尸体进入视野),又变成 true。
  • 影响:死亡后复活回城、或者带尸体重进游戏、或者走回去捡尸体时,屏幕出现"You Have Died"遮罩,hud-manager.ts:1235-1240 / 1530-1535 拦截所有点击,并把点击当成复活请求发出去,直到下一条 life>0 的 0x95 或点击后的本地复位才消失。对其他玩家,尸体包会把他们写进 _party,并清掉敌对、打开拾取许可(PvP 敌对标记丢失)。
  • 建议:0x74/0x8E 单独解成 CorpseAssign{ownerId, corpseId, assign},只用于把尸体单位和主人关联起来(名牌、拾取),不要动 isSelfDead,也不要进组队状态机。
  • 已有 issue:—
> **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#3` — [S1][R] F3 0x8E / 0x74(尸体归属)被当成"自己死了",活着时也会弹出死亡遮罩并拦截全部点击;对其他玩家则改写组队/敌对状态 - 位置:netproto 把两者都解成 `Party relation`:`src/netproto/d2gs/s2c/party.ts:84-97`、`181-194`;`src/client/world/client-world.ts:2258-2274`(`rawRel === 1 && rawUnitId === this.selfId` → `_isSelfDead = true`),以及 `2249-2256`(`CorpseAssign` 类型同理);其他玩家走 `2276-2312`:`rawOtherId !== undefined && rawRel === 1` → `lootPermit = true`、`hostile = false` - 原版:0x8E/0x74 的含义是"玩家 X 的尸体单位 = Y"。D2Game 在以下时刻发 assign=1:复活时在死亡点生成尸体(`PlrModes.cpp:497-512` 生成独立的 `pDeadBody`,`648` 发 0x8E,此时本人已经复活);带着存档尸体进游戏(`PlrSave.cpp:1653`、`PlrSave2.cpp:1201`);尸体进入视野(`SUnitMsg.cpp:140-145` 发 0x74)。尸体被捡回时发 assign=0(`PlrModes.cpp:728`)(V-src)。也就是说,收到"自己的尸体"恰恰说明本人是**活着**的。 - 实测:自己存活时 apply `8E 01 <self=1> <corpse=77>`,`isSelfDead` 变 true;收到 `LifeMana(life>0)` 后变回 false;再 apply 0x74(自己的尸体进入视野),又变成 true。 - 影响:死亡后复活回城、或者带尸体重进游戏、或者走回去捡尸体时,屏幕出现"You Have Died"遮罩,`hud-manager.ts:1235-1240 / 1530-1535` 拦截所有点击,并把点击当成复活请求发出去,直到下一条 life>0 的 0x95 或点击后的本地复位才消失。对其他玩家,尸体包会把他们写进 `_party`,并清掉敌对、打开拾取许可(PvP 敌对标记丢失)。 - 建议:0x74/0x8E 单独解成 `CorpseAssign{ownerId, corpseId, assign}`,只用于把尸体单位和主人关联起来(名牌、拾取),不要动 `isSelfDead`,也不要进组队状态机。 - 已有 issue:—
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#564
No description provided.