mirror of
https://github.com/redstrate/Physis.git
synced 2025-04-20 11:47:46 +00:00
Add file info testing, fix parsing bug
This commit is contained in:
parent
c7105e964d
commit
ab10cf4975
4 changed files with 54 additions and 9 deletions
BIN
resources/tests/test.fiin
Normal file
BIN
resources/tests/test.fiin
Normal file
Binary file not shown.
1
resources/tests/test.txt
Normal file
1
resources/tests/test.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Hello!
|
46
src/fiin.rs
46
src/fiin.rs
|
@ -1,8 +1,9 @@
|
||||||
use crate::gamedata::MemoryBuffer;
|
use crate::gamedata::MemoryBuffer;
|
||||||
use binrw::binrw;
|
use binrw::{binrw, BinrwNamedArgs, NullString};
|
||||||
use binrw::BinRead;
|
use binrw::BinRead;
|
||||||
use std::fs::read;
|
use std::fs::read;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
use std::ffi::CStr;
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[brw(magic = b"FileInfo")]
|
#[brw(magic = b"FileInfo")]
|
||||||
|
@ -10,7 +11,6 @@ use std::io::Cursor;
|
||||||
#[brw(little)]
|
#[brw(little)]
|
||||||
pub struct FileInfo {
|
pub struct FileInfo {
|
||||||
#[brw(pad_before = 16)]
|
#[brw(pad_before = 16)]
|
||||||
#[br(ignore)]
|
|
||||||
#[bw(calc = 1024)]
|
#[bw(calc = 1024)]
|
||||||
unknown: i32,
|
unknown: i32,
|
||||||
|
|
||||||
|
@ -20,24 +20,24 @@ pub struct FileInfo {
|
||||||
|
|
||||||
#[brw(pad_before = 992)]
|
#[brw(pad_before = 992)]
|
||||||
#[br(count = entries_size / 96)]
|
#[br(count = entries_size / 96)]
|
||||||
entries: Vec<FIINEntry>,
|
pub entries: Vec<FIINEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FIINEntry {
|
pub struct FIINEntry {
|
||||||
file_size: i32,
|
pub file_size: i32,
|
||||||
|
|
||||||
#[brw(pad_before = 4)]
|
#[brw(pad_before = 4)]
|
||||||
#[br(count = 64)]
|
#[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)]
|
#[bw(pad_size_to = 64)]
|
||||||
file_name: String,
|
#[bw(map = |x : &String | x.as_bytes())]
|
||||||
|
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
||||||
|
pub file_name: String,
|
||||||
|
|
||||||
#[br(count = 24)]
|
#[br(count = 24)]
|
||||||
#[bw(pad_size_to = 24)]
|
#[bw(pad_size_to = 24)]
|
||||||
sha1: Vec<u8>,
|
pub sha1: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileInfo {
|
impl FileInfo {
|
||||||
|
@ -52,7 +52,7 @@ impl FileInfo {
|
||||||
/// hashes.
|
/// hashes.
|
||||||
///
|
///
|
||||||
/// The new FileInfo structure can then be serialized back into retail-compatible form.
|
/// The new FileInfo structure can then be serialized back into retail-compatible form.
|
||||||
pub fn new(file_names: Vec<&str>) -> Option<FileInfo> {
|
pub fn new(file_names: &[&str]) -> Option<FileInfo> {
|
||||||
let mut entries = vec![];
|
let mut entries = vec![];
|
||||||
|
|
||||||
for name in file_names {
|
for name in file_names {
|
||||||
|
@ -68,3 +68,31 @@ impl FileInfo {
|
||||||
Some(FileInfo { entries })
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use physis::index;
|
use physis::index;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::read;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use hmac_sha512::Hash;
|
use hmac_sha512::Hash;
|
||||||
use physis::installer::install_game;
|
use physis::installer::install_game;
|
||||||
use physis::patch::apply_patch;
|
use physis::patch::apply_patch;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
use physis::fiin::FileInfo;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(not(feature = "retail_game_testing"), ignore)]
|
#[cfg_attr(not(feature = "retail_game_testing"), ignore)]
|
||||||
|
@ -30,6 +32,20 @@ fn test_gamedata_extract() {
|
||||||
assert!(gamedata.extract("exd/root.exl").is_some());
|
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 {
|
fn make_temp_install_dir(name: &str) -> String {
|
||||||
let installer_exe = env::var("FFXIV_INSTALLER").unwrap();
|
let installer_exe = env::var("FFXIV_INSTALLER").unwrap();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue