diff --git a/Cargo.lock b/Cargo.lock index 441992ff..771bd492 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3492,9 +3492,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" dependencies = [ "memchr", ] @@ -4061,9 +4061,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.2" +version = "3.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "079f3a42cd87588d924ed95b533f8d30a483388c4e400ab736a7058e34f16169" +checksum = "e73139bc5ec2d45e6c5fd85be5a46949c1c39a4c18e56915f5eb4c12f975e377" dependencies = [ "base64 0.22.1", "chrono", @@ -4079,9 +4079,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.2" +version = "3.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc03aad67c1d26b7de277d51c86892e7d9a0110a2fe44bf6b26cc569fba302d6" +checksum = "b80d3d6b56b64335c0180e5ffde23b3c5e08c14c585b51a15bd0e95393f46703" dependencies = [ "darling", "proc-macro2 1.0.86", @@ -5256,9 +5256,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wayland-backend" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34e9e6b6d4a2bb4e7e69433e0b35c7923b95d4dc8503a84d25ec917a4bbfdf07" +checksum = "269c04f203640d0da2092d1b8d89a2d081714ae3ac2f1b53e99f205740517198" dependencies = [ "cc", "downcast-rs", @@ -5270,9 +5270,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.3" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e63801c85358a431f986cffa74ba9599ff571fc5774ac113ed3b490c19a1133" +checksum = "08bd0f46c069d3382a36c8666c1b9ccef32b8b04f41667ca1fef06a1adcc2982" dependencies = [ "bitflags 2.6.0", "rustix 0.38.34", @@ -5293,9 +5293,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.3" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a206e8b2b53b1d3fcb9428fec72bc278ce539e2fa81fe2bfc1ab27703d5187b9" +checksum = "09414bcf0fd8d9577d73e9ac4659ebc45bcc9cff1980a350543ad8e50ee263b2" dependencies = [ "rustix 0.38.34", "wayland-client", @@ -5342,9 +5342,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67da50b9f80159dec0ea4c11c13e24ef9e7574bd6ce24b01860a175010cea565" +checksum = "edf466fc49a4feb65a511ca403fec3601494d0dee85dbf37fff6fa0dd4eec3b6" dependencies = [ "proc-macro2 1.0.86", "quick-xml", @@ -5353,9 +5353,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "105b1842da6554f91526c14a2a2172897b7f745a805d62af4ce698706be79c12" +checksum = "4a6754825230fa5b27bafaa28c30b3c9e72c55530581220cef401fa422c0fae7" dependencies = [ "dlib", "log", diff --git a/crates/uk-editor/src/project.rs b/crates/uk-editor/src/project.rs index 68d67497..51a6bb4e 100644 --- a/crates/uk-editor/src/project.rs +++ b/crates/uk-editor/src/project.rs @@ -8,20 +8,20 @@ use fs_err as fs; use rayon::prelude::*; use uk_content::{resource::ResourceData, util::IndexMap}; use uk_manager::{core::Manager, settings::Platform}; -use uk_mod::{pack::sanitise, unpack::ParallelZipReader, Meta}; +use uk_mod::{pack::sanitise, unpack::ParallelZipReader, zstd::zstd_safe::WriteBuf, Meta}; #[derive(Debug, Clone)] pub struct Project { - pub path: PathBuf, - pub meta: Meta, + pub path: PathBuf, + pub meta: Meta, pub files: BTreeSet, } impl Project { pub fn new(name: &str, path: &Path, platform: Platform) -> Self { Project { - path: path.join(name), - meta: Meta { + path: path.join(name), + meta: Meta { api: env!("CARGO_PKG_VERSION").into(), name: name.into(), author: Default::default(), @@ -75,6 +75,7 @@ impl Project { ) .context("Failed to parse mod meta")?; let path = core.settings().projects_dir().join(sanitise(&meta.name)); + let decomp = uk_mod::unpack::init_decompressor(); let files = zip .iter() .par_bridge() @@ -85,31 +86,34 @@ impl Project { let data = zip.get_file(file).with_context(|| { format!("Failed to read file {} from ZIP", file.display()) })?; - if matches!( - file.file_name() - .unwrap_or_default() - .to_str() - .unwrap_or_default(), - "meta.yml" | "manifest.yml" - ) { + let file_name = file + .file_name() + .unwrap_or_default() + .to_str() + .unwrap_or_default(); + if file_name.ends_with(".yml") || file_name.starts_with("thumb.") { fs::write(dest, data).with_context(|| { format!("Failed to extract file {}", file.display()) })?; return Ok(None); } - let resource: ResourceData = minicbor_ser::from_slice( - &uk_mod::zstd::decode_all(data.as_slice()).with_context(|| { + let decomp_size = + uk_mod::zstd::bulk::Decompressor::upper_bound(data.as_slice()) + .unwrap_or(data.len() * 1024); + let decomp_data = decomp + .lock() + .decompress(data.as_slice(), decomp_size) + .or_else(|_| uk_mod::zstd::decode_all(data.as_slice())) + .with_context(|| { format!("Failed to decompress contents of {} in ZIP", file.display()) - })?, - ) - .with_context(|| format!("Failed to parse resource {}", file.display()))?; + })?; + let resource: ResourceData = minicbor_ser::from_slice(&decomp_data) + .with_context(|| format!("Failed to parse resource {}", file.display()))?; let data = match resource { ResourceData::Binary(bin) => bin, - res => { - ron::ser::to_string_pretty(&res, Default::default()) - .expect("Failed to serialize resource to RON") - .into() - } + res => ron::ser::to_string_pretty(&res, Default::default()) + .expect("Failed to serialize resource to RON") + .into(), }; fs::write(dest, data) .with_context(|| format!("Failed to extract file {}", file.display()))?; diff --git a/crates/uk-mod/src/lib.rs b/crates/uk-mod/src/lib.rs index 2152e62e..fea8122a 100644 --- a/crates/uk-mod/src/lib.rs +++ b/crates/uk-mod/src/lib.rs @@ -22,7 +22,7 @@ pub struct Manifest { #[serde(rename = "content")] pub content_files: BTreeSet, #[serde(rename = "aoc")] - pub aoc_files: BTreeSet, + pub aoc_files: BTreeSet, } impl Manifest { diff --git a/crates/uk-mod/src/unpack.rs b/crates/uk-mod/src/unpack.rs index b37a1b31..b4d0b88d 100644 --- a/crates/uk-mod/src/unpack.rs +++ b/crates/uk-mod/src/unpack.rs @@ -77,10 +77,10 @@ impl std::fmt::Debug for ZipData { #[self_referencing] pub struct ParallelZipReader { - data: ZipData, + data: ZipData, #[borrows(data)] #[covariant] - zip: piz::ZipArchive<'this>, + zip: piz::ZipArchive<'this>, #[borrows(zip)] #[covariant] files: HashMap<&'this Path, &'this piz::read::FileMetadata<'this>>, @@ -153,7 +153,7 @@ impl ParallelZipReader { } #[inline] -fn init_decompressor() -> Arc>> { +pub fn init_decompressor() -> Arc>> { Arc::new(Mutex::new( zstd::bulk::Decompressor::with_dictionary(super::DICTIONARY).unwrap(), )) @@ -477,14 +477,14 @@ static RSTB_EXCLUDE_NAMES: &[&str] = &["ActorInfo.product.byml"]; // #[derive(Debug)] pub struct ModUnpacker { - dump: Arc, + dump: Arc, manifest: Option, - mods: Vec, - endian: Endian, - lang: Language, - rstb: DashMap>, - hashes: StockHashTable, - out_dir: PathBuf, + mods: Vec, + endian: Endian, + lang: Language, + rstb: DashMap>, + hashes: StockHashTable, + out_dir: PathBuf, } impl ModUnpacker { @@ -566,19 +566,18 @@ impl ModUnpacker { Ok(Err(e)) => anyhow_ext::bail!(e), Ok(Ok(_)) => (), Err(e) => { - anyhow::bail!( - e.downcast::() - .or_else(|e| { - e.downcast::<&'static str>().map(|s| Box::new((*s).into())) - }) - .unwrap_or_else(|_| { - Box::new( - "An unknown error occured, check the log for possible \ + anyhow::bail!(e + .downcast::() + .or_else(|e| { + e.downcast::<&'static str>().map(|s| Box::new((*s).into())) + }) + .unwrap_or_else(|_| { + Box::new( + "An unknown error occured, check the log for possible \ details." - .to_string(), - ) - }) - ) + .to_string(), + ) + })) } } }