import time,re,json,requests,io,random,subprocess
import numpy as np
from PIL import Image
from scipy import ndimage
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',2); o.set_preference('network.proxy.autoconfig_url','http://127.0.0.1:9999/proxy.pac')
d=webdriver.Firefox(service=Service('./gd0371/geckodriver'), options=o)
def xdo(*a): subprocess.run(['xdotool',*map(str,a)],check=False)
def state():
    return d.execute_script("""var s=document.querySelector('.geetest_slice'),b=document.querySelector('.geetest_bg'),r=document.querySelector('.geetest_result');
      return {sl:s?s.getBoundingClientRect().left:null,bl:b?b.getBoundingClientRect().left:null,style:s?s.getAttribute('style'):null,bg:b?getComputedStyle(b).backgroundImage:null,res:r?r.innerText:null,val:window.validateResult};""")
def gap(bg,sl):
    g=np.array(bg.convert('L')).astype(np.float32); sa=np.array(sl); full=sa[:,:,3]>128
    ys,xs=np.where(full); ax0,ay0=xs.min(),ys.min(); aw,ah=xs.max()-ax0+1,ys.max()-ay0+1
    am=full[ay0:ay0+ah,ax0:ax0+aw]; best=[]
    for th in range(50,141,10):
        dark=g<th; lab,n=ndimage.label(dark)
        for i in range(1,n+1):
            yy,xx=np.where(lab==i); a=len(xx)
            if a<300: continue
            x0,x1,y0,y1=xx.min(),xx.max(),yy.min(),yy.max(); w=x1-x0+1; h=y1-y0+1
            if abs(w-aw)>15 or abs(h-ah)>15: continue
            cm=lab[y0:y1+1,x0:x1+1]==i; A=np.zeros_like(cm); hh=min(ah,cm.shape[0]); ww=min(aw,cm.shape[1]); A[:hh,:ww]=am[:hh,:ww]
            inter=(A&cm).sum(); union=(A|cm).sum(); iou=inter/union if union else 0
            best.append((iou,int(x0)-int(ax0)))
    return max(best) if best else None
def drag(D,X,Y):
    xdo('mousemove',X,Y); time.sleep(0.3); xdo('mousedown',1); time.sleep(0.2)
    pos=0; over=random.uniform(2,4)
    while pos<D+over:
        pos=min(D+over,pos+random.uniform(2,6)); xdo('mousemove',int(X+pos),Y+random.choice([0,0,0,1,-1])); time.sleep(random.uniform(0.015,0.04))
    time.sleep(0.1)
    while pos>D: pos-=random.choice([1,2]); xdo('mousemove',int(X+pos),Y); time.sleep(random.uniform(0.02,0.04))
    time.sleep(0.1); xdo('mouseup',1)
try:
    d.set_window_position(0,0); d.set_window_size(1000,820); d.get(BASE)
    for _ in range(60):
        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')
    g0=gap(bg,sl); print('gap',g0)
    X=int(info['sx']+info['btn']['l']+info['btn']['w']/2); Y=int(info['sy']+info['btn']['t']+info['btn']['h']/2)
    scale=info['bg']['w']/bg.size[0]
    for off in [0,3,-3,6,-6]:
        D=(g0[1]+off)*scale
        print('drag offset',off,'D',D,'state_before',state())
        drag(D,X,Y); time.sleep(3.5)
        print('state_after',state())
        time.sleep(1.5)
finally: d.quit()
