Commit Graph

4 Commits

Author SHA1 Message Date
funman300 d7641175be Revert: remove the engine-provider kit detours entirely
Two client breakages in a row from detouring FUN_180033770 / sub_180033430 /
FUN_1800d73d0: the first cut froze FIFA at the "are both teams ready" prompt,
and the rate-limited rewrite CRASHED it at the same point. Rate limiting fixed
the I/O problem and the crash still happened, so the fault is the detours
themselves, not the logging.

Most likely cause: sub_180033430 is an address Ghidra never functionised, and at
least one of these is reached in a way a 14-byte inline patch cannot survive -
an interior branch target, or a callee taking stack arguments that the 4-register
wrapper silently drops when it tail-calls the original.

What the aborted runs did establish, and it is worth keeping:
  - KIT_SCAN fires for cardtype 7 with subtype 9 selector 2 AND selector 3, so
    BOTH the home and away club scans do run.
  - The FUT club enumerate (teamId 130000) did NOT occur in the crashed run
    before the kit screen, and KIT_DESC never fired at all.
  - KITS_AVAILABLE remains 0.
  - The "ret" value logged by kit_scan is the same constant for every call and
    is not a usable item pointer, so that reading was wrong.

Next attempt must NOT patch this code path. Read the state from outside the
process instead - /proc/PID/mem plus objdump against the live client, which
cannot crash the game because it never writes to it.
2026-08-23 18:39:44 +00:00
funman300 89cf5df71f kit_trace: rate-limited engine-provider traces (the first cut froze the client)
The previous version of these three detours hung FIFA at the "are both teams
ready" prompt. FUN_180033770 is POLLED - about 150 calls alternating between the
two real match team ids - and the wrapper did a synchronous write_log on every
one. That is the whole cause; the detours themselves were sound.

Rebuilt so the hot path costs nothing:

  - kit_enum returns immediately unless the team is the FUT club (130000), so
    the polled case does no formatting and no I/O at all. When it is the FUT
    club it reports the out-list length, i.e. how many kits were actually
    offered - the number that decides whether the carousel has anything.
  - kit_desc dedupes on the packed kit id, so a carousel that re-describes the
    same kit logs it once. It decodes teamid/year/slot for comparison against
    the active triple.
  - kit_scan only reports cardtype 7 and dedupes on (subtype, selector).

Dedupe is a fixed 16-slot lock-free SeenSet - no allocation, no locks, safe to
consult from a polled game thread. A full set stops reporting rather than
evicting, because the point is a bounded log.

Rule this file broke once and must not break again: no trace may log per-call on
a polled function.

Motivation changed too. The kit selector is not cosmetic: it is what blocks
entering a match, which also explains why every match in the capture corpus is a
DNF with an unpopulated params object - entered and backed out of. A screenshot
shows the carousel with two tiles, one named HOME and one labelled "undefined",
both with untextured white shirts, which is exactly sub_180033430 writing NAME
on a match and nothing at all on a miss.
2026-08-23 18:36:11 +00:00
funman300 0f2d66e8ca kit_trace: instrument the ENGINE-PROVIDER path, which nothing was watching
A live run refuted the model the existing traces were built on. KIT_SET never
fires, KIT_GET reports KITS_AVAILABLE=0, and FUN_1801c3480 is entered 810 times
without ever seeing a kit (772 players +0x60=1, 24 zeroed +0x60=4, 12 players
+0x60=6, 2 type-2 +0x60=4). So the DP command 0x7576 ->
FutSquadServiceImpl::setAvailableKits path is simply not the one in use.

The selector is fed by a provider CardsDLL registers into the FIFA engine -
singleton FUN_1800338f0, vtable 0x1801f1d68, slot +0x08 enumerate and +0x10
describe - and no trace covered it. Three passive detours added:

  KIT_ENUM  FUN_180033770  logs the teamId asked for; it answers only for the
                           FUT club 130000 and otherwise forwards to the engine
                           default, so a real team id here means our club items
                           were never in scope.
  KIT_DESC  sub_180033430  decodes the packed id into (teamid, year, slot). A
                           descriptor whose triple does not equal the active
                           home/away triple is left untouched, which is what
                           makes the engine substitute its own catalogue kit.
  KIT_SCAN  FUN_1800d73d0  the club scan behind getActiveKit: reports HIT with
                           the item fields, or MISS meaning the active triple
                           stays zero.

Prologues were dumped from the analysed Ghidra project (cardsdll.dll, base
0x180000000). Every copy length is instruction-aligned and none of the three
prologues is rip-relative, so the plain installer is correct for all of them -
unlike FUN_1801c3480, which needs the relocating installer for its
MOV RAX,[rip+...]. Note FUN_1800d73d0's prologue compares EDX against 2, so rdx
is the home/away selector (2/3), not the cardtype an earlier note assumed.

All three log then tail-call: behaviour is unchanged.
2026-08-23 17:55:04 +00:00
funman300 7edf682291 diag(fifa17): port the passive kit-selector trace onto main
Cherry-pick of 4b1d5aa from wip/kit-selector-re, which forked before the TLS
work and cannot be rebased: that branch predates fifa17_tls.rs/patch_mem.rs and
carries a large unrelated lineage (probe/lsx/recv_hook). Only the kit_trace
commit's own contents are taken.

Traces the client-side FUT pre-match kit path in CardsDLL: the GetMatchKits_DP
gate (KITS_AVAILABLE), setAvailableKits (home/away list count), the kit-item
clone driver (item type/subid/teamid at FUN_1801c3480), and the local teamkits
DB clone. Read-only passive detours reusing season_trace's installers, which
this widens to pub(crate).

The one open unknown it answers: the selector requires item+0x60 == 4, a pile
value the server has never been observed to produce (/club emits 1,
/purchased 6).

Verified in the cross-built artifact that the roster TLS gate patch is intact
alongside the new trace (fifa17_tls markers present, KIT_* markers present).
2026-08-21 04:15:58 +00:00