"""DIMENSION 2 batch 8: piles, the response registry, and the credits path. HYPOTHESES H1 0x180229cc0 is a {string,enum} table naming every itemState / pile value. 'trade'/'tradepile' in it would be the value a send-to-transfer-list MoveCard must carry. H2 The rows around 0x1802705f0 / 0x1802fb370 are a response registry that pairs each response class with its deserializer AND its handler; the handler for FutDiscardCard is what reads totalCredits. H3 FutUpdateCreditsServerResponse / FutUserCreditsServerResponse are the coin balance carriers; if the client refetches credits after a discard, the emulator must keep the balance consistent, not just echo totalCredits. CONTROL: FutCreateMatchServerResponse -> 0x180120380. """ import traceback, os OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/packres" try: print("CONTROL FutCreateMatchServerResponse ->", [hex(a) for a, v, e in class_deser("FutCreateMatchServerResponse")]) print("=" * 78) print("SECTION 1 -- itemState enum table 0x180229cc0") for i in range(24): p = qword(0x180229CC0 + i * 0x10) if p == 0: print(" [%d] NULL terminator" % i) break v = dword(0x180229CC8 + i * 0x10) print(" [%2d] %r -> %d" % (i, rd_str(p, 40), v)) print("SECTION 1b -- tradeState enum table 0x180229e40") for i in range(16): p = qword(0x180229E40 + i * 0x10) if p == 0: print(" [%d] NULL" % i) break print(" [%2d] %r -> %d" % (i, rd_str(p, 40), dword(0x180229E48 + i * 0x10))) print("SECTION 1c -- bidState decoder 0x180166380") print(dec(0x180166380)) print("=" * 78) print("SECTION 2 -- registry rows around the discard entries") for base, n in ((0x180270580, 0x60), (0x1802FB330, 0x40), (0x180220470, 0x40)): print("--- dump %#x ---" % base) for i in range(n): va = base + i * 8 try: q = qword(va) except Exception: break note = "" if 0x1801E5000 <= q <= 0x180290000: s = rd_str(q, 60) if s and all(0x20 <= ord(c) < 0x7F for c in s): note = "STR %r" % s if not note and 0x180001000 <= q < 0x1801E5000: f = fm.getFunctionAt(addr(q)) note = "FUNC %s" % (f.getName() if f else "(mid)") print(" %#x : %#018x %s" % (va, q, note)) print("=" * 78) print("SECTION 3 -- credits response classes") for c in ("FutUpdateCreditsServerResponse", "FutUserCreditsServerResponse", "FutMoveCardServerResponse", "FutGetPurchasedItemsServerResponse"): r = class_deser(c) print(" ", c, [(hex(a), hex(v), hex(e)) for a, v, e in r]) for a, v, e in set(r): s = dec(a) print("---- deser %#x len=%d ----" % (a, len(s))) print(s) break print("=" * 78) print("SECTION 4 -- MoveCard deser 0x180128600 FULL") s = dec(0x180128600) print("len(src) =", len(s)) print(s) with open(os.path.join(OUT, "d2_movecard_deser.txt"), "w") as f: f.write(s) except Exception: traceback.print_exc()