From 7766b3cd5de2ecb7132370c5f60ff0731115ade7 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 23 Feb 2025 15:02:08 -0500 Subject: [PATCH] Further array fixes and a new test I think I'm wrong about the ItemSlots struct, but let's see. --- src/array_property.rs | 63 ++++++++++++++++++++++++++++++++++++++---- src/set_property.rs | 1 + src/struct_property.rs | 4 +++ src/structs.rs | 2 +- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/array_property.rs b/src/array_property.rs index 9bc2c5a..9318836 100644 --- a/src/array_property.rs +++ b/src/array_property.rs @@ -1,24 +1,36 @@ -use crate::set_property::SetEntry; +use crate::map_property::{MabSubProperty}; use binrw::{binrw, BinRead, BinResult}; #[binrw::parser(reader, endian)] -fn custom_parser(size_in_bytes: u32) -> BinResult> { - let mut result = Vec::::new(); +fn custom_parser(size_in_bytes: u32, value_type: &str) -> BinResult> { + let mut result = Vec::::new(); let mut current = reader.stream_position().unwrap(); let end = current + size_in_bytes as u64 - 4; while current < end { - result.push(SetEntry::read_options(reader, endian, ()).unwrap()); + println!("current: {}, end: {}", current, end); + result.push(ArrayEntry::read_options(reader, endian, (value_type,)).unwrap()); current = reader.stream_position().unwrap(); } Ok(result) } + +#[binrw] +#[derive(Debug)] +#[br(import(value_type: &str))] +pub struct ArrayEntry { + #[br(args { magic: &value_type })] + #[br(dbg)] + pub key: MabSubProperty, +} + #[binrw] #[derive(Debug)] pub struct ArrayProperty { // Plus this int + #[br(dbg)] pub size_in_bytes: u32, #[br(temp)] @@ -28,11 +40,50 @@ pub struct ArrayProperty { #[br(count = key_name_length)] #[bw(map = |x : &String | x.as_bytes())] #[br(map = | x: Vec | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())] + #[br(dbg)] pub key_name: String, #[br(pad_before = 1)] pub unk: u32, - #[br(parse_with = custom_parser, args(size_in_bytes))] - pub entries: Vec, + #[br(parse_with = custom_parser, args(size_in_bytes, &key_name))] + pub entries: Vec, +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::map_property::MabSubProperty::String; + use binrw::BinRead; + use std::io::Cursor; + + #[test] + fn simple_array() { + // From Slot.sav + let data = [ + 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, + 0x53, 0x74, 0x72, + 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, + 0x00, 0x01, 0x00, + 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, + 0x72, 0x65, 0x64, + 0x73, 0x74, 0x72, + 0x61, 0x74, 0x65, + 0x00, + ]; + let mut cursor = Cursor::new(data); + let decoded = ArrayProperty::read_le(&mut cursor).unwrap(); + assert_eq!(decoded.size_in_bytes, 18); + assert_eq!(decoded.key_name, "StrProperty"); + let String(value_property) = &decoded.entries.first().unwrap().key else { + panic!("StrProperty!") + }; + assert_eq!(value_property.name, "redstrate"); + } } diff --git a/src/set_property.rs b/src/set_property.rs index 55861e1..06a3cfa 100644 --- a/src/set_property.rs +++ b/src/set_property.rs @@ -21,6 +21,7 @@ pub struct SetEntry { pub unk_type: String, #[br(args { magic: &unk_type })] + #[br(dbg)] pub key: StringBasedProperty, } diff --git a/src/struct_property.rs b/src/struct_property.rs index 8a1b92e..ba5e18a 100644 --- a/src/struct_property.rs +++ b/src/struct_property.rs @@ -76,6 +76,10 @@ pub enum Struct { #[br(pad_after = 9)] // "None" + 1 byte for endofstring + 4 bytes for length set: CarryCountProperty, }, + #[br(magic = b"ItemSlots\0")] + ItemSlots { + unk: [u8; 2125] + }, } #[binrw] diff --git a/src/structs.rs b/src/structs.rs index 37f97bb..56a5a26 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -10,7 +10,7 @@ pub struct DateTimeStruct { #[binrw] #[derive(Debug)] pub struct DALoadOptionStruct { - pub unk: [u8; 17], + pub unk: [u8; 69], // Contains LoadType property } #[binrw]