Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ecf2824e44 | |||
| f86dd83e21 | |||
| df143b0bf1 | |||
| 583da559b4 | |||
| 1a9b80d7df | |||
| 29ac575197 | |||
| c768f27d84 |
@@ -47,7 +47,7 @@ if (!(Test-Path $TOOL)) {
|
|||||||
|
|
||||||
# --- Build MPQ archives into dist/
|
# --- Build MPQ archives into dist/
|
||||||
Write-Host "Building MPQ archives from src/ -> dist/..."
|
Write-Host "Building MPQ archives from src/ -> dist/..."
|
||||||
& $TOOL $SRC_DIR $DIST_DIR
|
& $TOOL build-mpq $SRC_DIR $DIST_DIR
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
Write-Error "MPQ build failed!"
|
Write-Error "MPQ build failed!"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1,3 @@
|
|||||||
target/
|
target/
|
||||||
|
.sqlx/
|
||||||
|
.env
|
||||||
Generated
+171
-8
@@ -8,6 +8,15 @@ version = "2.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@@ -132,9 +141,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.6.0"
|
version = "4.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
|
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@@ -154,9 +163,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.6.0"
|
version = "4.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
|
checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -297,6 +306,29 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
|
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_filter"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.11.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"env_filter",
|
||||||
|
"jiff",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@@ -459,6 +491,30 @@ version = "1.0.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jiff"
|
||||||
|
version = "0.2.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e"
|
||||||
|
dependencies = [
|
||||||
|
"jiff-static",
|
||||||
|
"log",
|
||||||
|
"portable-atomic",
|
||||||
|
"portable-atomic-util",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jiff-static"
|
||||||
|
version = "0.2.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.91"
|
version = "0.3.91"
|
||||||
@@ -519,9 +575,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.29"
|
version = "0.4.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
@@ -568,6 +624,17 @@ dependencies = [
|
|||||||
"simd-adler32",
|
"simd-adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -674,6 +741,12 @@ dependencies = [
|
|||||||
"base64ct",
|
"base64ct",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs1"
|
name = "pkcs1"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
@@ -712,6 +785,15 @@ version = "1.13.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "portable-atomic-util"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
|
||||||
|
dependencies = [
|
||||||
|
"portable-atomic",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@@ -848,6 +930,35 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.10"
|
version = "0.9.10"
|
||||||
@@ -961,6 +1072,16 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||||
|
dependencies = [
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signature"
|
name = "signature"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
@@ -983,6 +1104,16 @@ version = "1.15.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.9.8"
|
version = "0.9.8"
|
||||||
@@ -1055,19 +1186,51 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tool"
|
name = "tool"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"env_logger",
|
||||||
|
"log",
|
||||||
|
"tokio",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"wow-mpq",
|
"wow-mpq",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.19.0"
|
version = "1.20.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
|
|||||||
@@ -4,5 +4,9 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clap = { version = "4.6.1", features = ["derive"] }
|
||||||
|
env_logger = "0.11.10"
|
||||||
|
log = "0.4.30"
|
||||||
|
tokio = { version = "1.52.3", features = ["full"] }
|
||||||
walkdir = "2.5.0"
|
walkdir = "2.5.0"
|
||||||
wow-mpq = "0.6.4"
|
wow-mpq = "0.6.4"
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
use clap::Args;
|
||||||
|
use log::info;
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
fs,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
use wow_mpq::{ArchiveBuilder, FormatVersion, ListfileOption, compression::flags};
|
||||||
|
|
||||||
|
#[derive(Args, Debug)]
|
||||||
|
pub struct BuildMpqCommand {
|
||||||
|
input_dir: PathBuf,
|
||||||
|
|
||||||
|
destination_dir: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute(args: BuildMpqCommand) -> Result<(), Box<dyn Error>> {
|
||||||
|
let data_dir = args.input_dir.join("Data");
|
||||||
|
if !data_dir.exists() {
|
||||||
|
return Err(format!("Data directory not found at {}", data_dir.display()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Found Data directory at {}", data_dir.display());
|
||||||
|
|
||||||
|
for entry in fs::read_dir(&data_dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
|
if !path.is_dir() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dir_name = entry.file_name().to_string_lossy().to_string();
|
||||||
|
|
||||||
|
if dir_name.starts_with("ruRU") {
|
||||||
|
for sub_entry in fs::read_dir(&path)? {
|
||||||
|
let sub_entry = sub_entry?;
|
||||||
|
let sub_path = sub_entry.path();
|
||||||
|
|
||||||
|
let sub_name = sub_entry.file_name().to_string_lossy().to_string();
|
||||||
|
let destination = args
|
||||||
|
.destination_dir
|
||||||
|
.join("Data")
|
||||||
|
.join(&dir_name)
|
||||||
|
.join(&sub_name);
|
||||||
|
|
||||||
|
let _ = build_mpq(&sub_path, &destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let destination = args.destination_dir.join("Data").join(&dir_name);
|
||||||
|
|
||||||
|
let _ = build_mpq(&path, &destination)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_mpq(input_dir: &Path, destination: &Path) -> Result<(), Box<dyn Error>> {
|
||||||
|
info!(
|
||||||
|
"Packing MPQ from {} to {}",
|
||||||
|
input_dir.display(),
|
||||||
|
destination.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut destination = destination.to_path_buf();
|
||||||
|
destination.set_extension("MPQ");
|
||||||
|
|
||||||
|
if let Some(parent) = destination.parent() {
|
||||||
|
fs::create_dir_all(parent)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut builder = ArchiveBuilder::new()
|
||||||
|
.version(FormatVersion::V2)
|
||||||
|
.block_size(7)
|
||||||
|
.default_compression(flags::ZLIB)
|
||||||
|
.listfile_option(ListfileOption::Generate);
|
||||||
|
|
||||||
|
let base = input_dir.canonicalize()?;
|
||||||
|
|
||||||
|
for entry in WalkDir::new(&base)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|e| e.ok())
|
||||||
|
.filter(|e| e.file_type().is_file())
|
||||||
|
{
|
||||||
|
let absolute_path = entry.path().canonicalize()?;
|
||||||
|
let relative_path = absolute_path.strip_prefix(&base)?;
|
||||||
|
|
||||||
|
builder = builder.add_file(&absolute_path, &relative_path.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = builder.build(&destination);
|
||||||
|
|
||||||
|
info!("Successfully packed {}", destination.display());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pub mod build_mpq;
|
||||||
+26
-96
@@ -1,111 +1,41 @@
|
|||||||
use std::env;
|
mod commands;
|
||||||
|
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use log::{error, info};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
|
|
||||||
use walkdir::WalkDir;
|
#[derive(Parser, Debug)]
|
||||||
use wow_mpq::compression::flags;
|
struct Cli {
|
||||||
use wow_mpq::{ArchiveBuilder, FormatVersion, ListfileOption};
|
#[command(subcommand)]
|
||||||
|
command: Commands,
|
||||||
/// Checks if a directory name looks like a WoW locale folder (e.g. ruRU, enUS, deDE).
|
|
||||||
fn is_locale_dir(name: &str) -> bool {
|
|
||||||
if name.len() != 4 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let b = name.as_bytes();
|
|
||||||
b[0].is_ascii_lowercase()
|
|
||||||
&& b[1].is_ascii_lowercase()
|
|
||||||
&& b[2].is_ascii_uppercase()
|
|
||||||
&& b[3].is_ascii_uppercase()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_mpq(input_dir: &Path, output_path: &Path) -> Result<(), Box<dyn Error>> {
|
#[derive(Subcommand, Debug)]
|
||||||
let mut output = output_path.to_path_buf();
|
enum Commands {
|
||||||
output.set_extension("MPQ");
|
BuildMpq(commands::build_mpq::BuildMpqCommand),
|
||||||
|
|
||||||
if let Some(parent) = output.parent() {
|
|
||||||
fs::create_dir_all(parent)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let base = input_dir.canonicalize()?;
|
#[tokio::main]
|
||||||
println!("Packing: {} -> {}", base.display(), output.display());
|
async fn main() {
|
||||||
|
env_logger::builder()
|
||||||
|
.filter_level(log::LevelFilter::Debug)
|
||||||
|
.format_target(false)
|
||||||
|
.format_timestamp(None)
|
||||||
|
.init();
|
||||||
|
|
||||||
let mut builder = ArchiveBuilder::new()
|
let args = Cli::parse();
|
||||||
.version(FormatVersion::V2)
|
|
||||||
.block_size(7) // 64 KB sectors
|
|
||||||
.default_compression(flags::ZLIB)
|
|
||||||
.listfile_option(ListfileOption::Generate);
|
|
||||||
|
|
||||||
for entry in WalkDir::new(&base)
|
if let Err(err) = run(args).await {
|
||||||
.into_iter()
|
error!("{}", err);
|
||||||
.filter_map(|e| e.ok())
|
|
||||||
.filter(|e| e.file_type().is_file())
|
|
||||||
{
|
|
||||||
let full_path = entry.path().canonicalize()?;
|
|
||||||
let rel_path = match full_path.strip_prefix(&base) {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(_) => {
|
|
||||||
eprintln!("Skipping (prefix mismatch): {}", full_path.display());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let archive_path = rel_path.to_string_lossy().replace('\\', "/");
|
|
||||||
println!(" Adding: {}", archive_path);
|
|
||||||
builder = builder.add_file(&full_path, &archive_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.build(&output)?;
|
|
||||||
println!("Created: {}", output.display());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
|
||||||
let args: Vec<String> = env::args().collect();
|
|
||||||
|
|
||||||
if args.len() != 3 {
|
|
||||||
eprintln!("Usage: tool <src_dir> <output_dir>");
|
|
||||||
eprintln!();
|
|
||||||
eprintln!(" src_dir — root of source tree (must contain Data/)");
|
|
||||||
eprintln!(" output_dir — destination root; MPQs are placed mirroring the src structure");
|
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let src_dir = PathBuf::from(&args[1]);
|
|
||||||
let output_dir = PathBuf::from(&args[2]);
|
|
||||||
|
|
||||||
let data_dir = src_dir.join("Data");
|
|
||||||
if !data_dir.exists() {
|
|
||||||
return Err(format!("Data/ not found inside src_dir: {}", src_dir.display()).into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for entry in fs::read_dir(&data_dir)? {
|
async fn run(args: Cli) -> Result<(), Box<dyn Error>> {
|
||||||
let entry = entry?;
|
info!("Starting tool...");
|
||||||
let path = entry.path();
|
|
||||||
if !path.is_dir() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = entry.file_name().to_string_lossy().to_string();
|
return match args.command {
|
||||||
|
Commands::BuildMpq(args) => commands::build_mpq::execute(args),
|
||||||
if is_locale_dir(&name) {
|
};
|
||||||
// e.g. ruRU/ — iterate its immediate subdirs, each is a patch source
|
|
||||||
for sub in fs::read_dir(&path)? {
|
|
||||||
let sub = sub?;
|
|
||||||
let sub_path = sub.path();
|
|
||||||
if !sub_path.is_dir() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let sub_name = sub.file_name().to_string_lossy().to_string();
|
|
||||||
let output_mpq = output_dir.join("Data").join(&name).join(&sub_name);
|
|
||||||
build_mpq(&sub_path, &output_mpq)?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Regular patch dir, e.g. patch-4/ or patch-Z/
|
|
||||||
let output_mpq = output_dir.join("Data").join(&name);
|
|
||||||
build_mpq(&path, &output_mpq)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("\nAll MPQ archives built successfully.");
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user