import time,re,json,requests,io,random,subprocess,math
import numpy as np, cv2
from PIL import Image
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
BASE='http://ein38eu95792b.4656hd15.cc/geetest_page.html'
o=Options(); o.set_preference('dom.webdriver.enabled',False); o.set_preference('network.trr.mode',5); o.set_preference('network.proxy.type',0)
o.set_preference('general.useragent.override','Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0')
d=webdriver.Firefox(service=Service('./gd0371/geckodriver'), options=o)
def xdo(*a): subprocess.run(['xdotool',*map(str,a)],check=False)
def cv_x(bg,sl,top):
    b=np.array(bg.convert('L')); s=np.array(sl.convert('RGBA')); sg=cv2.cvtColor(s,cv2.COLOR_RGBA2GRAY)
    h,w=sg.shape; top=max(0,min(b.shape[0]-h,top)); strip=b[top:top+h,:]; xs=[]
    for lo,hi in [(50,100),(80,160),(110,220)]:
        be=cv2.Canny(strip,lo,hi); se=cv2.Canny(sg,lo,hi)
        if be.sum()==0 or se.sum()==0: continue
        res=cv2.matchTemplate(be,se,cv2.TM_CCOEFF_NORMED); _,mx,_,ml=cv2.minMaxLoc(res); xs.append((ml[0],mx))
    xs.sort(); return xs[len(xs)//2] if xs else (0,0)
def human_drag(D,X,Y):
    xdo('mousemove',X+random.randint(-5,5),Y+random.randint(-2,2)); time.sleep(random.uniform(0.2,0.5))
    xdo('mousedown',1); time.sleep(random.uniform(0.12,0.3))
    # small backward jitter
    for _ in range(random.randint(1,2)):
        xdo('mousemove',int(X-random.uniform(0.5,1.5)),Y); time.sleep(random.uniform(0.02,0.05))
    over=random.uniform(3,6); total=D+over
    # minimum-jerk base with random time and tremor
    T=random.uniform(1.1,1.9); n=random.randint(45,65)
    last=0.0
    for i in range(1,n+1):
        s=i/n; p=10*s**3-15*s**4+6*s**5
        target=total*p + random.gauss(0,0.7)
        # occasional backward micro-move
        if random.random()<0.08: target=max(0,target-random.uniform(1,3))
        dx=target-last; last=target
        dy=random.gauss(0,0.6) if random.random()<0.5 else 0
        xdo('mousemove',int(X+last),int(Y+dy))
        if random.random()<0.12: time.sleep(random.uniform(0.05,0.16))
        else: time.sleep(T/n*random.uniform(0.6,1.6))
    time.sleep(random.uniform(0.1,0.25))
    # correct back to D
    cur=int(X+last); end=int(X+D)
    while cur>end:
        cur-=random.choice([1,1,2]); xdo('mousemove',cur,Y+random.choice([0,0,1,-1])); time.sleep(random.uniform(0.02,0.06))
    time.sleep(random.uniform(0.1,0.2)); xdo('mouseup',1)
try:
    d.set_window_position(0,0); d.set_window_size(1000,820); d.get(BASE)
    for _ in range(50):
        time.sleep(0.5)
        if d.execute_script("return document.querySelectorAll('.geetest_bg').length>0"): break
    time.sleep(1)
    info=d.execute_script("""function r(s){var e=document.querySelector(s);if(!e)return null;var b=e.getBoundingClientRect();return {t:b.top,l:b.left,w:b.width,h:b.height,bg:getComputedStyle(e).backgroundImage};}return {bg:r('.geetest_bg'),slice:r('.geetest_slice'),slicebg:r('.geetest_slice_bg'),btn:r('.geetest_btn'),sx:window.mozInnerScreenX,sy:window.mozInnerScreenY};""")
    def dl(u):
        m=re.search(r'url\("?([^")]+)"?\)',u or '');return requests.get(m.group(1).replace('http://','https://'),timeout=20,verify=False).content
    bg=Image.open(io.BytesIO(dl(info['bg']['bg']))).convert('RGB'); sl=Image.open(io.BytesIO(dl(info['slicebg']['bg']))).convert('RGBA')
    top=int(round((info['slice']['t']-info['bg']['t'])*bg.size[1]/info['bg']['h'])); top=max(0,min(bg.size[1]-sl.size[1],top))
    x,score=cv_x(bg,sl,top); D=x*(info['bg']['w']/bg.size[0])
    print('cv_x',x,'score',score,'D',D)
    X=int(info['sx']+info['btn']['l']+info['btn']['w']/2); Y=int(info['sy']+info['btn']['t']+info['btn']['h']/2)
    human_drag(D,X,Y); time.sleep(1.5)
    vurl=d.execute_script('return window.__vurl'); print('vurl',bool(vurl))
    if vurl:
        hdr={'Referer':'http://ein38eu95792b.4656hd15.cc/','User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0','Accept':'*/*'}
        r=requests.get(vurl,headers=hdr,timeout=20,verify=False)
        j=re.search(r'\((.*)\)\s*;?\s*$',r.text,re.S)
        if j:
            try:
                data=json.loads(j.group(1)); dd=data.get('data') or {}
                print('result',dd.get('result'),'fail',dd.get('fail_count'))
                if dd.get('result')=='success': open('gt_token.json','w').write(json.dumps(dd,ensure_ascii=False)); print('TOKEN OK')
            except Exception as e: print('parse err',e,r.text[:300])
finally: d.quit()
