import pymem

pm = pymem.Pymem(43084)
base = 0x7ff6afc20000
igs = pm.read_ulonglong(base + 0x4430108)
ui_root = pm.read_ulonglong(igs + 0x2f0)
print(f"UI Root: {hex(ui_root)}")

# Recursively search UI elements for text "MAP CONTENT" or "Lord of the Pit" or "MAP OBJECTIVES"
visited = set()
matches = []

def search_ui(elem, depth=0):
    if not elem or elem in visited or depth > 15:
        return
    visited.add(elem)
    
    # Read text at typical text offsets (e.g. +0x100..+0x200 or string structs)
    for off in range(0, 0x300, 8):
        val = pm.read_ulonglong(elem + off)
        if 0x100000000 <= val <= 0x7fffffffffff:
            try:
                raw = pm.read_bytes(val, 64)
                # check utf-16
                s16 = raw.split(b'\x00\x00')[0].decode('utf-16le', errors='ignore')
                if len(s16) >= 4 and s16.isprintable() and any(k in s16.lower() for k in ["content", "objective", "pit", "ritual", "breach", "shrine", "delirium"]):
                    matches.append((elem, off, "UTF16", s16))
                # check ascii
                s8 = raw.split(b'\x00')[0].decode('ascii', errors='ignore')
                if len(s8) >= 4 and s8.isprintable() and any(k in s8.lower() for k in ["content", "objective", "pit", "ritual", "breach", "shrine", "delirium"]):
                    matches.append((elem, off, "ASCII", s8))
            except: pass
            
    # Children at +0x48 (vector of child pointers)
    p1 = pm.read_ulonglong(elem + 0x48)
    p2 = pm.read_ulonglong(elem + 0x50)
    if 0x100000000 <= p1 <= p2 <= 0x7fffffffffff and (p2 - p1) % 8 == 0:
        cnt = (p2 - p1) // 8
        if cnt < 200:
            for i in range(cnt):
                child = pm.read_ulonglong(p1 + i * 8)
                search_ui(child, depth + 1)

search_ui(ui_root)
print(f"Found {len(matches)} matches in UI tree:")
for elem, off, enc, s in matches[:20]:
    print(f"  UIElem {hex(elem)} +0x{off:x} [{enc}]: {s}")
