From b7379367727474615d053f3eb86a57fea8ba257b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=88=91=E5=8F=AF=E8=83=BD=E5=BE=88=E5=BB=A2?= Date: Thu, 11 Jan 2024 14:48:51 +0800 Subject: [PATCH 1/4] :sparkles: Text asset decryption --- Cargo.lock | 144 ++++++++++++++---------------- extract/Cargo.toml | 6 ++ extract/src/class/asset_bundle.rs | 4 +- extract/src/class/sprite.rs | 2 +- extract/src/class/text_asset.rs | 67 ++++++++++++-- extract/src/class/texture_2d.rs | 2 +- extract/src/lib.rs | 74 ++++++++------- extract/tests/test_text.unity3d | Bin 0 -> 2720 bytes 8 files changed, 181 insertions(+), 118 deletions(-) create mode 100644 extract/tests/test_text.unity3d diff --git a/Cargo.lock b/Cargo.lock index 4d0af88..866b597 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,6 +82,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -234,14 +243,14 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] @@ -382,6 +391,17 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + [[package]] name = "either" version = "1.9.0" @@ -450,9 +470,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -477,6 +497,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "humantime" version = "2.1.0" @@ -713,7 +742,9 @@ name = "mltd-asset-extract" version = "0.1.0" dependencies = [ "acb", + "aes", "byteorder", + "cbc", "clap", "ctor", "env_logger", @@ -725,8 +756,10 @@ dependencies = [ "num-derive", "num-traits", "num_cpus", + "pbkdf2", "rabex", "rayon", + "sha1", "texture2ddecoder", ] @@ -854,6 +887,16 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1208,6 +1251,17 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -1226,6 +1280,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "1.0.109" @@ -1250,9 +1310,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -1432,15 +1492,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -1459,21 +1510,6 @@ dependencies = [ "windows-targets 0.52.0", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -1504,12 +1540,6 @@ dependencies = [ "windows_x86_64_msvc 0.52.0", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -1522,12 +1552,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -1540,12 +1564,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -1558,12 +1576,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -1576,12 +1588,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -1594,12 +1600,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -1612,12 +1612,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -1632,9 +1626,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.33" +version = "0.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7520bbdec7211caa7c4e682eb1fbe07abe20cee6756b6e00f537c82c11816aa" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" dependencies = [ "memchr", ] diff --git a/extract/Cargo.toml b/extract/Cargo.toml index bd113d2..161c34c 100644 --- a/extract/Cargo.toml +++ b/extract/Cargo.toml @@ -11,6 +11,12 @@ version = "0.1.0" # For decoding ACB audio acb = { path = "../acb" } +# For text asset decryption +aes = "0.8.3" +cbc = "0.1.2" +pbkdf2 = "0.12.2" +sha1 = "0.10.6" + # For reading numbers from binary data byteorder = "1.5.0" diff --git a/extract/src/class/asset_bundle.rs b/extract/src/class/asset_bundle.rs index df7bf15..95179b5 100644 --- a/extract/src/class/asset_bundle.rs +++ b/extract/src/class/asset_bundle.rs @@ -13,7 +13,7 @@ use rabex::read_ext::ReadUrexExt; use crate::utils::ReadAlignedExt; use crate::version::*; -pub fn _construct_p_ptr( +pub(super) fn _construct_p_ptr( reader: &mut R, serialized_file: &SerializedFile, ) -> Result> @@ -94,7 +94,7 @@ where Ok(asset_info) } -pub fn _construct_asset_bundle( +pub(super) fn _construct_asset_bundle( data: &[u8], serialized_file: &SerializedFile, ) -> Result> diff --git a/extract/src/class/sprite.rs b/extract/src/class/sprite.rs index 8893af4..b80c22a 100644 --- a/extract/src/class/sprite.rs +++ b/extract/src/class/sprite.rs @@ -18,7 +18,7 @@ use crate::version::*; use super::asset_bundle::_construct_p_ptr; use super::mesh::{construct_sub_mesh, construct_vertex_data}; -pub fn _construct_sprite( +pub(super) fn _construct_sprite( data: &[u8], serialized_file: &SerializedFile, ) -> Result> diff --git a/extract/src/class/text_asset.rs b/extract/src/class/text_asset.rs index 46eb154..a74c5c7 100644 --- a/extract/src/class/text_asset.rs +++ b/extract/src/class/text_asset.rs @@ -6,19 +6,21 @@ use std::path::Path; use std::slice::from_raw_parts; use std::str::FromStr; -use byteorder::BigEndian; -use byteorder::ByteOrder; -use byteorder::LittleEndian; +use aes::cipher::block_padding::Pkcs7; +use aes::cipher::inout::InOutBufReserved; +use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit}; +use aes::Aes192; +use byteorder::{BigEndian, ByteOrder, LittleEndian}; +use cbc::{Decryptor, Encryptor}; use rabex::files::SerializedFile; use rabex::objects::classes::TextAsset; use rabex::read_ext::ReadUrexExt; -use crate::utils::ffmpeg; -use crate::utils::ReadAlignedExt; +use crate::utils::{ffmpeg, ReadAlignedExt}; use crate::version::*; use crate::ExtractorArgs; -pub fn _construct_text_asset( +pub(super) fn _construct_text_asset( data: &[u8], serialized_file: &SerializedFile, ) -> Result> @@ -85,3 +87,56 @@ where output_path, ) } + +pub const MLTD_TEXT_PBKDF2_HMAC_SHA1_KEY: &[u8; 8] = b"Millicon"; +pub const MLTD_TEXT_PBKDF2_HMAC_SHA1_SALT: &[u8; 9] = b"DAISUL___"; +pub const MLTD_TEXT_PBKDF2_HMAC_SHA1_ROUNDS: u32 = 1000; + +#[rustfmt::skip] +/// The AES-192-CBC key used to decrypt the text asset. +/// +/// It is derived from [`MLTD_TEXT_PBKDF2_HMAC_SHA1_KEY`] and +/// [`MLTD_TEXT_PBKDF2_HMAC_SHA1_SALT`] using PBKDF2-HMAC-SHA1, where +/// the first 24 bytes of the derived key are used as the actual key. +pub const MLTD_TEXT_DECRYPT_KEY: &[u8; 24] = &[ + 0xad, 0x3f, 0x0f, 0x89, 0xee, 0x51, 0xc5, 0x37, + 0x73, 0x1f, 0x17, 0x96, 0xf7, 0x5c, 0x71, 0x84, + 0x01, 0x61, 0x75, 0x6d, 0xa0, 0xd4, 0x86, 0xc9, +]; + +#[rustfmt::skip] +/// The AES-192-CBC initialization vector used to decrypt the text asset. +/// +/// It is derived from [`MLTD_TEXT_PBKDF2_HMAC_SHA1_KEY`] and +/// [`MLTD_TEXT_PBKDF2_HMAC_SHA1_SALT`] using PBKDF2-HMAC-SHA1, where +/// the last 16 bytes of the derived key are used as the actual IV. +pub const MLTD_TEXT_DECRYPT_IV: &[u8; 16] = &[ + 0x4e, 0x40, 0xb3, 0x8a, 0xeb, 0xf1, 0xa8, 0x53, + 0x12, 0x2c, 0x5f, 0xad, 0xcc, 0xa3, 0x68, 0x5d, +]; + +pub type MltdTextEncryptor = Encryptor; +pub type MltdTextDecryptor = Decryptor; + +pub fn encrypt_text(text: &[u8]) -> Result, Box> { + let encryptor = + MltdTextEncryptor::new(MLTD_TEXT_DECRYPT_KEY.into(), MLTD_TEXT_DECRYPT_IV.into()); + let mut buf = text.to_owned(); + + let buf = InOutBufReserved::from_mut_slice(&mut buf, text.len()).map_err(|e| e.to_string())?; + let buf = encryptor.encrypt_padded_inout_mut::(buf).map_err(|e| e.to_string())?; + + Ok(buf.to_owned()) +} + +pub fn decrypt_text(cipher: &[u8]) -> Result, Box> { + let decryptor = + MltdTextDecryptor::new(MLTD_TEXT_DECRYPT_KEY.into(), MLTD_TEXT_DECRYPT_IV.into()); + let mut buf = cipher.to_owned(); + + let buf = decryptor + .decrypt_padded_inout_mut::(buf.as_mut_slice().into()) + .map_err(|e| e.to_string())?; + + Ok(buf.to_owned()) +} diff --git a/extract/src/class/texture_2d.rs b/extract/src/class/texture_2d.rs index 12bde38..4df2fd8 100644 --- a/extract/src/class/texture_2d.rs +++ b/extract/src/class/texture_2d.rs @@ -22,7 +22,7 @@ use crate::environment::Environment; use crate::utils::{ffmpeg, solve_puzzle, ReadAlignedExt}; use crate::{version::*, ExtractorArgs}; -fn _construct_texture_2d( +pub(super) fn _construct_texture_2d( data: &[u8], serialized_file: &SerializedFile, ) -> Result> diff --git a/extract/src/lib.rs b/extract/src/lib.rs index df96a40..427f53a 100644 --- a/extract/src/lib.rs +++ b/extract/src/lib.rs @@ -1,13 +1,12 @@ -mod class; -mod environment; -mod utils; -mod version; +pub mod class; +pub mod environment; +pub mod utils; +pub mod version; use std::error::Error; use std::fs::{read_dir, File}; use std::io::{Cursor, Seek, SeekFrom}; use std::path::{Path, PathBuf}; -use std::process::exit; use std::sync::atomic::{AtomicU64, Ordering}; #[cfg(not(feature = "debug"))] @@ -23,7 +22,7 @@ use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use rayon::ThreadPoolBuilder; use crate::class::asset_bundle::construct_asset_bundle; -use crate::class::text_asset::{construct_text_asset, extract_acb}; +use crate::class::text_asset::{construct_text_asset, decrypt_text, extract_acb}; use crate::class::texture_2d::extract_texture_2d; use crate::environment::{check_file_type, FileType}; @@ -31,8 +30,8 @@ use crate::environment::{check_file_type, FileType}; #[command(author, version, about, arg_required_else_help(true))] pub struct ExtractorArgs { /// The input directory or file - #[arg(value_name = "PATH")] - input: PathBuf, + #[arg(value_name = "PATH", num_args = 1..)] + input_paths: Vec, /// The output directory #[arg(short, long, value_name = "DIR", display_order = 1)] @@ -71,17 +70,36 @@ pub fn extract_media(args: &ExtractorArgs) -> Result<(), Box> { #[cfg(not(feature = "debug"))] create_dir_all(&args.output)?; - let input_realpath = args.input.canonicalize()?; + let mut entries = Vec::new(); + + for p in &args.input_paths { + let input_realpath = p.canonicalize()?; + + if input_realpath.is_file() { + entries.push(input_realpath); + } else if !input_realpath.is_dir() { + log::warn!("Input path is not a file or directory"); + } else { + let input_paths: Vec<_> = read_dir(input_realpath)?.collect(); + let mut input_paths = input_paths + .into_iter() + .filter(|r| { + if let Err(e) = r { + log::warn!("failed to read directory entry: {}", e); + } + r.is_ok() + }) + .map(|e| e.unwrap().path()) + .collect(); - if input_realpath.is_file() { - return extract_file(&input_realpath, args); + entries.append(&mut input_paths); + } } - if !input_realpath.is_dir() { - log::error!("Input path is not a file or directory"); - exit(1); - } + extract_files(&entries, args) +} +fn extract_files(input_paths: &[PathBuf], args: &ExtractorArgs) -> Result<(), Box> { log::debug!("setting progress bar"); let template = "{msg:60} {eta:4} [{wide_bar:.cyan/blue}] {percent:3}%"; @@ -95,9 +113,7 @@ pub fn extract_media(args: &ExtractorArgs) -> Result<(), Box> { } .progress_chars("##-"); - let entries: Vec<_> = read_dir(&args.input)?.collect(); - let progress_bar = ProgressBar::new(entries.len() as u64).with_style(progress_bar_style); - + let progress_bar = ProgressBar::new(input_paths.len() as u64).with_style(progress_bar_style); let finished_count = AtomicU64::new(0); log::debug!("setting thread pool"); @@ -105,22 +121,14 @@ pub fn extract_media(args: &ExtractorArgs) -> Result<(), Box> { let thread_pool_builder = ThreadPoolBuilder::new().num_threads(args.parallel as usize); thread_pool_builder.build_global()?; - entries.par_iter().for_each(|entry| { - let entry = match entry { - Ok(e) => e, - Err(e) => { - progress_bar.suspend(|| log::warn!("failed to read directory entry: {}", e)); - return; - } - }; - - if let Err(e) = extract_file(&entry.path(), args) { + input_paths.par_iter().for_each(|entry| { + if let Err(e) = extract_file(entry, args) { log::warn!("failed to extract file: {}", e); }; let cur_finished_count = finished_count.fetch_add(1, Ordering::AcqRel); progress_bar.inc(1); - progress_bar.set_message(format!("{}/{}", cur_finished_count, entries.len())); + progress_bar.set_message(format!("{}/{}", cur_finished_count, input_paths.len())); }); Ok(()) @@ -218,11 +226,11 @@ fn extract_object( match text_asset.m_Name.contains("acb") { true => extract_acb(data, &output_dir, args, serialized_file)?, false => { + let output_path = output_dir.join(text_asset.m_Name).with_extension("txt"); + log::info!("writing text to {}", output_path.display()); + #[cfg(not(feature = "debug"))] - write( - output_dir.join(text_asset.m_Name).with_extension(&args.audio_ext), - text_asset.m_Script.as_bytes(), - )?; + write(output_path, decrypt_text(text_asset.m_Script.as_bytes())?)?; } } } diff --git a/extract/tests/test_text.unity3d b/extract/tests/test_text.unity3d new file mode 100644 index 0000000000000000000000000000000000000000..a98121d3683a26f6823c95b541cbd91111ce3bc0 GIT binary patch literal 2720 zcmYjRc|26@7e9AqFb1J9TuVk#k!5Dck~T{;-pC*&kr^}BI%Z^shUA?R+TLi9Rv|^S zM@i{d()N~*k|;%riij!ow)1?0z zj+?`52Pbw6XF`gIR)WA2tyO4wn*#>tF#scNq_GF`B%n?KFaZ?~6mL&2dsjzxj9@k~ zXAU702%;SYqL?`@93c@M6C+|1qG%UTA!ChO|8oHP0D8!wO5^{->Yz9n3Be8%_@pyF zUep=oySXoX#oZeFKrg?PB6p1_g&T7(78*?P72qA6HWVjSqV2 zIM{mtALtr&fGnn^llTDsz@XwVnZgFL9P~8}KwpVNhy${JdA!22Zk;V#%g@f*W*njWvq@~^&^0U1C@s{CgZ@S zz?_GWgWMaS6QCD>z8V+k-c-!g00%k`2O|a!z{5Nuka`Fhh7(SZsgWBt!Hsa_7e$Vi z1H+gL#-su;H9&>)K8-4e8ZR)-!KYe z>OPFNnZ%f;#Ay8_h9&;5wulc*D?U*4rsH6KoexGcR4{`}4kH=P3?pfBfni;VDn#6- z0P#vNnpFuQ{^)>?>jA@7LDt7mJvZGjBRjW=6QDmuCE25rxMX^t3YZQmpfFinGKI;W z0L}zBPJq({%tm13j2eIs(`aNaFkMh4OxFo;LqMN{!$(a|nT(KorAkC%0+OP5DTG)m z5G@l#>jK|5UQGBc!hs`@$7#YYZ>dBsh?fv4b0FGJ5+j9VXISPZ5fKU<;D^L#5FoIG zY~&;W?ef%yuhigFi99}u@RlYe3*_<9@nSSyNS_DnrGlhP_@TRqNG6a2i7=j!A%&kT zM4mzjk_b_VkdP3UV3h2mNEXKnG4a)G}fU79Md0S{lXAa(&@vtc7wAd5q$oDJ$< zNZiEoSCI_~@3-D45wXLz+|?YwqyT~Fx;Cf_CK~lUY9G{1ETC*q#{w~rf4M&zKnhZ# zwlyTZ1PTW9Z&Xm8V7q-1Hy_W?gINaZR-lW)#8^$x6yR(BG!zO_L{ZUVnLLWknVl4$ z!e%?oj>?F0h?OfGQYU^RP9nhMR5Z^Z(!uO#qv|qNe3C%MN+D#@)D$5hW624H+yn|T z;#fjyQc@}_2AHfw&c?h&J0HK; z)p6=@MA=SKG|Ol0uj=QD1*+_W`*Z14VFy~r_A$34`L*bj3DUI-AM0&TpziKJxBk$c zj3suoTA^7)=4emN!}N>C`B<9PiL;kadR}czI4yFnD0o@N3V&PRHtAQuk-iJFOiN^S zDty1utW1%!zO8X=jMKZD_NmI?c}@@Wrb~0$yQ92))9sQvt1h>U%d`%k;hb{H$sXv8 z%v)yQP;vj8fzQ)!wbq{p-puM+;oY%mZJGC^nzzI{&+D%PSIZtWWyq9t?b4RDtc*P; zmnWN7Sw9NgYN(me^&NJc{q}7W|D-IrXwikOzJ}qwt1`{AXFu1pr?X9VoEldk?=J+j3k?Q;oPocl3uuWk2rR^Yd)hwkrevTyt| zvb%!c{PxA|Sg!y@>NDg1EB?=H*N)Nq^tGIyo*wnnvG{eisD0C|l#V;WXLKk_hw`!~ zpYv4Bbz8F|_He+@Ms?Tb3tdm!w=5jnxO60O@9SY3Cx=1p?f+!;a*gr%y>+4YE%w)3 zu1I%O9x_-wwfW28b|Q}XX6H(~nBH`+Q;h+)HqOjn_8@lWTw3YF@Ffu%X2pq%&l%l) z6ukbqpF;Ma&OCTm{^r2gU)L%eg5b^$qG@y2@J6qkewHuwbZuGM%+~PYsF1eNp_JTf z3!fa&@IN#B-Cfy%tCAlUnjLs6GoV(I_Xc%$8`l{)R{vy>8tx7Y%oluNeYmvzi8Q}O za8#8WZvNp5bBJ^2PB_zQ?bxp|j%4(c=Pu84>K}(2`8WPPsQs#{yf*`HbP;Ip2);*r zb^n@abMuLPa`xWSCyqYOy1PHNDa|G4r%8^u+P7`<`ONuYYUCb_e_NtzuBEn^?G;V^ zd~3Yb`Any|qCs|(=@nrjN>x)j>8Ii*$TH{G8*uVv-uk)hbK6;l{j=rhi13#(etazS$=!7p=YJejcix-fyu9FYw?u^{hKx)a)Wr5n`{I7277cztmAYK zH8<-g*04JIyF<2D7UxIW3V696ystf-|2fb7XJS`h$N4eOl;QNp7wdw~z8wpEXX1H9 zyE^a#?QC9P>H5Sjoa5MOIP}osnT3CA9q)6lL~`ab!Euk-#+`528g#?@`qx(x4JU^$ zDg6zPW?`!}Z@)i8JEr8hCll#qH{z37BRQvP1Du;3cMLN+YcXc|g1LXLfoFx!4gc_X z>99Mi*NOh+pUZO}G`1&{5GGUJwyA|$2bvXMDZWr&T7D$f-0eIuEUXV{y)oJu;+ME- zUhzGx#i3I_9I{L}aLsb8>}2FTKfEb%#C(};*9@PY$?}GGABEGTZBypU6GtF9EgpHdn{}&mh7kmH! literal 0 HcmV?d00001 From 44ca83916cb403852011ce99a3431f17f31a637a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=88=91=E5=8F=AF=E8=83=BD=E5=BE=88=E5=BB=A2?= Date: Thu, 11 Jan 2024 14:51:22 +0800 Subject: [PATCH 2/4] :money_with_wings: Add ko-fi --- .github/FUNDING.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/FUNDING.yaml b/.github/FUNDING.yaml index 582c172..eb13725 100644 --- a/.github/FUNDING.yaml +++ b/.github/FUNDING.yaml @@ -1,4 +1,5 @@ github: nicks96432 +ko_fi: nicks96432 patreon: nicks96432 custom: - "https://www.paypal.me/nicks96432" From 4d2f0ff69179782077ffad12e73658fda7ae1e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=88=91=E5=8F=AF=E8=83=BD=E5=BE=88=E5=BB=A2?= Date: Thu, 11 Jan 2024 15:54:14 +0800 Subject: [PATCH 3/4] :rotating_light: Fix lint --- extract/src/environment.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extract/src/environment.rs b/extract/src/environment.rs index e4f51e6..d27ad6e 100644 --- a/extract/src/environment.rs +++ b/extract/src/environment.rs @@ -5,7 +5,7 @@ use std::io::{Read, Seek, SeekFrom}; use byteorder::{BigEndian, ReadBytesExt}; use rabex::read_ext::ReadUrexExt; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct Environment { /// resource data that loaded from bundles resources: HashMap>, @@ -16,7 +16,7 @@ pub struct Environment { impl Environment { pub fn new() -> Self { - Self { resources: HashMap::new(), objects: HashMap::new() } + Self::default() } pub fn register_cab(&mut self, path: &str, buf: Vec) { From 8c32ae5a14f22fb98d8c0b5ab02aed85e1547884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=88=91=E5=8F=AF=E8=83=BD=E5=BE=88=E5=BB=A2?= Date: Thu, 11 Jan 2024 15:54:40 +0800 Subject: [PATCH 4/4] :heavy_minus_sign: Remove unused dependencies --- Cargo.lock | 58 ---------------------------------------------- extract/Cargo.toml | 2 -- 2 files changed, 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 866b597..10dc922 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,15 +82,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "block-padding" version = "0.3.3" @@ -391,17 +382,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - [[package]] name = "either" version = "1.9.0" @@ -497,15 +477,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - [[package]] name = "humantime" version = "2.1.0" @@ -756,10 +727,8 @@ dependencies = [ "num-derive", "num-traits", "num_cpus", - "pbkdf2", "rabex", "rayon", - "sha1", "texture2ddecoder", ] @@ -887,16 +856,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest", - "hmac", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -1251,17 +1210,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "simd-adler32" version = "0.3.7" @@ -1280,12 +1228,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - [[package]] name = "syn" version = "1.0.109" diff --git a/extract/Cargo.toml b/extract/Cargo.toml index 161c34c..e7f872f 100644 --- a/extract/Cargo.toml +++ b/extract/Cargo.toml @@ -14,8 +14,6 @@ acb = { path = "../acb" } # For text asset decryption aes = "0.8.3" cbc = "0.1.2" -pbkdf2 = "0.12.2" -sha1 = "0.10.6" # For reading numbers from binary data byteorder = "1.5.0"