fifa17-recon: the FUT-hub Transfer List tile counts, and the hub parser is NOT reflection

The Transfer List hub tile read "0 items / Selling 0" while a card was actively
listed. Enumerating the /hub parser FUN_180139610 straight from the on-disk
CardsDLL (objdump) refutes the old ENDPOINT_MAP claim that it uses C++ reflection
with "no atom ladder, nothing to enumerate": it has an ordinary running-sum atom
ladder reading 18 atoms. The tile is fed by hub.tradePile (0x333), a nested object
(sub-deser 0x18013ead0) reading count/selling/sold as scalar ints -- the same
scheme as GetAuctionCount, so serving it in the hub body is freeze-safe. The tile
never re-polls the standalone /tradePile/counts, which is why fixing that endpoint
alone did not move the tile.

Also: the hub tile polls LOWERCASE tradepile/counts while the Transfer List screen
uses camelCase tradePile; our case-sensitive routes matched only the screen, so the
tile's counts call fell through to /trade and got a shape the counts deser skips.
Made the tradePile routes case-insensitive.

And bake the proven transfer-market flags (FUT_TRADING/PILESIZES/TRADEABLE/
DISCARD_TABLE/DISCARD_SEND) into openfut-fut.sh so a plain `start` brings up the
working state instead of regressing trading to greyed-out.

- tools/utas_server.py: hub_data() serves tradePile:{count,selling,sold};
  tradePile routes now re.I
- tools/openfut-fut.sh: utas launched with the working flag set
- docs/ENDPOINT_MAP.md: full 18-atom hub map + tile map, correction of the
  reflection claim
- tools/ghidra_queries/objdump_atom_ladder.py: the objdump-based atom-ladder
  decoder used to derive the above

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lrx9to3pihN6Sm9sXgc8np
This commit is contained in:
funman300
2026-08-06 18:28:52 -07:00
parent 245c22161b
commit 31fc590b99
4 changed files with 156 additions and 13 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ SERVERS=(
"lsx lsx_responder_v2.py 4216 OPENFUT_LSX_EVENT_COUNT=100000"
"blaze blaze_responder_v3b.py 42127,42130,42131 -"
"roster roster_server.py 8081 -"
"utas utas_server.py 8099 -"
"utas utas_server.py 8099 FUT_TRADING=1 FUT_PILESIZES=1 FUT_TRADEABLE=1 FUT_DISCARD_TABLE=1 FUT_DISCARD_SEND=1"
"autopatch autopatch.py - -"
# POW/EASFC — the "EA FC servers unreachable" layer. Harmless when idle: it just
# binds 8094/8080 and nothing points at it unless FUT_POW=1 makes blaze serve the