"""D5 Q3/Q4 readers: who consumes the pack currency record ("coins"/"mtx", funds vs finalFunds) and who consumes the availability fields. HYPOTHESIS: the store tile / purchase validator looks the pack's currency vector up by the literal name "coins" (0x1801efea4) or "mtx" (0x1801efea0) and then reads +0x20 (funds) and/or +0x24 (finalFunds). Whichever offset the affordability compare uses is the one the server must make authoritative. CONTROL: xrefs_to(0x1801efea0) must include FUN_18013af30, FUN_180139070 and FUN_18013aae0, which we have already read and know reference "mtx". """ import traceback, os OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/packres" def w(name, text): p = os.path.join(OUT, name) with open(p, "w") as f: f.write(text) print("WROTE %s (%d bytes)" % (p, len(text))) try: buf = [] def P(*a): s = " ".join(str(x) for x in a); print(s); buf.append(s) ents = {} for va, nm in ((0x1801efea0, "mtx"), (0x1801efea4, "coins"), (0x1801efeb0, "%.0f"), (0x180232150, "purchase-atomname"), (0x1801fd44c, "TIME"), (0x180223228, "QUANTITY"), (0x180223238, "TIME_QUANTITY"), (0x180223214, "promo"), (0x18022321c, "deal")): try: xs = xrefs_to(va) except Exception as e: P("XREF %s ERR %s" % (nm, e)); continue P("XREFS %-20s %#x : %d" % (nm, va, len(xs))) for frm, typ, fn, e2 in xs: P(" %#x %-12s %s @ %#x" % (frm, typ, fn, e2)) if e2: ents.setdefault(e2, set()).add(nm) P("") P("=== functions to inspect ===") for e, s in sorted(ents.items()): P(" %#x %-28s %s" % (e, fname(e), sorted(s))) w("d5_q7_notes.txt", "\n".join(buf) + "\n") txt = [] for e in sorted(ents): src = dec(e) txt.append("// ===== %#x %s tags=%s len=%d\n%s" % (e, fname(e), sorted(ents[e]), len(src), src)) w("d5_q7_currency_readers.txt", "\n".join(txt)) print("DONE") except Exception: traceback.print_exc()