diff --git a/.gitignore b/.gitignore index ea8c4bf..48ee9ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +checksum.json diff --git a/Cargo.lock b/Cargo.lock index d26e51f..d07c24e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -38,7 +47,9 @@ name = "hash-gen" version = "0.1.0" dependencies = [ "memmap2", + "once_cell", "rayon", + "regex", "serde", "serde_json", "walkdir", @@ -72,6 +83,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + [[package]] name = "proc-macro2" version = "1.0.103" @@ -110,6 +127,35 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + [[package]] name = "ryu" version = "1.0.20" diff --git a/Cargo.toml b/Cargo.toml index 1f26d03..32abd20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,5 @@ xxhash-rust = { version = "0.8.15", features = ["xxh3"] } rayon = "1.10" memmap2 = "0.9" walkdir = "2.3" +regex = "1.12.2" +once_cell = "*" diff --git a/src/main.rs b/src/main.rs index 6b10a06..68f1a30 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,29 @@ use memmap2::Mmap; +use once_cell::sync::Lazy; use rayon::prelude::*; +use regex::Regex; use serde_json::json; use std::{ collections::BTreeMap, env, fs, fs::File, path::{Path, PathBuf}, - sync::Mutex, }; use walkdir::WalkDir; use xxhash_rust::xxh3::xxh3_64; -fn hash_file(path: &Path) -> (String, String) { +static RE: Lazy = Lazy::new(|| { + Regex::new(r"(metin2\.exe|granny2\.dll|SpeedTreeRT\.dll|BGM[/\\].*|lib[/\\].*|pack[/\\].*)") + .unwrap() +}); + +fn hash_file(path: &Path, base_path: &String) -> (String, String) { let file = File::open(path).expect("Failed to open file"); let mmap = unsafe { Mmap::map(&file).expect("Failed to mmap file") }; let hash = xxh3_64(&mmap); let hash_str = hash.to_string(); - let filename = path.file_name().unwrap().to_string_lossy().to_string(); + let filename = path.to_str().unwrap().to_string().replace(base_path, ""); (filename, hash_str) } @@ -25,12 +31,15 @@ fn collect_files(folder: &Path) -> Vec { WalkDir::new(folder) .into_iter() .filter_map(|e| e.ok()) - .filter(|e| e.path().is_file()) + .filter(|e| e.path().is_file() && RE.is_match(e.path().to_str().unwrap())) .map(|e| e.path().to_path_buf()) .collect() } fn main() -> std::io::Result<()> { + use std::time::Instant; + let now = Instant::now(); + let args: Vec = env::args().collect(); if args.len() != 2 { eprintln!("Usage: {} ", args[0]); @@ -45,11 +54,13 @@ fn main() -> std::io::Result<()> { let files = collect_files(folder); - let results: BTreeMap = files.par_iter().map(|f| hash_file(f)).collect(); + let results: BTreeMap = + files.par_iter().map(|f| hash_file(f, &args[1])).collect(); let json_output = json!({ "checksums": results }); - fs::write("checksum", serde_json::to_string_pretty(&json_output)?)?; - println!("Done! JSON saved to 'checksum'"); + fs::write("checksum.json", serde_json::to_string_pretty(&json_output)?)?; + let elapsed = now.elapsed(); + println!("Generated 'checksum', elapsed {:.2?}", elapsed); Ok(()) }