import ctypes
import ctypes.wintypes as w
import struct
import time
import subprocess
from PIL import ImageGrab

k32 = ctypes.WinDLL("kernel32", use_last_error=True)
u32 = ctypes.WinDLL("user32", use_last_error=True)

k32.OpenProcess.restype = w.HANDLE
k32.ReadProcessMemory.argtypes = [
    w.HANDLE, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)
]
k32.ReadProcessMemory.restype = w.BOOL
k32.WriteProcessMemory.argtypes = [
    w.HANDLE, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)
]
k32.WriteProcessMemory.restype = w.BOOL

# Attach to desktop
hdesk = u32.OpenDesktopW("Default", 0, False, 0x10000000)
if not hdesk:
    hdesk = u32.OpenInputDesktop(0, False, 0x10000000)
if hdesk:
    u32.SetThreadDesktop(hdesk)

def rpm(h, addr, size):
    buf = (ctypes.c_ubyte * size)()
    got = ctypes.c_size_t(0)
    if not k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, size, ctypes.byref(got)):
        return None
    return bytes(buf[: got.value])

def rpm_f32(h, addr):
    b = rpm(h, addr, 4)
    return struct.unpack("<f", b)[0] if b else None

def wpm_f32(h, addr, val):
    buf = (ctypes.c_ubyte * 4).from_buffer_copy(struct.pack("<f", val))
    got = ctypes.c_size_t(0)
    return bool(k32.WriteProcessMemory(h, ctypes.c_void_p(addr), buf, 4, ctypes.byref(got)))

out = subprocess.check_output(['powershell', '-Command', '(Get-Process -Name *PathOfExile*).Id'])
pid = int(out.decode().split()[0])
h = k32.OpenProcess(0x1F0FFF, False, pid)

igs = 0x48514e50f10
cam = struct.unpack("<Q", rpm(h, igs + 0x368, 8))[0]
zoom_addr = cam + 0x528

print(f"Initial Zoom @ {zoom_addr:#x}: {rpm_f32(h, zoom_addr)}")
img_before = ImageGrab.grab(all_screens=True)
img_before.save("captures/zoom_before_0_4.png")
print("Saved captures/zoom_before_0_4.png")

print("Writing Zoom = 0.4f (2.5x Zoom Out)...")
wpm_f32(h, zoom_addr, 0.4)
time.sleep(1.0)
print(f"Zoom during write: {rpm_f32(h, zoom_addr)}")

img_after = ImageGrab.grab(all_screens=True)
img_after.save("captures/zoom_after_0_4.png")
print("Saved captures/zoom_after_0_4.png")

# Now restore to 1.0f
wpm_f32(h, zoom_addr, 1.0)
print("Restored Zoom to 1.0f.")
