"""
wscapture.py — capture the game's WebSocket frames via CDP so we can see incoming
state and OUTGOING commands (the goal: find the "attack" packet). Auto-finds the
running flyffbot's debug port; logs to wslog.txt:
    <time> <SENT|RECV> op<opcode> len=<bytes> <payload hex (truncated)>
No reload needed — enabling the Network domain reports frames on the already-open
socket. Run while you play; Ctrl+C to stop.
"""
import time
import base64
import urllib.request
from playwright.sync_api import sync_playwright

MAXHEX = 200  # how much of each payload to log (hex chars)


def find_port(a=9222, b=9250):
    for port in range(a, b):
        try:
            urllib.request.urlopen(f"http://127.0.0.1:{port}/json/version", timeout=0.3)
            return port
        except Exception:
            pass
    return None


def decode(opcode, payload):
    if opcode == 2:                       # binary
        try:
            data = base64.b64decode(payload)
        except Exception:
            data = b""
        return len(data), data.hex()
    b = (payload or "").encode("utf-8", "replace")   # text
    return len(b), "TXT:" + (payload or "")


def main():
    port = find_port()
    if not port:
        print("No CDP debug port found — is a flyffbot window running?")
        return
    print(f"Connecting to CDP port {port} ...")
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(f"http://127.0.0.1:{port}")
        ctx = browser.contexts[0]
        page = ctx.pages[0]
        cdp = ctx.new_cdp_session(page)
        cdp.send("Network.enable")
        out = open("wslog.txt", "w", encoding="utf-8")
        t0 = time.time()
        n = [0]

        def log(direction, params):
            r = params.get("response", {})
            ln, hx = decode(r.get("opcode"), r.get("payloadData", ""))
            out.write(f"{time.time()-t0:8.2f} {direction} op{r.get('opcode')} "
                      f"len={ln:5d} {hx[:MAXHEX]}\n")
            out.flush()
            n[0] += 1

        cdp.on("Network.webSocketFrameSent", lambda pr: log("SENT", pr))
        cdp.on("Network.webSocketFrameReceived", lambda pr: log("RECV", pr))
        print("Capturing WebSocket frames -> wslog.txt. Play the game (attack mobs).")
        while True:
            time.sleep(2)
            print(f"  {n[0]} frames captured")


if __name__ == "__main__":
    main()
