fix(ui): #372 — Chat filter labels resolve from their real table 0x2300000D

The 13 ID_ChatOption_TextFilter_* labels (and their _Desc tooltips) live
in string table 0x2300000D, not the 0x23000003 options table the section
headers and slider labels use. Dat-verified: the targeted sweep missed
(0x23000001-0A), the control key resolved ('Auto Target' — machinery
fine), and the exhaustive all-tables sweep (ProbeFilterLabelHome, now a
permanent env-gated probe) hit exactly once: 0x2300000D -> 'Combat'. The
initializer decomp confirms the hash KEYS are the symbol names verbatim
(the vftable-member operands at 0x006f04cd are the known pooled-string
artifact); only the research doc's table attribution was inferred rather
than dat-verified — corrected in §8.

All 13 rows now render their captions instead of the honest-fallback
blanks the first connected gate saw. Full Release suite green (one
Core.Net loss-simulation timing flake on the first run, green targeted
and on rerun).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-11 12:28:43 +02:00
parent 057d8cd703
commit 348d794359
3 changed files with 66 additions and 3 deletions

View file

@ -81,6 +81,17 @@ public static class ChatOptionsPageController
private const uint StringTableId = 0x23000003u;
/// <summary>#372 (2026-08-11): the <c>ID_ChatOption_TextFilter_*</c>
/// label/tooltip family lives in its OWN string table — an exhaustive
/// live-DAT sweep (OptionsPanelLiveMountProbeTests.ProbeFilterLabelHome)
/// found the keys resolve ONLY in <c>0x2300000D</c>, not the
/// <c>0x23000003</c> options table the section headers and slider labels
/// use (the research doc's §8 table-attribution was inferred, not
/// dat-verified — the keys themselves were always right). All 13 filter
/// rows rendered blank-captioned at the first connected gate because of
/// this one wrong table id.</summary>
private const uint FilterStringTableId = 0x2300000Du;
/// <summary>The slider leaf inside either slider row template's subtree.</summary>
private const uint SliderElementId = 0x1000021Cu;
@ -461,9 +472,9 @@ public static class ChatOptionsPageController
continue; // research doc §5.2: the main window has no Gameplay row.
FilterRowSpec rowSpec = FilterRows[i];
string? label = resolveString(StringTableId, DatStringResolver.ComputeHash(rowSpec.RetailLabelKey));
string? label = resolveString(FilterStringTableId, DatStringResolver.ComputeHash(rowSpec.RetailLabelKey));
string? tooltip = resolveString(
StringTableId, DatStringResolver.ComputeHash(rowSpec.RetailLabelKey + "_Desc"));
FilterStringTableId, DatStringResolver.ComputeHash(rowSpec.RetailLabelKey + "_Desc"));
if (label is null)
Console.WriteLine(
$"[D.2b] ChatOptionsPageController: filter row label "