use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process;
use wsz::archive::{pack_wsz_dir, unpack_wsz};
use wsz::sprites::SpriteManager;
use wsz::Wsz;
fn get_filename_without_extension(path: &str) -> String {
let path = Path::new(path);
path.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("unknown")
.to_string()
}
fn print_usage(program: &str) {
eprintln!("Usage:");
eprintln!(" Extract: {} --extract <path_to_wsz_file>", program);
eprintln!(" Pack: {} --pack <directory_to_pack>", program);
eprintln!(" Screenshot: {} --screenshot <path_to_wsz_file>", program);
}
fn pack_sprites(args: &Vec<String>) {
if args.len() < 3 {
eprintln!("Error: No directory specified for packing");
print_usage(&args[0]);
process::exit(1);
}
let dir_path = Path::new(&args[2]);
println!("Packing directory: {}", dir_path.display());
let wsz_name = format!(
"{}.wsz",
dir_path.file_name().and_then(|s| s.to_str()).unwrap_or("skin")
);
let output_path = dir_path.with_file_name(wsz_name);
match pack_wsz_dir(dir_path, &output_path) {
Ok(()) => println!("Successfully packed WSZ file!"),
Err(err) => {
eprintln!("Error packing WSZ file: {}", err);
process::exit(1);
}
}
}
fn extract_sprites(args: &Vec<String>) {
let wsz_path = &args[2];
let base_dir = get_filename_without_extension(wsz_path);
match unpack_wsz(wsz_path) {
Ok(contents) => {
println!("Found {} files", contents.len());
let sprite_manager = SpriteManager::new();
let sprite_sheets = SpriteManager::sprite_sheet_names();
for sheet in sprite_sheets {
match sprite_manager.extract_sprite_sheet_from_archive(&contents, &sheet) {
Ok(sprites) => {
if !sprites.is_empty() {
let bmp_base = Path::new(&sheet)
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or(&sheet)
.to_uppercase();
let sprite_dir = PathBuf::from(&base_dir).join(&bmp_base);
fs::create_dir_all(&sprite_dir)
.expect(&format!("Failed to create directory for {}", bmp_base));
for (name, sprite_img) in &sprites {
if sprite_img.width() == 0 || sprite_img.height() == 0 {
println!("Skipping sprite {} because it has no size", name);
continue;
}
let output_path = sprite_dir.join(format!("{}.png", name));
sprite_img
.save(&output_path)
.expect(&format!("Failed to save sprite {}", name));
}
println!("Extracted {} sprites from {}", sprites.len(), sheet);
} else {
println!("No sprites found in {}", sheet);
}
}
Err(err) => {
eprintln!("Error extracting sprites from {}: {}", sheet, err);
}
}
}
for (name, content) in &contents {
let name = Path::new(name).file_name().unwrap().to_str().unwrap();
let lower_name = name.to_lowercase();
if !lower_name.ends_with(".bmp") {
let output_path = PathBuf::from(&base_dir).join(&name);
fs::write(&output_path, content).expect(&format!("Failed to save {}", name));
println!("Saved {} to {}", name, output_path.display());
}
}
}
Err(err) => {
eprintln!("Error unpacking WSZ file: {}", err);
process::exit(1);
}
}
}
fn screenshot(args: &Vec<String>) {
let wsz_path = &args[2];
let screenshot_path = "screenshot.png";
let wsz = Wsz::from_file_path(wsz_path).unwrap();
let screenshot = wsz.render_screenshot().unwrap();
screenshot.save(screenshot_path).unwrap();
println!("Created screenshot at {}", screenshot_path);
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
print_usage(&args[0]);
process::exit(1);
}
if args[1] == "--pack" {
pack_sprites(&args);
} else if args[1] == "--screenshot" {
screenshot(&args);
} else if args[1] == "--extract" {
extract_sprites(&args);
} else {
eprintln!("Invalid command: {}", args[1]);
print_usage(&args[0]);
process::exit(1);
}
}