Reorganize the entire project
This commit is contained in:
parent
53aba498d1
commit
3b26da6b57
44 changed files with 424 additions and 359 deletions
|
@ -40,8 +40,8 @@ pub fn serialized_struct(_metadata: TokenStream, input: TokenStream)
|
|||
field_names.push(our_custom_name.clone());
|
||||
let field_tokens = field.to_token_stream();
|
||||
let new_field_token_stream = quote! {
|
||||
#[br(parse_with = crate::structs::read_struct_field, args(#our_custom_name))]
|
||||
#[bw(write_with = crate::structs::write_struct_field, args(#our_custom_name))]
|
||||
#[br(parse_with = crate::structure::read_struct_field, args(#our_custom_name))]
|
||||
#[bw(write_with = crate::structure::write_struct_field, args(#our_custom_name))]
|
||||
#field_tokens
|
||||
};
|
||||
let buffer = ::syn::parse::Parser::parse2(
|
||||
|
@ -54,8 +54,8 @@ pub fn serialized_struct(_metadata: TokenStream, input: TokenStream)
|
|||
// Add "None" field
|
||||
let none_field_stream = quote! {
|
||||
#[br(temp)]
|
||||
#[bw(calc = crate::structs::GenericProperty { property_name: "None".to_string(), type_name: "".to_string(), key: None } )]
|
||||
none_field: crate::structs::GenericProperty
|
||||
#[bw(calc = crate::property::generic_property::GenericProperty { property_name: "None".to_string(), type_name: "".to_string(), key: None } )]
|
||||
none_field: crate::property::generic_property::GenericProperty
|
||||
};
|
||||
let buffer = ::syn::parse::Parser::parse2(
|
||||
syn::Field::parse_named,
|
||||
|
@ -75,7 +75,7 @@ pub fn serialized_struct(_metadata: TokenStream, input: TokenStream)
|
|||
#input
|
||||
|
||||
#[automatically_derived]
|
||||
impl crate::structs::PropertyBase for #id {
|
||||
impl crate::property::PropertyBase for #id {
|
||||
fn type_name() -> &'static str {
|
||||
return "StructProperty";
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ pub fn serialized_struct(_metadata: TokenStream, input: TokenStream)
|
|||
}
|
||||
|
||||
fn size_in_bytes(&self) -> u32 {
|
||||
#( #field_types::size_in_bytes(&self.#field_idents) )+* + #( (crate::structs::calc_struct_field_prelude_byte_size(stringify!(#field_types), #field_names, #field_types::struct_name()) ) )+* + 9 // for "none" field
|
||||
#( #field_types::size_in_bytes(&self.#field_idents) )+* + #( (crate::structure::calc_struct_field_prelude_byte_size(stringify!(#field_types), #field_names, #field_types::struct_name()) ) )+* + 9 // for "none" field
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use binrw::BinRead;
|
||||
use ireko::{CompressedSaveFile, GenericTaggedObject};
|
||||
use ireko::CompressedSaveFile;
|
||||
use ireko::save_object::generic::GenericTaggedObject;
|
||||
use std::env;
|
||||
use std::io::Cursor;
|
||||
|
||||
|
|
146
src/lib.rs
146
src/lib.rs
|
@ -1,155 +1,15 @@
|
|||
pub mod array_property;
|
||||
pub mod bool_property;
|
||||
mod build_data;
|
||||
mod common;
|
||||
mod da_assemble_id_data;
|
||||
mod da_customize_asset_id;
|
||||
mod da_humanoid_coloring_data;
|
||||
mod da_humanoid_figure_data;
|
||||
mod da_load_option;
|
||||
mod da_machine_coloring_data;
|
||||
mod da_module_color;
|
||||
mod da_module_item_data;
|
||||
mod da_trigger_data;
|
||||
mod da_tuning_data;
|
||||
mod da_tuning_point_data;
|
||||
mod datetime;
|
||||
mod enum_property;
|
||||
pub mod float_property;
|
||||
mod guid;
|
||||
pub mod int_property;
|
||||
mod linear_color;
|
||||
mod localprofile;
|
||||
pub mod map_property;
|
||||
mod name_property;
|
||||
mod persistent;
|
||||
mod primary_asset_id;
|
||||
mod primary_asset_type;
|
||||
mod quat;
|
||||
mod save_slot_info;
|
||||
pub mod set_property;
|
||||
mod slot;
|
||||
pub mod str_property;
|
||||
pub mod struct_property;
|
||||
mod structs;
|
||||
mod transform;
|
||||
mod vector;
|
||||
pub mod property;
|
||||
pub mod save_object;
|
||||
pub mod structure;
|
||||
|
||||
use binrw::helpers::until_eof;
|
||||
use std::fs::write;
|
||||
use std::io::{Cursor, Read};
|
||||
|
||||
use crate::array_property::ArrayProperty;
|
||||
use crate::bool_property::BoolProperty;
|
||||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use crate::float_property::FloatProperty;
|
||||
use crate::int_property::IntProperty;
|
||||
use crate::map_property::MapProperty;
|
||||
use crate::name_property::NameProperty;
|
||||
use crate::set_property::SetProperty;
|
||||
use crate::str_property::StrProperty;
|
||||
use crate::struct_property::StructProperty;
|
||||
use binrw::{BinRead, BinResult, BinWrite, binrw};
|
||||
use flate2::bufread::ZlibDecoder;
|
||||
|
||||
// Used in ArrayProperty exclusively, but could be used instead of magic above
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
#[br(import { magic: &str, name: &str })]
|
||||
pub enum Property {
|
||||
#[br(pre_assert("NameProperty" == magic))]
|
||||
Name(NameProperty),
|
||||
#[br(pre_assert("StructProperty" == magic))]
|
||||
Struct(StructProperty),
|
||||
#[br(pre_assert("FloatProperty" == magic))]
|
||||
Float(FloatProperty),
|
||||
#[br(pre_assert("StrProperty" == magic))]
|
||||
String(StrProperty),
|
||||
#[br(pre_assert("BoolProperty" == magic))]
|
||||
Bool(BoolProperty),
|
||||
#[br(pre_assert("IntProperty" == magic))]
|
||||
Int(IntProperty),
|
||||
#[br(pre_assert("ArrayProperty" == magic))]
|
||||
Array(ArrayProperty),
|
||||
#[br(pre_assert("MapProperty" == magic))]
|
||||
Map(MapProperty),
|
||||
#[br(pre_assert("SetProperty" == magic))]
|
||||
Set(SetProperty),
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct Entry {
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub name: String,
|
||||
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
#[br(if(name != "None"))]
|
||||
pub type_name: String,
|
||||
|
||||
#[br(if(name != "None"), args { magic: &type_name, name: &name })]
|
||||
pub r#type: Option<Property>,
|
||||
}
|
||||
|
||||
#[binrw::parser(reader, endian)]
|
||||
fn custom_tagged_object_parser(size_in_bytes: u32) -> BinResult<Vec<Entry>> {
|
||||
let mut result = Vec::<Entry>::new();
|
||||
|
||||
let mut current = reader.stream_position()?;
|
||||
let end = current + size_in_bytes as u64 - 4; // for the size bits
|
||||
|
||||
while current < end {
|
||||
let entry = Entry::read_options(reader, endian, ())?;
|
||||
if entry.name == "None" {
|
||||
break;
|
||||
}
|
||||
result.push(entry);
|
||||
current = reader.stream_position()?;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[binrw::writer(writer, endian)]
|
||||
fn custom_tagged_object_writer(entries: &Vec<Entry>) -> BinResult<()> {
|
||||
for entry in entries {
|
||||
entry.write_options(writer, endian, ())?
|
||||
}
|
||||
// Write "none" entry at the end
|
||||
let none_entry = Entry {
|
||||
name: "None".to_string(),
|
||||
type_name: "".to_string(),
|
||||
r#type: None,
|
||||
};
|
||||
none_entry.write_options(writer, endian, ())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct GenericTaggedObject {
|
||||
pub size_in_bytes: u32,
|
||||
#[br(parse_with = custom_tagged_object_parser, args(size_in_bytes))]
|
||||
#[bw(write_with = custom_tagged_object_writer)]
|
||||
pub entries: Vec<Entry>,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct PersistentObject {
|
||||
pub size_in_bytes: u32,
|
||||
#[br(pad_after = 4)]
|
||||
pub profile: persistent::Persistent,
|
||||
}
|
||||
|
||||
impl GenericTaggedObject {
|
||||
pub fn entry(&self, key: &str) -> Option<&Entry> {
|
||||
let entries: Vec<&Entry> = self.entries.iter().filter(|e| e.name == key).collect();
|
||||
entries.first().copied()
|
||||
}
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct TaggedSerialization<T>
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use crate::map_property::{KeyType, StringMapKey};
|
||||
use crate::struct_property::Struct;
|
||||
use binrw::{BinRead, BinResult, binrw};
|
||||
|
||||
use crate::{
|
||||
common::{read_string_with_length, write_string_with_length},
|
||||
structure::Struct,
|
||||
};
|
||||
|
||||
use super::{
|
||||
PropertyBase,
|
||||
map_property::{KeyType, StringMapKey},
|
||||
};
|
||||
|
||||
fn calculate_header_size(key_name: &str, array_key_data: &ArrayKeyData) -> u64 {
|
||||
// TODO: blah, needs to take into account everything before the first item
|
||||
match array_key_data {
|
||||
|
@ -19,7 +26,7 @@ fn calculate_header_size(key_name: &str, array_key_data: &ArrayKeyData) -> u64 {
|
|||
}
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for ArrayProperty {
|
||||
impl PropertyBase for ArrayProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"ArrayProperty"
|
||||
}
|
||||
|
@ -83,7 +90,7 @@ fn calc_size_in_bytes(prop: &ArrayProperty) -> u32 {
|
|||
|
||||
for entry in &prop.entries {
|
||||
size += match &entry.key {
|
||||
ArrayValue::Struct { r#struct } => crate::struct_property::calc_size_in_bytes(r#struct),
|
||||
ArrayValue::Struct { r#struct } => crate::structure::calc_size_in_bytes(r#struct),
|
||||
ArrayValue::String(string_map_key) => {
|
||||
crate::common::size_of_string_with_length(&string_map_key.value)
|
||||
}
|
||||
|
@ -158,7 +165,6 @@ pub struct ArrayProperty {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::map_property::StringMapKey;
|
||||
use binrw::{BinRead, BinWrite};
|
||||
use std::io::Cursor;
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
use crate::common::{read_bool_from, write_bool_as};
|
||||
use binrw::binrw;
|
||||
|
||||
use super::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct BoolProperty {
|
||||
|
@ -10,7 +12,7 @@ pub struct BoolProperty {
|
|||
pub value: bool,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for BoolProperty {
|
||||
impl PropertyBase for BoolProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"IntProperty"
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use binrw::binrw;
|
||||
|
||||
use super::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct EnumProperty {
|
||||
|
@ -15,7 +17,7 @@ pub struct EnumProperty {
|
|||
pub value: String,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for EnumProperty {
|
||||
impl PropertyBase for EnumProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"EnumProperty"
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use super::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct FloatProperty {
|
||||
|
@ -9,7 +11,7 @@ pub struct FloatProperty {
|
|||
pub value: f32,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for FloatProperty {
|
||||
impl PropertyBase for FloatProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"FloatProperty"
|
||||
}
|
23
src/property/generic_property.rs
Normal file
23
src/property/generic_property.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use crate::{
|
||||
common::{read_string_with_length, write_string_with_length},
|
||||
save_object::generic::Property,
|
||||
};
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct GenericProperty {
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub property_name: String,
|
||||
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
#[br(if(property_name != "None"))]
|
||||
pub type_name: String,
|
||||
|
||||
#[br(if(property_name != "None"))]
|
||||
#[br(args { magic: &type_name, name: &property_name})]
|
||||
pub key: Option<Box<Property>>,
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use super::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct IntProperty {
|
||||
|
@ -9,7 +11,7 @@ pub struct IntProperty {
|
|||
pub value: u32,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for IntProperty {
|
||||
impl PropertyBase for IntProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"IntProperty"
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
use crate::common::{
|
||||
read_bool_from, read_string_with_length, write_bool_as, write_string_with_length,
|
||||
};
|
||||
use crate::guid::Guid;
|
||||
use crate::struct_property::Struct;
|
||||
use crate::structs::{GenericProperty, PropertyBase};
|
||||
use binrw::{BinRead, BinResult, binrw};
|
||||
|
||||
use crate::{
|
||||
common::{read_bool_from, read_string_with_length, write_bool_as, write_string_with_length},
|
||||
structure::{Struct, guid::Guid},
|
||||
};
|
||||
|
||||
use super::{PropertyBase, generic_property::GenericProperty};
|
||||
|
||||
// parse until we can't parse no more. kind of a hack for how we run into the end of Persistent.Sav
|
||||
#[binrw::parser(reader, endian)]
|
||||
fn cc() -> BinResult<Vec<GenericProperty>> {
|
||||
|
@ -225,7 +226,7 @@ fn calc_entry_size_in_bytes(prop: &MapProperty) -> u32 {
|
|||
+ crate::common::size_of_string_with_length(&struct_maybe_key.unk_type)
|
||||
+ crate::common::size_of_string_with_length(&struct_maybe_key.struct_name)
|
||||
+ 17
|
||||
+ crate::struct_property::calc_size_in_bytes(&struct_maybe_key.r#struct)
|
||||
+ crate::structure::calc_size_in_bytes(&struct_maybe_key.r#struct)
|
||||
}
|
||||
MapKeyProperty::Enum(map_sub_enum_property) => {
|
||||
crate::common::size_of_string_with_length(&map_sub_enum_property.value)
|
||||
|
@ -242,7 +243,7 @@ fn calc_entry_size_in_bytes(prop: &MapProperty) -> u32 {
|
|||
+ crate::common::size_of_string_with_length(&struct_maybe_key.unk_type)
|
||||
+ crate::common::size_of_string_with_length(&struct_maybe_key.struct_name)
|
||||
+ 17
|
||||
+ crate::struct_property::calc_size_in_bytes(&struct_maybe_key.r#struct)
|
||||
+ crate::structure::calc_size_in_bytes(&struct_maybe_key.r#struct)
|
||||
}
|
||||
MapKeyProperty::SomeID3(guid) => guid.size_in_bytes(),
|
||||
MapKeyProperty::SoftObjectProperty(string_map_key) => {
|
||||
|
@ -292,7 +293,7 @@ pub struct MapProperty {
|
|||
pub entries: Vec<MapEntry>,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for MapProperty {
|
||||
impl PropertyBase for MapProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"MapProperty"
|
||||
}
|
||||
|
@ -310,7 +311,6 @@ impl crate::structs::PropertyBase for MapProperty {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::map_property::MabSubProperty::{Int, String};
|
||||
use binrw::{BinRead, BinWrite};
|
||||
use std::io::Cursor;
|
||||
|
||||
|
@ -333,7 +333,7 @@ mod tests {
|
|||
let MapKeyProperty::String(key_property) = &decoded.entries.first().unwrap().key else {
|
||||
panic!("StrProperty!")
|
||||
};
|
||||
let String(value_property) = &decoded.entries.first().unwrap().value else {
|
||||
let MabSubProperty::String(value_property) = &decoded.entries.first().unwrap().value else {
|
||||
panic!("StrProperty!")
|
||||
};
|
||||
assert_eq!(key_property.value, "AR0XJGFWA6HNIQ1AAUJ9UR828");
|
||||
|
@ -359,7 +359,7 @@ mod tests {
|
|||
key: MapKeyProperty::String(StringMapKey {
|
||||
value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string(),
|
||||
}),
|
||||
value: String(MapSubStrProperty {
|
||||
value: MabSubProperty::String(MapSubStrProperty {
|
||||
value: "NAME 1".to_string(),
|
||||
}),
|
||||
}],
|
||||
|
@ -403,7 +403,7 @@ mod tests {
|
|||
let MapKeyProperty::Enum(key_property) = &decoded.entries.first().unwrap().key else {
|
||||
panic!("Name!")
|
||||
};
|
||||
let Int(value_property) = &decoded.entries.first().unwrap().value else {
|
||||
let MabSubProperty::Int(value_property) = &decoded.entries.first().unwrap().value else {
|
||||
panic!("Int!")
|
||||
};
|
||||
assert_eq!(key_property.value, "SelectedMachine");
|
22
src/property/mod.rs
Normal file
22
src/property/mod.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
pub mod array_property;
|
||||
pub mod bool_property;
|
||||
pub mod enum_property;
|
||||
pub mod float_property;
|
||||
pub mod generic_property;
|
||||
pub mod int_property;
|
||||
pub mod map_property;
|
||||
pub mod name_property;
|
||||
pub mod set_property;
|
||||
pub mod str_property;
|
||||
pub mod struct_property;
|
||||
|
||||
pub(crate) trait PropertyBase {
|
||||
fn type_name() -> &'static str;
|
||||
fn size_in_bytes(&self) -> u32;
|
||||
|
||||
// these are only relevant for structs:
|
||||
// FIXME: this isn't great'
|
||||
fn struct_name() -> Option<&'static str> {
|
||||
None
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use binrw::binrw;
|
||||
|
||||
use super::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct NameProperty {
|
||||
|
@ -14,7 +16,7 @@ pub struct NameProperty {
|
|||
pub value: String,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for NameProperty {
|
||||
impl PropertyBase for NameProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"NameProperty"
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use crate::map_property::{KeyType, MapSubStrProperty};
|
||||
use crate::structs::GenericProperty;
|
||||
use binrw::{BinRead, BinResult, binrw};
|
||||
|
||||
use super::{
|
||||
PropertyBase,
|
||||
generic_property::GenericProperty,
|
||||
map_property::{KeyType, MapSubStrProperty},
|
||||
};
|
||||
|
||||
// hack, we should be checking for "none" instead
|
||||
#[binrw::parser(reader, endian)]
|
||||
fn cc() -> BinResult<Vec<GenericProperty>> {
|
||||
|
@ -88,7 +92,7 @@ pub struct SetProperty {
|
|||
pub entries: Vec<SetEntry>,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for SetProperty {
|
||||
impl PropertyBase for SetProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"SetProperty"
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use binrw::binrw;
|
||||
|
||||
use super::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct StrProperty {
|
||||
|
@ -14,7 +16,7 @@ pub struct StrProperty {
|
|||
pub value: String,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for StrProperty {
|
||||
impl PropertyBase for StrProperty {
|
||||
fn type_name() -> &'static str {
|
||||
"StrProperty"
|
||||
}
|
18
src/property/struct_property.rs
Normal file
18
src/property/struct_property.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::{
|
||||
common::{read_string_with_length, write_string_with_length},
|
||||
structure::Struct,
|
||||
};
|
||||
use binrw::binrw;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct StructProperty {
|
||||
pub unk: u32,
|
||||
#[brw(pad_before = 4)]
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub struct_name: String,
|
||||
#[br(args { magic: &struct_name })]
|
||||
#[brw(pad_before = 17)]
|
||||
pub r#struct: Struct,
|
||||
}
|
100
src/save_object/generic.rs
Normal file
100
src/save_object/generic.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
use binrw::{BinRead, BinResult, BinWrite, binrw};
|
||||
|
||||
use crate::{
|
||||
common::{read_string_with_length, write_string_with_length},
|
||||
property::{
|
||||
array_property::ArrayProperty, bool_property::BoolProperty, float_property::FloatProperty,
|
||||
int_property::IntProperty, map_property::MapProperty, name_property::NameProperty,
|
||||
set_property::SetProperty, str_property::StrProperty, struct_property::StructProperty,
|
||||
},
|
||||
};
|
||||
|
||||
// Used in ArrayProperty exclusively, but could be used instead of magic above
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
#[br(import { magic: &str, name: &str })]
|
||||
pub enum Property {
|
||||
#[br(pre_assert("NameProperty" == magic))]
|
||||
Name(NameProperty),
|
||||
#[br(pre_assert("StructProperty" == magic))]
|
||||
Struct(StructProperty),
|
||||
#[br(pre_assert("FloatProperty" == magic))]
|
||||
Float(FloatProperty),
|
||||
#[br(pre_assert("StrProperty" == magic))]
|
||||
String(StrProperty),
|
||||
#[br(pre_assert("BoolProperty" == magic))]
|
||||
Bool(BoolProperty),
|
||||
#[br(pre_assert("IntProperty" == magic))]
|
||||
Int(IntProperty),
|
||||
#[br(pre_assert("ArrayProperty" == magic))]
|
||||
Array(ArrayProperty),
|
||||
#[br(pre_assert("MapProperty" == magic))]
|
||||
Map(MapProperty),
|
||||
#[br(pre_assert("SetProperty" == magic))]
|
||||
Set(SetProperty),
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct Entry {
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub name: String,
|
||||
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
#[br(if(name != "None"))]
|
||||
pub type_name: String,
|
||||
|
||||
#[br(if(name != "None"), args { magic: &type_name, name: &name })]
|
||||
pub r#type: Option<Property>,
|
||||
}
|
||||
|
||||
#[binrw::parser(reader, endian)]
|
||||
fn custom_tagged_object_parser(size_in_bytes: u32) -> BinResult<Vec<Entry>> {
|
||||
let mut result = Vec::<Entry>::new();
|
||||
|
||||
let mut current = reader.stream_position()?;
|
||||
let end = current + size_in_bytes as u64 - 4; // for the size bits
|
||||
|
||||
while current < end {
|
||||
let entry = Entry::read_options(reader, endian, ())?;
|
||||
if entry.name == "None" {
|
||||
break;
|
||||
}
|
||||
result.push(entry);
|
||||
current = reader.stream_position()?;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[binrw::writer(writer, endian)]
|
||||
fn custom_tagged_object_writer(entries: &Vec<Entry>) -> BinResult<()> {
|
||||
for entry in entries {
|
||||
entry.write_options(writer, endian, ())?
|
||||
}
|
||||
// Write "none" entry at the end
|
||||
let none_entry = Entry {
|
||||
name: "None".to_string(),
|
||||
type_name: "".to_string(),
|
||||
r#type: None,
|
||||
};
|
||||
none_entry.write_options(writer, endian, ())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct GenericTaggedObject {
|
||||
pub size_in_bytes: u32,
|
||||
#[br(parse_with = custom_tagged_object_parser, args(size_in_bytes))]
|
||||
#[bw(write_with = custom_tagged_object_writer)]
|
||||
pub entries: Vec<Entry>,
|
||||
}
|
||||
|
||||
impl GenericTaggedObject {
|
||||
pub fn entry(&self, key: &str) -> Option<&Entry> {
|
||||
let entries: Vec<&Entry> = self.entries.iter().filter(|e| e.name == key).collect();
|
||||
entries.first().copied()
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{
|
||||
use crate::property::{
|
||||
bool_property::BoolProperty, int_property::IntProperty, map_property::MapProperty,
|
||||
str_property::StrProperty,
|
||||
};
|
4
src/save_object/mod.rs
Normal file
4
src/save_object/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
pub mod generic;
|
||||
pub mod localprofile;
|
||||
pub mod persistent;
|
||||
pub mod slot;
|
|
@ -1,7 +1,15 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use crate::{
|
||||
array_property::ArrayProperty, bool_property::BoolProperty, build_data::DABuildDataStruct, da_tuning_point_data::DATuningPointData, int_property::IntProperty,
|
||||
map_property::MapProperty, name_property::NameProperty,
|
||||
set_property::SetProperty, str_property::StrProperty, transform::TransformStruct,
|
||||
property::{
|
||||
array_property::ArrayProperty, bool_property::BoolProperty, int_property::IntProperty,
|
||||
map_property::MapProperty, name_property::NameProperty, set_property::SetProperty,
|
||||
str_property::StrProperty,
|
||||
},
|
||||
structure::{
|
||||
build_data::DABuildDataStruct, da_tuning_point_data::DATuningPointData,
|
||||
transform::TransformStruct,
|
||||
},
|
||||
};
|
||||
|
||||
#[paramacro::serialized_struct("Transform")]
|
||||
|
@ -97,3 +105,11 @@ pub struct Persistent {
|
|||
#[paramacro::serialized_field = "bUseSaveSlot"]
|
||||
use_save_slot: BoolProperty,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct PersistentObject {
|
||||
pub size_in_bytes: u32,
|
||||
#[br(pad_after = 4)]
|
||||
pub profile: Persistent,
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
use crate::{
|
||||
bool_property::BoolProperty, da_load_option::DALoadOptionStruct, datetime::DateTimeStruct,
|
||||
float_property::FloatProperty, int_property::IntProperty,
|
||||
name_property::NameProperty, save_slot_info::SaveSlotInfoStruct, str_property::StrProperty,
|
||||
property::{
|
||||
bool_property::BoolProperty, float_property::FloatProperty, int_property::IntProperty,
|
||||
name_property::NameProperty, str_property::StrProperty,
|
||||
},
|
||||
structure::{
|
||||
da_load_option::DALoadOptionStruct, datetime::DateTimeStruct,
|
||||
save_slot_info::SaveSlotInfoStruct,
|
||||
},
|
||||
};
|
||||
|
||||
#[paramacro::serialized_struct("Transform")]
|
116
src/structs.rs
116
src/structs.rs
|
@ -1,116 +0,0 @@
|
|||
use crate::Property;
|
||||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use binrw::{BinRead, BinResult, BinWrite, binrw};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct GenericProperty {
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub property_name: String,
|
||||
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
#[br(if(property_name != "None"))]
|
||||
pub type_name: String,
|
||||
|
||||
#[br(if(property_name != "None"))]
|
||||
#[br(args { magic: &type_name, name: &property_name})]
|
||||
pub key: Option<Box<Property>>,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct StructFieldPrelude {
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub property_name: String,
|
||||
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub type_name: String,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct StructPrelude {
|
||||
pub size_in_bytes: u32,
|
||||
#[brw(pad_before = 4)]
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
#[brw(pad_after = 17)]
|
||||
pub struct_name: String,
|
||||
}
|
||||
|
||||
#[binrw::parser(reader, endian)]
|
||||
pub(crate) fn read_struct_field<T: BinRead<Args<'static> = ()> + Debug>(
|
||||
name: &str,
|
||||
) -> BinResult<T> {
|
||||
let prelude = StructFieldPrelude::read_le(reader)?;
|
||||
if prelude.property_name != name {
|
||||
panic!(
|
||||
"Property name doesn't match! Is supposed to be {} but is actually {}",
|
||||
name, prelude.property_name
|
||||
);
|
||||
}
|
||||
// TODO: type check with type_name()
|
||||
if prelude.type_name == "StructProperty" {
|
||||
StructPrelude::read_le(reader)?;
|
||||
}
|
||||
let val = T::read_options(reader, endian, ())?;
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
pub(crate) trait PropertyBase {
|
||||
fn type_name() -> &'static str;
|
||||
fn size_in_bytes(&self) -> u32;
|
||||
|
||||
// these are only relevant for structs:
|
||||
// FIXME: this isn't great'
|
||||
fn struct_name() -> Option<&'static str> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[binrw::writer(writer, endian)]
|
||||
pub(crate) fn write_struct_field<T: PropertyBase + BinWrite<Args<'static> = ()> + Debug>(
|
||||
structure: &T,
|
||||
name: &str,
|
||||
) -> BinResult<()> {
|
||||
let prelude = StructFieldPrelude {
|
||||
property_name: name.to_string(),
|
||||
type_name: T::type_name().to_string(),
|
||||
};
|
||||
prelude.write_le(writer)?;
|
||||
if T::type_name() == "StructProperty" {
|
||||
let struct_prelude = StructPrelude {
|
||||
size_in_bytes: T::size_in_bytes(structure),
|
||||
struct_name: T::struct_name().unwrap().to_string(),
|
||||
};
|
||||
struct_prelude.write_le(writer)?;
|
||||
}
|
||||
structure.write_options(writer, endian, ())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn calc_struct_field_prelude_byte_size(
|
||||
type_name: &str,
|
||||
field_name: &str,
|
||||
struct_name: Option<&str>,
|
||||
) -> u32 {
|
||||
let mut base_size = crate::common::size_of_string_with_length(field_name);
|
||||
|
||||
// This is an easy way to detect properties that are actually structs
|
||||
if struct_name.is_some() {
|
||||
base_size += crate::common::size_of_string_with_length("StructProperty")
|
||||
+ crate::common::size_of_string_with_length(struct_name.unwrap())
|
||||
+ 4
|
||||
+ 17
|
||||
+ 4; // see struct prelude
|
||||
} else {
|
||||
base_size += crate::common::size_of_string_with_length(type_name);
|
||||
}
|
||||
|
||||
base_size
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
use crate::da_assemble_id_data::DAAssembleIdDataStruct;
|
||||
use crate::da_customize_asset_id::DACustomizeAssetIdDataStruct;
|
||||
use crate::da_trigger_data::DATriggerDataStruct;
|
||||
use crate::da_tuning_data::DATuningDataStruct;
|
||||
use crate::str_property::StrProperty;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::property::str_property::StrProperty;
|
||||
|
||||
use super::{
|
||||
da_assemble_id_data::DAAssembleIdDataStruct,
|
||||
da_customize_asset_id::DACustomizeAssetIdDataStruct, da_trigger_data::DATriggerDataStruct,
|
||||
da_tuning_data::DATuningDataStruct,
|
||||
};
|
||||
|
||||
#[paramacro::serialized_struct("DABuildData")]
|
||||
#[derive(Debug)]
|
||||
pub struct DABuildDataStruct {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{da_machine_coloring_data::DAMachineColoringDataStruct, guid::Guid};
|
||||
use super::{da_machine_coloring_data::DAMachineColoringDataStruct, guid::Guid};
|
||||
|
||||
#[paramacro::serialized_struct("DAAssembleIdData")]
|
||||
#[derive(Debug)]
|
|
@ -1,5 +1,7 @@
|
|||
use crate::{
|
||||
bool_property::BoolProperty, da_humanoid_coloring_data::DAHumanoidColoringDataStruct,
|
||||
use crate::property::bool_property::BoolProperty;
|
||||
|
||||
use super::{
|
||||
da_humanoid_coloring_data::DAHumanoidColoringDataStruct,
|
||||
da_humanoid_figure_data::DAHumanoidFigureData, primary_asset_id::PrimaryAssetIdStruct,
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::linear_color::LinearColorStruct;
|
||||
use super::linear_color::LinearColorStruct;
|
||||
|
||||
#[paramacro::serialized_struct("DAHumanoidColoringData")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::float_property::FloatProperty;
|
||||
use crate::property::float_property::FloatProperty;
|
||||
|
||||
#[paramacro::serialized_struct("DAHumanoidFigureData")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::int_property::IntProperty;
|
||||
use crate::property::int_property::IntProperty;
|
||||
|
||||
#[paramacro::serialized_struct("DALoadOption")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::da_module_color::DAModuleColorStruct;
|
||||
use super::da_module_color::DAModuleColorStruct;
|
||||
|
||||
#[paramacro::serialized_struct("DAMachineColoringData")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::linear_color::LinearColorStruct;
|
||||
use super::linear_color::LinearColorStruct;
|
||||
|
||||
#[paramacro::serialized_struct("DAModuleColor")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::int_property::IntProperty;
|
||||
use crate::property::int_property::IntProperty;
|
||||
|
||||
#[paramacro::serialized_struct("DAModuleItemData")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::enum_property::EnumProperty;
|
||||
use crate::property::enum_property::EnumProperty;
|
||||
|
||||
#[paramacro::serialized_struct("DATriggerData")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::map_property::MapProperty;
|
||||
use crate::property::map_property::MapProperty;
|
||||
|
||||
#[paramacro::serialized_struct("DATuningData")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::int_property::IntProperty;
|
||||
use crate::property::int_property::IntProperty;
|
||||
|
||||
#[paramacro::serialized_struct("DATuningPointData")]
|
||||
#[derive(Debug)]
|
|
@ -1,6 +1,6 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use crate::structs::PropertyBase;
|
||||
use crate::property::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
|
@ -1,6 +1,8 @@
|
|||
use binrw::binrw;
|
||||
use std::fmt;
|
||||
|
||||
use crate::property::PropertyBase;
|
||||
|
||||
// See https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/Misc/FGuid
|
||||
#[binrw]
|
||||
pub struct Guid {
|
||||
|
@ -10,7 +12,7 @@ pub struct Guid {
|
|||
pub d: u32,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for Guid {
|
||||
impl PropertyBase for Guid {
|
||||
fn type_name() -> &'static str {
|
||||
"StructProperty"
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use crate::property::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct LinearColorStruct {
|
||||
|
@ -9,7 +11,7 @@ pub struct LinearColorStruct {
|
|||
pub a: f32,
|
||||
}
|
||||
|
||||
impl crate::structs::PropertyBase for LinearColorStruct {
|
||||
impl PropertyBase for LinearColorStruct {
|
||||
fn type_name() -> &'static str {
|
||||
"StructProperty"
|
||||
}
|
|
@ -1,27 +1,53 @@
|
|||
use crate::build_data::DABuildDataStruct;
|
||||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use crate::da_assemble_id_data::DAAssembleIdDataStruct;
|
||||
use crate::da_customize_asset_id::DACustomizeAssetIdDataStruct;
|
||||
use crate::da_humanoid_coloring_data::DAHumanoidColoringDataStruct;
|
||||
use crate::da_humanoid_figure_data::DAHumanoidFigureData;
|
||||
use crate::da_load_option::DALoadOptionStruct;
|
||||
use crate::da_machine_coloring_data::DAMachineColoringDataStruct;
|
||||
use crate::da_module_color::DAModuleColorStruct;
|
||||
use crate::da_module_item_data::DAModuleItemDataStruct;
|
||||
use crate::da_trigger_data::DATriggerDataStruct;
|
||||
use crate::da_tuning_data::DATuningDataStruct;
|
||||
use crate::da_tuning_point_data::DATuningPointData;
|
||||
use crate::datetime::DateTimeStruct;
|
||||
use crate::guid::Guid;
|
||||
use crate::linear_color::LinearColorStruct;
|
||||
use crate::primary_asset_id::PrimaryAssetIdStruct;
|
||||
use crate::primary_asset_type::PrimaryAssetTypeStruct;
|
||||
use crate::quat::QuatStruct;
|
||||
use crate::save_slot_info::SaveSlotInfoStruct;
|
||||
use crate::structs::PropertyBase;
|
||||
use crate::transform::TransformStruct;
|
||||
use crate::vector::VectorStruct;
|
||||
use binrw::binrw;
|
||||
use binrw::{BinRead, BinResult, BinWrite, binrw};
|
||||
use build_data::DABuildDataStruct;
|
||||
use da_assemble_id_data::DAAssembleIdDataStruct;
|
||||
use da_customize_asset_id::DACustomizeAssetIdDataStruct;
|
||||
use da_humanoid_coloring_data::DAHumanoidColoringDataStruct;
|
||||
use da_humanoid_figure_data::DAHumanoidFigureData;
|
||||
use da_load_option::DALoadOptionStruct;
|
||||
use da_machine_coloring_data::DAMachineColoringDataStruct;
|
||||
use da_module_color::DAModuleColorStruct;
|
||||
use da_module_item_data::DAModuleItemDataStruct;
|
||||
use da_trigger_data::DATriggerDataStruct;
|
||||
use da_tuning_data::DATuningDataStruct;
|
||||
use da_tuning_point_data::DATuningPointData;
|
||||
use datetime::DateTimeStruct;
|
||||
use guid::Guid;
|
||||
use linear_color::LinearColorStruct;
|
||||
use primary_asset_id::PrimaryAssetIdStruct;
|
||||
use primary_asset_type::PrimaryAssetTypeStruct;
|
||||
use quat::QuatStruct;
|
||||
use save_slot_info::SaveSlotInfoStruct;
|
||||
use std::fmt::Debug;
|
||||
use transform::TransformStruct;
|
||||
use vector::VectorStruct;
|
||||
|
||||
use crate::{
|
||||
common::{read_string_with_length, write_string_with_length},
|
||||
property::PropertyBase,
|
||||
};
|
||||
|
||||
pub mod build_data;
|
||||
pub mod da_assemble_id_data;
|
||||
pub mod da_customize_asset_id;
|
||||
pub mod da_humanoid_coloring_data;
|
||||
pub mod da_humanoid_figure_data;
|
||||
pub mod da_load_option;
|
||||
pub mod da_machine_coloring_data;
|
||||
pub mod da_module_color;
|
||||
pub mod da_module_item_data;
|
||||
pub mod da_trigger_data;
|
||||
pub mod da_tuning_data;
|
||||
pub mod da_tuning_point_data;
|
||||
pub mod datetime;
|
||||
pub mod guid;
|
||||
pub mod linear_color;
|
||||
pub mod primary_asset_id;
|
||||
pub mod primary_asset_type;
|
||||
pub mod quat;
|
||||
pub mod save_slot_info;
|
||||
pub mod transform;
|
||||
pub mod vector;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
|
@ -114,13 +140,84 @@ pub(crate) fn calc_size_in_bytes(r#struct: &Struct) -> u32 {
|
|||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct StructProperty {
|
||||
pub unk: u32,
|
||||
pub struct StructFieldPrelude {
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub property_name: String,
|
||||
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub type_name: String,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct StructPrelude {
|
||||
pub size_in_bytes: u32,
|
||||
#[brw(pad_before = 4)]
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
#[brw(pad_after = 17)]
|
||||
pub struct_name: String,
|
||||
#[br(args { magic: &struct_name })]
|
||||
#[brw(pad_before = 17)]
|
||||
pub r#struct: Struct,
|
||||
}
|
||||
|
||||
#[binrw::parser(reader, endian)]
|
||||
pub(crate) fn read_struct_field<T: BinRead<Args<'static> = ()> + Debug>(
|
||||
name: &str,
|
||||
) -> BinResult<T> {
|
||||
let prelude = StructFieldPrelude::read_le(reader)?;
|
||||
if prelude.property_name != name {
|
||||
panic!(
|
||||
"Property name doesn't match! Is supposed to be {} but is actually {}",
|
||||
name, prelude.property_name
|
||||
);
|
||||
}
|
||||
// TODO: type check with type_name()
|
||||
if prelude.type_name == "StructProperty" {
|
||||
StructPrelude::read_le(reader)?;
|
||||
}
|
||||
let val = T::read_options(reader, endian, ())?;
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
#[binrw::writer(writer, endian)]
|
||||
pub(crate) fn write_struct_field<T: PropertyBase + BinWrite<Args<'static> = ()> + Debug>(
|
||||
structure: &T,
|
||||
name: &str,
|
||||
) -> BinResult<()> {
|
||||
let prelude = StructFieldPrelude {
|
||||
property_name: name.to_string(),
|
||||
type_name: T::type_name().to_string(),
|
||||
};
|
||||
prelude.write_le(writer)?;
|
||||
if T::type_name() == "StructProperty" {
|
||||
let struct_prelude = StructPrelude {
|
||||
size_in_bytes: T::size_in_bytes(structure),
|
||||
struct_name: T::struct_name().unwrap().to_string(),
|
||||
};
|
||||
struct_prelude.write_le(writer)?;
|
||||
}
|
||||
structure.write_options(writer, endian, ())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn calc_struct_field_prelude_byte_size(
|
||||
type_name: &str,
|
||||
field_name: &str,
|
||||
struct_name: Option<&str>,
|
||||
) -> u32 {
|
||||
let mut base_size = crate::common::size_of_string_with_length(field_name);
|
||||
|
||||
// This is an easy way to detect properties that are actually structs
|
||||
if struct_name.is_some() {
|
||||
base_size += crate::common::size_of_string_with_length("StructProperty")
|
||||
+ crate::common::size_of_string_with_length(struct_name.unwrap())
|
||||
+ 4
|
||||
+ 17
|
||||
+ 4; // see struct prelude
|
||||
} else {
|
||||
base_size += crate::common::size_of_string_with_length(type_name);
|
||||
}
|
||||
|
||||
base_size
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
use crate::{name_property::NameProperty, primary_asset_type::PrimaryAssetTypeStruct};
|
||||
use crate::property::name_property::NameProperty;
|
||||
|
||||
use super::primary_asset_type::PrimaryAssetTypeStruct;
|
||||
|
||||
#[paramacro::serialized_struct("PrimaryAssetId")]
|
||||
#[derive(Debug)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::name_property::NameProperty;
|
||||
use crate::property::name_property::NameProperty;
|
||||
|
||||
#[paramacro::serialized_struct("PrimaryAssetType")]
|
||||
#[derive(Debug)]
|
|
@ -1,6 +1,6 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use crate::structs::PropertyBase;
|
||||
use crate::property::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{
|
||||
array_property::ArrayProperty, datetime::DateTimeStruct, name_property::NameProperty,
|
||||
str_property::StrProperty,
|
||||
use crate::property::{
|
||||
array_property::ArrayProperty, name_property::NameProperty, str_property::StrProperty,
|
||||
};
|
||||
|
||||
use super::datetime::DateTimeStruct;
|
||||
|
||||
#[paramacro::serialized_struct("SaveSlotInfo")]
|
||||
#[derive(Debug)]
|
||||
pub struct SaveSlotInfoStruct {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{quat::QuatStruct, vector::VectorStruct};
|
||||
use super::{quat::QuatStruct, vector::VectorStruct};
|
||||
|
||||
#[paramacro::serialized_struct("Transform")]
|
||||
#[derive(Debug)]
|
|
@ -1,6 +1,6 @@
|
|||
use binrw::binrw;
|
||||
|
||||
use crate::structs::PropertyBase;
|
||||
use crate::property::PropertyBase;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
|
@ -1,5 +1,6 @@
|
|||
use binrw::{BinRead, BinWrite};
|
||||
use ireko::{GenericTaggedObject, TaggedSerialization};
|
||||
use ireko::TaggedSerialization;
|
||||
use ireko::save_object::generic::GenericTaggedObject;
|
||||
use std::fs::read;
|
||||
use std::io::Cursor;
|
||||
use std::path::PathBuf;
|
||||
|
|
Loading…
Add table
Reference in a new issue