Add hook debug tooling and refine RT3 atlas
This commit is contained in:
parent
860d1aed90
commit
57bf0666e0
38 changed files with 14437 additions and 873 deletions
|
|
@ -31,9 +31,9 @@ What this note is for:
|
|||
- GameSpy-facing callback and live-route semantics
|
||||
- Selector-view refresh, retry, and probe state
|
||||
|
||||
Highest-value open edge:
|
||||
Latest local closure:
|
||||
|
||||
- The remaining multiplayer edge is narrower now:
|
||||
- The remaining multiplayer branch is narrower now:
|
||||
the status-route callback vector is bounded through selector-text or averaged-sample publication,
|
||||
control-id-list seeding, scalar-query forwarding, and the validated cookie or extended-payload
|
||||
callbacks. The selector-view sidecar is tighter too: `[entry+0x80]` now reads as the averaged
|
||||
|
|
@ -49,6 +49,10 @@ Highest-value open edge:
|
|||
`0x5906f0` tears down the decoded schema dictionary rooted at `[this+0x08]`, `0x590540/0x5905a0`
|
||||
acquire and release refcounted shared schema strings through the global pool, and `0x5908c0`
|
||||
now reads as the live receive/decode state machine serviced by `0x591290` in table states `2/3`.
|
||||
The owner-callback mode split above that runtime is tighter now too: mode `0` comes from the
|
||||
generic append-notify lane `0x590370`, mode `1` from compact upsert `0x590d00`, mode `2` from
|
||||
generic remove-notify `0x590430`, and modes `6/5/3` from the receive/decode state machine
|
||||
`0x5908c0`.
|
||||
The higher transport bring-up split is tighter too: `0x596090` now clearly constructs
|
||||
`[transport+0xba4]` through `0x5905e0` with owner callback `0x595a40`, then seeds the local
|
||||
field-cache family `[transport+0x1724]` through `0x5a08f0` with helper `0x595b60`, and then
|
||||
|
|
@ -83,15 +87,31 @@ Highest-value open edge:
|
|||
`+0x0c/+0x10/+0x18` metadata triplet and the replay modes later consume the pointer through
|
||||
`0x5933a0`. The negative result is stronger too: local text-side xrefs still show no direct
|
||||
store to `[transport+0x1778]`, and a wider sweep also failed to show any obvious `lea`-based
|
||||
replay-band writer. So the sidecar writer remains upstream of this leaf capacity publisher. The
|
||||
replay-band writer. The owned request lifecycle now tightens that further too:
|
||||
`0x593330/0x593370/0x593380/0x5934e0/0x5933a0` fully own `[transport+0x1780]`, `0x1784`, and
|
||||
`0x1788`, while still leaving `[transport+0x1778]` outside that family; the neighboring active
|
||||
opcode reset path `0x5929a0` also only targets `[transport+0x17fc]`. Constructor and teardown
|
||||
passes around `0x596090/0x5961b0/0x5962e0` tighten that negative result further: those owners
|
||||
seed or clear the neighboring replay-band fields while still leaving `[transport+0x1778]`
|
||||
untouched. A full-binary literal-offset sweep tightens it further still: the only direct
|
||||
`0x1778` hit in `RT3.exe` is the read in `0x595bc0`. One nearby ambiguity is now closed too: the
|
||||
mode-`5` mirror path in `0x595a40` and `0x595e10` does not seed `[transport+0x1778]`; it writes
|
||||
`[transport+0x54]` and mirrors the same staged route companion dword only into queue-side slot
|
||||
`[transport+0x1724+0x24]` through `0x005a0940`. So the sidecar writer remains upstream of this
|
||||
leaf capacity publisher. The
|
||||
payload split is tighter too:
|
||||
`0x592ae0` now grounds opcode `2` as a seven-dword descriptor payload with an owned string slot
|
||||
at `+0x08`, so live mode supplies a populated payload while modes `3` and `5` deliberately
|
||||
enqueue an all-zero payload and reuse only the sidecar metadata in the wrapper. Those two modes
|
||||
are tighter now too: they are not generic replay guesses, they are the live receive-state owner
|
||||
callbacks emitted by `0x5911e0 -> 0x5908c0`. So they are best read as delayed metadata replays
|
||||
over one cached work record, not over a standalone custom cache object. The producer side is
|
||||
tighter now too: callback-table attach,
|
||||
over one cached work record, not over a standalone custom cache object. The capacity owner split
|
||||
itself is tighter now too: `0x595bc0` only does real work for modes
|
||||
`0`, `3`, and `5`; the upstream table still delivers modes `1`, `2`, and `6`, but those are
|
||||
explicit no-ops in the capacity leaf. So the callback-owner edge is now effectively closed: the
|
||||
route-callback table feeds the capacity publisher only through the live append lane and the two
|
||||
replay lanes, while the remaining missing piece is still the upstream sidecar producer, not the
|
||||
owner-mode wiring. The producer side is tighter now too: callback-table attach,
|
||||
bound-route requests, selector-text route requests, and the type-`9` text fastpath all stage
|
||||
that same `+0x0c/+0x10/+0x18` triplet through `0x5934e0`, so the capacity replay sidecar is
|
||||
clearly reusing one broader transport work-record family. The generic owner-callback split above that family is tighter now
|
||||
|
|
@ -125,34 +145,52 @@ Highest-value open edge:
|
|||
`0x5904d0` family, not a vague collection clear.
|
||||
The callback-table attach side now
|
||||
constrains the same work-record metadata family a little further too: `0x593650` deliberately
|
||||
duplicates one caller metadata dword into both work fields `+0x0c` and `+0x18`, while preserving
|
||||
the remaining caller callback function pointer in `+0x10`. The lower opcode wrappers are tighter
|
||||
now too: both `0x592a40` and `0x592a70` consume that staged triplet in the order `( callback fn
|
||||
+0x10, callback companion +0x18, drain context id +0x0c )`. So the replay-side triplet is
|
||||
clearly a broader transport callback-wrapper family, not one fixed route-only tuple. The type-`9`
|
||||
text fastpath confirms the same split from the other side too: `0x593d00` only emits the
|
||||
follow-on callback lane when work field `+0x10` is nonnull, and then forwards `(+0x10, +0x18,
|
||||
+0x0c)` into `0x593170` as callback function, callback companion, and trailing drain context.
|
||||
duplicates its first caller metadata dword into both work fields `+0x0c` and `+0x10`, while
|
||||
carrying the second caller metadata dword in `+0x18`. The lower opcode wrappers are tighter now
|
||||
too: `0x592a40` turned out not to be the real 0x08-byte binding leaf at all, but the explicit
|
||||
opcode-`1` trigger wrapper whose constructor is a no-op and whose active-side service is
|
||||
`0x5913c0`. The real lower binding leaf is `0x592c40`, which builds the local `0x08`-byte
|
||||
payload later deep-copied by the explicit opcode-`5` family `0x591540/0x591570/0x591580`. The
|
||||
earlier opcode-`4` reading was just the table-indexing mistake: `0x5928a0` multiplies the pushed
|
||||
selector by `0x10`, so selector `4` lands on the row at `0x5e2044`, not the row at `0x5e2034`.
|
||||
So
|
||||
the replay-side triplet is still a broader transport callback-wrapper family, not one fixed
|
||||
route-only tuple. The type-`9` text fastpath confirms the same split from the other side too:
|
||||
`0x593d00` only emits the follow-on callback lane when work field `+0x10` is nonnull, and then
|
||||
forwards `(+0x10, +0x18, +0x0c)` into `0x593170` as callback function, callback companion, and
|
||||
trailing drain context.
|
||||
The nearby field-subscription side is tighter too: `0x592b50` now clearly uses
|
||||
`[transport+0x1774]` as a cached progress percentage under the `[transport+0xba4]` callback
|
||||
table, and `0x5962e0` seeds that percentage to `1` just before the first immediate mode-`3`
|
||||
snapshot. The nearby route-callback-table lifecycle is tighter now too: `0x596090` seeds
|
||||
`[transport+0xba0]` as the callback-plumbing enable latch, clears staged payload slot
|
||||
`[transport+0xb50]`, and constructs the three owner branches rooted at `[transport+0xba4]`,
|
||||
`[transport+0x1164]`, and `[transport+0x18bc]`. The matching local cleanup is tighter too:
|
||||
`0x5962c0` is the explicit staged route-callback payload clear on `[transport+0xb50]`, while
|
||||
`0x595ce0` now clearly resets only the capacity-descriptor route callback table at
|
||||
`[transport+0x1164]`, not the field-subscription table at `[transport+0xba4]`. The only
|
||||
meaningful gap left on the capacity side is the still-unrecovered writer that stages
|
||||
`[transport+0x1778]`. The carried sidecar fields are no longer anonymous: current evidence now
|
||||
says they are just the same cached callback-wrapper triplet reused by other work-record families,
|
||||
namely drain context id `+0x0c`, callback function `+0x10`, and callback companion `+0x18`.
|
||||
The negative result is stronger now too: the neighboring replay-band fields
|
||||
`[transport+0x176c]`, `[transport+0x1770]`, `[transport+0x1774]`, `[transport+0x177c]`,
|
||||
`[transport+0x1780]`, and `[transport+0x1784]` all have direct local lifecycle owners, but
|
||||
`[transport+0x1778]` still only appears as the single read in `0x595bc0`. So this is no longer
|
||||
a local ownership gap: no local writer is grounded, and the remaining staging path is best read
|
||||
as upstream and indirect rather than one ordinary direct field store in the local text cluster.
|
||||
`[transport+0x1164]`, and `[transport+0x18bc]`; `0x596210` is the recurring service sweep over
|
||||
those same three tables plus the local field-cache and queued-descriptor families; `0x596060`
|
||||
is the explicit `gsi_am_rating` reset; and `0x596530` is the reopen-from-stored-label sibling
|
||||
above that same am-rating table. The matching local cleanup is tighter too: `0x5962c0` is the
|
||||
explicit staged route-callback payload clear on `[transport+0xb50]`, while `0x595ce0` now
|
||||
clearly resets only the capacity-descriptor route callback table at `[transport+0x1164]`, not
|
||||
the field-subscription table at `[transport+0xba4]`. The only meaningful gap left on the
|
||||
capacity side is no longer a local writer search. The carried
|
||||
sidecar fields are no longer anonymous: current evidence now says they are just the same cached
|
||||
callback-wrapper triplet reused by other work-record families, namely drain context id `+0x0c`,
|
||||
callback function `+0x10`, and callback companion `+0x18`. The negative result is stronger now
|
||||
too: the neighboring replay-band fields `[transport+0x176c]`, `[transport+0x1770]`,
|
||||
`[transport+0x1774]`, `[transport+0x177c]`, `[transport+0x1780]`, and `[transport+0x1784]` all
|
||||
have direct local lifecycle owners, but `[transport+0x1778]` still only appears as the single
|
||||
read in `0x595bc0`; even the broader callback-owner lifecycle now skips it while touching those
|
||||
neighbors, including bring-up `0x596090`, recurring service `0x596210`, am-rating reset/reopen
|
||||
`0x596060/0x596530`, teardown `0x5961b0`, and field-subscription open `0x5962e0`. The
|
||||
constructor now closes that negative result further: `0x58dc50` bulk-zeroes the full transport
|
||||
body and still never seeds `[transport+0x1778]` before later explicit neighbor initialization.
|
||||
So this edge is now locally closed: no writer is grounded anywhere in `RT3.exe`, and the
|
||||
remaining staging path is best read as an upstream callback or worker handoff rather than one
|
||||
missing ordinary field store in the local text cluster. The callback-binding family at
|
||||
`0x5934e0 -> 0x593650 -> 0x58f2f0` now gives the cleanest local boundary for that claim:
|
||||
RT3 stages and later consumes the shared work-record metadata triplet, but the sidecar itself
|
||||
still appears only as a borrowed cached pointer at `0x595bc0`, never as a locally seeded
|
||||
replay-band field.
|
||||
One adjacent staged-route callback is
|
||||
tighter now too: `0x595860` is the submit-result handler below
|
||||
`0x5958e0`, using the already-grounded third selector-generation counter at `[transport+0xac0]`
|
||||
|
|
@ -212,10 +250,10 @@ Highest-value open edge:
|
|||
gate and the same queued fallback, mode `2` removes pending descriptors from the queued family,
|
||||
mode `3` forces mode `2` when the primary-endpoint table is empty, mode `4` updates the deferred
|
||||
route-status state around `[this+0x1ed4]` and `[this+0x1ed8]`, and mode `5` copies the staged
|
||||
route companion dword at `[this+0x490]` into `[this+0x54]` while mirroring that value into the
|
||||
local field-cache family. The route-event dispatcher side is cleaner too:
|
||||
route companion dword at `[this+0x490]` into `[this+0x54]` while mirroring that value into
|
||||
queue-side slot `[this+0x1724+0x24]` through `0x005a0940`. The route-event dispatcher side is cleaner too:
|
||||
the mode-`5` tails in both callback families do not copy a descriptor-local field. They mirror the
|
||||
transport-staged companion dword at `[this+0x490]` into `[this+0x54]` and the local field-cache
|
||||
family instead. The `gsi_am_rating` maintenance lane is tighter now too: it sorts the
|
||||
transport-staged companion dword at `[this+0x490]` into `[this+0x54]` and that same queue-side
|
||||
slot instead, not into `[this+0x1778]`. The `gsi_am_rating` maintenance lane is tighter now too: it sorts the
|
||||
primary-endpoint descriptor table through `0x590310` in mode `1` with key `gsi_am_rating`, then
|
||||
selects the new head through `0x590480` rather than treating the table as pure insertion order.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue