import frida, time, subprocess, sys
ADB="/opt/android-sdk/platform-tools/adb"
JS=r"""
function ins(){var m=Process.findModuleByName("libil2cpp.so");if(!m)return false;var b=m.base;
 function T(f){try{f();}catch(e){send({warn:""+e});}}
 // force get_playButtonMode -> 2
 T(function(){Interceptor.attach(b.add(0x244e42),{onLeave:function(rv){rv.replace(ptr(2));}});});
 // trace match chain
 [[0xea27d3,"OnSelectSniperMode"],[0xd31a4f,"Matchmaking.Initiate"],[0xd86224,"CreateMatch.MoveNext"],[0xd34da2,"CreateBotMatch"],[0x1003e66,"CreateRoom(online)"],[0xd3c97a,"OnJoinedRoom"],[0xd3cb37,"LoadLevel"],[0xe484bd,"GameController.Start"],[0xe9ea40,"SignalUnlocksToTutorial"]].forEach(function(x){T(function(){Interceptor.attach(b.add(x[0]),{onEnter:function(){send({info:"CHAIN "+x[1]});}});});});
 T(function(){var ab=Process.findModuleByName("libc.so").findExportByName("abort");Interceptor.attach(ab,{onEnter:function(){var bt=Thread.backtrace(this.context,Backtracer.ACCURATE).slice(0,10).map(function(a){var mm=Process.findModuleByAddress(a);return mm?mm.name+"+0x"+a.sub(mm.base).toString(16):""+a;}).join(",");send({info:"*** ABORT "+bt});}});});
 send({info:"__ready playButtonMode forced to 2"});return true;}
if(!ins()){var iv=setInterval(function(){if(ins())clearInterval(iv);},120);}
"""
dev=frida.get_usb_device(timeout=10)
pid=int(subprocess.run([ADB,"shell","pidof","se.foglo.svt"],capture_output=True,text=True).stdout.split()[0])
s=dev.attach(pid); sc=s.create_script(JS); t0=time.time()
s.on("detached", lambda r,c=None: print("DETACH %s @%.1f"%(r,time.time()-t0),flush=True))
sc.on("message",lambda m,d: print("[%5.1f] %s"%(time.time()-t0,m.get("payload",m)),flush=True))
sc.load()
time.sleep(2)
print("=== tapping SNIPER ===",flush=True)
subprocess.run([ADB,"shell","input","tap","690","730"])
time.sleep(25)
