Implement proper map parsing, fix array parsing
Finally finished and figured out how maps are handled. It didn't encode the number of items, it's based on how many bytes you read. I also fixed arrays so they're also correct, and we'll see if sets break.
This commit is contained in:
parent
874ca0a968
commit
9dd335f80e
5 changed files with 210 additions and 70 deletions
|
@ -1,10 +1,27 @@
|
||||||
use crate::set_property::SetEntry;
|
use crate::set_property::SetEntry;
|
||||||
use binrw::binrw;
|
use binrw::{binrw, BinRead, BinResult};
|
||||||
|
use crate::map_property::{KeyType, MapEntry};
|
||||||
|
|
||||||
|
#[binrw::parser(reader, endian)]
|
||||||
|
fn custom_parser(size_in_bytes: u32, key_name: &str) -> BinResult<Vec<SetEntry>> {
|
||||||
|
let mut result = Vec::<SetEntry>::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, (key_name,)).unwrap());
|
||||||
|
current = reader.stream_position().unwrap();
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ArrayProperty {
|
pub struct ArrayProperty {
|
||||||
pub unk: u32,
|
// Plus this int
|
||||||
|
pub size_in_bytes: u32,
|
||||||
|
|
||||||
#[br(temp)]
|
#[br(temp)]
|
||||||
#[bw(ignore)]
|
#[bw(ignore)]
|
||||||
#[br(pad_before = 4)]
|
#[br(pad_before = 4)]
|
||||||
|
@ -15,8 +32,8 @@ pub struct ArrayProperty {
|
||||||
pub key_name: String,
|
pub key_name: String,
|
||||||
|
|
||||||
#[br(pad_before = 1)]
|
#[br(pad_before = 1)]
|
||||||
pub num_array_entries: u32,
|
pub unk: u32,
|
||||||
|
|
||||||
#[br(count = num_array_entries, args { inner: (&*key_name,) })]
|
#[br(parse_with = custom_parser, args(size_in_bytes, &key_name))]
|
||||||
pub entries: Vec<SetEntry>,
|
pub entries: Vec<SetEntry>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,8 @@ pub enum StringBasedProperty {
|
||||||
Int(IntProperty),
|
Int(IntProperty),
|
||||||
#[br(pre_assert("MapProperty" == magic))]
|
#[br(pre_assert("MapProperty" == magic))]
|
||||||
Map(MapProperty),
|
Map(MapProperty),
|
||||||
|
#[br(pre_assert("SetProperty" == magic))]
|
||||||
|
Set(SetProperty),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
|
@ -79,6 +81,7 @@ pub enum StringBasedProperty {
|
||||||
pub struct Entry {
|
pub struct Entry {
|
||||||
#[br(temp)]
|
#[br(temp)]
|
||||||
#[bw(ignore)]
|
#[bw(ignore)]
|
||||||
|
#[br(dbg)]
|
||||||
pub name_length: u32,
|
pub name_length: u32,
|
||||||
#[br(count = name_length)]
|
#[br(count = name_length)]
|
||||||
#[bw(map = |x : &String | x.as_bytes())]
|
#[bw(map = |x : &String | x.as_bytes())]
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use std::io::{Read, Seek, SeekFrom};
|
||||||
use crate::read_bool_from;
|
use crate::read_bool_from;
|
||||||
use crate::struct_property::Struct;
|
use crate::struct_property::Struct;
|
||||||
use crate::structs::PrimaryAssetNameProperty;
|
use crate::structs::PrimaryAssetNameProperty;
|
||||||
use binrw::binrw;
|
use binrw::{binrw, BinRead, BinResult};
|
||||||
use binrw::helpers::until_exclusive;
|
use binrw::helpers::until_exclusive;
|
||||||
|
|
||||||
// A struct without a name
|
// A struct without a name
|
||||||
|
@ -15,6 +16,16 @@ pub struct AnonymousStruct {
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MapSubStructProperty {
|
pub struct MapSubStructProperty {
|
||||||
|
#[br(temp)]
|
||||||
|
#[bw(ignore)]
|
||||||
|
pub unk_name_length: u32,
|
||||||
|
#[br(args { is_map: true })]
|
||||||
|
pub r#struct: Struct,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StructMaybeKey {
|
||||||
#[br(temp)]
|
#[br(temp)]
|
||||||
#[bw(ignore)]
|
#[bw(ignore)]
|
||||||
pub unk_name_length: u32,
|
pub unk_name_length: u32,
|
||||||
|
@ -29,11 +40,12 @@ pub struct MapSubStructProperty {
|
||||||
#[br(count = unk_type_length)]
|
#[br(count = unk_type_length)]
|
||||||
#[bw(map = |x : &String | x.as_bytes())]
|
#[bw(map = |x : &String | x.as_bytes())]
|
||||||
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
||||||
|
#[br(pad_after = 8)] // nothingness and then length for the struct
|
||||||
pub unk_type: String,
|
pub unk_type: String,
|
||||||
#[br(temp)]
|
|
||||||
#[bw(ignore)]
|
#[br(dbg)]
|
||||||
#[br(pad_before = 8)] // dunno what this is
|
#[br(pad_before = 4)] // type length
|
||||||
pub name_length: u32,
|
#[br(args { is_map: true })]
|
||||||
pub r#struct: Struct,
|
pub r#struct: Struct,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,16 +112,12 @@ pub struct GuidStruct {
|
||||||
// Used in MapProperty exclusively, seems to be a shortened version of some Properties
|
// Used in MapProperty exclusively, seems to be a shortened version of some Properties
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[br(import { magic: &str, unk: &UnknownType, is_value: bool })]
|
#[br(import { magic: &str, is_value: bool })]
|
||||||
pub enum MabSubProperty {
|
pub enum MabSubProperty {
|
||||||
#[br(pre_assert("NameProperty" == magic))]
|
#[br(pre_assert("NameProperty" == magic))]
|
||||||
Name(MapSubNameProperty),
|
Name(MapSubNameProperty),
|
||||||
#[br(pre_assert("StructProperty" == magic && *unk == UnknownType::RealStruct))]
|
#[br(pre_assert("StructProperty" == magic))]
|
||||||
Struct(MapSubStructProperty),
|
Struct(MapSubStructProperty),
|
||||||
#[br(pre_assert("StructProperty" == magic && *unk == UnknownType::AnonymousStruct))]
|
|
||||||
AnonymousStruct(AnonymousStruct), // assuming all value structs are anonymous for now
|
|
||||||
#[br(pre_assert("StructProperty" == magic && *unk == UnknownType::Guid || *unk == UnknownType::Guid2))]
|
|
||||||
GuidStruct(GuidStruct), // assuming all value structs are anonymous for now
|
|
||||||
#[br(pre_assert("FloatProperty" == magic))]
|
#[br(pre_assert("FloatProperty" == magic))]
|
||||||
Float(MapSubFloatProperty),
|
Float(MapSubFloatProperty),
|
||||||
#[br(pre_assert("StrProperty" == magic))]
|
#[br(pre_assert("StrProperty" == magic))]
|
||||||
|
@ -124,42 +132,102 @@ pub enum MabSubProperty {
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[br(import(key_type: &str, value_type: &str, key_unk: &UnknownType, value_unk: &UnknownType))]
|
pub struct GuidStructThing {
|
||||||
pub struct MapEntry {
|
pub guid: [u8; 16],
|
||||||
//#[br(pad_before = 8)]
|
}
|
||||||
#[br(args { magic: key_type, unk: key_unk, is_value: true})]
|
|
||||||
pub key: MabSubProperty,
|
|
||||||
|
|
||||||
#[br(args {magic: value_type, unk: value_unk, is_value: true})]
|
#[binrw]
|
||||||
//#[br(if(!key_is_none(&key)))]
|
#[derive(Debug)]
|
||||||
|
pub struct SomeIDStruct {
|
||||||
|
pub guid: [u8; 16],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SomeID2Struct {
|
||||||
|
pub guid: [u8; 16],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StringMapKey {
|
||||||
|
pub enum_length: u32,
|
||||||
|
#[br(count = enum_length)]
|
||||||
|
#[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 r#enum: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[br(import { magic: &KeyType })]
|
||||||
|
pub enum MapKeyProperty {
|
||||||
|
#[br(pre_assert(*magic == KeyType::String))]
|
||||||
|
String(StringMapKey),
|
||||||
|
#[br(pre_assert(*magic == KeyType::StructMaybe))]
|
||||||
|
StructMaybe(StructMaybeKey),
|
||||||
|
#[br(pre_assert(*magic == KeyType::Enum))]
|
||||||
|
Enum(MapSubEnumProperty),
|
||||||
|
#[br(pre_assert(*magic == KeyType::EnumAgain))]
|
||||||
|
EnumAgain(MapSubEnumProperty),
|
||||||
|
#[br(pre_assert(*magic == KeyType::GUID))]
|
||||||
|
GUID(GuidStructThing),
|
||||||
|
#[br(pre_assert(*magic == KeyType::SomeID))]
|
||||||
|
SomeID(SomeIDStruct),
|
||||||
|
#[br(pre_assert(*magic == KeyType::SomeID2))]
|
||||||
|
SomeID2(SomeID2Struct),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_empty(key: &MapKeyProperty) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[br(import(key_type: &KeyType, value_type: &str))]
|
||||||
|
pub struct MapEntry {
|
||||||
|
#[br(args { magic: key_type})]
|
||||||
|
#[br(dbg)]
|
||||||
|
pub key: MapKeyProperty,
|
||||||
|
|
||||||
|
#[br(args {magic: value_type, is_value: true})]
|
||||||
|
#[br(dbg)]
|
||||||
pub value: MabSubProperty,
|
pub value: MabSubProperty,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[brw(repr = u8)]
|
#[brw(repr = u32)]
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub enum UnknownType {
|
#[derive(PartialEq, Clone)]
|
||||||
// literally all guesswork, idk
|
pub enum KeyType {
|
||||||
String = 0x0,
|
String = 0x1,
|
||||||
Name = 0x31,
|
GUID = 0x3,
|
||||||
Int = 0xBA,
|
SomeID = 0x6,
|
||||||
RealStruct = 0x51,
|
SomeID2 = 0x10,
|
||||||
Enum = 0x21,
|
EnumAgain = 0x4,
|
||||||
Guid = 0x45,
|
Enum = 0x7,
|
||||||
IDK = 0x44,
|
StructMaybe = 0xC,
|
||||||
Guid2 = 0x5,
|
}
|
||||||
AnonymousStruct = 0xF,
|
|
||||||
|
#[binrw::parser(reader, endian)]
|
||||||
|
fn custom_parser(size_in_bytes: u32, key_type: &KeyType, value_type: &str) -> BinResult<Vec<MapEntry>> {
|
||||||
|
let mut result = Vec::<MapEntry>::new();
|
||||||
|
|
||||||
|
let mut current = reader.stream_position().unwrap();
|
||||||
|
let end = current + size_in_bytes as u64 - 5 - 3;
|
||||||
|
|
||||||
|
while current < end {
|
||||||
|
result.push(MapEntry::read_options(reader, endian, (&key_type, &value_type)).unwrap());
|
||||||
|
current = reader.stream_position().unwrap();
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MapProperty {
|
pub struct MapProperty {
|
||||||
/*
|
|
||||||
pub key_unk: UnknownType,
|
|
||||||
#[br(pad_after = 2)] // actually might need all 4 bytes?
|
|
||||||
|
|
||||||
pub value_unk: UnknownType,*/
|
|
||||||
// Plus this int
|
// Plus this int
|
||||||
|
#[br(dbg)]
|
||||||
pub size_in_bytes: u32,
|
pub size_in_bytes: u32,
|
||||||
|
|
||||||
#[br(temp)]
|
#[br(temp)]
|
||||||
|
@ -179,16 +247,12 @@ pub struct MapProperty {
|
||||||
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
||||||
pub value_name: String,
|
pub value_name: String,
|
||||||
|
|
||||||
//#[br(pad_before = 5)]
|
#[br(pad_before = 5)]
|
||||||
//
|
#[br(dbg)]
|
||||||
//pub num_map_entries: u32,
|
pub key_type: KeyType,
|
||||||
#[br(count = size_in_bytes + 1)]
|
|
||||||
#[br(temp)]
|
#[br(parse_with = custom_parser, args(size_in_bytes, &key_type, &value_name))]
|
||||||
#[bw(ignore)]
|
pub entries: Vec<MapEntry>,
|
||||||
pub dummy_data: Vec<u8>,
|
|
||||||
// TODO: uncomment when map parsing reliably works, otherwise just dummy the data out
|
|
||||||
//#[br(count = num_map_entries, args { inner: (&*key_name, &*value_name, &key_unk, &value_unk) })]
|
|
||||||
//pub entries: Vec<MapEntry>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -215,14 +279,14 @@ mod tests {
|
||||||
assert_eq!(decoded.size_in_bytes, 49);
|
assert_eq!(decoded.size_in_bytes, 49);
|
||||||
assert_eq!(decoded.key_name, "StrProperty");
|
assert_eq!(decoded.key_name, "StrProperty");
|
||||||
assert_eq!(decoded.value_name, "StrProperty");
|
assert_eq!(decoded.value_name, "StrProperty");
|
||||||
/*let String(key_property) = &decoded.entries.first().unwrap().key else {
|
let MapKeyProperty::String(key_property) = &decoded.entries.first().unwrap().key else {
|
||||||
panic!("StrProperty!")
|
panic!("StrProperty!")
|
||||||
};
|
};
|
||||||
let String(value_property) = &decoded.entries.first().unwrap().value else {
|
let String(value_property) = &decoded.entries.first().unwrap().value else {
|
||||||
panic!("StrProperty!")
|
panic!("StrProperty!")
|
||||||
};
|
};
|
||||||
assert_eq!(key_property.name, "AR0XJGFWA6HNIQ1AAUJ9UR828");
|
assert_eq!(key_property.r#enum, "AR0XJGFWA6HNIQ1AAUJ9UR828");
|
||||||
assert_eq!(value_property.name, "NAME 1");*/
|
assert_eq!(value_property.name, "NAME 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -252,14 +316,14 @@ mod tests {
|
||||||
assert_eq!(decoded.size_in_bytes, 186);
|
assert_eq!(decoded.size_in_bytes, 186);
|
||||||
assert_eq!(decoded.key_name, "NameProperty");
|
assert_eq!(decoded.key_name, "NameProperty");
|
||||||
assert_eq!(decoded.value_name, "IntProperty");
|
assert_eq!(decoded.value_name, "IntProperty");
|
||||||
/*let Name(key_property) = &decoded.entries.first().unwrap().key else {
|
let MapKeyProperty::Enum(key_property) = &decoded.entries.first().unwrap().key else {
|
||||||
panic!("Name!")
|
panic!("Name!")
|
||||||
};
|
};
|
||||||
let Int(value_property) = &decoded.entries.first().unwrap().value else {
|
let Int(value_property) = &decoded.entries.first().unwrap().value else {
|
||||||
panic!("Int!")
|
panic!("Int!")
|
||||||
};
|
};
|
||||||
assert_eq!(key_property.sub_property_name, "SelectedMachine");
|
assert_eq!(key_property.r#enum, "SelectedMachine");
|
||||||
assert_eq!(value_property.value, 2);*/
|
assert_eq!(value_property.value, 2);
|
||||||
// TODO: test the rest of the values
|
// TODO: test the rest of the values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
use crate::structs::{
|
use crate::structs::{CarryCountProperty, DAAssembleIdDataStruct, DABuildDataStruct, DACharacterCommonStatusStruct, DALoadOptionStruct, DAMachineColoringDataStruct, DAModuleColorStruct, DAModuleItemDataStruct, DateTimeStruct, GuidStruct, LinearColorStruct, ParamsStruct, PrimaryAssetIdStruct, PrimaryAssetNameProperty, SaveSlotInfoStruct};
|
||||||
DAAssembleIdDataStruct, DABuildDataStruct, DACharacterCommonStatusStruct, DALoadOptionStruct,
|
|
||||||
DAMachineColoringDataStruct, DAModuleColorStruct, DAModuleItemDataStruct, DateTimeStruct,
|
|
||||||
GuidStruct, LinearColorStruct, ParamsStruct, PrimaryAssetIdStruct, PrimaryAssetTypeStruct,
|
|
||||||
SaveSlotInfoStruct,
|
|
||||||
};
|
|
||||||
use binrw::binrw;
|
use binrw::binrw;
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[br(import { is_map: bool })]
|
||||||
pub enum Struct {
|
pub enum Struct {
|
||||||
#[br(magic = b"DateTime\0")]
|
#[br(magic = b"DateTime\0")]
|
||||||
DateTime(DateTimeStruct),
|
DateTime(DateTimeStruct),
|
||||||
|
@ -20,7 +16,15 @@ pub enum Struct {
|
||||||
#[br(magic = b"Params\0")]
|
#[br(magic = b"Params\0")]
|
||||||
Params(ParamsStruct),
|
Params(ParamsStruct),
|
||||||
#[br(magic = b"PrimaryAssetType\0")]
|
#[br(magic = b"PrimaryAssetType\0")]
|
||||||
PrimaryAssetType(PrimaryAssetTypeStruct),
|
PrimaryAssetType {
|
||||||
|
#[br(pad_before = 17)]
|
||||||
|
#[br(dbg)]
|
||||||
|
name: PrimaryAssetNameProperty,
|
||||||
|
#[br(pad_before = 9)] // "None" and it's length in bytes plus the null terminator
|
||||||
|
#[br(pad_after = 9)] // ditto
|
||||||
|
#[br(dbg)]
|
||||||
|
primary_asset_name: PrimaryAssetNameProperty,
|
||||||
|
},
|
||||||
#[br(magic = b"PrimaryAssetId\0")]
|
#[br(magic = b"PrimaryAssetId\0")]
|
||||||
PrimaryAssetId(PrimaryAssetIdStruct),
|
PrimaryAssetId(PrimaryAssetIdStruct),
|
||||||
#[br(magic = b"DAModuleItemData\0")]
|
#[br(magic = b"DAModuleItemData\0")]
|
||||||
|
@ -37,6 +41,42 @@ pub enum Struct {
|
||||||
DAModuleColor(DAModuleColorStruct),
|
DAModuleColor(DAModuleColorStruct),
|
||||||
#[br(magic = b"LinearColor\0")]
|
#[br(magic = b"LinearColor\0")]
|
||||||
LinearColor(LinearColorStruct),
|
LinearColor(LinearColorStruct),
|
||||||
|
#[br(magic = b"CarryCount\0")]
|
||||||
|
CarryCount {
|
||||||
|
#[br(dbg)]
|
||||||
|
carry_count: CarryCountProperty,
|
||||||
|
#[br(dbg)]
|
||||||
|
#[br(pad_before = 15)] // "StoreCount" + 4 bytes for length + 1 byte for endofstring
|
||||||
|
#[br(pad_after = 9)] // "None" + 1 byte for endofstring + 4 bytes for length
|
||||||
|
store_count: CarryCountProperty,
|
||||||
|
},
|
||||||
|
#[br(magic = b"Map\0")]
|
||||||
|
Map {
|
||||||
|
#[br(dbg)]
|
||||||
|
#[br(pad_after = 9)] // "None" + 1 byte for endofstring + 4 bytes for length
|
||||||
|
map: CarryCountProperty,
|
||||||
|
},
|
||||||
|
// TODO: im almost certain this isn't a struct name
|
||||||
|
#[br(magic = b"ID\0")]
|
||||||
|
ID {
|
||||||
|
unk: [u8; 149], // not sure how to parse this yet
|
||||||
|
#[br(dbg)]
|
||||||
|
#[br(pad_after = 9)] // "None" and it's length in bytes plus the null terminator
|
||||||
|
name: PrimaryAssetNameProperty,
|
||||||
|
|
||||||
|
#[br(dbg)]
|
||||||
|
#[br(pad_after = 9)] // "None" and it's length in bytes plus the null terminator
|
||||||
|
primary_asset_name: PrimaryAssetNameProperty,
|
||||||
|
|
||||||
|
#[br(dbg)]
|
||||||
|
data: [u8; 137],
|
||||||
|
},
|
||||||
|
#[br(magic = b"Set\0")]
|
||||||
|
Set {
|
||||||
|
#[br(dbg)]
|
||||||
|
#[br(pad_after = 9)] // "None" + 1 byte for endofstring + 4 bytes for length
|
||||||
|
set: CarryCountProperty,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
|
@ -47,5 +87,6 @@ pub struct StructProperty {
|
||||||
#[bw(ignore)]
|
#[bw(ignore)]
|
||||||
#[br(pad_before = 4)]
|
#[br(pad_before = 4)]
|
||||||
pub name_length: u32,
|
pub name_length: u32,
|
||||||
|
#[br(args { is_map: false })]
|
||||||
pub r#struct: Struct,
|
pub r#struct: Struct,
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,35 +38,49 @@ pub struct ParamsStruct {
|
||||||
pub struct PrimaryAssetNameProperty {
|
pub struct PrimaryAssetNameProperty {
|
||||||
#[br(temp)]
|
#[br(temp)]
|
||||||
#[bw(ignore)]
|
#[bw(ignore)]
|
||||||
|
#[br(dbg)]
|
||||||
pub property_name_length: u32,
|
pub property_name_length: u32,
|
||||||
#[br(count = property_name_length)]
|
#[br(count = property_name_length)]
|
||||||
#[bw(map = |x : &String | x.as_bytes())]
|
#[bw(map = |x : &String | x.as_bytes())]
|
||||||
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
||||||
|
#[br(dbg)]
|
||||||
pub property_name: String,
|
pub property_name: String,
|
||||||
|
|
||||||
#[br(temp)]
|
#[br(temp)]
|
||||||
#[bw(ignore)]
|
#[bw(ignore)]
|
||||||
#[br(if(property_name != "None"))]
|
#[br(if(property_name != "None"))]
|
||||||
|
#[br(dbg)]
|
||||||
pub type_length: u32,
|
pub type_length: u32,
|
||||||
#[br(count = type_length)]
|
#[br(count = type_length)]
|
||||||
#[bw(map = |x : &String | x.as_bytes())]
|
#[bw(map = |x : &String | x.as_bytes())]
|
||||||
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
||||||
#[br(if(property_name != "None"))]
|
#[br(if(property_name != "None"))]
|
||||||
|
#[br(dbg)]
|
||||||
pub type_name: String,
|
pub type_name: String,
|
||||||
|
|
||||||
#[br(if(property_name != "None"))]
|
#[br(if(property_name != "None"))]
|
||||||
#[br(args { magic: &type_name})]
|
#[br(args { magic: &type_name})]
|
||||||
|
//#[br(dbg)]
|
||||||
pub key: Option<Box<StringBasedProperty>>,
|
pub key: Option<Box<StringBasedProperty>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PrimaryAssetTypeStruct {
|
pub struct CarryCountProperty {
|
||||||
#[br(pad_before = 17)]
|
#[br(temp)]
|
||||||
name: PrimaryAssetNameProperty,
|
#[bw(ignore)]
|
||||||
#[br(pad_before = 9)] // "None" and it's length in bytes plus the null terminator
|
#[br(dbg)]
|
||||||
#[br(pad_after = 9)] // ditto
|
pub property_name_length: u32,
|
||||||
primary_asset_name: PrimaryAssetNameProperty,
|
#[br(count = property_name_length)]
|
||||||
|
#[bw(map = |x : &String | x.as_bytes())]
|
||||||
|
#[br(map = | x: Vec<u8> | String::from_utf8(x).unwrap().trim_matches(char::from(0)).to_string())]
|
||||||
|
#[br(dbg)]
|
||||||
|
pub property_name: String,
|
||||||
|
|
||||||
|
#[br(args { magic: &property_name})]
|
||||||
|
//#[br(dbg)]
|
||||||
|
pub key: Option<Box<StringBasedProperty>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
|
@ -79,7 +93,8 @@ pub struct PrimaryAssetIdStruct {
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DAModuleItemDataStruct {
|
pub struct DAModuleItemDataStruct {
|
||||||
pub unk: [u8; 17],
|
#[br(pad_before = 17)]
|
||||||
|
pub module_level: PrimaryAssetNameProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
|
|
Loading…
Add table
Reference in a new issue