mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 10:54:38 +00:00
Add hash-list command to print hashed pak contents
This commit is contained in:
parent
e790cfe6b3
commit
543c0927aa
2 changed files with 66 additions and 1 deletions
|
@ -20,4 +20,5 @@ path-clean = "0.1.0"
|
|||
path-slash = "0.2.1"
|
||||
rayon = "1.6.1"
|
||||
repak = { version = "0.1.7", path = "../repak" }
|
||||
sha2 = "0.10.7"
|
||||
strum = { workspace = true }
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, BufReader, BufWriter};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -27,6 +28,17 @@ struct ActionList {
|
|||
strip_prefix: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct ActionHashList {
|
||||
/// Input .pak path
|
||||
#[arg(index = 1)]
|
||||
input: String,
|
||||
|
||||
/// Prefix to strip from entry path
|
||||
#[arg(short, long, default_value = "../../../")]
|
||||
strip_prefix: String,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct ActionUnpack {
|
||||
/// Input .pak path
|
||||
|
@ -106,6 +118,8 @@ enum Action {
|
|||
Info(ActionInfo),
|
||||
/// List .pak files
|
||||
List(ActionList),
|
||||
/// List .pka files and the SHA256 of their contents. Useful for finding differences between paks
|
||||
HashList(ActionHashList),
|
||||
/// Unpack .pak file
|
||||
Unpack(ActionUnpack),
|
||||
/// Pack directory into .pak file
|
||||
|
@ -153,6 +167,7 @@ fn main() -> Result<(), repak::Error> {
|
|||
match args.action {
|
||||
Action::Info(action) => info(aes_key, action),
|
||||
Action::List(action) => list(aes_key, action),
|
||||
Action::HashList(action) => hash_list(aes_key, action),
|
||||
Action::Unpack(action) => unpack(aes_key, action),
|
||||
Action::Pack(action) => pack(action),
|
||||
Action::Get(action) => get(aes_key, action),
|
||||
|
@ -193,7 +208,56 @@ fn list(aes_key: Option<aes::Aes256>, action: ActionList) -> Result<(), repak::E
|
|||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
for f in stripped {
|
||||
println!("{}", f.display());
|
||||
println!("{}", f.to_slash_lossy());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn hash_list(aes_key: Option<aes::Aes256>, action: ActionHashList) -> Result<(), repak::Error> {
|
||||
let mut reader = BufReader::new(File::open(&action.input)?);
|
||||
let pak = repak::PakReader::new_any(&mut reader, aes_key)?;
|
||||
|
||||
let mount_point = PathBuf::from(pak.mount_point());
|
||||
let prefix = Path::new(&action.strip_prefix);
|
||||
|
||||
let full_paths = pak
|
||||
.files()
|
||||
.into_iter()
|
||||
.map(|f| (mount_point.join(&f), f))
|
||||
.collect::<Vec<_>>();
|
||||
let stripped = full_paths
|
||||
.iter()
|
||||
.map(|(full_path, _path)| {
|
||||
full_path.strip_prefix(prefix)
|
||||
.map_err(|_| repak::Error::PrefixMismatch {
|
||||
path: full_path.to_string_lossy().to_string(),
|
||||
prefix: prefix.to_string_lossy().to_string(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let hashes: std::sync::Arc<std::sync::Mutex<BTreeMap::<std::borrow::Cow<'_, str>, Vec<u8>>>> = Default::default();
|
||||
|
||||
full_paths.par_iter().zip(stripped).try_for_each_init(
|
||||
|| (hashes.clone(), File::open(&action.input)),
|
||||
|(hashes, file), ((_full_path, path), stripped)| -> Result<(), repak::Error> {
|
||||
use sha2::Digest;
|
||||
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
pak.read_file(
|
||||
path,
|
||||
&mut BufReader::new(file.as_ref().unwrap()),
|
||||
&mut hasher,
|
||||
)?;
|
||||
let hash = hasher.finalize();
|
||||
hashes.lock().unwrap().insert(stripped.to_slash_lossy(), hash.to_vec());
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
for (file, hash) in hashes.lock().unwrap().iter() {
|
||||
println!("{} {}", hex::encode(hash), file);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in a new issue