bhd: hashes, tests and stuff
This commit is contained in:
parent
de2513e22a
commit
019818f5f0
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -26,6 +26,11 @@ dependencies = [
|
|||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
|
@ -96,6 +101,33 @@ dependencies = [
|
|||
"version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
|
@ -110,6 +142,8 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -186,6 +220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
|
||||
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
|
||||
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||
|
@ -195,6 +230,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
"checksum nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
|
||||
"checksum num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
||||
"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
|
||||
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
|
|
|
@ -9,3 +9,5 @@ edition = "2018"
|
|||
[dependencies]
|
||||
clap = "2.33"
|
||||
nom = "5"
|
||||
num-bigint = "0.2"
|
||||
num-traits = "0.2"
|
||||
|
|
6240
res/namefile.txt
Normal file
6240
res/namefile.txt
Normal file
File diff suppressed because it is too large
Load diff
34
src/main.rs
34
src/main.rs
|
@ -9,12 +9,14 @@ use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
|||
//extern crate nom;
|
||||
use nom::Err::{Error as NomError, Failure as NomFailure};
|
||||
|
||||
mod name_hashes;
|
||||
mod parsers {
|
||||
pub mod bhd;
|
||||
}
|
||||
use parsers::*;
|
||||
|
||||
fn main() {
|
||||
let default_namefilepath: &str = &get_default_namefilepath();
|
||||
let matches = App::new("Rusted Iron Ring")
|
||||
.setting(AppSettings::ArgRequiredElseHelp)
|
||||
.subcommand(SubCommand::with_name("bhd")
|
||||
|
@ -31,7 +33,8 @@ fn main() {
|
|||
.short("n")
|
||||
.long("names")
|
||||
.takes_value(true)
|
||||
.required(false)))
|
||||
.required(false)
|
||||
.default_value(default_namefilepath)))
|
||||
.get_matches();
|
||||
|
||||
match matches.subcommand() {
|
||||
|
@ -40,17 +43,25 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_default_namefilepath() -> String {
|
||||
let programpath: PathBuf = current_exe().unwrap();
|
||||
let programdir: &Path = programpath.parent().unwrap();
|
||||
let mut namefilepath: PathBuf = PathBuf::from(programdir);
|
||||
namefilepath.push("res/namefile.json");
|
||||
String::from(namefilepath.to_str().unwrap())
|
||||
}
|
||||
|
||||
fn cmd_bhd(args: &ArgMatches) -> Result::<(), Error> {
|
||||
let filepath: &str = args.value_of("file").unwrap();
|
||||
let outputpath: &str = args.value_of("output").unwrap();
|
||||
let namefilepath: &str = args.value_of("namefile").unwrap_or(&get_default_namefilepath());
|
||||
let mut bhd_file: File = File::open(filepath)?;
|
||||
let namefilepath: &str = args.value_of("namefile").unwrap();
|
||||
let mut bhd_file = File::open(filepath)?;
|
||||
let file_len = bhd_file.metadata()?.len() as usize;
|
||||
let mut bhd_data = vec![0u8; file_len];
|
||||
bhd_file.read_exact(&mut bhd_data)?;
|
||||
|
||||
let bhd = match bhd::parse(&bhd_data) {
|
||||
Ok((_, bhd)) => { println!("BHD: {:?}", bhd); bhd }
|
||||
Ok((_, bhd)) => { bhd }
|
||||
Err(NomError(e)) | Err(NomFailure(e)) => {
|
||||
let (_, kind) = e;
|
||||
let reason = format!("{:?} {:?}", kind, kind.description());
|
||||
|
@ -61,13 +72,12 @@ fn cmd_bhd(args: &ArgMatches) -> Result::<(), Error> {
|
|||
}
|
||||
};
|
||||
|
||||
let names = name_hashes::load_name_map(&namefilepath)?;
|
||||
|
||||
let bdt_filepath = PathBuf::from(filepath).with_extension("bdt");
|
||||
let bdt_file = File::open(bdt_filepath.to_str().unwrap())?;
|
||||
|
||||
bhd::extract(&bhd, &bdt_file, &names, &outputpath);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_default_namefilepath() -> String {
|
||||
let programpath: PathBuf = current_exe().unwrap();
|
||||
let programdir: &Path = programpath.parent().unwrap();
|
||||
let mut namefilepath: PathBuf = PathBuf::from(programdir);
|
||||
namefilepath.push("res/namefile.json");
|
||||
String::from(namefilepath.to_str().unwrap())
|
||||
}
|
||||
|
|
58
src/name_hashes.rs
Normal file
58
src/name_hashes.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, Error};
|
||||
|
||||
extern crate num_bigint;
|
||||
use num_bigint::BigUint;
|
||||
extern crate num_traits;
|
||||
use num_traits::identities::Zero;
|
||||
|
||||
/// Compute the weird hash for a string. Same mechanic since DeS.
|
||||
pub fn hash(s: &str) -> u32 {
|
||||
let s = s.to_lowercase();
|
||||
let mut val = BigUint::zero();
|
||||
for c in s.chars() {
|
||||
val *= 37u8;
|
||||
val += c as u32;
|
||||
}
|
||||
val.to_u32_digits()[0]
|
||||
}
|
||||
|
||||
/// Get the string representation for this hash.
|
||||
pub fn hash_as_string(h: u32) -> String {
|
||||
format!("{:08X}", h)
|
||||
}
|
||||
|
||||
/// Load a namelist file into a map.
|
||||
///
|
||||
/// Format for the input file should be the following for every line:
|
||||
/// CAFECAFE: /chr/whatever.ext
|
||||
pub fn load_name_map(path: &str) -> Result<HashMap<String, String>, Error> {
|
||||
let mut names = HashMap::new();
|
||||
let namefile = File::open(path)?;
|
||||
for line_ in BufReader::new(namefile).lines() {
|
||||
if let Ok(line) = line_ {
|
||||
let (hash, name) = line.split_at(8);
|
||||
names.insert(hash.to_string(), name[2..].to_string());
|
||||
}
|
||||
}
|
||||
println!("{:?}", names);
|
||||
Ok(names)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
assert_eq!(hash("/chr/c0000.anibnd.dcx"), 0xF8630FB1);
|
||||
assert_eq!(hash("/param/DrawParam/default_DrawParam.parambnd.dcx"), 0xD9209D30);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash_as_string() {
|
||||
assert_eq!(hash_as_string(0xCAFECAFE), "CAFECAFE");
|
||||
assert_eq!(hash_as_string(0xDECE), "0000DECE");
|
||||
}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
|
||||
extern crate nom;
|
||||
use nom::{IResult};
|
||||
use nom::combinator::verify;
|
||||
|
@ -78,7 +81,6 @@ pub fn parse(i: &[u8]) -> IResult<&[u8], Bhd> {
|
|||
|
||||
let mut buckets: Vec<Vec<BhdFile>> = vec!();
|
||||
for b in 0..header.num_buckets {
|
||||
println!("Bucket {}", b);
|
||||
let bucket_info = &bucket_infos[b as usize];
|
||||
let bucket_data = &full_file[bucket_info.offset as usize..];
|
||||
let (_, bucket) = count(parse_file, bucket_info.count as usize)(bucket_data)?;
|
||||
|
@ -89,7 +91,6 @@ pub fn parse(i: &[u8]) -> IResult<&[u8], Bhd> {
|
|||
}
|
||||
|
||||
/// Extract files from a BHD/BDT pair.
|
||||
pub fn extract(bhd: Bhd, bdt_path: &str) {
|
||||
|
||||
pub fn extract(bhd: &Bhd, bdt_file: &File, names: &HashMap<String, String>, outputpath: &str) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue