use std::collections::BTreeMap; use sylpheed_formats::{idxd::IdxdObject, PakArchive}; 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; } } }