use rvz::HeaderRead;
use rvz::Rvz;
use wii_disk::Disc;
use std::fs::File;
use std::io::Read;
use std::io::Seek;
use std::path::PathBuf;
use clap::Parser;
#[derive(Parser)]
struct Cli {
#[arg(short, long)]
fetch_icon: bool,
files: Vec<PathBuf>,
}
trait ReadSeek: std::io::Read + Seek {}
impl<T: Seek + Read> ReadSeek for T {}
pub fn main() {
let args = Cli::parse();
if args.files.is_empty() {
return;
}
println!("[");
for (i, path) in args.files.iter().enumerate() {
let mut f = File::open(path).unwrap();
let disk: &mut dyn ReadSeek = if f.has_rvz_magic() {
let io = Rvz::new(f);
if let Err(err) = io {
eprintln!("Error: {err}");
continue;
}
&mut io.unwrap()
} else {
&mut f
};
let disk = Disc::try_from(disk);
if let Err(ref err) = disk {
eprintln!("Error: {err}");
continue;
}
let disk = disk.unwrap();
let header = &disk.metadata.header;
println!("\t{{");
println!("\t\t\"filename\": \"{}\",", path.display());
println!("\t\t\"console ID\": \"{}\",", header.console_id);
println!("\t\t\"game code\": \"{}\",", header.game_code);
println!("\t\t\"country code\": \"{}\",", header.country_code);
println!("\t\t\"maker code\": \"{}\",", header.maker_code);
println!("\t\t\"disk ID\": \"0x{:02X}\",", header.disk_id);
println!("\t\t\"version\": \"0x{:02X}\",", header.version);
println!(
"\t\t\"audio streaming\": \"0x{:02X}\",",
header.audio_streaming
);
println!(
"\t\t\"stream buffer size\": \"0x{:02X}\",",
header.stream_buffer_size
);
println!("\t\t\"magic\": \"0x{:08X}\",", header.magic);
println!("\t\t\"game name\": \"{}\",", header.game_name);
println!(
"\t\t\"disable hash verification\": \"0x{:02X}\",",
header.disable_hash_verification
);
println!(
"\t\t\"disable disc encryption\": \"0x{:02X}\",",
header.disable_disc_encryption
);
for partition in disk.metadata.partition_tables.partitions {
println!("\t\t\"partition {:X}\": {{", partition.offset);
println!("\t\t\t\"offset\": \"0x{:08X}\",", partition.offset);
println!("\t\t\t\"type\": \"0x{:08X}\",", partition.type_);
println!("\t\t\t\"ticket\": \"0x{:X?}\",", partition.ticket);
println!("\t\t\t\"TMD size\": {},", partition.tmd_size);
println!("\t\t\t\"TMD offset\": \"0x{:016X}\",", partition.tmd_offset);
println!("\t\t\t\"cert chain size\": {},", partition.cert_chain_size);
println!(
"\t\t\t\"cert chain offset\": \"0x{:016X}\",",
partition.cert_chain_offset
);
println!(
"\t\t\t\"h3 table offset\": \"0x{:016X}\",",
partition.h3_table_offset
);
println!(
"\t\t\t\"data offset\": \"0x{:016X}\",",
partition.data_offset
);
println!("\t\t\t\"data size\": {},", partition.data_size);
println!("\t\t}},");
}
if i == (args.files.len() - 1) {
println!("\t}}");
} else {
println!("\t}},");
}
}
println!("]");
}