"""
hpoverlay.py — inject a live HP-sensor overlay into the game window so you can compare
the in-game HP display with our memory-read sensor in real time.

Reads HP via the pointer chain (discovered by RE + memory analysis):
  controller = *(1230588)            (stable global)
  entity     = *(controller + 7792)  (live player entity)
  curHP_ratio= f32 @ entity + 308    (0..1)
  maxHP      = i32 @ entity + 316
  currentHP  = round(ratio * maxHP)

The overlay self-updates in-page (setInterval), so it keeps running after this script
exits. Run again to refresh/move it. Run with `off` to remove it.
"""
import sys, urllib.request
from playwright.sync_api import sync_playwright

OVERLAY_JS = r"""(()=>{
  const ADDR=1230588, ENT=7792, RATIO=308, MAX=316;
  let el=document.getElementById('hpSensor');
  if(!el){ el=document.createElement('div'); el.id='hpSensor';
    el.style.cssText='position:fixed!important;top:118px!important;right:8px!important;left:auto!important;'+
      'bottom:auto!important;z-index:2147483647;background:rgba(10,10,14,.92);color:#7dff7d;'+
      'font:bold 13px/1.3 monospace;padding:6px 9px;border:1px solid #3a7;border-radius:6px;'+
      'box-shadow:0 2px 8px rgba(0,0,0,.6);user-select:none;width:150px';
    (document.documentElement||document.body).appendChild(el);
  }
  if(window.__hpTimer) clearInterval(window.__hpTimer);
  window.__hpTimer=setInterval(()=>{
    try{
      const dv=new DataView(HEAPU8.buffer);
      const c=dv.getUint32(ADDR,true);
      const e=dv.getUint32(c+ENT,true);
      const r=dv.getFloat32(e+RATIO,true);
      const m=dv.getInt32(e+MAX,true);
      if(m>0 && m<100000 && r>=0 && r<=1.2){
        el.innerHTML='sensor HP<br>'+Math.round(r*m)+' / '+m+'<br><span style="color:#8ab">'+(r*100).toFixed(1)+'%</span>';
      } else { el.textContent='sensor HP: (not in-game?)'; }
    }catch(err){ el.textContent='sensor HP: err'; }
  }, 200);
})()"""

OFF_JS = "(()=>{if(window.__hpTimer)clearInterval(window.__hpTimer);const e=document.getElementById('hpSensor');if(e)e.remove();})()"

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

def main():
    p = port()
    if p is None:
        print("No live game on 9222-9250 — launch it first."); return
    with sync_playwright() as pw:
        page = pw.chromium.connect_over_cdp(f"http://127.0.0.1:{p}").contexts[0].pages[0]
        if len(sys.argv) > 1 and sys.argv[1] == "off":
            page.evaluate(OFF_JS); print("HP sensor overlay removed.")
        else:
            page.evaluate(OVERLAY_JS)
            print("HP sensor overlay injected (top-right, below the bot panel). Compare it to the in-game HP.")
            print("It self-updates; this script can exit. Run 'python hpoverlay.py off' to remove.")

if __name__ == "__main__":
    main()
