use sylpheed_formats::{idxd::IdxdObject, PakArchive}; use std::collections::BTreeMap; fn main(){ let disc=std::env::var("SYLPHEED_DISC").unwrap(); let arc=PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap(); // schemas whose type0/content is squadron/formation/route/group/position let mut hit:BTreeMap=BTreeMap::new(); for e in arc.entries(){ let Ok(b)=arc.read(e) else{continue}; let Ok(o)=IdxdObject::parse(&b) else{continue}; let t=o.tokens(); let t0=t.first().cloned().unwrap_or_default(); let joined:String=t.iter().take(20).map(|s|s.as_str()).collect::>().join(" "); if ["Squadron","Formation","Route","UnitGroup","Position","Spawn","Wave","Frame","NullFrame"].iter().any(|k|t0.contains(k)||joined.contains(k)){ let ent=hit.entry(o.schema_hash).or_insert((0,t0.clone(),joined.chars().take(90).collect())); ent.0+=1; } } let mut v:Vec<_>=hit.into_iter().collect(); v.sort_by_key(|x|std::cmp::Reverse(x.1.0)); for (s,(c,t0,sample)) in &v{ println!("[{s:08x}] ×{c:<4} type0={t0:<18.18} :: {sample}"); } // dump a Squadron/UnitGroup blob fully to see if it has positions (binary floats) or refs println!("\n─── sample squadron/formation blob (first matching) ───"); for e in arc.entries(){ let Ok(b)=arc.read(e) else{continue}; let Ok(o)=IdxdObject::parse(&b) else{continue}; let t=o.tokens(); let t0=t.first().cloned().unwrap_or_default(); if t0.contains("Squadron")||t0.contains("Formation")||t0.contains("UnitGroup"){ println!("schema {:08x} type0={t0} count={} tokens={}, blob {}B", o.schema_hash,o.count,t.len(),b.len()); for (i,tk) in t.iter().take(30).enumerate(){ print!("{i:>2}:{tk:<20.20}"); if i%4==3{println!();} } println!(); // scan blob for float-like values (reasonable coords) in the binary region let nfloats=(0..b.len().saturating_sub(4)).step_by(4).filter(|&i|{let f=f32::from_be_bytes([b[i],b[i+1],b[i+2],b[i+3]]); f.is_finite()&&f.abs()>1.0&&f.abs()<1e6}).count(); println!(" ~{nfloats} plausible BE-float words in blob (positions live in binary region if high)"); break; } } }