use std::env; use std::error::Error; use std::path::PathBuf; use walkdir::WalkDir; use wow_mpq::compression::flags; use wow_mpq::{ArchiveBuilder, FormatVersion, ListfileOption}; fn main() -> Result<(), Box> { // Read arguments let args: Vec = env::args().collect(); if args.len() != 3 { eprintln!("Usage: mpq-builder "); std::process::exit(1); } let input_dir = PathBuf::from(&args[1]); let mut output_file = PathBuf::from(&args[2]); output_file.set_extension("MPQ"); if !input_dir.exists() { return Err("Input directory does not exist".into()); } // Normalize base path (important for Windows) let base = input_dir.canonicalize()?; println!("Input directory: {}", base.display()); println!("Output file: {}", output_file.display()); // Configure MPQ builder let mut builder = ArchiveBuilder::new() .version(FormatVersion::V2) .block_size(7) // 64KB sectors .default_compression(flags::ZLIB) .listfile_option(ListfileOption::Generate); // Walk directory for entry in WalkDir::new(&base) .into_iter() .filter_map(|e| e.ok()) .filter(|e| e.file_type().is_file()) { // Canonicalize each file path to avoid StripPrefixError. let full_path = entry.path().canonicalize()?; // Safely compute relative path let rel_path = match full_path.strip_prefix(&base) { Ok(p) => p, Err(_) => { eprintln!("Skipping (prefix mismatch): {}", full_path.display()); continue; } }; // Convert to MPQ-style path (forward slashes) let archive_path = rel_path.to_string_lossy().replace("\\", "/"); println!("Adding: {}", archive_path); builder = builder.add_file(&full_path, &archive_path); } // Build archive builder.build(&output_file)?; println!("MPQ archive created: {}", output_file.display()); Ok(()) }