"""D3 Q2 cont: resolve the auction-count struct.

FUN_1800377c0 publishes NUM_CURRENT_AUCTIONS = u16 [S+0x36], NUM_MAX_AUCTIONS =
int [S+0x30], and IS_MAX_AUCTIONS = !(max<0 || current<max), where
S = model->vt+0x130().

HYPOTHESIS: S is a sub-object of the same model singleton (vtable 0x18021c2a0)
and S+0x30 is fed from the same settings applier family as model+0x1fd1c
(TRADE_PILE_SIZE). If S+0x30 is 0 then IS_MAX_AUCTIONS is permanently TRUE.

CONTROL: slot +0xa58 of the same vtable must decompile to the known
"mov eax,[rcx+0x1fd1c]; ret" TRADE_PILE_SIZE stub. If it does not, the vtable
base or the slot arithmetic is wrong and nothing else in this run is trustworthy.

Also decompiles FUN_1800d7b70 (the CARDS_CB_ERR_* name table) and locates
CARDS_CB_ERR_FEATURE_UNAVAILABLE's numeric id.
"""
import traceback

try:
    VT = 0x18021c2a0
    for slot in (0x130, 0xa58, 0xa60, 0x270):
        t = qword(VT + slot)
        f = fm.getFunctionAt(addr(t))
        print("=" * 78)
        print("### vt+%#x -> %#x  %s   bytes=%s"
              % (slot, t, f.getName() if f else "?", read_bytes(t, 16).hex()))
        print(dec(t))
        print()

    print("#" * 78)
    print("### FUN_1800d7b70  CARDS_CB_ERR_* table")
    src = dec(0x1800d7b70)
    print("len(src)=%d" % len(src))
    print(src)

    print("#" * 78)
    print("### FUN_1800d7170 / FUN_180009c80 -- which service is being acquired")
    for a in (0x1800d7170, 0x180009c80, 0x180018bd0, 0x180009b60):
        s = dec(a)
        print("--- %#x len=%d" % (a, len(s)))
        print(s)
except Exception:
    traceback.print_exc()
