"""Test writing Zoom at +0x528 to real POE2 Camera.
"""
import ctypes
import ctypes.wintypes as w
import struct
import time
import subprocess

k32 = ctypes.WinDLL("kernel32", 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

def rpm_f32(h, addr):
    buf = (ctypes.c_ubyte * 4)()
    got = ctypes.c_size_t(0)
    if k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, 4, ctypes.byref(got)):
        return struct.unpack("<f", bytes(buf))[0]
    return 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)

cam_addr = 0x48514f60e00
zoom_addr = cam_addr + 0x528

orig_val = rpm_f32(h, zoom_addr)
print(f"Current Zoom @ {zoom_addr:#x}: {orig_val}")

# Try writing 1.5
print("Writing 1.5 to Zoom @ +0x528...")
ok = wpm_f32(h, zoom_addr, 1.5)
print(f"WriteProcessMemory result: {ok}")

# Read back over 500ms
for i in range(10):
    time.sleep(0.05)
    cur = rpm_f32(h, zoom_addr)
    print(f"[{i*50:3d}ms] Zoom = {cur}")

# Restore
wpm_f32(h, zoom_addr, orig_val)
print(f"Restored to {orig_val}")
