[Parity][motion-input][S1][R] 按区域 ID 判断"怪物是不是 NPC":城里任何怪物都会同时发 0x04 + 0x2F + 0x13,并在本地立即弹出 NPC 菜单;城外的 NPC 被当成敌人 #589

Closed
opened 2026-10-02 11:42:43 +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 公认行为。

来源审计项:motion-input#9 — [S1][R] 9. 按区域 ID 判断"怪物是不是 NPC":城里任何怪物都会同时发 0x04 + 0x2F + 0x13,并在本地立即弹出 NPC 菜单;城外的 NPC 被当成敌人

  • 位置:command-mapper.ts:516-544(城镇分支)、:545-565(城外分支);world/client-world.ts:901-903(noteOutgoingCommand 收到 'NpcInit' 时设置 npcId);session/online-session.ts:395-397 → :1133-1141(MoveToUnit/NpcInit/Interact 走 forwardCommandToAdapter,不经过限流,并立即 note);ui-model/hud-model.ts:976-992(只要 npcId 有值且 window === 'none' 就 openNpcMenu)
  • 代码:const isTownArea = this.world.areaId === 1 || … || this.world.areaId === 109,然后一次性发出 MoveToUnit + NpcInit + Interact
  • 原版:
    • 服务器处理对怪物的 0x13:按 D2Common_10399 计算距离,≤6 才交互;6 到 9 之间代为走近并设置 InteractData;≥9 什么都不做(V-src PlrMsg.cpp:486-532)。
    • 0x2F 要求每个坐标轴上的距离都 ≤10(PlrMsg.cpp:2709-2741,配合 sub_6FC83C60,:1158-1178)。
    • 能否交互由 monstats 的 npc / interact 列决定(V-data)。城外 interact=1 的有 izualghost #406、drehyaiced #528、ancientstatue1-3 #538-540,还有 Duriel 巢穴里的 tyrael1 #251;城内的 act2guard1 #203 npc=1 但 interact 为空,roguehire #271 的 npc 为空。
    • 城镇 ID 列表本身与 DRLG_IsTownLevel 一致(V-src DrlgDrlg.cpp:808-822),但和 common/world/scene-population.ts:56 的 isTownLevel 重复了一份。
  • 影响:
    • (a) 远处点 NPC 时,服务器会忽略 0x13 和 0x2F,角色只会走过去,对话不会打开;可本地菜单已经弹出(人没到、服务器也没建立会话,之后的 0x38 等请求都无效)。
    • (b) 城外的 Izual 幽魂、冰冻的 Anya、Duriel 巢穴里的 Tyrael 被当成敌人:默认 Attack 下只会走过去,换了其他技能则会攻击他们,任务对话无法触发。
    • (c) 在城里点卫兵、佣兵、召唤物,也会发 NpcInit/Interact。
  • 建议:用 monstats 的 interact(以及 npc)判断。先发 0x04 走近,到交互距离后再发 0x13。只有收到服务器的 NPC 交互回包后才打开菜单。城镇判断复用 isTownLevel。
  • 已有 issue:—(#558 只涉及佣兵雇佣对话框)
> **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 公认行为。 ### 来源审计项:`motion-input#9` — [S1][R] 9. 按区域 ID 判断"怪物是不是 NPC":城里任何怪物都会同时发 0x04 + 0x2F + 0x13,并在本地立即弹出 NPC 菜单;城外的 NPC 被当成敌人 - 位置:`command-mapper.ts:516-544`(城镇分支)、`:545-565`(城外分支);`world/client-world.ts:901-903`(`noteOutgoingCommand` 收到 `'NpcInit'` 时设置 npcId);`session/online-session.ts:395-397` → `:1133-1141`(MoveToUnit/NpcInit/Interact 走 `forwardCommandToAdapter`,不经过限流,并立即 note);`ui-model/hud-model.ts:976-992`(只要 npcId 有值且 `window === 'none'` 就 `openNpcMenu`) - 代码:`const isTownArea = this.world.areaId === 1 || … || this.world.areaId === 109`,然后一次性发出 `MoveToUnit` + `NpcInit` + `Interact` - 原版: - 服务器处理对怪物的 0x13:按 `D2Common_10399` 计算距离,≤6 才交互;6 到 9 之间代为走近并设置 InteractData;≥9 什么都不做(V-src `PlrMsg.cpp:486-532`)。 - 0x2F 要求每个坐标轴上的距离都 ≤10(`PlrMsg.cpp:2709-2741`,配合 `sub_6FC83C60`,`:1158-1178`)。 - 能否交互由 monstats 的 `npc` / `interact` 列决定(V-data)。城外 interact=1 的有 izualghost #406、drehyaiced #528、ancientstatue1-3 #538-540,还有 Duriel 巢穴里的 tyrael1 #251;城内的 act2guard1 #203 npc=1 但 interact 为空,roguehire #271 的 npc 为空。 - 城镇 ID 列表本身与 `DRLG_IsTownLevel` 一致(V-src `DrlgDrlg.cpp:808-822`),但和 `common/world/scene-population.ts:56` 的 `isTownLevel` 重复了一份。 - 影响: - (a) 远处点 NPC 时,服务器会忽略 0x13 和 0x2F,角色只会走过去,对话不会打开;可本地菜单已经弹出(人没到、服务器也没建立会话,之后的 0x38 等请求都无效)。 - (b) 城外的 Izual 幽魂、冰冻的 Anya、Duriel 巢穴里的 Tyrael 被当成敌人:默认 Attack 下只会走过去,换了其他技能则会攻击他们,任务对话无法触发。 - (c) 在城里点卫兵、佣兵、召唤物,也会发 NpcInit/Interact。 - 建议:用 monstats 的 `interact`(以及 `npc`)判断。先发 0x04 走近,到交互距离后再发 0x13。只有收到服务器的 NPC 交互回包后才打开菜单。城镇判断复用 `isTownLevel`。 - 已有 issue:—(#558 只涉及佣兵雇佣对话框)
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#589
No description provided.