From 3bd6fbf9c3adcb57c889dd693f1654c877927a4a Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 6 Aug 2022 21:16:09 -0400 Subject: [PATCH] Enable support for writing the file info format This is the first step in enabling write support for a format! I wanted to see how binwrite works with one of the game's simplest formats. --- Cargo.lock | 7 +++++++ Cargo.toml | 5 ++++- src/fiin.rs | 41 ++++++++++++++++++++++++++++++++++------- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 792605b..0420c84 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -443,6 +443,7 @@ dependencies = [ "paste", "serde", "serde_json", + "sha1_smol", ] [[package]] @@ -603,6 +604,12 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "syn" version = "1.0.99" diff --git a/Cargo.toml b/Cargo.toml index a7ce699..cb6ebd5 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,4 +43,7 @@ hard-xml = "1.13.0" # needed for textools skel parsing serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } \ No newline at end of file +serde = { version = "1.0", features = ["derive"] } + +# needed for file info (fiin) +sha1_smol = "1.0.0" \ No newline at end of file diff --git a/src/fiin.rs b/src/fiin.rs index 65b0481..9d67c2c 100644 --- a/src/fiin.rs +++ b/src/fiin.rs @@ -1,33 +1,42 @@ use std::ffi::CString; +use std::fs::read; use std::io::Cursor; -use binrw::binread; +use binrw::binrw; use crate::gamedata::MemoryBuffer; use binrw::BinRead; -#[binread] -#[br(magic = b"FileInfo")] +#[binrw] +#[brw(magic = b"FileInfo")] #[derive(Debug)] pub struct FileInfo { - #[br(pad_before = 20)] + #[brw(pad_before = 16)] + #[br(ignore)] + #[bw(calc = 1024)] + unknown : i32, + #[br(temp)] + #[bw(calc = (entries.len() * 96) as i32)] entries_size : i32, - #[br(pad_before = 992)] + #[brw(pad_before = 992)] #[br(count = entries_size / 96)] entries : Vec } -#[binread] +#[binrw] #[derive(Debug)] pub struct FIINEntry { file_size : i32, - #[br(pad_before = 4)] + #[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, #[br(count = 24)] + #[bw(pad_size_to = 24)] sha1 : Vec } @@ -36,4 +45,22 @@ impl FileInfo { let mut cursor = Cursor::new(buffer); Some(FileInfo::read(&mut cursor).ok()?) } + + pub fn new(file_names : Vec<&str>) -> Option { + let mut entries = vec![]; + + for name in file_names { + let file = &read(&name).expect("Cannot read file."); + + entries.push(FIINEntry { + file_size: file.len() as i32, + file_name: name.to_string(), + sha1: sha1_smol::Sha1::from(file).digest().bytes().to_vec() + }); + } + + Some(FileInfo { + entries + }) + } } \ No newline at end of file