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(); let tables: [(u32, &str); 4] = [ (0x0426e81d, "Player / physics+scoring"), (0x6ab4825a, "Weapon"), (0x43faa517, "Unit / craft"), (0x3c5b0549, "Vessel / capital ship"), ]; for (want, label) in tables { // collect all records of this schema let mut recs: Vec = vec![]; for e in arc.entries() { let Ok(b) = arc.read(e) else { continue }; let Ok(o) = IdxdObject::parse(&b) else { continue; }; if o.schema_hash == want { recs.push(o); } } // field-union (explicit-valued keys), with occurrence count let mut cols: BTreeMap = BTreeMap::new(); for o in &recs { for (k, _) in o.resolved_fields() { *cols.entry(k.into()).or_default() += 1; } } println!("\n╔══ {label} [{want:08x}] {} records ══", recs.len()); let mut cv: Vec<_> = cols.into_iter().collect(); cv.sort_by_key(|x| std::cmp::Reverse(x.1)); let colstr: String = cv .iter() .take(28) .map(|(k, c)| format!("{k}({c})")) .collect::>() .join(" "); println!("║ numeric/enum fields: {colstr}"); // dump 2 sample records: identity + explicit fields for o in recs.iter().take(2) { let id = o.get_raw("ID").unwrap_or("?"); let name = o.get_raw("Name").unwrap_or(""); print!("║ • {id}"); if !name.is_empty() { print!(" «{name}»"); } println!(); let fields: Vec = o .resolved_fields() .iter() .map(|(k, v)| format!("{k}={v}")) .collect(); for chunk in fields.chunks(5) { println!("║ {}", chunk.join(" ")); } } } }