// Research only: current assembly SHA c5e02e6e984f7e5577c78b995a8efeee2d06ee22e67d484ad5e859c8bf21e144. // Wave formation consumer f0c9d50 calls this flat row getter at RVA 1e33bb30. // Only that getter and the verified existing serializer run; no battle is created. const ids=globalThis.CW_FORMATION_IDS; if(!Array.isArray(ids)||!ids.length||ids.length>128||ids.some(x=>!Number.isInteger(x)||x<=0))throw Error('Bounded formation ID plan required'); const m=Process.getModuleByName('GameAssembly.dll'); const check=(rva,expected)=>{const b=Array.from(new Uint8Array(m.base.add(rva).readByteArray(expected.length)));if(b.some((x,i)=>x!==expected[i]))throw Error('Entry identity differs');}; check(0x1e33bb30,[0x56,0x48,0x83,0xec,0x60]);check(0x1d3efb60,[0x56,0x57,0x48,0x83,0xec,0x28]); const read=new NativeFunction(m.base.add(0x1e33bb30),'pointer',['uint32','pointer']); const serialize=new NativeFunction(m.base.add(0x1d3efb60),'pointer',['pointer','pointer']); let index=0,done=false; Interceptor.attach(m.base.add(0xdb5f860),{onLeave(){if(done)return;try{for(let n=0;n<4&&index65536)throw Error('Row bound');send({kind:'ROW',id,json:v.add(0x14).readUtf16String(length)});}if(index===ids.length){done=true;send({kind:'END',count:index});}}catch(e){done=true;send({kind:'ERROR',error:String(e)});}}}); send({kind:'BEGIN',count:ids.length});