[Parity][render][S1][H][R] OVERLAY_METADATA 是自造的"状态→overlay"表:帧数、偏移、光照、混合方式与 states.txt / overlay.txt 全部不符 #603

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

来源审计项:render#2 — [S1][H][R] OVERLAY_METADATA 是自造的"状态→overlay"表:帧数、偏移、光照、混合方式与 states.txt / overlay.txt 全部不符

  • 位置:src/client/view/unit-drawables.ts:204-225(表),:509-547(state → overlay 路径,这是唯一的"按状态画 overlay"路径),:446、:456、:469、:474、:488、:493(用 ov.overlayId 查同一张表)

  • 代码:

    8: { overlayId: 8, token: 'Salvation', totalFrames: 16, blendMode: 'additive', yOffset: 4, lightRadius: 12, lightColor: [255, 240, 180] },
    const meta = OVERLAY_METADATA[stateId]   // L518,每帧对 unit.states 逐个查
    
  • 原版(V-data states.txt 的 overlay1..4 列 + overlay.txt):

    stateId(states.txt 行) 代码 meta 原版
    1 freeze 'Freeze' 15 帧 + 光 8 (110,175,255) overlay1..4 全空,只有 colorpri 100 / colorshift 108 / light 150,215,255
    2 poison 'Poison' 12 帧 overlay 全空,colorpri 95 / colorshift 104 / light 128,255,128
    8 resistall 'Salvation' 16 帧,yOff 4,光 12 aura_resistall_front + aura_resistall_back(overlay.txt #9/#10):20 帧,AnimRate 16,Trans 3,Radius 6,211,148,255;back 行 PreDraw=1
    9 amplifydamage 14 帧,yOff −42,光 8 (255,90,60) curseamplifydamage(#128):24 帧,Height1-4 = 14/0/−14/−60,Radius 6,255,64,64
    10/20/88 frozen/chilling/shiverarmor 16 帧,光 10 frozenarmor/chillarmor/shiverarmor(#38-40):24 帧,Radius 13,200,200,255
    16 enchant 16 帧 + 光 10 overlay 全空
    28 conviction 16 帧,光 12 convictionfront(#120,Filename null,2 帧)+ convictionback(#121,21 帧,AnimRate 6,PreDraw 1,Radius 0)
    30 energyshield 16 帧,yOff −36,光 11 energyshield(#86):ManaShieldBall 8 帧,AnimRate 8,Trans 5,Radius 0
    32/51 battleorders/battlecommand 16 帧,光 12 #155/#160:20 帧,AnimRate 8,Radius 0
    33 might 16 帧,光 12 aura_might_front/back(#11/#12):15 帧,Xoffset 4,Radius 0;back PreDraw 1
    49 fanaticism 16 帧,光 13 fanaticismfront/back(#116/#117):30 帧,AnimRate 6,Radius 0
    60/61 decrepify/lowerresist 14 帧,yOff −42,光 8/9 #136/#137:24/29 帧,Height 14/0/−14/−60,Radius 6,0,0,255
    101 holyshield 16 帧 + 光 11 overlay 全空

    其他问题:

    • 实际绘制时,world-renderer 用 overlayArtMap 里的小写别名去找图(overlays-meta.ts:23245-23652:"might"→MIGHT_FRONT、"salvation"→SALVATION_FRONT、"fanaticism"→FANATICISM_BACK……),所以成对的 front/back 只能画出其中一张。
    • PreDraw(back 层应画在单位身后)虽已载入 CANONICAL_113C_OVERLAYS.preDraw,但没有任何渲染代码使用;overlay 一律 sortY = worldY + 1 画在单位前面。
    • Height1-4 没有载入。
    • L446 用 ov.overlayId 查这张"按 stateId 建键"的表,但 client-world 里的 overlayId 是一个自增计数器(client-world.ts:325、:446)。L519 也用 overlayId === stateId 去重,计数器值恰好等于某个 stateId 时会误伤。
  • 影响:

    • 冻结、中毒、Enchant、Holy Shield 的单位身上出现原版没有的 overlay(找不到图时会报 missing art),并且一定会加上一盏自造的光(光照与图是否找到无关,L535-545)。
    • 光环、诅咒、护甲类 overlay 的帧数、高度、混合方式、光照半径和颜色都与原版不同;front/back 只画一半,层次也错了。
    • client-world 把诅咒 overlay 按一次性挂上(client-world.ts:807 attachUnitOverlay(m, curseOverlay, false)),所以诅咒持续期间头顶那个循环图标,实际上只能靠这张自造表来显示。
  • 建议:删掉 OVERLAY_METADATA。改为 stateId → states.txt.overlay1..4 → overlay.txt 行,全部参数取自该行(Frames、AnimRate、Trans、PreDraw、Xoffset/Yoffset、Height1-4 按单位高度档、Radius/InitRadius、RGB)。state 没有 overlay 就不画。overlay 的标识用 overlay.txt 行号,不要用计数器。

  • 已有 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 公认行为。 ### 来源审计项:`render#2` — [S1][H][R] `OVERLAY_METADATA` 是自造的"状态→overlay"表:帧数、偏移、光照、混合方式与 states.txt / overlay.txt 全部不符 - 位置:`src/client/view/unit-drawables.ts:204-225`(表),`:509-547`(state → overlay 路径,这是唯一的"按状态画 overlay"路径),`:446`、`:456`、`:469`、`:474`、`:488`、`:493`(用 `ov.overlayId` 查同一张表) - 代码: ```ts 8: { overlayId: 8, token: 'Salvation', totalFrames: 16, blendMode: 'additive', yOffset: 4, lightRadius: 12, lightColor: [255, 240, 180] }, const meta = OVERLAY_METADATA[stateId] // L518,每帧对 unit.states 逐个查 ``` - 原版(V-data `states.txt` 的 overlay1..4 列 + `overlay.txt`): | stateId(states.txt 行) | 代码 meta | 原版 | |---|---|---| | 1 freeze | 'Freeze' 15 帧 + 光 8 (110,175,255) | **overlay1..4 全空**,只有 colorpri 100 / colorshift 108 / light 150,215,255 | | 2 poison | 'Poison' 12 帧 | **overlay 全空**,colorpri 95 / colorshift 104 / light 128,255,128 | | 8 resistall | 'Salvation' 16 帧,yOff 4,光 12 | `aura_resistall_front` + `aura_resistall_back`(overlay.txt #9/#10):20 帧,AnimRate 16,Trans 3,Radius 6,211,148,255;back 行 PreDraw=1 | | 9 amplifydamage | 14 帧,yOff −42,光 8 (255,90,60) | `curseamplifydamage`(#128):24 帧,Height1-4 = 14/0/−14/−60,Radius 6,255,64,64 | | 10/20/88 frozen/chilling/shiverarmor | 16 帧,光 10 | `frozenarmor`/`chillarmor`/`shiverarmor`(#38-40):24 帧,Radius 13,200,200,255 | | 16 enchant | 16 帧 + 光 10 | **overlay 全空** | | 28 conviction | 16 帧,光 12 | `convictionfront`(#120,Filename `null`,2 帧)+ `convictionback`(#121,21 帧,AnimRate 6,PreDraw 1,Radius 0) | | 30 energyshield | 16 帧,yOff −36,光 11 | `energyshield`(#86):ManaShieldBall 8 帧,AnimRate 8,**Trans 5**,Radius 0 | | 32/51 battleorders/battlecommand | 16 帧,光 12 | #155/#160:20 帧,AnimRate 8,Radius 0 | | 33 might | 16 帧,光 12 | `aura_might_front/back`(#11/#12):15 帧,Xoffset 4,Radius 0;back PreDraw 1 | | 49 fanaticism | 16 帧,光 13 | `fanaticismfront/back`(#116/#117):30 帧,AnimRate 6,Radius 0 | | 60/61 decrepify/lowerresist | 14 帧,yOff −42,光 8/9 | #136/#137:24/29 帧,Height 14/0/−14/−60,Radius 6,0,0,255 | | 101 holyshield | 16 帧 + 光 11 | **overlay 全空** | 其他问题: - 实际绘制时,world-renderer 用 `overlayArtMap` 里的小写别名去找图(`overlays-meta.ts:23245-23652`:`"might"→MIGHT_FRONT`、`"salvation"→SALVATION_FRONT`、`"fanaticism"→FANATICISM_BACK`……),所以成对的 front/back 只能画出其中一张。 - `PreDraw`(back 层应画在单位身后)虽已载入 `CANONICAL_113C_OVERLAYS.preDraw`,但没有任何渲染代码使用;overlay 一律 `sortY = worldY + 1` 画在单位前面。 - `Height1-4` 没有载入。 - L446 用 `ov.overlayId` 查这张"按 stateId 建键"的表,但 client-world 里的 `overlayId` 是一个自增计数器(`client-world.ts:325`、`:446`)。L519 也用 `overlayId === stateId` 去重,计数器值恰好等于某个 stateId 时会误伤。 - 影响: - 冻结、中毒、Enchant、Holy Shield 的单位身上出现原版没有的 overlay(找不到图时会报 missing art),并且一定会加上一盏自造的光(光照与图是否找到无关,L535-545)。 - 光环、诅咒、护甲类 overlay 的帧数、高度、混合方式、光照半径和颜色都与原版不同;front/back 只画一半,层次也错了。 - client-world 把诅咒 overlay 按一次性挂上(`client-world.ts:807` `attachUnitOverlay(m, curseOverlay, false)`),所以诅咒持续期间头顶那个循环图标,实际上只能靠这张自造表来显示。 - 建议:删掉 `OVERLAY_METADATA`。改为 `stateId → states.txt.overlay1..4 → overlay.txt 行`,全部参数取自该行(Frames、AnimRate、Trans、PreDraw、Xoffset/Yoffset、Height1-4 按单位高度档、Radius/InitRadius、RGB)。state 没有 overlay 就不画。overlay 的标识用 overlay.txt 行号,不要用计数器。 - 已有 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#603
No description provided.