"""Q1/Q2/Q4: decompile every capacity consumer found in q_mk_pile_1.

HYPOTHESIS: the "0/0" pair is model+0x1fd1c (TRADE_PILE_SIZE) and a second count,
and the TradePileFull / IS_MAX_AUCTIONS predicates compare a live count against
that capacity. FUN_1800377c0 reads [rsi+0x30] and [rsi+0x36] -- I need to know
whether rsi is the model (offsets would then be 0x30/0x36, NOT 0x1fd1c, so a
different object) or a view struct fed from the model.

CONTROL: FUN_18006cc60 is the PROVEN publisher shape (lea rdx,name; call [r+0x38]).
If FUN_18000d550 decompiles to the same shape, TRADE_PILE_SIZE is output-only by
the same mechanism, which answers Q3 negatively with the template the brief asked
for.

Also dumps the .data neighbourhood of the two absolute-pointer table entries
(0x1802d3560 maximumTradePileSize, 0x1802d3898 pileSizeClientData) to identify
what kind of table they live in (atom-name table vs clientdata field table).
"""
import struct, traceback

try:
    for a, tag in [
        (0x18000d550, "publisher of TRADE_PILE_SIZE (Q3 template test)"),
        (0x1800377c0, "publisher of NUM_MAX_AUCTIONS / IS_MAX_AUCTIONS"),
        (0x180038250, "TradePileFull raiser #1"),
        (0x180038450, "TradePileFull raiser #2"),
        (0x18011dbf0, "the TRADE_PILE_SIZE applier (writes +0x1fd1c)"),
    ]:
        src = dec(a)
        print("\n\n########## %#x  %s  (len=%d) ##########" % (a, tag, len(src)))
        print(src)

except Exception:
    traceback.print_exc()

try:
    print("\n\n########## .data table neighbourhoods ##########")
    for t, nm in [(0x1802d3560, "maximumTradePileSize"), (0x1802d3898, "pileSizeClientData")]:
        print("\n--- entry %#x  (%s)" % (t, nm))
        for off in range(-0x60, 0x61, 8):
            p = t + off
            try:
                v = qword(p)
            except Exception:
                continue
            s = ""
            if 0x1801e5000 <= v < 0x18028a000 or 0x18028a000 <= v < 0x1802f0000:
                try:
                    txt = rd_str(v, 60)
                    if txt and all(32 <= ord(c) < 127 for c in txt):
                        s = "  -> %r" % txt
                except Exception:
                    pass
            f = fm.getFunctionAt(addr(v)) if 0x180001000 <= v < 0x1801e5000 else None
            if f:
                s = "  -> FUNC %s" % f.getName()
            print("   %+#5x  %#018x%s" % (off, v, s))
except Exception:
    traceback.print_exc()

try:
    print("\n\n########## GetMaxPileSize registration site 0x18003f5b7 ##########")
    src = dec(0x18003f120)
    print("len=%d" % len(src))
    print(src)
except Exception:
    traceback.print_exc()
