dcd470cddc509d3aab72c5c8a49bac60b44be37e
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a3fd51692f |
fifa17-recon: the trading gate is still shut, and two of yesterday's conclusions were wrong
Ships the club-item subtype correction and the tradeable plumbing, and records two
refutations of claims made earlier in the same session. Nothing here is a working fix
for trading; the honest state is that the gate is still closed and we now know more
about why.
REFUTED 1: "the Blaze client-config store opens the trading gate". It does not, and the
flag is inert. IS_TRADING_ENABLED is an OUTPUT NAME. FUN_18006cc60 is a publisher: at
0x18006ccc6 it calls [rax+0x270] to READ gate byte 0x1fd2e, then lea rdx,[
IS_TRADING_ENABLED] and hands the value out under that name. The only rip-relative
reference to the literal 0x1801fc118 in all of .text is that lea; there is no comparison
against it anywhere, so no client-config key of that name can be read as an input. That
also undermines the IS_* store keys shipped beside it: their apparent success was never
actually attributed to them.
REFUTED 2: "the gate byte flipped to 1". It reads 0. It was measured as 1 shortly after
CardsDLL mapped and that was over-claimed as a success; a thorough re-measurement read 0
on the SAME pid and model pointer, and a fresh session reads 0 with an unambiguous raw
dump (model+0x1fd18.. = 01000000 00000000 00000000 00000000 3c000000 01 01 00 01, the 00
being 0x1fd2e). Either the first read was transient or something clears it after login.
The only writer is FUN_18011dc50 at 0x18011dc91, so a 0 means something RAN and wrote it.
AND THE "/settings IS DEAD" CLAIM FALLS TOO. FUN_18011dc50 is not unreachable: it is a
VIRTUAL method at model vtable slot +0x988 (absolute pointer 0x18021cc28). A direct-call
search found no callers because Ghidra does not resolve virtual calls, which is the same
dispatch-form trap that has now produced seven wrong verdicts here. The real chain is
settings response -> FUN_180174630 -> FUN_18013c6d0 (deser)
-> completion callback FUN_180173e00 -> vt+0x988 and vt+0x998 -> gate bytes
and FUN_180173e00 bails before applying anything unless the int at response+0x1c is
zero. Which atom writes +0x1c is unknown and is the thing worth chasing.
The measurement behind that claim also had a gap: it checked +0x1fd14, +0x1fd4c and
+0x1fd54 for the maximumTradePileSize=77 probe but NOT +0x1fd1c, which is the actual
TRADE_PILE_SIZE (read via vt+0xa58 = FUN_18011bf30). So the probe never tested the field
it needed to. Serving 77 and reading +0x1fd1c is the clean falsifier and is still open.
Recovered and worth keeping: an authoritative slot-to-name table from the publisher.
vt+0x270 IS_TRADING_ENABLED -> +0x1fd2e vt+0x2b0 IS_FRIENDLY_SEASON_ENABLED -> +0x1fd3a
vt+0x2b8 IS_TOURNAMENT_QUIT_ENABLED -> +0x1fd3b vt+0x2c0 IS_PROCESSING_STATE_ENABLED -> +0x1fd3c
vt+0x2c8 IS_DRAFT_MODE_ENABLED -> +0x1fd3d vt+0x2d8 IS_STORY_MODE_REWARD_ENABLED -> +0x1fd3f
vt+0x2f0 IS_RETURNING_USER_REWARDS_SCREEN -> +0x1fd40 vt+0xa58 TRADE_PILE_SIZE -> +0x1fd1c
That also locates the red TRANSFER LIST 0/0: it is +0x1fd1c, currently 0.
WHAT IS ACTUALLY SHIPPED HERE, all default off:
* FUT_TRADEABLE sends untradeable=false. Verified landing at item+0x49 (stored
INVERTED by case 0x361) on a live club record. Applied on every READ path, not only
in _item(), because the save holds 246 items minted before the flag existed and the
club route serves them straight from the save. That gap was caught by reading the
served JSON, not by unit-testing the factory.
* FUT_TRADING adds tradingEnabled and IS_TRADING_ENABLED to the Blaze config. Kept
only as a record of the refutation, with the reasoning inline so nobody retries it.
* fut_clubitems FAMILIES subtypes corrected: kit 9, stadium 10, badge 11 (cardtype 7,
not 9), ball 30, league logo 31. Every previous value sat in the 0x91..0x96 TROPHY
block. probe_shelf's candidate set lacked 9, 10 and 11, so the probe route the docs
preferred could never have answered this for three of five families.
* Club kits and badges now carry teamid, reintroduced ALONE after the 2026-08-05 crash
(which was never bisected; value is the established suspect and that response also
carried 30 items across five wrong subtypes). itemType dropped: it was unobserved and
never copied into the record.
Live: 439 contract checks, 414 card-family checks, market suite, all pass. The transfer
market still refuses with zero requests and the menu entries are still greyed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
ccf912c157 |
fifa17-recon: club items crashed the client -- unestablished fields, and too wide a blast radius
The game hung and then crashed on the first equippables fetch. My fault twice over.
CAUSE, primary. I copied teamid, leagueid and value straight out of the fcc row as
extras. `value` appears elsewhere as an OBJECT member (displayGroup {"value": ...}),
and a scalar where an object is expected is the type-desync busy loop at 0x1801c7f1a
-- which presents exactly as "the game is taking its time" and then dies. Omission is
safe; an unestablished field is not. That is this project's own rule and I broke it
for three fields that were not needed to draw a card. All three are gone.
CAUSE, contributing. The last request before the crash was type=equippables&count=11
and we answered with 30 items spanning FIVE unverified cardsubtypeids at once: the
widest possible blast radius for a wrong shape, and it tells you nothing about which
subtype was wrong. equippables now answers [] until the subtypes are confirmed one
family at a time, and shelf() takes a families= filter so a test can serve exactly one.
Adds FUT_CLUBITEMS=probe:<family>, which serves one item per candidate subtype for a
single family, so the screen names the correct subtype instead of me guessing a third
time. Eight items, one family, one question.
The flag already defaulted off, so a plain restart cannot serve any of this.
439 + 414 checks green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUT92pz6RWKih9dSr8ZpxW
|
||
|
|
3b58b29094 |
fifa17-recon: club-item counts, and packs that contain more than footballers
Correcting an overstatement first: I said every card family works. Balls, stadia,
badges and kits do not, and this is the start of that, not the finish.
CLUB ITEMS (FUT_CLUBITEMS=1, default off). tools/fut_clubitems.py builds shelves from
the game's own tables: fcc_balls 42, fcc_stadium 78, fcc_badgecards 656,
fcc_kitcards 1482, fcc_leaguelogos 44, each with its real carddbid AND its real
cardassetid. Counts are wired into the club stat set, replacing the honest zeros
rather than appending a second row per id (the deserializer does
store[ctx][statId] = value, so two rows for one id is a coin toss).
Counts FIRST and on purpose. The consumables round proved the count gates the fetch:
the client does not ask for an item list until club/stats reports a non-zero count,
and the CLUB tab reads 0x1e balls, 0x28 kits, 0x14 stadia. Arming the counters is what
makes the client name the item route, which is the one thing static reading has never
produced for this family -- cardtype 9 has NO arm in the merge, so nothing about it is
discoverable from the card DB.
What is deliberately NOT guessed: which cardsubtypeid means ball versus stadium. The
eight values that reach cardtype 9 are {30,31,145..150} and the assignment appears in
none of the 149 dumped tables. probe_shelf() serves one item per candidate so the
screen can say which is which, rather than shipping a guess into someone's club.
PACKS (FUT_PACK_MIX=1, default on). A pack is no longer eleven footballers: roughly a
quarter of each pack is now consumables and occasionally staff, as a ratio so it
scales from a 5-card bronze to an 11-card premium. Club items are excluded until their
subtypes are verified -- a pack is the worst place to discover a wrong subtype,
because the card lands in the save and has to be cleaned out by hand.
Also fixes the art id AT THE SOURCE. fut_consumables now sets cardassetid from the
fcc_ tables, so a pack-granted consumable renders correctly too. The earlier fix only
corrected the copy served by the club route, which meant packs would have dealt cards
with the green NOT FOUND box again.
Pack tests run against a COPY of the profile, after an earlier test persisted 15 cards
into the live save and had to be undone by hand.
439 + 414 checks green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUT92pz6RWKih9dSr8ZpxW
|