every dialog is the reference's own, and the trainer loads on demand

- every dialog is the reference's own: `StaticPopup.xml` + `StaticPopup.lua` load off the player's chain, and 0308's engine with its 37 dialogs leaves `UiPanels.xml`; all 76 of the reference's dialogs are the stock table's, 28 of which no file of ours had ever registered (the resurrect family among them); the nine hidden listener frames that existed only because benilla once had no `UIParent_OnEvent` come home to it verbatim from UIParent.lua, and the seven files that were nothing but a dialog and its driver are deleted; what the swap surfaced: the reference capitalises the countdown's unit word ("5 Minutes until release") where ours had lowercased it, and ESC in the typed delete confirm's box is swallowed — the entry names no escape handler; arms for events this engine never fires (PLAYER_SKINNED, TRADE_REQUEST) wait on their feeds rather than being armed blind (1960)
- the social window and the unit menus are the reference's own files: `FriendsFrame.xml` loads off the chain and our transcription is deleted — its twelve dialogs re-homed, `FRIENDLIST_SHOW` fired as the answer to an explicit `ShowFriends()`, and `Get`/`SetLookingForGroup` a client-side flag until their bodies are carved; `UnitPopup.xml` loads off the chain, our row catalogue and its driver frame go, and nine verbs are built for it — `HasFullControl` off the player-control flag the reference reads at `0x51a158`, `UnitPlayerOrPetInParty`/`InRaid` over a new unit owner, and the six pet one-shots, each pressing the bar's own reaction or command slot word through the same latch and `CMSG_PET_ACTION`, confirmed by wow-re's carve; the Guild Leave/Promote confirms 1958 believed nothing registered were our social file's all along, and the duplicate went with it (1958, 1959)
- the trainer loads on demand: our `TrainerFrame.xml` is deleted and no row replaces it — `Blizzard_TrainerUI` loads off the player's own chain through the reference's `ClassTrainerFrame_LoadUI`, and the LoadOnDemand `Blizzard_*` addons are registry rows read off the chain; the timing IS the mechanism: the list builder writes the state-filter mask to 3 on every `SMSG_TRAINER_LIST` (`0x4d75d9`) and the stock addon pushes its saved filters exactly once, on its own ADDON_LOADED — which fires on the session's first trainer, after that packet, so the saved filters win that open and an eager load would never have applied them; the loader holds an anchor to a sibling not built yet and applies it once the subtree exists; and `UNIT_FLAGS` fires only on a change between two snapshots — wow-re's trio found the per-field watch bridge runs no notify pass on the create leg, correcting 1953 (1957)
- the additive window, built and withdrawn the same hour: under `BLEND_ADD` every additive particle draw commutes with every other, so same-key additive draws can be regrouped exactly — built in the effect lane's merge walk and measured on the crowd rig (Stormwind, forty partybots): the adjacency merge already folds about half the effect items and the regroup found two more folds in a frame of ninety-three, so the pre-regroup walk is what runs; what stays: an `fx=` items/merged census on the FPS probe line, a `DRESS_PART` line per drawn part of the self body on the dress census, and the regression the A/B uncovered: 1948's stock chat migration dropped the drain's plain-line sender, so every `WOW_PROBE_CHAT` rig — the crowd rig's forty `.partybot add`s among them — had gone silent on the server; a probe's slash-less line reaches the wire as SAY again (1955)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-04 20:57:24 +07:00
co-authored by Claude Fable 5.1
parent a43e2c9a88
commit 404708859a
116 changed files with 2215 additions and 8202 deletions
@@ -173,14 +173,42 @@ pub(in crate::script) fn install(lua: &Lua) -> mlua::Result<()> {
// the same field the setter below writes, which is table-level evidence rather than a
// name that happens to be in the image.
//
// Its sibling `GetMaxBytes` is in the image too and is NOT added: we do not model
// `maxBytes` at all (a separate field with a `-1` sentinel), and a getter for a field we
// do not have would answer confidently with a number that means nothing.
"GetMaxLetters",
lua.create_function(|lua, this: Table| {
with_editbox(lua, &this, |eb| eb.max_letters as i64)
})?,
)?;
m.set(
// `SetMaxBytes 0x798f30` — `SetMaxLetters`'s sibling in every respect but the sentinel:
// the same EXACT count gate (`0x798fbc cmp eax,2`, the second of the four `lua_gettop`
// callers), the same raw coerce of the value, and a field of its own at `+0x33c` whose
// no-limit value is **-1** where `maxLetters`'s is 0 (`0x799012 jle` → `0x799022`; the
// ctor writes -1 at `0x7799df`) — wow-re `numeric-arg-coercion-law.md` and `ui.md`'s
// CSimpleEditBox layout. So a non-positive argument is unlimited, a positive one caps
// the buffer's BYTES. The stock StaticPopup_Show calls it for any entry carrying
// `maxBytes` — none of the reference's own 76 does, so the reach is an addon's (1960).
"SetMaxBytes",
lua.create_function(|lua, (this, args): (Table, mlua::MultiValue)| {
let args: Vec<Value> = args.into_iter().collect();
if args.len() != 1 {
return Err(mlua::Error::runtime(
"Usage: <unnamed>:SetMaxBytes(maxBytes)",
));
}
let n = crate::script::binding_abi::coerced_number(lua, args.first().cloned());
let n = n as i64;
with_editbox(lua, &this, |eb| {
eb.max_bytes = (n > 0).then_some(n as usize);
})
})?,
)?;
m.set(
// The read half: -1 while unlimited, the reference's own stored sentinel.
"GetMaxBytes",
lua.create_function(|lua, this: Table| {
with_editbox(lua, &this, |eb| eb.max_bytes.map_or(-1, |n| n as i64))
})?,
)?;
m.set(
// `SetMaxLetters 0x799110` — one of only FOUR widget bindings in the whole registrar that
// calls `lua_gettop` (wow-re `numeric-arg-coercion-law.md` Q3), and its gate is EXACT: