# VERIFICATION pass for the "unserved screens" census. Re-derives, independently: # 1. FUN_180043b90 (claimed club-stats panel provider) -- FULL decompile, length, # brace balance, every switch arm, and case-6's row list. # 2. FUN_180094ce0 (the LIVE-PROVEN eight-row staff panel) -- to check that both # panels obtain their data object the same way, which is the only thing that # licenses "the JSON we send reaches those tiles". # 3. FUN_18012fd40 -- atom -> type-id map, specifically the consumable arms. # 4. FUN_18013c6d0 -- settings deser: length, brace balance, distinct atoms, # which getter reads `value`, and whether 0x100 appears. # 5. FUN_18012f4f0 -- the club/stats URL builder's closed mode set. import re def report(name, a): c = dec(a) bal = c.count("{") - c.count("}") print("=== %s @%#x len=%d braces_balanced=%s ends=%r" % (name, a, len(c), bal == 0, c.rstrip()[-40:])) return c print("#" * 72) print("# 1. FUN_180043b90") c = report("FUN_180043b90", 0x180043b90) open("/tmp/ver_43b90.c", "w").write(c) cases = re.findall(r"^\s*(case \w+|default):", c, re.M) print("switch arms seen:", cases) # every string literal passed as the row name, in order, with the typeid before it rows = re.findall(r'0x800\)\)\(\w+,([0-9a-fx]+)\);|"(CARDS_NO_[A-Z_]+)",(\w+)\)', c) print("--- case 6 region ---") i = c.find("case 6:") j = c.find("case 7:", i) if j == -1: j = len(c) seg = c[i:j] if i != -1 else "(no case 6)" print("case6 segment len", len(seg)) for m in re.finditer(r'0x800\)\)\((\w+),([0-9a-fx]+)\)|"(CARDS_NO_[A-Z_]+)"', seg): print(" ", m.group(0)) # where does the data object come from? print("--- data-object acquisition (first 30 lines) ---") print("\n".join(c.splitlines()[:32])) print("#" * 72) print("# 2. FUN_180094ce0 (live-proven staff panel, for comparison)") c2 = report("FUN_180094ce0", 0x180094ce0) open("/tmp/ver_94ce0.c", "w").write(c2) print("\n".join(c2.splitlines()[:34])) print("#" * 72) print("# 3. FUN_18012fd40 atom -> typeid") c3 = report("FUN_18012fd40", 0x18012fd40) open("/tmp/ver_12fd40.c", "w").write(c3) print(c3) print("#" * 72) print("# 4. FUN_18013c6d0 settings deser") c4 = report("FUN_18013c6d0", 0x18013c6d0) open("/tmp/ver_13c6d0.c", "w").write(c4) atoms = sorted(set(int(x, 16) for x in re.findall(r"case 0x([0-9a-f]+):", c4))) print("distinct case atoms: %d" % len(atoms), [hex(a) for a in atoms]) print("0x100 present:", 0x100 in atoms) print("getter callsites:", sorted(set(re.findall(r"FUN_1801c7[0-9a-f]{3}", c4)))) for pat in ("0xa2", "0x354", "0x377"): print(" %s occurrences: %d" % (pat, c4.count(pat))) print("#" * 72) print("# 5. FUN_18012f4f0 club/stats URL builder") c5 = report("FUN_18012f4f0", 0x18012f4f0) print(c5)