fifa17-recon: sweep can target the non-player card tables
The merge FUN_180141660 dispatches on record+0x4c, which FUN_1800d8330 derives
from cardsubtypeid alone, and each branch queries a different table by
carddbid = record+0x18 -- the same field players use for playerid:
0..3 -> 1 players (live-proven) 5 -> 3 headcoachcards
4 -> 2 manager 8 -> 4 fitnesscoachcards
6 -> 10 gkcoachcards 7 -> 5 physiocards
9..b -> 7 unidentified absent -> 0x156 -> 0, no merge at all
So a 't<subtype>@' prefix on the sweep window probes any of them the same way
players were probed: 't5@auto:1-20000:5000'.
Only cardsubtypeid changes. itemType stays 'player' because the merge dispatches
on the subtype alone and the wire shape of a real staff item has NEVER been
observed -- across every logged session the client has only ever asked for
type=player and type=custom. Inventing a shape for an unobserved request is the
change class behind every freeze this project has had.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUT92pz6RWKih9dSr8ZpxW
This commit is contained in:
@@ -1305,10 +1305,34 @@ def sweep_window():
|
||||
# fetches; one probe at the end reads them all.
|
||||
_SWEEP_SPEC = None
|
||||
_SWEEP_POS = 0
|
||||
_SWEEP_SUBTYPE = 0 # 0..3 = player; see _parse_window for the other tables
|
||||
|
||||
|
||||
def _parse_window(win):
|
||||
"""'lo-hi' or 'auto:lo-hi:step' -> (lo, hi, step or None). None on garbage."""
|
||||
"""'lo-hi' or 'auto:lo-hi:step' -> (lo, hi, step or None). None on garbage.
|
||||
|
||||
An optional 't<subtype>@' prefix sweeps a NON-PLAYER card table. The merge
|
||||
FUN_180141660 dispatches on record+0x4c, which FUN_1800d8330 derives from
|
||||
cardsubtypeid alone, and each branch queries a different table by
|
||||
carddbid = record+0x18 (the same field players use for playerid):
|
||||
|
||||
0..3 -> 1 players 5 -> 3 headcoachcards
|
||||
4 -> 2 manager 8 -> 4 fitnesscoachcards
|
||||
6 -> 10 gkcoachcards 7 -> 5 physiocards
|
||||
9..b -> 7 (unidentified) absent -> 0x156 -> 0, NO merge at all
|
||||
|
||||
So 't5@auto:1-20000:5000' sweeps head coaches exactly the way the default
|
||||
sweeps players. Nothing about the non-player branches is live-proven yet;
|
||||
they are read out of the binary.
|
||||
"""
|
||||
global _SWEEP_SUBTYPE
|
||||
_SWEEP_SUBTYPE = 0
|
||||
if win.startswith("t") and "@" in win:
|
||||
head, win = win.split("@", 1)
|
||||
try:
|
||||
_SWEEP_SUBTYPE = int(head[1:], 0)
|
||||
except ValueError:
|
||||
return None
|
||||
auto = win.startswith("auto:")
|
||||
step = None
|
||||
if auto:
|
||||
@@ -1358,13 +1382,21 @@ def sweep_items():
|
||||
else:
|
||||
start, end = lo, hi
|
||||
|
||||
out = [_item(SWEEP_ID_BASE + (pid - lo), pid, SWEEP_SENTINEL_RATING,
|
||||
"ST", 0, 0, 0, [1, 1, 1, 1, 1, 1])
|
||||
for pid in range(start, end + 1)]
|
||||
log(" SWEEP: serving %d candidate playerid(s) %d..%d%s "
|
||||
out = []
|
||||
for pid in range(start, end + 1):
|
||||
it = _item(SWEEP_ID_BASE + (pid - lo), pid, SWEEP_SENTINEL_RATING,
|
||||
"ST", 0, 0, 0, [1, 1, 1, 1, 1, 1])
|
||||
if _SWEEP_SUBTYPE:
|
||||
# Only the subtype is changed. itemType stays "player" because the
|
||||
# merge dispatches on cardsubtypeid alone and the wire shape for a
|
||||
# staff item has never been observed -- inventing one is the change
|
||||
# class that freezes the client.
|
||||
it["cardsubtypeid"] = _SWEEP_SUBTYPE
|
||||
out.append(it)
|
||||
log(" SWEEP: serving %d candidate id(s) %d..%d%s subtype=%d "
|
||||
"[synthetic, nothing saved]"
|
||||
% (len(out), start, end,
|
||||
(" (auto, %d..%d done)" % (lo, end)) if step else ""))
|
||||
(" (auto, %d..%d done)" % (lo, end)) if step else "", _SWEEP_SUBTYPE))
|
||||
return out
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user