"""ADVERSARIAL BATCH 3.

PRIORITY-1 ATTACK: FUN_180098f20 is the ONLY referencer of both 'fcc_leaguelogos'
and 'LeagueName_Abbr_15_%d'. If it resolves a league-logo display name from the DB,
then the claim "cardtype 9 has no resolver at all, so ball and leaguelogo need
localizedName + description off the wire" is WRONG, and that claim changes what we
serve.

ALSO:
  H11 FUN_180108c00 deserializes atom 0x32f (tournamentType) and computes
      subtype = value + 0x91.  (the trophy claim)
  H12 FUN_1801bfac0 arm iVar5 == 0x1e -> FUT_UC_BALL, and the 0x1f arm.
  H13 DAT_18022315c is the string "rare"  (supports low-dword-of-uStack_130 = rareflag)
  H14 the deser's stack struct -> record copy: which stack slot becomes record+0x58.

CONTROL for the "who calls X" questions: FUN_180119bd0 must come back with >=1
caller (we already proved FUN_1800f6c40 calls it through vtable slot +0x498 --
though that is an INDIRECT call, so a direct-xref method may legitimately return 0;
that is exactly why the control matters and why a 0 here is NOT an absence).
"""
import traceback, os

OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/cards/adv"

try:
    print("=== H13: strings at the DAT_ addresses used as DB column names ===")
    for a in (0x18022315c, 0x1801eeeb0, 0x1802ef590, 0x18021ce7c, 0x18021ce7f, 0x1801e9caf):
        try:
            print("  0x%x -> %r" % (a, rd_str(a, 40)))
        except Exception as e:
            print("  0x%x -> ERR %s" % (a, e))

    print()
    print("=== PRIORITY 1: FUN_180098f20 FULL (the fcc_leaguelogos referencer) ===")
    src = dec(0x180098f20)
    open(os.path.join(OUT, "FUN_180098f20.c"), "w").write(src)
    print("len=%d" % len(src))
    print(src)

    print()
    print("=== who calls FUN_180098f20 ? ===")
    for fa, label in ((0x180098f20, "leaguelogo resolver"),
                      (0x180119bd0, "CONTROL kit/stadium/badge resolver (indirect-only expected)"),
                      (0x18011a860, "generic resolver +0x490"),
                      (0x180094580, "third FUT_UC_KITS user"),
                      (0x1800991a0, "fcc_myclubs user"),
                      (0x180099490, "leagues/countryid/Badge user")):
        xs = xrefs_to(fa)
        print("  0x%x %-52s %d refs: %s" %
              (fa, label, len(xs), sorted(set("%s@0x%x" % (x[2], x[3]) for x in xs))))

    print()
    print("=== H11: FUN_180108c00 FULL (tournamentType -> subtype 0x91+) ===")
    src = dec(0x180108c00)
    open(os.path.join(OUT, "FUN_180108c00.c"), "w").write(src)
    print("len=%d" % len(src))
    print(src[:9000])
    if len(src) > 9000:
        print("... [remainder in FUN_180108c00.c]")

    print()
    print("=== FUN_1800fed90 FULL (the 0x91..0x96 switch) ===")
    src = dec(0x1800fed90)
    open(os.path.join(OUT, "FUN_1800fed90.c"), "w").write(src)
    print("len=%d" % len(src))
    print(src)

    print()
    print("=== re-decompile the item deser MYSELF (do not trust the other agent's copy) ===")
    src = dec(0x18013fe00, timeout=600)
    p = os.path.join(OUT, "FUN_18013fe00.c")
    open(p, "w").write(src)
    print("len=%d -> %s" % (len(src), p))
    # print only the lines that matter for H14
    for i, ln in enumerate(src.splitlines(), 1):
        if ("uStack_130" in ln or "local_100" in ln or "FUN_180141660" in ln
                or "local_13c" in ln or "local_138" in ln):
            print("  %4d: %s" % (i, ln))

    print()
    print("=== also dump the card-detail builder for the 0x1e / 0x1f arms ===")
    src = dec(0x1801bfac0, timeout=600)
    open(os.path.join(OUT, "FUN_1801bfac0.c"), "w").write(src)
    print("len=%d" % len(src))
    for i, ln in enumerate(src.splitlines(), 1):
        if ("0x1e" in ln or "0x1f" in ln or "FUT_UC_BALL" in ln or "FUN_1801a8640" in ln
                or "Stadium" in ln or "Badge" in ln or "FUT_UC_KITS" in ln
                or "LeagueName" in ln or "fcc_" in ln):
            print("  %4d: %s" % (i, ln))

except Exception:
    traceback.print_exc()
