import frida, time, subprocess
ADB="/opt/android-sdk/platform-tools/adb"
JS=r"""
function rd(p){ try{if(p.isNull())return null;var l=p.add(8).readS32();if(l<0||l>128)return null;return p.add(0xc).readUtf16String(l);}catch(e){return null;} }
function ins(){ var m=Process.findModuleByName("libil2cpp.so"); if(!m) return false;
 var b=m.base; var seen={};
 // FetchCommodity result for each id
 Interceptor.attach(b.add(0x22ba97),{onEnter:function(a){this.id=rd(a[0])||rd(a[1]);},onLeave:function(rv){ if(this.id){var k="Fetch "+this.id+" "+(rv.isNull()?"MISS":"OK@"+rv); if(!seen[k]){seen[k]=1;send(k);}} }});
 // LoadInventoryItem: log the productId being loaded
 Interceptor.attach(b.add(0xd8c232),{onEnter:function(a){ send("LoadInventoryItem section="+a[1]); }});
 // SetEquippedRifle onEnter: dump this + owned-rifles list [this+0x4c] count
 Interceptor.attach(b.add(0xd99193),{onEnter:function(a){ try{ var self=a[0]; var lst=self.add(0x4c).readPointer(); var cnt=lst.isNull()?-1:lst.add(0xc).readS32(); send("SetEquippedRifle this="+self+" ownedRifles[0x4c]="+lst+" count="+cnt); }catch(e){send("SER-err "+e);} }});
 Interceptor.attach(b.add(0xd99264),{onEnter:function(a){ try{ var self=a[0]; var lst=self.add(0x48).readPointer(); send("SetEquippedBag this="+self+" [0x48]="+lst); }catch(e){} }});
 send("__ready"); return true; }
if(!ins()){ var iv=setInterval(function(){ if(ins()) clearInterval(iv); },120); }
"""
subprocess.run([ADB,"shell","am","force-stop","se.foglo.svt"])
dev=frida.get_usb_device(timeout=10); pid=dev.spawn(["se.foglo.svt"])
s=dev.attach(pid); sc=s.create_script(JS); t0=time.time()
s.on("detached", lambda r,c=None: print("DETACH @%.1f %s"%(time.time()-t0,r),flush=True))
sc.on("message",lambda m,d: print("[%5.1f] %s"%(time.time()-t0,m.get("payload",m)),flush=True))
sc.load(); dev.resume(pid)
time.sleep(30)
