[Parity][motion-input][S1][H] 本地玩家预测速度写死为 9 / 13.5,FRW、体力耗尽、减速等都没有接入 #587

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#7 — [S1][H] 7. 本地玩家预测速度写死为 9 / 13.5,FRW、体力耗尽、减速等都没有接入

  • 位置:src/client/motion/predictor.ts:29-31(常量)、:151-153(默认值)、:159-166(getEffectiveSpeedSubTilesPerSec)、:172-174(setFasterRunWalkPercent,全仓没有调用方);session/online-session.ts:300(new LocalMovementPredictor() 不传任何配置)
  • 代码:export const D2_BASE_WALK_SUBTILES_PER_SEC = 9.0 // 6 yards/s * 1.5 sub-tiles/yard;return Math.max(1.5, base + D2_BASE_WALK_SUBTILES_PER_SEC * (effFrw / 100))
  • 原版:
    • 速度 = charstats WalkVelocity << 8 × nVelocityPercent / 100。
    • nVelocityPercent = 递减后的 item_fastermovevelocity + STAT_VELOCITYPERCENT,下限 25(Units.cpp:1672-1693)。递减公式是 v*150/(v+150),负值同样套用,按 C 整数除法截断(Units.cpp:1231-1252)。
    • 跑步时临时加上 STAT_VELOCITYPERCENT = 100*RunVelocity/WalkVelocity − 100(Units.cpp:701-712、732-735)。
    • charstats 中所有职业都是 WalkVelocity 6 / RunVelocity 9,RunDrain 为 20,Assassin #7 为 15(V-data charstats.txt)。
    • 每帧位移为 ((a2*vel)>>6)*dir>>12(FP16,dir 向量长度 4096,Step.cpp:23-153),a2≤0 时取 1024(PathMisc.cpp:1121-1153)。如果玩家的 a2 就是 1024,步行为 0.375 子格/帧,即 9.375 子格/秒,跑步为 14.0625 子格/秒。a2 的实际取值未核实,见待确认。
  • 影响:
    • 穿 FRW 装备,或有 Burst of Speed、Vigor、Feral Rage 时,本地比服务器慢。
    • 体力耗尽(服务器强制步行),或被冰冻、Decrepify 减速时,本地比服务器快。
    • 两种情况都会让位置门(LifeMana 0x95/0x18 检查)判定超差,触发重同步请求或 0x15 回拉,正常游玩中经常能看到。
    • FRW 的叠加方式本身(walkBase × eff / 100 加到 base 上)与原版一致;但负 FRW 没有套递减公式(predictor.ts:164),下限 1.5 子格/秒也不等于原版的 25%(:165)。
    • 9.0 / 13.5 是"6 / 9 码每秒 × 1.5"的近似值,绕过了 charstats,换 mod 就会出错。
  • 建议:用 charstats WalkVelocity / RunVelocity 加上本地玩家的 stat(item_fastermovevelocity、velocitypercent、体力)实时计算速度;跑还是走以服务器的体力状态为准;按 25 Hz 整帧步进。
  • 已有 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 公认行为。 ### 来源审计项:`motion-input#7` — [S1][H] 7. 本地玩家预测速度写死为 9 / 13.5,FRW、体力耗尽、减速等都没有接入 - 位置:`src/client/motion/predictor.ts:29-31`(常量)、`:151-153`(默认值)、`:159-166`(`getEffectiveSpeedSubTilesPerSec`)、`:172-174`(`setFasterRunWalkPercent`,全仓没有调用方);`session/online-session.ts:300`(`new LocalMovementPredictor()` 不传任何配置) - 代码:`export const D2_BASE_WALK_SUBTILES_PER_SEC = 9.0 // 6 yards/s * 1.5 sub-tiles/yard`;`return Math.max(1.5, base + D2_BASE_WALK_SUBTILES_PER_SEC * (effFrw / 100))` - 原版: - 速度 = charstats `WalkVelocity << 8` × `nVelocityPercent / 100`。 - `nVelocityPercent` = 递减后的 `item_fastermovevelocity` + `STAT_VELOCITYPERCENT`,下限 25(`Units.cpp:1672-1693`)。递减公式是 `v*150/(v+150)`,负值同样套用,按 C 整数除法截断(`Units.cpp:1231-1252`)。 - 跑步时临时加上 `STAT_VELOCITYPERCENT = 100*RunVelocity/WalkVelocity − 100`(`Units.cpp:701-712`、`732-735`)。 - charstats 中所有职业都是 WalkVelocity 6 / RunVelocity 9,RunDrain 为 20,Assassin #7 为 15(V-data `charstats.txt`)。 - 每帧位移为 `((a2*vel)>>6)*dir>>12`(FP16,dir 向量长度 4096,`Step.cpp:23-153`),a2≤0 时取 1024(`PathMisc.cpp:1121-1153`)。如果玩家的 a2 就是 1024,步行为 0.375 子格/帧,即 9.375 子格/秒,跑步为 14.0625 子格/秒。a2 的实际取值未核实,见待确认。 - 影响: - 穿 FRW 装备,或有 Burst of Speed、Vigor、Feral Rage 时,本地比服务器慢。 - 体力耗尽(服务器强制步行),或被冰冻、Decrepify 减速时,本地比服务器快。 - 两种情况都会让位置门(LifeMana 0x95/0x18 检查)判定超差,触发重同步请求或 0x15 回拉,正常游玩中经常能看到。 - FRW 的叠加方式本身(walkBase × eff / 100 加到 base 上)与原版一致;但负 FRW 没有套递减公式(`predictor.ts:164`),下限 1.5 子格/秒也不等于原版的 25%(`:165`)。 - 9.0 / 13.5 是"6 / 9 码每秒 × 1.5"的近似值,绕过了 charstats,换 mod 就会出错。 - 建议:用 charstats `WalkVelocity` / `RunVelocity` 加上本地玩家的 stat(`item_fastermovevelocity`、`velocitypercent`、体力)实时计算速度;跑还是走以服务器的体力状态为准;按 25 Hz 整帧步进。 - 已有 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#587
No description provided.