"""DIMENSION 2 Q3/Q4: readers for the refusing modes + SBC/Objectives bytes.

HYPOTHESIS: for season/draft/tournament the gate byte is read only to be
republished to the script layer (publisher) or to gate an unrelated sub-panel, not
to open the mode from a server response. SBC/Objectives have settings fields
(0x1fd2c/0x1fd42/0x1fd28, 0x1fd44) but NO IS_* publisher name; find their readers.

CONTROL: the applier FUN_18011dc50 must contain `mov [rdi+0x1fd3a],al` (season)
preceded by a `cmp [reg+FIELD],1 / sete al`, giving the season struct field index;
we already know trading is field +0x28 -> byte 0x1fd2e, so that pairing in the same
decompile validates the field-index reading.
"""
import traceback
try:
    print("=" * 70)
    print("APPLIER FUN_18011dc50 (field -> byte, full)")
    print("=" * 70)
    d = dec(0x18011dc50)
    print("len:", len(d))
    print(d)

    # readers to inspect: season 0x2b0 candidates (non-publisher), draft hub builder
    for label, fa in [
        ("SEASON reader FUN_1800b0e20 (slot 0x2b0)", 0x1800b0e20),
        ("SEASON reader FUN_18011e3c0 (slot 0x2b0)", 0x18011e3c0),
        ("DRAFT hub-tile builder FUN_1800b2680 (slot 0x2c8)", 0x1800b2680),
    ]:
        print("=" * 70)
        print(label)
        print("=" * 70)
        d = dec(fa)
        print("len:", len(d))
        print(d[:6000])

    print("=" * 70)
    print("SBC / OBJECTIVES byte disp-scans (.text, form-agnostic)")
    print("=" * 70)
    for name, disp in [
        ("allowUntradeableForSquadBuildingSets", 0x1fd2c),
        ("squadBuildingSetsGracePeriodMinutes", 0x1fd28),
        ("allowGracePeriodForSquadBuildingSets", 0x1fd42),
        ("enableObjectives", 0x1fd44),
        ("packOpeningAnimationEnabled", 0x1fd45),
    ]:
        pat = disp.to_bytes(4, "little")
        hits = find_all(pat, blocks=(".text",))
        print("\n%-40s disp %#x  (%d hit(s))" % (name, disp, len(hits)))
        for h in hits:
            f = fm.getFunctionContaining(addr(h))
            fn = f.getName() if f else "?"
            ent = int(f.getEntryPoint().getOffset()) if f else 0
            ins = (listing.getInstructionAt(addr(h - 3)) or
                   listing.getInstructionAt(addr(h - 2)) or
                   listing.getInstructionAt(addr(h)))
            print("    %#011x  in %-16s (%#x)  ins~ %s"
                  % (h, fn, ent, str(ins) if ins else "?"))
except Exception:
    traceback.print_exc()
