[Parity][net-world][S1][R] 别的玩家进入视野(0x59 坐标非零)时,selfId 会被改成那个玩家 #563

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#2 — [S1][R] F2 别的玩家进入视野(0x59 坐标非零)时,selfId 会被改成那个玩家

  • 位置:src/netproto/d2gs/s2c/units.ts:208(isSelf: x !== 0 || y !== 0)→ src/client/world/client-world.ts:1765-1782(UnitAssign:if (ev.isSelf === true || this.selfId === 0) { this.selfId = unit.id ... },随后覆盖 _self.name/charClass/x/y)
  • 原版:0x59 本身没有"是不是自己"的标志。D2Game 里唯一的发送点是单位加入客户端视野时(SUnitMsg.cpp:52-55 → SCmd.cpp:605-616 sub_6FC3D1F0),坐标取自 UNITS_GetCoords,对其他玩家就是真实坐标。自己的身份由进游戏时单独发的 0x0B(unit type + GUID)告知(Clients.cpp:413 SendPacketSize06(pClient, 0x0B, nUnitType, nUnitGUID))(V-src)。仓库 14 份 d2gs 抓包里,自己的 0x59 都是 x=y=0,序号 4,早于 0x0B(序号 11–15)(V-data 抓包 tests/fixtures/netproto/*.d2cap)。所以这个启发式正好反了:自己被判成非 self,别人被判成 self。
  • 实测:先按真实顺序 apply 自己的 0x59(id=1, 0,0) 和 0x0B(id=1),selfId=1;再 apply 另一个玩家的 0x59(id=2, 野蛮人, 5120,5130),selfId=2,_self.name="Other",charClass=4,_self.x/y 变成对方坐标。
  • 影响:多人游戏里只要有别的玩家进入视野,本地"自己"就换人了:自身属性、技能、死亡判定、施法回声、摄像机和面板全部错乱。
  • 建议:只用 0x0B(及后续 0x15 等明确针对自身的包)的 GUID 认定 self;0x59 不再推断 isSelf;selfId === 0 时"第一个玩家就是自己"的兜底一并去掉(见 F21)。
  • 已有 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#2` — [S1][R] F2 别的玩家进入视野(0x59 坐标非零)时,`selfId` 会被改成那个玩家 - 位置:`src/netproto/d2gs/s2c/units.ts:208`(`isSelf: x !== 0 || y !== 0`)→ `src/client/world/client-world.ts:1765-1782`(`UnitAssign`:`if (ev.isSelf === true || this.selfId === 0) { this.selfId = unit.id ... }`,随后覆盖 `_self.name/charClass/x/y`) - 原版:0x59 本身没有"是不是自己"的标志。D2Game 里唯一的发送点是单位加入客户端视野时(`SUnitMsg.cpp:52-55` → `SCmd.cpp:605-616 sub_6FC3D1F0`),坐标取自 `UNITS_GetCoords`,对其他玩家就是真实坐标。自己的身份由进游戏时单独发的 0x0B(unit type + GUID)告知(`Clients.cpp:413` `SendPacketSize06(pClient, 0x0B, nUnitType, nUnitGUID)`)(V-src)。仓库 14 份 d2gs 抓包里,自己的 0x59 都是 x=y=0,序号 4,早于 0x0B(序号 11–15)(V-data 抓包 `tests/fixtures/netproto/*.d2cap`)。所以这个启发式正好反了:自己被判成非 self,别人被判成 self。 - 实测:先按真实顺序 apply 自己的 0x59(id=1, 0,0) 和 0x0B(id=1),`selfId=1`;再 apply 另一个玩家的 0x59(id=2, 野蛮人, 5120,5130),`selfId=2`,`_self.name="Other"`,`charClass=4`,`_self.x/y` 变成对方坐标。 - 影响:多人游戏里只要有别的玩家进入视野,本地"自己"就换人了:自身属性、技能、死亡判定、施法回声、摄像机和面板全部错乱。 - 建议:只用 0x0B(及后续 0x15 等明确针对自身的包)的 GUID 认定 self;0x59 不再推断 `isSelf`;`selfId === 0` 时"第一个玩家就是自己"的兜底一并去掉(见 F21)。 - 已有 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#563
No description provided.