use anyhow::{bail, Result};
use larian_formats::{
bg3::{ModuleInfoAttribute, ModuleInfoNode, Save, Version},
lsf,
lspk::{self, DecompressedLspk},
};
use std::{fs::File, path::PathBuf};
pub fn parse(paths: Vec<PathBuf>) -> Result<()> {
for path in paths {
let displayed_path = path.display().to_string();
println!("{displayed_path}");
for _ in displayed_path.chars() {
print!("-");
}
println!();
let file = File::open(&path)?;
match path.extension().map(|s| s.to_string_lossy()).as_deref() {
Some("zip") => {
let data = lspk::entry_from_zipfile(&file)?;
parse_lspk(&data.1)?;
}
Some("lsf") => {
let data = lsf::Reader::new(file)?.read()?;
data.print_summary();
}
Some("pak") => {
let data = lspk::Reader::new(file)?.read()?;
parse_lspk(&data)?;
}
_other => {
bail!("expected .lsf or .pak file");
}
}
println!();
}
Ok(())
}
fn parse_lspk(data: &DecompressedLspk) -> Result<()> {
let Save { version, region } = data.extract_meta_lsx()?.extract_meta_lsx_data()?;
let Version {
major,
minor,
revision,
build,
} = version;
println!("Game version : {major}.{minor}.{revision}.{build}");
let info = region
.node
.children
.node
.iter()
.find(|child| child.id == "ModuleInfo");
if let Some(ModuleInfoNode { attribute, .. }) = info {
let mut info = [("", ""), ("", ""), ("", ""), ("", "")];
for ModuleInfoAttribute { id, value, .. } in attribute {
if id == "Name" {
info[0] = (id, value);
} else if id == "Folder" {
info[1] = (id, value);
} else if id == "Version" || id == "Version64" {
info[2] = (id, value);
} else if id == "UUID" {
info[3] = (id, value);
}
}
for (id, value) in info {
if !id.is_empty() {
println!("{id:<13}: {value}");
}
}
}
Ok(())
}