use std::fs;
use wow_mpq::{
Archive, ArchiveBuilder, AttributesOption, FormatVersion, ListfileOption, compression::flags,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Creating simple archive...");
ArchiveBuilder::new()
.add_file_data(b"Hello, MPQ!".to_vec(), "readme.txt")
.add_file_data(b"Some game data".to_vec(), "data/game.dat")
.build("simple.mpq")?;
println!("Created simple.mpq");
println!("\nCreating archive from files...");
fs::create_dir_all("test_files")?;
fs::write("test_files/config.ini", "[Game]\nVersion=1.0")?;
fs::write("test_files/data.bin", vec![0xDE, 0xAD, 0xBE, 0xEF])?;
ArchiveBuilder::new()
.version(FormatVersion::V2)
.add_file("test_files/config.ini", "config.ini")
.add_file("test_files/data.bin", "data.bin")
.build("from_files.mpq")?;
println!("Created from_files.mpq");
println!("\nCreating customized archive...");
fs::write(
"custom_list.txt",
"(listfile)\r\nreadme.txt\r\nsecret.dat\r\n",
)?;
ArchiveBuilder::new()
.version(FormatVersion::V3)
.block_size(4) .default_compression(flags::BZIP2)
.listfile_option(ListfileOption::External("custom_list.txt".into()))
.add_file_data_with_options(
b"Not compressed".to_vec(),
"readme.txt",
0, false, 0x0409, )
.add_file_data_with_options(
b"Super secret data".to_vec(),
"secret.dat",
flags::ZLIB,
true, 0, )
.build("custom.mpq")?;
println!("Created custom.mpq");
println!("\nVerifying archives...");
for archive_name in &["simple.mpq", "from_files.mpq", "custom.mpq"] {
println!("\nChecking {archive_name}:");
let mut archive = Archive::open(archive_name)?;
match archive.list() {
Ok(files) => {
println!(" Files in archive:");
for file in files {
println!(
" - {} ({} bytes, compressed: {} bytes)",
file.name, file.size, file.compressed_size
);
}
}
Err(_) => {
println!(" No (listfile) found - cannot enumerate files");
}
}
}
println!("\nCreating archive with attributes file...");
ArchiveBuilder::new()
.version(FormatVersion::V2)
.listfile_option(ListfileOption::Generate)
.attributes_option(AttributesOption::GenerateFull) .default_compression(flags::ZLIB)
.add_file_data(b"Test data with attributes".to_vec(), "test.txt")
.add_file_data(b"Binary data".to_vec(), "data/binary.dat")
.build("with_attributes.mpq")?;
println!("Created with_attributes.mpq");
println!("\nCreating archives in different MPQ versions...");
let test_data = vec![
(
"version_test.txt",
b"Same content in all versions".as_slice(),
),
("data/test.bin", &[0x01, 0x02, 0x03, 0x04]),
];
for (version, name) in [
(FormatVersion::V1, "v1_archive.mpq"),
(FormatVersion::V2, "v2_archive.mpq"),
(FormatVersion::V3, "v3_archive.mpq"),
(FormatVersion::V4, "v4_archive.mpq"),
] {
let mut builder = ArchiveBuilder::new()
.version(version)
.listfile_option(ListfileOption::Generate);
for (filename, content) in &test_data {
builder = builder.add_file_data(content.to_vec(), filename);
}
builder.build(name)?;
println!(" Created {name} (version {version:?})");
}
let all_archives = [
"simple.mpq",
"from_files.mpq",
"custom.mpq",
"with_attributes.mpq",
"v1_archive.mpq",
"v2_archive.mpq",
"v3_archive.mpq",
"v4_archive.mpq",
];
println!("\nFinal verification of all archives:");
for archive_name in &all_archives {
match Archive::open(archive_name) {
Ok(mut archive) => match archive.get_info() {
Ok(info) => {
println!(
" {} - Format: {:?}, Files: {}, Size: {} KB",
archive_name,
info.format_version,
info.file_count,
info.file_size / 1024
);
}
Err(_) => {
println!(" {archive_name} - Could not get archive info");
}
},
Err(e) => {
println!(" {archive_name} - Error: {e}");
}
}
}
fs::remove_dir_all("test_files").ok();
fs::remove_file("custom_list.txt").ok();
println!(
"\nExample complete! Created {} archives demonstrating different features.",
all_archives.len()
);
println!("Archives can be cleaned up manually if desired.");
Ok(())
}