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!
This commit is contained in:
Joshua Goins 2025-02-24 00:30:16 -05:00
parent 02269ecc68
commit 8f55d00e24
18 changed files with 1472 additions and 203 deletions

View file

@ -1,16 +1,42 @@
use crate::common::{read_string_with_length, write_string_with_length}; 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}; 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)] #[binrw::parser(reader, endian)]
fn custom_parser(size_in_bytes: u32, value_type: &str) -> BinResult<Vec<ArrayEntry>> { fn custom_parser(
size_in_bytes: u32,
key_name: &str,
value_type: &KeyType,
key_data: &ArrayKeyData,
) -> BinResult<Vec<ArrayEntry>> {
let mut result = Vec::<ArrayEntry>::new(); let mut result = Vec::<ArrayEntry>::new();
let mut current = reader.stream_position()?; 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 { 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()?; current = reader.stream_position()?;
} }
Ok(result) Ok(result)
@ -18,10 +44,23 @@ fn custom_parser(size_in_bytes: u32, value_type: &str) -> BinResult<Vec<ArrayEnt
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
#[br(import(value_type: &str))] #[br(import { magic: &KeyType, key_data: &ArrayKeyData })]
pub enum ArrayValue {
#[br(pre_assert(KeyType::ArrayStruct == *magic))]
Struct {
#[br(args { magic: match key_data { ArrayKeyData::Struct{ struct_name, .. } => { 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 { pub struct ArrayEntry {
#[br(args { magic: &value_type })] #[br(args { magic: value_type, key_data: key_data })]
pub key: MabSubProperty, pub key: ArrayValue,
} }
fn calc_size_in_bytes(entries: &Vec<ArrayEntry>) -> u32 { fn calc_size_in_bytes(entries: &Vec<ArrayEntry>) -> u32 {
@ -29,6 +68,30 @@ fn calc_size_in_bytes(entries: &Vec<ArrayEntry>) -> u32 {
18 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] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct ArrayProperty { pub struct ArrayProperty {
@ -41,20 +104,21 @@ pub struct ArrayProperty {
pub key_name: String, pub key_name: String,
#[brw(pad_before = 1)] #[brw(pad_before = 1)]
#[bw(calc = 1)] pub key_type: KeyType,
pub unk: u32,
#[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<ArrayEntry>, pub entries: Vec<ArrayEntry>,
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::map_property::MabSubProperty::String; use crate::map_property::StringMapKey;
use binrw::{BinRead, BinWrite}; use binrw::{BinRead, BinWrite};
use std::io::Cursor; use std::io::Cursor;
use crate::map_property::MapSubStrProperty;
#[test] #[test]
fn read_simple_array() { fn read_simple_array() {
@ -68,7 +132,7 @@ mod tests {
let mut cursor = Cursor::new(data); let mut cursor = Cursor::new(data);
let decoded = ArrayProperty::read_le(&mut cursor).unwrap(); let decoded = ArrayProperty::read_le(&mut cursor).unwrap();
assert_eq!(decoded.key_name, "StrProperty"); 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!") panic!("StrProperty!")
}; };
assert_eq!(value_property.value, "redstrate"); assert_eq!(value_property.value, "redstrate");
@ -84,13 +148,13 @@ mod tests {
]; ];
let property = ArrayProperty { let property = ArrayProperty {
key_name: "StrProperty".to_string(), key_name: "StrProperty".to_string(),
entries: vec![ key_type: KeyType::String,
ArrayEntry { key_data: ArrayKeyData::String(),
key: String(MapSubStrProperty { entries: vec![ArrayEntry {
key: ArrayValue::String(StringMapKey {
value: "redstrate".to_string(), value: "redstrate".to_string(),
}), }),
} }],
],
}; };
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
@ -101,4 +165,171 @@ mod tests {
assert_eq!(expected_data, &buffer[..]); 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);
}
} }

View file

@ -26,12 +26,8 @@ mod tests {
#[test] #[test]
fn write_false() { fn write_false() {
let expected_data: [u8; 10] = [ let expected_data: [u8; 10] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 let property = BoolProperty { value: false };
];
let property = BoolProperty {
value: false
};
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
{ {
@ -52,12 +48,8 @@ mod tests {
#[test] #[test]
fn write_true() { fn write_true() {
let expected_data: [u8; 10] = [ let expected_data: [u8; 10] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00];
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 let property = BoolProperty { value: true };
];
let property = BoolProperty {
value: true
};
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
{ {

633
src/build_data.rs Normal file
View file

@ -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();
}
}

View file

@ -1,16 +1,12 @@
use binrw::{BinRead, BinWrite};
use binrw::BinResult; use binrw::BinResult;
use binrw::{BinRead, BinWrite};
pub(crate) fn read_bool_from<T: From<u8> + PartialEq>(x: T) -> bool { pub(crate) fn read_bool_from<T: From<u8> + PartialEq>(x: T) -> bool {
x == T::from(1u8) x == T::from(1u8)
} }
pub(crate) fn write_bool_as<T: From<u8>>(x: &bool) -> T { pub(crate) fn write_bool_as<T: From<u8>>(x: &bool) -> T {
if *x { if *x { T::from(1u8) } else { T::from(0u8) }
T::from(1u8)
} else {
T::from(0u8)
}
} }
#[binrw::parser(reader, endian)] #[binrw::parser(reader, endian)]
@ -52,7 +48,6 @@ pub(crate) fn write_string_with_length(string: &String) -> BinResult<()> {
Ok(()) Ok(())
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -30,9 +30,7 @@ mod tests {
let expected_data: [u8; 13] = [ let expected_data: [u8; 13] = [
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x76, 0x9c, 0x45, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x76, 0x9c, 0x45,
]; ];
let property = FloatProperty { let property = FloatProperty { value: 5006.8184 };
value: 5006.8184
};
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
{ {

View file

@ -1,5 +1,5 @@
use std::fmt;
use binrw::binrw; use binrw::binrw;
use std::fmt;
// See https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/Misc/FGuid // See https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/Misc/FGuid
#[binrw] #[binrw]
@ -7,11 +7,14 @@ pub struct Guid {
pub a: u32, pub a: u32,
pub b: u32, pub b: u32,
pub c: u32, pub c: u32,
pub d: u32 pub d: u32,
} }
impl fmt::Debug for Guid { impl fmt::Debug for Guid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 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
))
} }
} }

View file

@ -30,9 +30,7 @@ mod tests {
let expected_data: [u8; 13] = [ let expected_data: [u8; 13] = [
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]; ];
let property = IntProperty { let property = IntProperty { value: 0 };
value: 0
};
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
{ {
@ -58,9 +56,7 @@ mod tests {
let expected_data: [u8; 13] = [ let expected_data: [u8; 13] = [
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
]; ];
let property = IntProperty { let property = IntProperty { value: 4 };
value: 4
};
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
{ {

View file

@ -1,16 +1,21 @@
pub mod array_property; pub mod array_property;
pub mod bool_property; pub mod bool_property;
mod build_data;
mod common; mod common;
pub mod float_property; pub mod float_property;
mod guid;
pub mod int_property; pub mod int_property;
mod linear_color;
pub mod map_property; pub mod map_property;
mod name_property;
mod primary_asset_id;
mod primary_asset_type;
pub mod set_property; pub mod set_property;
pub mod str_property; pub mod str_property;
pub mod struct_property; pub mod struct_property;
mod structs; mod structs;
mod guid;
use binrw::helpers::{until, until_eof}; use binrw::helpers::until_eof;
use crate::array_property::ArrayProperty; use crate::array_property::ArrayProperty;
use crate::bool_property::BoolProperty; use crate::bool_property::BoolProperty;
@ -21,12 +26,12 @@ use crate::map_property::MapProperty;
use crate::set_property::SetProperty; use crate::set_property::SetProperty;
use crate::str_property::StrProperty; use crate::str_property::StrProperty;
use crate::struct_property::StructProperty; 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 // Used in ArrayProperty exclusively, but could be used instead of magic above
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
#[br(import { magic: &str })] #[br(import { magic: &str, name: &str })]
pub enum Property { pub enum Property {
#[br(pre_assert("NameProperty" == magic))] #[br(pre_assert("NameProperty" == magic))]
Name(StrProperty), Name(StrProperty),
@ -45,7 +50,10 @@ pub enum Property {
#[br(pre_assert("MapProperty" == magic))] #[br(pre_assert("MapProperty" == magic))]
Map(MapProperty), Map(MapProperty),
#[br(pre_assert("SetProperty" == magic))] #[br(pre_assert("SetProperty" == magic))]
Set(SetProperty), Set {
#[br(args(name))]
value: SetProperty,
},
} }
#[binrw] #[binrw]
@ -60,15 +68,31 @@ pub struct Entry {
#[br(if(name != "None"))] #[br(if(name != "None"))]
pub type_name: String, 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<Property>, pub r#type: Option<Property>,
} }
#[binrw::parser(reader, endian)]
fn custom_tagged_object_parser(size_in_bytes: u32) -> BinResult<Vec<Entry>> {
let mut result = Vec::<Entry>::new();
let mut current = reader.stream_position()?;
let end = current + size_in_bytes as u64;
while current < end {
result.push(Entry::read_options(reader, endian, ())?);
current = reader.stream_position()?;
}
Ok(result)
}
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct TaggedObject { pub struct TaggedObject {
pub size_in_bytes: u32, 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<Entry>, pub entries: Vec<Entry>,
} }

31
src/linear_color.rs Normal file
View file

@ -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);
}
}

View file

@ -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::struct_property::Struct;
use crate::structs::PrimaryAssetNameProperty; use crate::structs::PrimaryAssetNameProperty;
use binrw::helpers::until_exclusive;
use binrw::{BinRead, BinResult, binrw}; use binrw::{BinRead, BinResult, binrw};
use crate::guid::Guid;
// A struct without a name // parse until we can't parse no more. kind of a hack for how we run into the end of Persistent.Sav
#[binrw] #[binrw::parser(reader, endian)]
#[derive(Debug)] fn cc() -> BinResult<Vec<PrimaryAssetNameProperty>> {
pub struct AnonymousStruct { let mut result = Vec::<PrimaryAssetNameProperty>::new();
#[br(parse_with = until_exclusive(|entry: &PrimaryAssetNameProperty| entry.property_name == "None"))]
fields: Vec<PrimaryAssetNameProperty>, loop {
if let Ok(str) = PrimaryAssetNameProperty::read_options(reader, endian, ()) {
result.push(str);
} else {
break;
}
}
Ok(result)
} }
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct MapSubStructProperty { pub struct MapSubStructProperty {
#[br(temp)] #[br(parse_with = cc)]
#[bw(ignore)] fields: Vec<PrimaryAssetNameProperty>,
pub unk_name_length: u32,
pub r#struct: Struct,
} }
#[binrw] #[binrw]
@ -34,7 +40,12 @@ pub struct StructMaybeKey {
#[bw(write_with = write_string_with_length)] #[bw(write_with = write_string_with_length)]
pub unk_type: String, 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, pub r#struct: Struct,
} }
@ -64,7 +75,7 @@ pub struct MapSubStrProperty {
#[derive(Debug)] #[derive(Debug)]
pub struct MapSubBoolProperty { pub struct MapSubBoolProperty {
#[br(map = read_bool_from::<u8>)] #[br(map = read_bool_from::<u8>)]
#[bw(ignore)] #[bw(map = write_bool_as::<u8>)]
pub value: bool, pub value: bool,
} }
@ -129,6 +140,10 @@ pub enum MapKeyProperty {
SomeID(Guid), SomeID(Guid),
#[br(pre_assert(*magic == KeyType::SomeID2))] #[br(pre_assert(*magic == KeyType::SomeID2))]
SomeID2(Guid), SomeID2(Guid),
#[br(pre_assert(*magic == KeyType::ArrayStruct))]
ArrayStruct(StructMaybeKey),
#[br(pre_assert(*magic == KeyType::Unknown2))]
SomeID3(Guid),
} }
#[binrw] #[binrw]
@ -142,17 +157,24 @@ pub struct MapEntry {
pub value: MabSubProperty, pub value: MabSubProperty,
} }
// TODO: im worried that set/array/map actually share same of the same values...
#[binrw] #[binrw]
#[brw(repr = u32)] #[brw(repr = u32)]
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum KeyType { pub enum KeyType {
None = 0x0,
String = 0x1, String = 0x1,
SetStruct = 0x2,
SetStruct2 = 0x2f,
GUID = 0x3, GUID = 0x3,
SomeID = 0x6, SomeID = 0x6,
SomeID2 = 0x10, SomeID2 = 0x10,
EnumAgain = 0x4, EnumAgain = 0x4,
Enum = 0x7, Enum = 0x7,
StructMaybe = 0xC, StructMaybe = 0xC,
ArrayStruct = 0xA, // Only used in ArrayProperty
Unknown = 0x2E, // AcquiredItemBoxIds in Persistent.sav
Unknown2 = 0x33, // CharacterPersistentDataList in Persistent.sav
} }
#[binrw::parser(reader, endian)] #[binrw::parser(reader, endian)]
@ -198,9 +220,9 @@ pub struct MapProperty {
pub value_name: String, pub value_name: String,
#[brw(pad_before = 5)] #[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<MapEntry>, pub entries: Vec<MapEntry>,
} }
@ -251,15 +273,15 @@ mod tests {
let property = MapProperty { let property = MapProperty {
key_name: "StrProperty".to_string(), key_name: "StrProperty".to_string(),
value_name: "StrProperty".to_string(), value_name: "StrProperty".to_string(),
key_type: KeyType::String, map_key_type: KeyType::String,
entries: vec![ entries: vec![MapEntry {
MapEntry { key: MapKeyProperty::String(StringMapKey {
key: MapKeyProperty::String(StringMapKey { value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string() }), value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string(),
}),
value: String(MapSubStrProperty { value: String(MapSubStrProperty {
value: "NAME 1".to_string(), value: "NAME 1".to_string(),
}), }),
} }],
],
}; };
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();

15
src/name_property.rs Normal file
View file

@ -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,
}

44
src/primary_asset_id.rs Normal file
View file

@ -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();
}
}

40
src/primary_asset_type.rs Normal file
View file

@ -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();
}
}

View file

@ -1,36 +1,132 @@
use crate::Property; use crate::common::{read_string_with_length, write_string_with_length};
use crate::common::read_string_with_length; use crate::map_property::{KeyType, MapSubStrProperty};
use binrw::binrw; use crate::struct_property::Struct;
use binrw::{BinRead, BinResult, binrw};
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct SetEntry { #[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)] #[br(parse_with = read_string_with_length)]
#[bw(ignore)] #[bw(write_with = write_string_with_length)]
pub unk_name: String, struct_type: String,
#[br(parse_with = read_string_with_length)] #[br(parse_with = read_string_with_length)]
#[bw(ignore)] #[bw(write_with = write_string_with_length)]
pub unk_type: String, r#type: String,
#[br(parse_with = read_string_with_length)]
#[br(args { magic: &unk_type })] #[bw(write_with = write_string_with_length)]
pub key: Property, #[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] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct SetProperty { #[br(import(value_type: &str, key_type: &str))]
pub unk: u32, pub struct SetEntry {
#[br(args { magic: value_type, name: key_type })]
pub key: SetValue,
}
#[br(pad_before = 4, parse_with = read_string_with_length)] #[binrw::parser(reader, endian)]
#[bw(ignore)] fn custom_parser(size_in_bytes: u32, value_type: &str, key_type: &str) -> BinResult<Vec<SetEntry>> {
let mut result = Vec::<SetEntry>::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, pub key_name: String,
#[br(pad_before = 5)] #[brw(pad_before = 5)]
pub num_set_entries: u32, pub key_type: KeyType,
#[br(count = num_set_entries)] #[br(parse_with = custom_parser, args(size_in_bytes, &key_name, &name))]
pub entries: Vec<SetEntry>, pub entries: Vec<SetEntry>,
} }
#[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 // TODO: write test

View file

@ -1,84 +1,77 @@
use crate::structs::{CarryCountProperty, DAAssembleIdDataStruct, DABuildDataStruct, DACharacterCommonStatusStruct, DALoadOptionStruct, DAMachineColoringDataStruct, DAModuleColorStruct, DAModuleItemDataStruct, DateTimeStruct, GuidStruct, LinearColorStruct, PrimaryAssetIdStruct, PrimaryAssetNameProperty, SaveSlotInfoStruct}; use crate::build_data::DABuildDataStruct;
use binrw::binrw; use crate::common::{read_string_with_length, write_string_with_length};
use crate::guid::Guid; 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] #[binrw]
#[derive(Debug)] #[derive(Debug)]
#[br(import { magic: &str })]
pub enum Struct { pub enum Struct {
#[br(magic = b"DateTime\0")] #[br(pre_assert(magic == "DateTime"))]
DateTime(DateTimeStruct), DateTime(DateTimeStruct),
#[br(magic = b"DALoadOption\0")] #[br(pre_assert(magic == "DALoadOption"))]
DALoadOption(DALoadOptionStruct), DALoadOption(DALoadOptionStruct),
#[br(magic = b"SaveSlotInfo\0")] #[br(pre_assert(magic == "SaveSlotInfo"))]
SaveSlotInfo(SaveSlotInfoStruct), SaveSlotInfo(SaveSlotInfoStruct),
#[br(magic = b"DACharacterCommonStatus\0")] #[br(pre_assert(magic == "DACharacterCommonStatus"))]
DACharacterCommonStatus(DACharacterCommonStatusStruct), DACharacterCommonStatus(DACharacterCommonStatusStruct),
#[br(magic = b"PrimaryAssetType\0")] #[br(pre_assert(magic == "PrimaryAssetType"))]
PrimaryAssetType { PrimaryAssetType(PrimaryAssetTypeStruct),
#[br(pad_before = 17)] #[br(pre_assert(magic == "PrimaryAssetId"))]
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")]
PrimaryAssetId(PrimaryAssetIdStruct), PrimaryAssetId(PrimaryAssetIdStruct),
#[br(magic = b"DAModuleItemData\0")] #[br(pre_assert(magic == "DAModuleItemData"))]
DAModuleItemData(DAModuleItemDataStruct), DAModuleItemData(DAModuleItemDataStruct),
#[br(magic = b"DABuildData\0")] #[br(pre_assert(magic == "DABuildData"))]
DABuildData(DABuildDataStruct), DABuildData(DABuildDataStruct),
#[br(magic = b"DAAssembleIdData\0")] #[br(pre_assert(magic == "DAAssembleIdData"))]
DAAssembleIdData(DAAssembleIdDataStruct), DAAssembleIdData(DAAssembleIdDataStruct),
#[br(magic = b"Guid\0")] #[br(pre_assert(magic == "Guid"))]
Guid(GuidStruct), Guid(Guid),
#[br(magic = b"DAMachineColoringData\0")] #[br(pre_assert(magic == "DAMachineColoringData"))]
DAMachineColoringData(DAMachineColoringDataStruct), DAMachineColoringData(DAMachineColoringDataStruct),
#[br(magic = b"DAModuleColor\0")] #[br(pre_assert(magic == "DAModuleColor"))]
DAModuleColor(DAModuleColorStruct), DAModuleColor(DAModuleColorStruct),
#[br(magic = b"LinearColor\0")] #[br(pre_assert(magic == "LinearColor"))]
LinearColor(LinearColorStruct), LinearColor(LinearColorStruct),
#[br(magic = b"CarryCount\0")] #[br(pre_assert(magic == "DATriggerData"))]
CarryCount { DATriggerData(DATriggerDataStruct),
carry_count: CarryCountProperty, #[br(pre_assert(magic == "DACustomizeAssetIdData"))]
DACustomizeAssetIdData(DACustomizeAssetIdDataStruct),
#[br(pad_before = 15)] // "StoreCount" + 4 bytes for length + 1 byte for endofstring #[br(pre_assert(magic == "DATuningData"))]
#[br(pad_after = 9)] // "None" + 1 byte for endofstring + 4 bytes for length DATuningData(DATuningDataStruct),
store_count: CarryCountProperty, #[br(pre_assert(magic == "DAHumanoidColoringData"))]
}, DAHumanoidColoringData(DAHumanoidColoringDataStruct),
#[br(magic = b"Map\0")] #[br(pre_assert(magic == "DAHumanoidFigureData"))]
Map { DAHumanoidFigureData(DAHumanoidFigureData),
#[br(pad_after = 9)] // "None" + 1 byte for endofstring + 4 bytes for length #[br(pre_assert(magic == "DATuningPointData"))]
map: CarryCountProperty, DATuningPointData(DATuningPointData),
}, #[br(pre_assert(magic == "Transform"))]
// TODO: im almost certain this isn't a struct name Transform(TransformStruct),
#[br(magic = b"ID\0")] #[br(pre_assert(magic == "Quat"))]
ID { Quat(QuatStruct),
unk: [u8; 149], // not sure how to parse this yet #[br(pre_assert(magic == "Vector"))]
Vector(VectorStruct),
#[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] },
} }
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct StructProperty { pub struct StructProperty {
pub unk: u32, pub unk: u32,
#[br(temp)] #[brw(pad_before = 4)]
#[bw(ignore)] #[br(parse_with = read_string_with_length)]
#[br(pad_before = 4)] #[bw(write_with = write_string_with_length)]
pub name_length: u32, pub struct_name: String,
#[br(args { magic: &struct_name })]
#[br(pad_before = 17)]
pub r#struct: Struct, pub r#struct: Struct,
} }

View file

@ -1,7 +1,7 @@
use crate::Property; use crate::Property;
use crate::build_data::DABuildDataStruct;
use crate::common::{read_string_with_length, write_string_with_length};
use binrw::binrw; use binrw::binrw;
use crate::common::read_string_with_length;
use crate::guid::Guid;
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
@ -27,80 +27,208 @@ pub struct DACharacterCommonStatusStruct {
pub unk: [u8; 17], pub unk: [u8; 17],
} }
// TODO: replace all usage of this with StructField
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct PrimaryAssetNameProperty { pub struct PrimaryAssetNameProperty {
#[br(parse_with = read_string_with_length)] #[br(parse_with = read_string_with_length)]
#[bw(ignore)] #[bw(write_with = write_string_with_length)]
pub property_name: String, pub property_name: String,
#[br(parse_with = read_string_with_length)] #[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, pub type_name: String,
#[br(if(property_name != "None"))] #[br(if(property_name != "None"))]
#[br(args { magic: &type_name})] #[br(args { magic: &type_name, name: &property_name})]
pub key: Option<Box<Property>>, pub key: Option<Box<Property>>,
} }
// TODO: allow specializing into structs for StructProperty, and so on
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct CarryCountProperty { #[br(import { name: &str, r#type: &str })]
pub struct StructField {
#[br(parse_with = read_string_with_length)] #[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, pub property_name: String,
#[br(args { magic: &property_name})] #[br(parse_with = read_string_with_length)]
pub key: Option<Box<Property>>, #[bw(write_with = write_string_with_length)]
} #[br(assert(type_name == r#type))]
pub type_name: String,
#[binrw] #[br(if(property_name != "None"))]
#[derive(Debug)] #[br(args { magic: &type_name, name: &property_name })]
pub struct PrimaryAssetIdStruct { pub key: Option<Box<Property>>,
#[br(pad_before = 17)]
asset: PrimaryAssetNameProperty,
} }
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct DAModuleItemDataStruct { pub struct DAModuleItemDataStruct {
#[br(pad_before = 17)] #[br(pad_after = 9)] // none
pub module_level: PrimaryAssetNameProperty, pub module_level: PrimaryAssetNameProperty,
} }
#[binrw]
#[derive(Debug)]
pub struct DABuildDataStruct {
pub unk: [u8; 17],
}
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct DAAssembleIdDataStruct { pub struct DAAssembleIdDataStruct {
pub unk: [u8; 17], pub hanger: PrimaryAssetNameProperty,
} pub headset: PrimaryAssetNameProperty,
pub mobility: PrimaryAssetNameProperty,
#[binrw] pub thruster: PrimaryAssetNameProperty,
#[derive(Debug)] pub utility: PrimaryAssetNameProperty,
pub struct GuidStruct { pub primary_front_weapon: PrimaryAssetNameProperty,
#[br(pad_before = 17)] pub secondary_front_weapon: PrimaryAssetNameProperty,
pub guid: Guid pub left_rear_weapon: PrimaryAssetNameProperty,
pub right_rear_weapon: PrimaryAssetNameProperty,
// has none at the end
#[br(pad_after = 9)]
pub coloring_data: PrimaryAssetNameProperty,
} }
#[binrw] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct DAMachineColoringDataStruct { 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] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct DAModuleColorStruct { 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] #[binrw]
#[derive(Debug)] #[derive(Debug)]
pub struct LinearColorStruct { pub struct DATriggerDataStruct {
pub unk: [u8; 33], 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,
} }

BIN
tests/resources/Slot.bin Normal file

Binary file not shown.

View file

@ -1,8 +1,8 @@
use binrw::{BinRead, BinWrite};
use ireko::TaggedSerialization;
use std::fs::read; use std::fs::read;
use std::io::Cursor; use std::io::Cursor;
use std::path::PathBuf; use std::path::PathBuf;
use binrw::{BinRead, BinWrite};
use ireko::TaggedSerialization;
#[test] #[test]
fn roundtrip_localprofile() { fn roundtrip_localprofile() {
@ -31,3 +31,31 @@ fn roundtrip_localprofile() {
// Ensure our written version is the same as retail // Ensure our written version is the same as retail
assert_eq!(new_data.as_slice(), &data[..]); 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<u8> = 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[..]);
}