From 8f55d00e249505d52622d22773cf7978768d08c8 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 24 Feb 2025 00:30:16 -0500 Subject: [PATCH] Complete Persistent.sav parsing, fix up a ton of things This is unfortunately one giant commit, but this now (partially) parses Persistent.sav. There is still some structs and data left to parse, and we're suspiciously missing 3KiB of data at the end. But... progress! --- src/array_property.rs | 271 ++++++++++++++-- src/bool_property.rs | 20 +- src/build_data.rs | 633 ++++++++++++++++++++++++++++++++++++++ src/common.rs | 9 +- src/float_property.rs | 4 +- src/guid.rs | 9 +- src/int_property.rs | 8 +- src/lib.rs | 38 ++- src/linear_color.rs | 31 ++ src/map_property.rs | 74 +++-- src/name_property.rs | 15 + src/primary_asset_id.rs | 44 +++ src/primary_asset_type.rs | 40 +++ src/set_property.rs | 138 +++++++-- src/struct_property.rs | 113 ++++--- src/structs.rs | 196 ++++++++++-- tests/resources/Slot.bin | Bin 0 -> 908 bytes tests/roundtrip.rs | 32 +- 18 files changed, 1472 insertions(+), 203 deletions(-) create mode 100644 src/build_data.rs create mode 100644 src/linear_color.rs create mode 100644 src/name_property.rs create mode 100644 src/primary_asset_id.rs create mode 100644 src/primary_asset_type.rs create mode 100644 tests/resources/Slot.bin diff --git a/src/array_property.rs b/src/array_property.rs index 1d3b5a3..a8f0d70 100644 --- a/src/array_property.rs +++ b/src/array_property.rs @@ -1,16 +1,42 @@ use crate::common::{read_string_with_length, write_string_with_length}; -use crate::map_property::MabSubProperty; +use crate::map_property::{KeyType, StringMapKey}; +use crate::struct_property::Struct; use binrw::{BinRead, BinResult, binrw}; +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 { + ArrayKeyData::String() => 0, + ArrayKeyData::Struct { + name, + type_name, + struct_name, + } => { + // for magic numbers see padding in ArrayKeyData + // plus null terminator + (name.len() + type_name.len() + struct_name.len() + 18 + 7 + key_name.len() + 1) as u64 + } + } +} + #[binrw::parser(reader, endian)] -fn custom_parser(size_in_bytes: u32, value_type: &str) -> BinResult> { +fn custom_parser( + size_in_bytes: u32, + key_name: &str, + value_type: &KeyType, + key_data: &ArrayKeyData, +) -> BinResult> { let mut result = Vec::::new(); let mut current = reader.stream_position()?; - let end = current + size_in_bytes as u64 - 4; + let end = current + size_in_bytes as u64 - 4 - calculate_header_size(key_name, key_data); while current < end { - result.push(ArrayEntry::read_options(reader, endian, (value_type,))?); + result.push(ArrayEntry::read_options( + reader, + endian, + (value_type, key_data), + )?); current = reader.stream_position()?; } Ok(result) @@ -18,10 +44,23 @@ fn custom_parser(size_in_bytes: u32, value_type: &str) -> BinResult { struct_name }, _ => { "" }} })] + r#struct: Struct, + }, + #[br(pre_assert(KeyType::String == *magic))] + String(StringMapKey), +} + +#[binrw] +#[derive(Debug)] +#[br(import(value_type: &KeyType, key_data: &ArrayKeyData))] pub struct ArrayEntry { - #[br(args { magic: &value_type })] - pub key: MabSubProperty, + #[br(args { magic: value_type, key_data: key_data })] + pub key: ArrayValue, } fn calc_size_in_bytes(entries: &Vec) -> u32 { @@ -29,6 +68,30 @@ fn calc_size_in_bytes(entries: &Vec) -> u32 { 18 } +#[binrw] +#[derive(Debug)] +#[br(import { key_type: &KeyType })] +pub enum ArrayKeyData { + #[br(pre_assert(*key_type == KeyType::String))] + String(), + #[br(pre_assert(*key_type == KeyType::ArrayStruct))] + Struct { + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + name: String, + + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + type_name: String, + + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + #[br(pad_before = 8)] // idk + #[br(pad_after = 17)] // super idk + struct_name: String, + }, +} + #[binrw] #[derive(Debug)] pub struct ArrayProperty { @@ -41,20 +104,21 @@ pub struct ArrayProperty { pub key_name: String, #[brw(pad_before = 1)] - #[bw(calc = 1)] - pub unk: u32, + pub key_type: KeyType, - #[br(parse_with = custom_parser, args(size_in_bytes, &key_name))] + #[br(args { key_type: &key_type })] + pub key_data: ArrayKeyData, + + #[br(parse_with = custom_parser, args(size_in_bytes, &key_name, &key_type, &key_data))] pub entries: Vec, } #[cfg(test)] mod tests { use super::*; - use crate::map_property::MabSubProperty::String; + use crate::map_property::StringMapKey; use binrw::{BinRead, BinWrite}; use std::io::Cursor; - use crate::map_property::MapSubStrProperty; #[test] fn read_simple_array() { @@ -68,7 +132,7 @@ mod tests { let mut cursor = Cursor::new(data); let decoded = ArrayProperty::read_le(&mut cursor).unwrap(); assert_eq!(decoded.key_name, "StrProperty"); - let String(value_property) = &decoded.entries.first().unwrap().key else { + let ArrayValue::String(value_property) = &decoded.entries.first().unwrap().key else { panic!("StrProperty!") }; assert_eq!(value_property.value, "redstrate"); @@ -84,13 +148,13 @@ mod tests { ]; let property = ArrayProperty { key_name: "StrProperty".to_string(), - entries: vec![ - ArrayEntry { - key: String(MapSubStrProperty { - value: "redstrate".to_string(), - }), - } - ], + key_type: KeyType::String, + key_data: ArrayKeyData::String(), + entries: vec![ArrayEntry { + key: ArrayValue::String(StringMapKey { + value: "redstrate".to_string(), + }), + }], }; let mut buffer: Vec = Vec::new(); @@ -101,4 +165,171 @@ mod tests { assert_eq!(expected_data, &buffer[..]); } + + #[test] + fn read_complex_array() { + // From Persistent.sav + let data = [ + 0x5f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x6c, + 0x6f, 0x74, 0x73, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x0e, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, + 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x50, 0x6f, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, 0x5f, 0x50, 0x6f, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, + 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, + 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, + 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, + 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, + 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, + 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, + 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, + 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, + 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, + 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, + 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, + 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, + 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, + ]; + let mut cursor = Cursor::new(data); + let decoded = ArrayProperty::read_le(&mut cursor).unwrap(); + assert_eq!(decoded.key_name, "StructProperty"); + assert_eq!(decoded.entries.len(), 10); + } } diff --git a/src/bool_property.rs b/src/bool_property.rs index e6a6682..c8c450d 100644 --- a/src/bool_property.rs +++ b/src/bool_property.rs @@ -23,15 +23,11 @@ mod tests { let decoded = BoolProperty::read_le(&mut cursor).unwrap(); assert!(!decoded.value); } - + #[test] fn write_false() { - let expected_data: [u8; 10] = [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - ]; - let property = BoolProperty { - value: false - }; + let expected_data: [u8; 10] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let property = BoolProperty { value: false }; let mut buffer: Vec = Vec::new(); { @@ -41,7 +37,7 @@ mod tests { assert_eq!(expected_data, &buffer[..]); } - + #[test] fn read_true() { let data = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00]; @@ -52,12 +48,8 @@ mod tests { #[test] fn write_true() { - let expected_data: [u8; 10] = [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 - ]; - let property = BoolProperty { - value: true - }; + let expected_data: [u8; 10] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00]; + let property = BoolProperty { value: true }; let mut buffer: Vec = Vec::new(); { diff --git a/src/build_data.rs b/src/build_data.rs new file mode 100644 index 0000000..e860695 --- /dev/null +++ b/src/build_data.rs @@ -0,0 +1,633 @@ +use crate::structs::StructField; +use binrw::binrw; + +#[binrw] +#[derive(Debug)] +pub struct DABuildDataStruct { + #[br(args { name: "Name", r#type: "StrProperty" })] + pub name: StructField, + + #[br(args { name: "Assemble", r#type: "StructProperty" })] + pub assemble: StructField, + + #[br(args { name: "Trigger", r#type: "StructProperty" })] + pub trigger: StructField, + + #[br(args { name: "Customize", r#type: "StructProperty" })] + pub customize: StructField, + + #[br(args { name: "Tuning", r#type: "StructProperty" })] + #[brw(pad_after = 9)] + pub tuning: StructField, +} + +#[cfg(test)] +mod tests { + use super::*; + use binrw::BinRead; + use std::io::Cursor; + + #[test] + fn read_build_data() { + let data = [ + 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x71, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x44, 0x41, + 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x65, 0x49, 0x64, 0x44, 0x61, 0x74, 0x61, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x48, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x47, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x89, + 0xd9, 0x69, 0x90, 0x61, 0xda, 0x47, 0x80, 0xe1, 0xc4, 0xad, 0x6e, 0xf9, 0x95, 0xc0, + 0x08, 0x00, 0x00, 0x00, 0x48, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x47, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x28, 0xe3, 0x56, 0xab, + 0x86, 0xf9, 0x4e, 0xb3, 0x0c, 0x34, 0x41, 0x3f, 0x07, 0x12, 0x01, 0x09, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, + 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0xca, 0x98, 0x86, 0xf0, 0x51, 0x64, + 0x4f, 0xa6, 0x12, 0x50, 0xb4, 0x68, 0xa2, 0x5d, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x54, + 0x68, 0x72, 0x75, 0x73, 0x74, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x75, 0x69, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xed, 0x7a, 0x32, 0x57, 0x2a, 0x13, 0x45, 0xa4, + 0xc4, 0x0c, 0x04, 0x2a, 0x05, 0x15, 0x94, 0x08, 0x00, 0x00, 0x00, 0x55, 0x74, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x75, 0x69, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x89, 0xc3, 0x76, 0xcb, 0x69, 0xf7, 0xb8, 0x47, 0x89, 0x6d, 0x5f, 0xd7, + 0x64, 0x19, 0x7a, 0xdd, 0x13, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x47, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x1e, 0x01, 0x6f, + 0x63, 0x1d, 0x26, 0x48, 0xbd, 0xcd, 0x20, 0x66, 0x36, 0xe1, 0xa4, 0x00, 0x15, 0x00, + 0x00, 0x00, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, + 0x6e, 0x74, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x75, + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x6a, 0xe2, 0x65, 0xe3, 0xff, 0x1e, 0x46, + 0xb7, 0x76, 0x0b, 0xe9, 0x9d, 0x5d, 0x85, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x4c, 0x65, + 0x66, 0x74, 0x52, 0x65, 0x61, 0x72, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x47, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x52, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x61, 0x72, 0x57, 0x65, 0x61, + 0x70, 0x6f, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x44, 0x61, 0x74, 0x61, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x61, + 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x48, 0x61, 0x6e, 0x67, + 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4d, + 0x61, 0x69, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x8e, 0x23, 0x3e, 0x45, 0xa1, + 0x85, 0x3e, 0x9f, 0xaa, 0xaa, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x53, 0x75, 0x62, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0xc6, 0x29, 0x3d, 0x69, 0x55, + 0x0b, 0x3d, 0x7e, 0xaa, 0xca, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, + 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, + 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x47, 0x6c, 0x6f, 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x6e, 0xc0, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x08, 0x00, 0x00, 0x00, 0x48, 0x65, + 0x61, 0x64, 0x73, 0x65, 0x74, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x8e, 0x23, + 0x3e, 0x45, 0xa1, 0x85, 0x3e, 0x9f, 0xaa, 0xaa, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x53, 0x75, 0x62, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0xc6, 0x29, + 0x3d, 0x69, 0x55, 0x0b, 0x3d, 0x7e, 0xaa, 0xca, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, + 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, + 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x6c, 0x6f, 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, + 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x6e, 0xc0, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x09, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, + 0x41, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2a, 0x8e, 0x23, 0x3e, 0x45, 0xa1, 0x85, 0x3e, 0x9f, 0xaa, 0xaa, 0x3e, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x53, 0x75, 0x62, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6d, 0xc6, 0x29, 0x3d, 0x69, 0x55, 0x0b, 0x3d, 0x7e, 0xaa, 0xca, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x6c, 0x6f, 0x77, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x6e, 0xc0, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, 0x09, 0x00, 0x00, 0x00, 0x54, 0x68, 0x72, 0x75, 0x73, 0x74, 0x65, 0x72, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4d, 0x61, 0x69, 0x6e, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xaa, 0x4a, 0x3e, 0x26, 0xc7, 0x8d, 0x3e, 0x9f, + 0xaa, 0xaa, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x53, 0x75, 0x62, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0xc6, 0x29, 0x3d, 0x69, 0x55, 0x0b, 0x3d, 0x7e, + 0xaa, 0xca, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x6e, + 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, + 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, + 0x6c, 0x6f, 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x6e, 0xc0, 0x3d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x08, 0x00, 0x00, 0x00, 0x55, 0x74, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4d, + 0x61, 0x69, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x8e, 0x23, 0x3e, 0x45, 0xa1, + 0x85, 0x3e, 0x9f, 0xaa, 0xaa, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x53, 0x75, 0x62, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0xc6, 0x29, 0x3d, 0x69, 0x55, + 0x0b, 0x3d, 0x7e, 0xaa, 0xca, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, + 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, + 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x47, 0x6c, 0x6f, 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x6e, 0xc0, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x13, 0x00, 0x00, 0x00, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x70, + 0x6f, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4d, + 0x61, 0x69, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, + 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x53, 0x75, 0x62, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0xd8, 0x50, 0x3c, 0x40, 0x89, + 0xcf, 0x3c, 0x00, 0x00, 0xe0, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, + 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, + 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x47, 0x6c, 0x6f, 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x6e, 0xc0, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x15, 0x00, 0x00, 0x00, 0x53, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x57, 0x65, + 0x61, 0x70, 0x6f, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, + 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x53, 0x75, 0x62, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, + 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0xd8, 0x50, 0x3c, + 0x40, 0x89, 0xcf, 0x3c, 0x00, 0x00, 0xe0, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, + 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, + 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x47, 0x6c, 0x6f, 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, + 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, + 0x6e, 0xc0, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x4c, 0x65, 0x66, 0x74, 0x52, 0x65, 0x61, 0x72, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4d, 0x61, 0x69, + 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x53, 0x75, + 0x62, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0xd8, 0x50, 0x3c, 0x40, 0x89, 0xcf, 0x3c, + 0x00, 0x00, 0xe0, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x49, 0x6e, + 0x6e, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, + 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x47, 0x6c, 0x6f, 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x6e, 0xc0, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x52, 0x69, 0x67, 0x68, + 0x74, 0x52, 0x65, 0x61, 0x72, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x44, 0x41, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, + 0x3f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x53, 0x75, 0x62, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcb, 0xd8, 0x50, 0x3c, 0x40, 0x89, 0xcf, 0x3c, 0x00, 0x00, 0xe0, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x6e, 0x65, 0x72, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, 0xcc, 0x4c, 0x3d, 0xcd, + 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x6c, 0x6f, + 0x77, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x6e, 0xc0, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, + 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x08, 0x00, 0x00, 0x00, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x3f, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x41, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x41, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x45, 0x44, 0x41, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x00, 0x25, 0x00, 0x00, 0x00, 0x45, 0x44, 0x41, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x3a, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x45, 0x6e, 0x75, 0x6d, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x45, 0x44, 0x41, 0x57, 0x65, 0x61, 0x70, + 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x45, 0x44, 0x41, 0x57, 0x65, 0x61, + 0x70, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x4c, 0x65, 0x66, 0x74, 0x52, 0x65, 0x61, 0x72, 0x57, + 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x43, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x45, + 0x44, 0x41, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x45, 0x44, 0x41, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x52, 0x69, 0x67, + 0x68, 0x74, 0x52, 0x65, 0x61, 0x72, 0x57, 0x65, 0x61, 0x70, 0x6f, 0x6e, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0xa1, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x41, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, + 0x64, 0x44, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x42, + 0x6f, 0x64, 0x79, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, + 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x42, 0x6f, 0x64, 0x79, + 0x50, 0x61, 0x72, 0x74, 0x73, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, + 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, + 0x5f, 0x42, 0x44, 0x50, 0x5f, 0x43, 0x48, 0x30, 0x30, 0x35, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x61, 0x63, 0x65, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x49, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, + 0x74, 0x73, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, 0x5f, 0x46, 0x43, + 0x50, 0x5f, 0x43, 0x48, 0x30, 0x30, 0x33, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, + 0x6e, 0x65, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x48, 0x61, + 0x69, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, + 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x48, 0x61, 0x69, 0x72, 0x50, 0x61, 0x72, 0x74, 0x73, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x49, 0x74, 0x65, 0x6d, 0x5f, 0x46, 0x48, 0x50, 0x5f, 0x43, 0x48, 0x30, 0x30, 0x35, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x42, 0x61, 0x63, 0x6b, 0x48, 0x61, 0x69, 0x72, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x42, 0x61, 0x63, 0x6b, 0x48, 0x61, 0x69, 0x72, 0x50, 0x61, 0x72, 0x74, 0x73, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, 0x5f, 0x42, 0x48, 0x50, 0x5f, + 0x43, 0x48, 0x30, 0x30, 0x35, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x44, + 0x61, 0x74, 0x61, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0xdc, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x41, 0x48, 0x75, 0x6d, 0x61, 0x6e, + 0x6f, 0x69, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x61, 0x74, + 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x53, 0x6b, 0x69, 0x6e, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x6c, 0x3f, 0x00, 0x00, + 0x6c, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x09, 0x00, 0x00, 0x00, 0x48, 0x61, 0x69, 0x72, + 0x42, 0x61, 0x73, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, + 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x0e, 0x00, 0x00, + 0x00, 0x48, 0x61, 0x69, 0x72, 0x47, 0x72, 0x61, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x18, 0x3f, 0xe0, + 0xda, 0x2d, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x0e, 0x00, 0x00, 0x00, 0x48, 0x61, 0x69, + 0x72, 0x48, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x3f, 0xf8, 0x38, 0x7b, 0x3f, 0x50, 0x55, 0x1d, 0x3f, 0x00, + 0x00, 0x80, 0x3f, 0x0b, 0x00, 0x00, 0x00, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x00, 0x00, + 0x30, 0x3e, 0x00, 0x00, 0x30, 0x3e, 0x00, 0x00, 0x80, 0x3f, 0x05, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x4c, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x00, + 0x38, 0x2a, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x05, 0x00, 0x00, + 0x00, 0x45, 0x79, 0x65, 0x52, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, + 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, + 0x00, 0x38, 0x2a, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x09, 0x00, + 0x00, 0x00, 0x42, 0x6f, 0x64, 0x79, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd5, 0x95, 0xaf, 0x3d, 0x80, 0x2a, 0xae, 0x3d, 0x7e, 0xaa, 0xca, 0x3d, 0x00, + 0x00, 0x80, 0x3f, 0x09, 0x00, 0x00, 0x00, 0x42, 0x6f, 0x64, 0x79, 0x53, 0x75, 0x62, + 0x31, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x02, 0x50, 0x3e, 0x19, 0x00, 0x1a, 0x3e, + 0x00, 0x00, 0x60, 0x3e, 0x00, 0x00, 0x80, 0x3f, 0x09, 0x00, 0x00, 0x00, 0x42, 0x6f, + 0x64, 0x79, 0x53, 0x75, 0x62, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x55, 0x95, + 0x3d, 0x82, 0x55, 0x95, 0x3d, 0x82, 0x55, 0x95, 0x3d, 0x00, 0x00, 0x80, 0x3f, 0x09, + 0x00, 0x00, 0x00, 0x42, 0x6f, 0x64, 0x79, 0x53, 0x75, 0x62, 0x33, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x29, 0x81, 0x3e, 0x00, 0x00, 0xa0, 0x3e, 0xf3, 0xff, 0x6a, 0x3e, + 0x00, 0x00, 0x80, 0x3f, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x46, 0x69, 0x67, 0x75, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x44, 0x41, 0x48, 0x75, 0x6d, 0x61, 0x6e, 0x6f, 0x69, 0x64, 0x46, + 0x69, 0x67, 0x75, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x42, 0x75, 0x73, 0x74, 0x55, 0x70, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x7a, 0x54, 0x3f, 0x06, + 0x00, 0x00, 0x00, 0x46, 0x61, 0x74, 0x55, 0x70, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x46, + 0x6c, 0x6f, 0x61, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x7a, 0xd4, 0x34, 0x06, 0x00, + 0x00, 0x00, 0x41, 0x72, 0x6d, 0x55, 0x70, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x46, 0x6c, + 0x6f, 0x61, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x4c, 0x65, 0x67, 0x55, 0x70, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x46, 0x6c, 0x6f, + 0x61, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x7a, 0x65, 0x3f, 0x08, 0x00, 0x00, 0x00, + 0x57, 0x61, 0x69, 0x73, 0x74, 0x55, 0x70, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x46, 0x6c, + 0x6f, 0x61, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x62, 0x49, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x46, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x68, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x42, 0x6f, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x62, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, 0x72, 0x6f, 0x6e, + 0x74, 0x48, 0x61, 0x69, 0x72, 0x4d, 0x65, 0x73, 0x68, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x42, 0x6f, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x62, + 0x49, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x48, 0x61, 0x69, + 0x72, 0x4d, 0x65, 0x73, 0x68, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x42, 0x6f, 0x6f, 0x6c, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x54, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x44, 0x41, 0x54, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x44, 0x61, 0x74, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x54, + 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4d, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x61, 0x76, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x44, 0x61, 0x74, 0x61, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x0a, 0x3f, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x61, 0x76, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0xb7, 0x3e, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + ]; + let mut cursor = Cursor::new(data); + let decoded = DABuildDataStruct::read_le(&mut cursor).unwrap(); + } +} diff --git a/src/common.rs b/src/common.rs index 3fae8d0..d3ab2a7 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,16 +1,12 @@ -use binrw::{BinRead, BinWrite}; use binrw::BinResult; +use binrw::{BinRead, BinWrite}; pub(crate) fn read_bool_from + PartialEq>(x: T) -> bool { x == T::from(1u8) } pub(crate) fn write_bool_as>(x: &bool) -> T { - if *x { - T::from(1u8) - } else { - T::from(0u8) - } + if *x { T::from(1u8) } else { T::from(0u8) } } #[binrw::parser(reader, endian)] @@ -52,7 +48,6 @@ pub(crate) fn write_string_with_length(string: &String) -> BinResult<()> { Ok(()) } - #[cfg(test)] mod tests { use super::*; diff --git a/src/float_property.rs b/src/float_property.rs index fcc0977..7b93bc4 100644 --- a/src/float_property.rs +++ b/src/float_property.rs @@ -30,9 +30,7 @@ mod tests { let expected_data: [u8; 13] = [ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x76, 0x9c, 0x45, ]; - let property = FloatProperty { - value: 5006.8184 - }; + let property = FloatProperty { value: 5006.8184 }; let mut buffer: Vec = Vec::new(); { diff --git a/src/guid.rs b/src/guid.rs index 572beee..411a6be 100644 --- a/src/guid.rs +++ b/src/guid.rs @@ -1,5 +1,5 @@ -use std::fmt; use binrw::binrw; +use std::fmt; // See https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/Misc/FGuid #[binrw] @@ -7,11 +7,14 @@ pub struct Guid { pub a: u32, pub b: u32, pub c: u32, - pub d: u32 + pub d: u32, } impl fmt::Debug for Guid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&format!("{:02X}{:02X}{:02X}{:02X}", self.a, self.b, self.c, self.d)) + f.write_str(&format!( + "{:02X}{:02X}{:02X}{:02X}", + self.a, self.b, self.c, self.d + )) } } diff --git a/src/int_property.rs b/src/int_property.rs index e90184c..abff50d 100644 --- a/src/int_property.rs +++ b/src/int_property.rs @@ -30,9 +30,7 @@ mod tests { let expected_data: [u8; 13] = [ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; - let property = IntProperty { - value: 0 - }; + let property = IntProperty { value: 0 }; let mut buffer: Vec = Vec::new(); { @@ -58,9 +56,7 @@ mod tests { let expected_data: [u8; 13] = [ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ]; - let property = IntProperty { - value: 4 - }; + let property = IntProperty { value: 4 }; let mut buffer: Vec = Vec::new(); { diff --git a/src/lib.rs b/src/lib.rs index 35d6eb7..b2fda63 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,21 @@ pub mod array_property; pub mod bool_property; +mod build_data; mod common; pub mod float_property; +mod guid; pub mod int_property; +mod linear_color; pub mod map_property; +mod name_property; +mod primary_asset_id; +mod primary_asset_type; pub mod set_property; pub mod str_property; pub mod struct_property; mod structs; -mod guid; -use binrw::helpers::{until, until_eof}; +use binrw::helpers::until_eof; use crate::array_property::ArrayProperty; use crate::bool_property::BoolProperty; @@ -21,12 +26,12 @@ use crate::map_property::MapProperty; use crate::set_property::SetProperty; use crate::str_property::StrProperty; use crate::struct_property::StructProperty; -use binrw::binrw; +use binrw::{BinRead, BinResult, binrw}; // Used in ArrayProperty exclusively, but could be used instead of magic above #[binrw] #[derive(Debug)] -#[br(import { magic: &str })] +#[br(import { magic: &str, name: &str })] pub enum Property { #[br(pre_assert("NameProperty" == magic))] Name(StrProperty), @@ -45,7 +50,10 @@ pub enum Property { #[br(pre_assert("MapProperty" == magic))] Map(MapProperty), #[br(pre_assert("SetProperty" == magic))] - Set(SetProperty), + Set { + #[br(args(name))] + value: SetProperty, + }, } #[binrw] @@ -60,15 +68,31 @@ pub struct Entry { #[br(if(name != "None"))] pub type_name: String, - #[br(if(name != "None"), args { magic: &type_name })] + #[br(if(name != "None"), args { magic: &type_name, name: &name })] pub r#type: Option, } +#[binrw::parser(reader, endian)] +fn custom_tagged_object_parser(size_in_bytes: u32) -> BinResult> { + let mut result = Vec::::new(); + + let mut current = reader.stream_position()?; + let end = current + size_in_bytes as u64; + + while current < end { + result.push(Entry::read_options(reader, endian, ())?); + current = reader.stream_position()?; + } + Ok(result) +} + #[binrw] #[derive(Debug)] pub struct TaggedObject { pub size_in_bytes: u32, - #[br(parse_with = until(|entry: &Entry| entry.name == "None"))] + //#[br(parse_with = custom_tagged_object_parser, args(size_in_bytes))] + //#[br(parse_with = until(|entry: &Entry| entry.name == "None"))] + #[br(parse_with = until_eof)] pub entries: Vec, } diff --git a/src/linear_color.rs b/src/linear_color.rs new file mode 100644 index 0000000..9f4e278 --- /dev/null +++ b/src/linear_color.rs @@ -0,0 +1,31 @@ +use binrw::binrw; + +#[binrw] +#[derive(Debug)] +pub struct LinearColorStruct { + pub r: f32, + pub g: f32, + pub b: f32, + pub a: f32, +} + +#[cfg(test)] +mod tests { + use super::*; + use binrw::BinRead; + use std::io::Cursor; + + #[test] + fn read_color() { + let data = [ + 0x2a, 0x8e, 0x23, 0x3e, 0x45, 0xa1, 0x85, 0x3e, 0x9f, 0xaa, 0xaa, 0x3e, 0x00, 0x00, + 0x00, 0x00, + ]; + let mut cursor = Cursor::new(data); + let decoded = LinearColorStruct::read_le(&mut cursor).unwrap(); + assert_eq!(decoded.r, 0.159722); + assert_eq!(decoded.g, 0.260996); + assert_eq!(decoded.b, 0.333333); + assert_eq!(decoded.a, 0.0); + } +} diff --git a/src/map_property.rs b/src/map_property.rs index dc4cc7d..76af7e6 100644 --- a/src/map_property.rs +++ b/src/map_property.rs @@ -1,25 +1,31 @@ -use crate::common::{read_bool_from, read_string_with_length, write_string_with_length}; +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::PrimaryAssetNameProperty; -use binrw::helpers::until_exclusive; use binrw::{BinRead, BinResult, binrw}; -use crate::guid::Guid; -// A struct without a name -#[binrw] -#[derive(Debug)] -pub struct AnonymousStruct { - #[br(parse_with = until_exclusive(|entry: &PrimaryAssetNameProperty| entry.property_name == "None"))] - fields: Vec, +// 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> { + let mut result = Vec::::new(); + + loop { + if let Ok(str) = PrimaryAssetNameProperty::read_options(reader, endian, ()) { + result.push(str); + } else { + break; + } + } + Ok(result) } #[binrw] #[derive(Debug)] pub struct MapSubStructProperty { - #[br(temp)] - #[bw(ignore)] - pub unk_name_length: u32, - pub r#struct: Struct, + #[br(parse_with = cc)] + fields: Vec, } #[binrw] @@ -34,7 +40,12 @@ pub struct StructMaybeKey { #[bw(write_with = write_string_with_length)] pub unk_type: String, - #[br(pad_before = 4)] // type length + #[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, } @@ -64,7 +75,7 @@ pub struct MapSubStrProperty { #[derive(Debug)] pub struct MapSubBoolProperty { #[br(map = read_bool_from::)] - #[bw(ignore)] + #[bw(map = write_bool_as::)] pub value: bool, } @@ -129,6 +140,10 @@ pub enum MapKeyProperty { SomeID(Guid), #[br(pre_assert(*magic == KeyType::SomeID2))] SomeID2(Guid), + #[br(pre_assert(*magic == KeyType::ArrayStruct))] + ArrayStruct(StructMaybeKey), + #[br(pre_assert(*magic == KeyType::Unknown2))] + SomeID3(Guid), } #[binrw] @@ -142,17 +157,24 @@ pub struct MapEntry { pub value: MabSubProperty, } +// TODO: im worried that set/array/map actually share same of the same values... #[binrw] #[brw(repr = u32)] #[derive(Debug, PartialEq, Clone)] pub enum KeyType { + None = 0x0, String = 0x1, + SetStruct = 0x2, + SetStruct2 = 0x2f, GUID = 0x3, SomeID = 0x6, SomeID2 = 0x10, EnumAgain = 0x4, Enum = 0x7, StructMaybe = 0xC, + ArrayStruct = 0xA, // Only used in ArrayProperty + Unknown = 0x2E, // AcquiredItemBoxIds in Persistent.sav + Unknown2 = 0x33, // CharacterPersistentDataList in Persistent.sav } #[binrw::parser(reader, endian)] @@ -198,9 +220,9 @@ pub struct MapProperty { pub value_name: String, #[brw(pad_before = 5)] - pub key_type: KeyType, + pub map_key_type: KeyType, - #[br(parse_with = custom_parser, args(size_in_bytes, &key_type, &value_name))] + #[br(parse_with = custom_parser, args(size_in_bytes, &map_key_type, &value_name))] pub entries: Vec, } @@ -251,15 +273,15 @@ mod tests { let property = MapProperty { key_name: "StrProperty".to_string(), value_name: "StrProperty".to_string(), - key_type: KeyType::String, - entries: vec![ - MapEntry { - key: MapKeyProperty::String(StringMapKey { value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string() }), - value: String(MapSubStrProperty { - value: "NAME 1".to_string(), - }), - } - ], + map_key_type: KeyType::String, + entries: vec![MapEntry { + key: MapKeyProperty::String(StringMapKey { + value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string(), + }), + value: String(MapSubStrProperty { + value: "NAME 1".to_string(), + }), + }], }; let mut buffer: Vec = Vec::new(); diff --git a/src/name_property.rs b/src/name_property.rs new file mode 100644 index 0000000..a2a43cc --- /dev/null +++ b/src/name_property.rs @@ -0,0 +1,15 @@ +use crate::common::{read_string_with_length, write_string_with_length}; +use binrw::binrw; + +#[binrw] +#[derive(Debug)] +pub struct NameProperty { + #[brw(pad_after = 6)] + // Only add + 1 for the null terminator if the string *isn't* empty. + #[bw(calc = value.len() as u32 + 4 + if value.is_empty() { 0 } else { 1})] + pub size_in_bytes: u32, + + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + pub value: String, +} diff --git a/src/primary_asset_id.rs b/src/primary_asset_id.rs new file mode 100644 index 0000000..a301661 --- /dev/null +++ b/src/primary_asset_id.rs @@ -0,0 +1,44 @@ +use crate::structs::StructField; +use binrw::binrw; + +#[binrw] +#[derive(Debug)] +pub struct PrimaryAssetIdStruct { + //#[brw(pad_before = 17)] + //#[br(pad_after = 9)] // "None" + #[br(args {name: "PrimaryAssetType", r#type: "StructProperty" })] + primary_asset_type: StructField, +} + +#[cfg(test)] +mod tests { + use super::*; + use binrw::BinRead; + use std::io::Cursor; + + #[test] + fn read_id() { + let data = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x50, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, + 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x49, + 0x74, 0x65, 0x6d, 0x5f, 0x50, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x4e, 0x6f, 0x6e, 0x65, 0x00, + ]; + let mut cursor = Cursor::new(data); + let decoded = PrimaryAssetIdStruct::read_le(&mut cursor).unwrap(); + } +} diff --git a/src/primary_asset_type.rs b/src/primary_asset_type.rs new file mode 100644 index 0000000..8bf924b --- /dev/null +++ b/src/primary_asset_type.rs @@ -0,0 +1,40 @@ +use crate::structs::StructField; +use binrw::binrw; + +#[binrw] +#[derive(Debug)] +pub struct PrimaryAssetTypeStruct { + #[brw(pad_after = 9)] + #[br(args { name: "Name", r#type: "NameProperty" })] + name: StructField, + #[brw(pad_after = 9)] + #[br(args { name: "PrimaryAssetName", r#type: "NameProperty" })] + primary_asset_name: StructField, +} + +#[cfg(test)] +mod tests { + use super::*; + use binrw::BinRead; + use std::io::Cursor; + + #[test] + fn read_id() { + let data = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x42, 0x61, 0x63, 0x6b, 0x48, 0x61, 0x69, 0x72, 0x50, 0x61, 0x72, 0x74, 0x73, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, 0x5f, 0x42, 0x48, 0x50, 0x5f, 0x43, + 0x48, 0x30, 0x30, 0x35, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, + 0x11, 0x00, 0x00, + ]; + let mut cursor = Cursor::new(data); + let decoded = PrimaryAssetTypeStruct::read_le(&mut cursor).unwrap(); + } +} diff --git a/src/set_property.rs b/src/set_property.rs index d21c3a0..18f7fcc 100644 --- a/src/set_property.rs +++ b/src/set_property.rs @@ -1,36 +1,132 @@ -use crate::Property; -use crate::common::read_string_with_length; -use binrw::binrw; +use crate::common::{read_string_with_length, write_string_with_length}; +use crate::map_property::{KeyType, MapSubStrProperty}; +use crate::struct_property::Struct; +use binrw::{BinRead, BinResult, binrw}; #[binrw] #[derive(Debug)] -pub struct SetEntry { - #[br(parse_with = read_string_with_length)] - #[bw(ignore)] - pub unk_name: String, - - #[br(parse_with = read_string_with_length)] - #[bw(ignore)] - pub unk_type: String, - - #[br(args { magic: &unk_type })] - pub key: Property, +#[br(import { magic: &str, name: &str })] +pub enum SetValue { + // NOTE: the name checking is just a temporary workaround + #[br(pre_assert("StructProperty" == magic && name != "OpenedStrongBoxIds" && name != "AcquiredItemBoxIds"))] + Struct { + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + struct_type: String, + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + r#type: String, + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + #[br(pad_before = 8)] + struct_type_for_some_reason_again: String, + #[br(args { magic: &struct_type_for_some_reason_again })] + #[brw(pad_before = 17)] + r#struct: Struct, + }, + #[br(pre_assert("StringProperty" == magic || "NameProperty" == magic))] + String(MapSubStrProperty), + #[br(pre_assert("StructProperty" == magic && name == "AcquiredItemBoxIds"))] + Unknown { unk: [u8; 736] }, + #[br(pre_assert("StructProperty" == magic && name == "OpenedStrongBoxIds"))] + Unknown2 { unk: [u8; 64] }, } #[binrw] #[derive(Debug)] -pub struct SetProperty { - pub unk: u32, +#[br(import(value_type: &str, key_type: &str))] +pub struct SetEntry { + #[br(args { magic: value_type, name: key_type })] + pub key: SetValue, +} - #[br(pad_before = 4, parse_with = read_string_with_length)] - #[bw(ignore)] +#[binrw::parser(reader, endian)] +fn custom_parser(size_in_bytes: u32, value_type: &str, key_type: &str) -> BinResult> { + let mut result = Vec::::new(); + + let mut current = reader.stream_position()?; + let end = current + size_in_bytes as u64 - 8; + + while current < end { + result.push(SetEntry::read_options( + reader, + endian, + (value_type, key_type), + )?); + current = reader.stream_position()?; + } + Ok(result) +} + +#[binrw] +#[derive(Debug)] +#[br(import(name: &str))] +pub struct SetProperty { + pub size_in_bytes: u32, + + #[brw(pad_before = 4)] + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] pub key_name: String, - #[br(pad_before = 5)] - pub num_set_entries: u32, + #[brw(pad_before = 5)] + pub key_type: KeyType, - #[br(count = num_set_entries)] + #[br(parse_with = custom_parser, args(size_in_bytes, &key_name, &name))] pub entries: Vec, } +#[cfg(test)] +mod tests { + use super::*; + use binrw::BinRead; + use std::io::Cursor; + + #[test] + fn read_struct_set() { + // From Persistent.sav + let data = [ + 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x42, 0x61, 0x63, 0x6b, 0x48, 0x61, 0x69, + 0x72, 0x50, 0x61, 0x72, 0x74, 0x73, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, + 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, + 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, + 0x6d, 0x5f, 0x42, 0x48, 0x50, 0x5f, 0x43, 0x48, 0x30, 0x30, 0x35, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, + 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x42, 0x61, 0x63, 0x6b, 0x48, 0x61, 0x69, 0x72, + 0x50, 0x61, 0x72, 0x74, 0x73, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, + 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, + 0x5f, 0x42, 0x48, 0x50, 0x5f, 0x43, 0x48, 0x30, 0x30, 0x33, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, + 0x00, + ]; + let mut cursor = Cursor::new(data); + let decoded = SetProperty::read_le(&mut cursor).unwrap(); + assert_eq!(decoded.key_name, "StructProperty"); + } +} + // TODO: write test diff --git a/src/struct_property.rs b/src/struct_property.rs index 8699359..70f904b 100644 --- a/src/struct_property.rs +++ b/src/struct_property.rs @@ -1,84 +1,77 @@ -use crate::structs::{CarryCountProperty, DAAssembleIdDataStruct, DABuildDataStruct, DACharacterCommonStatusStruct, DALoadOptionStruct, DAMachineColoringDataStruct, DAModuleColorStruct, DAModuleItemDataStruct, DateTimeStruct, GuidStruct, LinearColorStruct, PrimaryAssetIdStruct, PrimaryAssetNameProperty, SaveSlotInfoStruct}; -use binrw::binrw; +use crate::build_data::DABuildDataStruct; +use crate::common::{read_string_with_length, write_string_with_length}; use crate::guid::Guid; +use crate::linear_color::LinearColorStruct; +use crate::primary_asset_id::PrimaryAssetIdStruct; +use crate::primary_asset_type::PrimaryAssetTypeStruct; +use crate::structs::{ + DAAssembleIdDataStruct, DACharacterCommonStatusStruct, DACustomizeAssetIdDataStruct, + DAHumanoidColoringDataStruct, DAHumanoidFigureData, DALoadOptionStruct, + DAMachineColoringDataStruct, DAModuleColorStruct, DAModuleItemDataStruct, DATriggerDataStruct, + DATuningDataStruct, DATuningPointData, DateTimeStruct, QuatStruct, SaveSlotInfoStruct, + TransformStruct, VectorStruct, +}; +use binrw::binrw; #[binrw] #[derive(Debug)] +#[br(import { magic: &str })] pub enum Struct { - #[br(magic = b"DateTime\0")] + #[br(pre_assert(magic == "DateTime"))] DateTime(DateTimeStruct), - #[br(magic = b"DALoadOption\0")] + #[br(pre_assert(magic == "DALoadOption"))] DALoadOption(DALoadOptionStruct), - #[br(magic = b"SaveSlotInfo\0")] + #[br(pre_assert(magic == "SaveSlotInfo"))] SaveSlotInfo(SaveSlotInfoStruct), - #[br(magic = b"DACharacterCommonStatus\0")] + #[br(pre_assert(magic == "DACharacterCommonStatus"))] DACharacterCommonStatus(DACharacterCommonStatusStruct), - #[br(magic = b"PrimaryAssetType\0")] - PrimaryAssetType { - #[br(pad_before = 17)] - name: PrimaryAssetNameProperty, - #[br(pad_before = 9)] // "None" and it's length in bytes plus the null terminator - #[br(pad_after = 9)] // ditto - primary_asset_name: PrimaryAssetNameProperty, - }, - #[br(magic = b"PrimaryAssetId\0")] + #[br(pre_assert(magic == "PrimaryAssetType"))] + PrimaryAssetType(PrimaryAssetTypeStruct), + #[br(pre_assert(magic == "PrimaryAssetId"))] PrimaryAssetId(PrimaryAssetIdStruct), - #[br(magic = b"DAModuleItemData\0")] + #[br(pre_assert(magic == "DAModuleItemData"))] DAModuleItemData(DAModuleItemDataStruct), - #[br(magic = b"DABuildData\0")] + #[br(pre_assert(magic == "DABuildData"))] DABuildData(DABuildDataStruct), - #[br(magic = b"DAAssembleIdData\0")] + #[br(pre_assert(magic == "DAAssembleIdData"))] DAAssembleIdData(DAAssembleIdDataStruct), - #[br(magic = b"Guid\0")] - Guid(GuidStruct), - #[br(magic = b"DAMachineColoringData\0")] + #[br(pre_assert(magic == "Guid"))] + Guid(Guid), + #[br(pre_assert(magic == "DAMachineColoringData"))] DAMachineColoringData(DAMachineColoringDataStruct), - #[br(magic = b"DAModuleColor\0")] + #[br(pre_assert(magic == "DAModuleColor"))] DAModuleColor(DAModuleColorStruct), - #[br(magic = b"LinearColor\0")] + #[br(pre_assert(magic == "LinearColor"))] LinearColor(LinearColorStruct), - #[br(magic = b"CarryCount\0")] - CarryCount { - carry_count: CarryCountProperty, - - #[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(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(pad_after = 9)] // "None" and it's length in bytes plus the null terminator - name: PrimaryAssetNameProperty, - - #[br(pad_after = 9)] // "None" and it's length in bytes plus the null terminator - primary_asset_name: PrimaryAssetNameProperty, - - data: [u8; 137], - }, - #[br(magic = b"Set\0")] - Set { - #[br(pad_after = 9)] // "None" + 1 byte for endofstring + 4 bytes for length - set: CarryCountProperty, - }, - #[br(magic = b"ItemSlots\0")] - ItemSlots { unk: [u8; 2125] }, + #[br(pre_assert(magic == "DATriggerData"))] + DATriggerData(DATriggerDataStruct), + #[br(pre_assert(magic == "DACustomizeAssetIdData"))] + DACustomizeAssetIdData(DACustomizeAssetIdDataStruct), + #[br(pre_assert(magic == "DATuningData"))] + DATuningData(DATuningDataStruct), + #[br(pre_assert(magic == "DAHumanoidColoringData"))] + DAHumanoidColoringData(DAHumanoidColoringDataStruct), + #[br(pre_assert(magic == "DAHumanoidFigureData"))] + DAHumanoidFigureData(DAHumanoidFigureData), + #[br(pre_assert(magic == "DATuningPointData"))] + DATuningPointData(DATuningPointData), + #[br(pre_assert(magic == "Transform"))] + Transform(TransformStruct), + #[br(pre_assert(magic == "Quat"))] + Quat(QuatStruct), + #[br(pre_assert(magic == "Vector"))] + Vector(VectorStruct), } #[binrw] #[derive(Debug)] pub struct StructProperty { pub unk: u32, - #[br(temp)] - #[bw(ignore)] - #[br(pad_before = 4)] - pub name_length: 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 })] + #[br(pad_before = 17)] pub r#struct: Struct, } diff --git a/src/structs.rs b/src/structs.rs index b8c8c67..189afb2 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,7 +1,7 @@ use crate::Property; +use crate::build_data::DABuildDataStruct; +use crate::common::{read_string_with_length, write_string_with_length}; use binrw::binrw; -use crate::common::read_string_with_length; -use crate::guid::Guid; #[binrw] #[derive(Debug)] @@ -27,80 +27,208 @@ pub struct DACharacterCommonStatusStruct { pub unk: [u8; 17], } +// TODO: replace all usage of this with StructField #[binrw] #[derive(Debug)] pub struct PrimaryAssetNameProperty { #[br(parse_with = read_string_with_length)] - #[bw(ignore)] + #[bw(write_with = write_string_with_length)] pub property_name: String, #[br(parse_with = read_string_with_length)] - #[bw(ignore)] + #[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})] + #[br(args { magic: &type_name, name: &property_name})] pub key: Option>, } +// TODO: allow specializing into structs for StructProperty, and so on #[binrw] #[derive(Debug)] -pub struct CarryCountProperty { +#[br(import { name: &str, r#type: &str })] +pub struct StructField { #[br(parse_with = read_string_with_length)] - #[bw(ignore)] + #[bw(write_with = write_string_with_length)] + #[br(assert(property_name == name))] pub property_name: String, - #[br(args { magic: &property_name})] - pub key: Option>, -} + #[br(parse_with = read_string_with_length)] + #[bw(write_with = write_string_with_length)] + #[br(assert(type_name == r#type))] + pub type_name: String, -#[binrw] -#[derive(Debug)] -pub struct PrimaryAssetIdStruct { - #[br(pad_before = 17)] - asset: PrimaryAssetNameProperty, + #[br(if(property_name != "None"))] + #[br(args { magic: &type_name, name: &property_name })] + pub key: Option>, } #[binrw] #[derive(Debug)] pub struct DAModuleItemDataStruct { - #[br(pad_before = 17)] + #[br(pad_after = 9)] // none pub module_level: PrimaryAssetNameProperty, } -#[binrw] -#[derive(Debug)] -pub struct DABuildDataStruct { - pub unk: [u8; 17], -} - #[binrw] #[derive(Debug)] pub struct DAAssembleIdDataStruct { - pub unk: [u8; 17], -} - -#[binrw] -#[derive(Debug)] -pub struct GuidStruct { - #[br(pad_before = 17)] - pub guid: Guid + pub hanger: PrimaryAssetNameProperty, + pub headset: PrimaryAssetNameProperty, + pub mobility: PrimaryAssetNameProperty, + pub thruster: PrimaryAssetNameProperty, + pub utility: PrimaryAssetNameProperty, + pub primary_front_weapon: PrimaryAssetNameProperty, + pub secondary_front_weapon: PrimaryAssetNameProperty, + pub left_rear_weapon: PrimaryAssetNameProperty, + pub right_rear_weapon: PrimaryAssetNameProperty, + // has none at the end + #[br(pad_after = 9)] + pub coloring_data: PrimaryAssetNameProperty, } #[binrw] #[derive(Debug)] pub struct DAMachineColoringDataStruct { - pub unk: [u8; 17], + pub hanger: PrimaryAssetNameProperty, + + pub headset: PrimaryAssetNameProperty, + pub mobility: PrimaryAssetNameProperty, + pub thruster: PrimaryAssetNameProperty, + pub utility: PrimaryAssetNameProperty, + pub primary_front_weapon: PrimaryAssetNameProperty, + pub secondary_front_weapon: PrimaryAssetNameProperty, + pub left_rear_weapon: PrimaryAssetNameProperty, + // has none at the end + #[br(pad_after = 9)] + pub right_rear_weapon: PrimaryAssetNameProperty, +} + +#[binrw] +#[derive(Debug)] +pub struct DAHumanoidColoringDataStruct { + pub skin: PrimaryAssetNameProperty, + pub hair_base: PrimaryAssetNameProperty, + pub hair_gradation: PrimaryAssetNameProperty, + pub hair_highlight: PrimaryAssetNameProperty, + pub head_option: PrimaryAssetNameProperty, + pub eye_l: PrimaryAssetNameProperty, + pub eye_r: PrimaryAssetNameProperty, + pub body_main: PrimaryAssetNameProperty, + pub body_sub1: PrimaryAssetNameProperty, + pub body_sub2: PrimaryAssetNameProperty, + // has none at the end + #[br(pad_after = 9)] + pub body_sub3: PrimaryAssetNameProperty, } #[binrw] #[derive(Debug)] pub struct DAModuleColorStruct { - pub unk: [u8; 17], + pub main: PrimaryAssetNameProperty, + pub sub: PrimaryAssetNameProperty, + pub inner: PrimaryAssetNameProperty, + // has none at the end + #[br(pad_after = 9)] + pub glow: PrimaryAssetNameProperty, } #[binrw] #[derive(Debug)] -pub struct LinearColorStruct { - pub unk: [u8; 33], +pub struct DATriggerDataStruct { + pub unk: [u8; 319], // trigger weapon config in game +} + +#[binrw] +#[derive(Debug)] +pub struct DACustomizeAssetIdDataStruct { + pub body: PrimaryAssetNameProperty, + + pub face: PrimaryAssetNameProperty, + + pub front_hair: PrimaryAssetNameProperty, + + pub back_hair: PrimaryAssetNameProperty, + + pub coloring_data: PrimaryAssetNameProperty, + + pub figure_data: PrimaryAssetNameProperty, + + pub inverse_face_mesh: PrimaryAssetNameProperty, + + pub inverse_front_hair_mesh: PrimaryAssetNameProperty, + + // has none at the end + #[brw(pad_after = 9)] + pub inverse_back_hair_mesh: PrimaryAssetNameProperty, +} + +#[binrw] +#[derive(Debug)] +pub struct DAHumanoidFigureData { + pub bust_up: PrimaryAssetNameProperty, + + pub fat_up: PrimaryAssetNameProperty, + + pub arm_up: PrimaryAssetNameProperty, + + pub leg_up: PrimaryAssetNameProperty, + // has none at the end + #[brw(pad_after = 9)] + pub waist_up: PrimaryAssetNameProperty, +} + +#[binrw] +#[derive(Debug)] +pub struct DATuningDataStruct { + #[brw(pad_after = 9)] + pub granted_tuning_point_list: PrimaryAssetNameProperty, +} + +#[binrw] +#[derive(Debug)] +pub struct SavedBuildData { + pub build_data: DABuildDataStruct, +} + +#[binrw] +#[derive(Debug)] +pub struct DATuningPointData { + #[br(args { name: "TuningPoint", r#type: "IntProperty" })] + tuning_point: StructField, + #[br(args { name: "MaxTuningPoint", r#type: "IntProperty" })] + #[brw(pad_after = 9)] // none + max_tuning_point: StructField, +} + +#[binrw] +#[derive(Debug)] +pub struct TransformStruct { + #[br(args { name: "Rotation", r#type: "StructProperty" })] + rotation: StructField, + #[br(args { name: "Translation", r#type: "StructProperty" })] + translation: StructField, + #[br(args { name: "Scale3D", r#type: "StructProperty" })] + #[brw(pad_after = 9)] // none + scale: StructField, +} + +#[binrw] +#[derive(Debug)] +pub struct QuatStruct { + // TODO: check if w is actually in front or in the back, this is a guess + pub w: f32, + pub x: f32, + pub y: f32, + pub z: f32, +} + +#[binrw] +#[derive(Debug)] +pub struct VectorStruct { + pub x: f32, + pub y: f32, + pub z: f32, } diff --git a/tests/resources/Slot.bin b/tests/resources/Slot.bin new file mode 100644 index 0000000000000000000000000000000000000000..6d0f02f27e501e38c5d189adcfd6a08833e0b7c6 GIT binary patch literal 908 zcmbtTy-ve05O&3n%D+Gih=GxTB?&^PEJ$h7mR4Vt>Q4h?Cr{R31tJW= zsh8<`|Nik+Yh`*uakzlgx7|_{HoXzNV}3U?&?e zYl3=>P+=wJa6Lm93{2axXRwKN_OlKLyzj&zixw9(1F#jCt_Xg}Ilxx>ebu3ZBnq;uoy}D`Hrqwe|E6Jb`_c<$wQJ@xwML$@{HW#WAJc@a_8psU>=87uO*u*;f zNfMY>-J=wB2phX)-c`$`Tl@UVtz28S-K}19Te;I5!CGNIqyI_dH7Z`VKq9N)uExfU z|1IE2O6V9iMj1F8j^I3UA+}McVPxc~Qk)r3Q=GjfL3yI!;P)V?H(N>?>yGSA9RAi7 U!Qx?FAUtR&$a>ml-EVyR4ZNAbxBvhE literal 0 HcmV?d00001 diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs index b031285..163c28c 100644 --- a/tests/roundtrip.rs +++ b/tests/roundtrip.rs @@ -1,8 +1,8 @@ +use binrw::{BinRead, BinWrite}; +use ireko::TaggedSerialization; use std::fs::read; use std::io::Cursor; use std::path::PathBuf; -use binrw::{BinRead, BinWrite}; -use ireko::TaggedSerialization; #[test] fn roundtrip_localprofile() { @@ -31,3 +31,31 @@ fn roundtrip_localprofile() { // Ensure our written version is the same as retail assert_eq!(new_data.as_slice(), &data[..]); } + +#[test] +fn roundtrip_slot() { + let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + d.push("tests/resources"); + d.push("Slot.bin"); + + let mut data = read(d).unwrap(); + let mut cursor = Cursor::new(&mut data); + + let local_profile = TaggedSerialization::read_le(&mut cursor).unwrap(); + let tagged_object = &local_profile.objs[0]; + assert_eq!(tagged_object.size_in_bytes, 900); + + tagged_object.entry("Players").unwrap(); + tagged_object.entry("Level").unwrap(); + + // TODO: check values + + let mut new_data: Vec = Vec::new(); + { + let mut new_cursor = Cursor::new(&mut new_data); + local_profile.write_le(&mut new_cursor).unwrap(); + } + + // Ensure our written version is the same as retail + assert_eq!(new_data.as_slice(), &data[..]); +}