From ab10cf497534ce9e5fb15eda741b5df48ba96839 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 20 Oct 2022 11:44:54 -0400 Subject: [PATCH] Add file info testing, fix parsing bug --- resources/tests/test.fiin | Bin 0 -> 1216 bytes resources/tests/test.txt | 1 + src/fiin.rs | 46 ++++++++++++++++++++++++++++++-------- tests/integration_test.rs | 16 +++++++++++++ 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 resources/tests/test.fiin create mode 100644 resources/tests/test.txt diff --git a/resources/tests/test.fiin b/resources/tests/test.fiin new file mode 100644 index 0000000000000000000000000000000000000000..793fbaacbf0edc2a0fb1cf609275b4f6b23d0649 GIT binary patch literal 1216 zcmZ?E%t`gkOUq|K2P_N>2hhbv`J*8)8Un*A1lXXyDM>9Z(JQGaA=h)6COR>ePuImW zl&?Eubl``C;P1xCAhU##%}=e!A=iANpNn*7PAk;)y1w|N$ogj@ala-vgUkW|2gV*T literal 0 HcmV?d00001 diff --git a/resources/tests/test.txt b/resources/tests/test.txt new file mode 100644 index 0000000..05a682b --- /dev/null +++ b/resources/tests/test.txt @@ -0,0 +1 @@ +Hello! \ No newline at end of file diff --git a/src/fiin.rs b/src/fiin.rs index 98cdecb..db89e1e 100644 --- a/src/fiin.rs +++ b/src/fiin.rs @@ -1,8 +1,9 @@ use crate::gamedata::MemoryBuffer; -use binrw::binrw; +use binrw::{binrw, BinrwNamedArgs, NullString}; use binrw::BinRead; use std::fs::read; use std::io::Cursor; +use std::ffi::CStr; #[binrw] #[brw(magic = b"FileInfo")] @@ -10,7 +11,6 @@ use std::io::Cursor; #[brw(little)] pub struct FileInfo { #[brw(pad_before = 16)] - #[br(ignore)] #[bw(calc = 1024)] unknown: i32, @@ -20,24 +20,24 @@ pub struct FileInfo { #[brw(pad_before = 992)] #[br(count = entries_size / 96)] - entries: Vec, + pub entries: Vec, } #[binrw] #[derive(Debug)] pub struct FIINEntry { - file_size: i32, + pub file_size: i32, #[brw(pad_before = 4)] #[br(count = 64)] - #[br(map = | x: Vec < u8 > | String::from_utf8(x).unwrap())] - #[bw(map = | x : &String | x.as_bytes().to_vec())] #[bw(pad_size_to = 64)] - file_name: String, + #[bw(map = |x : &String | x.as_bytes())] + #[br(map = | x: Vec | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())] + pub file_name: String, #[br(count = 24)] #[bw(pad_size_to = 24)] - sha1: Vec, + pub sha1: Vec, } impl FileInfo { @@ -52,7 +52,7 @@ impl FileInfo { /// hashes. /// /// The new FileInfo structure can then be serialized back into retail-compatible form. - pub fn new(file_names: Vec<&str>) -> Option { + pub fn new(file_names: &[&str]) -> Option { let mut entries = vec![]; for name in file_names { @@ -68,3 +68,31 @@ impl FileInfo { Some(FileInfo { entries }) } } + +#[cfg(test)] +mod tests { + use super::*; + use std::fs::read; + use std::path::PathBuf; + use crate::fiin::FileInfo; + + fn common_setup() -> FileInfo { + let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + d.push("resources/tests"); + d.push("test.fiin"); + + FileInfo::from_existing(&read(d).unwrap()).unwrap() + } + + #[test] + fn basic_parsing() { + let fiin = common_setup(); + + assert_eq!(fiin.entries[0].file_name, + "test.txt"); + + assert_eq!(fiin.entries[1].file_name, + "test.exl"); + } +} + diff --git a/tests/integration_test.rs b/tests/integration_test.rs index a2a8aa5..412f48f 100755 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,11 +1,13 @@ use std::collections::HashMap; use physis::index; use std::env; +use std::fs::read; use std::process::Command; use hmac_sha512::Hash; use physis::installer::install_game; use physis::patch::apply_patch; use walkdir::WalkDir; +use physis::fiin::FileInfo; #[test] #[cfg_attr(not(feature = "retail_game_testing"), ignore)] @@ -30,6 +32,20 @@ fn test_gamedata_extract() { assert!(gamedata.extract("exd/root.exl").is_some()); } +#[test] +#[cfg_attr(not(feature = "retail_game_testing"), ignore)] +fn test_fiin() { + let game_dir = env::var("FFXIV_GAME_DIR").unwrap(); + + let fiin_path = format!("{game_dir}/boot/fileinfo.fiin"); + let fiin = FileInfo::from_existing(&read(fiin_path).unwrap()).unwrap(); + + assert_eq!(fiin.entries[0].file_name, + "steam_api.dll"); + assert_eq!(fiin.entries[1].file_name, + "steam_api64.dll"); +} + fn make_temp_install_dir(name: &str) -> String { let installer_exe = env::var("FFXIV_INSTALLER").unwrap();