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::map_property::MabSubProperty;
use crate::map_property::{KeyType, StringMapKey};
use crate::struct_property::Struct;
use binrw::{BinRead, BinResult, binrw};
fn calculate_header_size(key_name: &str, array_key_data: &ArrayKeyData) -> u64 {
// TODO: blah, needs to take into account everything before the first item
match array_key_data {
ArrayKeyData::String() => 0,
ArrayKeyData::Struct {
name,
type_name,
struct_name,
} => {
// for magic numbers see padding in ArrayKeyData
// plus null terminator
(name.len() + type_name.len() + struct_name.len() + 18 + 7 + key_name.len() + 1) as u64
}
}
}
#[binrw::parser(reader, endian)]
fn custom_parser(size_in_bytes: u32, value_type: &str) -> BinResult<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 current = reader.stream_position()?;
let end = current + size_in_bytes as u64 - 4;
let end = current + size_in_bytes as u64 - 4 - calculate_header_size(key_name, key_data);
while current < end {
result.push(ArrayEntry::read_options(reader, endian, (value_type,))?);
result.push(ArrayEntry::read_options(
reader,
endian,
(value_type, key_data),
)?);
current = reader.stream_position()?;
}
Ok(result)
@ -18,10 +44,23 @@ fn custom_parser(size_in_bytes: u32, value_type: &str) -> BinResult<Vec<ArrayEnt
#[binrw]
#[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 {
#[br(args { magic: &value_type })]
pub key: MabSubProperty,
#[br(args { magic: value_type, key_data: key_data })]
pub key: ArrayValue,
}
fn calc_size_in_bytes(entries: &Vec<ArrayEntry>) -> u32 {
@ -29,6 +68,30 @@ fn calc_size_in_bytes(entries: &Vec<ArrayEntry>) -> u32 {
18
}
#[binrw]
#[derive(Debug)]
#[br(import { key_type: &KeyType })]
pub enum ArrayKeyData {
#[br(pre_assert(*key_type == KeyType::String))]
String(),
#[br(pre_assert(*key_type == KeyType::ArrayStruct))]
Struct {
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
name: String,
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
type_name: String,
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
#[br(pad_before = 8)] // idk
#[br(pad_after = 17)] // super idk
struct_name: String,
},
}
#[binrw]
#[derive(Debug)]
pub struct ArrayProperty {
@ -41,20 +104,21 @@ pub struct ArrayProperty {
pub key_name: String,
#[brw(pad_before = 1)]
#[bw(calc = 1)]
pub unk: u32,
pub key_type: KeyType,
#[br(parse_with = custom_parser, args(size_in_bytes, &key_name))]
#[br(args { key_type: &key_type })]
pub key_data: ArrayKeyData,
#[br(parse_with = custom_parser, args(size_in_bytes, &key_name, &key_type, &key_data))]
pub entries: Vec<ArrayEntry>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::map_property::MabSubProperty::String;
use crate::map_property::StringMapKey;
use binrw::{BinRead, BinWrite};
use std::io::Cursor;
use crate::map_property::MapSubStrProperty;
#[test]
fn read_simple_array() {
@ -68,7 +132,7 @@ mod tests {
let mut cursor = Cursor::new(data);
let decoded = ArrayProperty::read_le(&mut cursor).unwrap();
assert_eq!(decoded.key_name, "StrProperty");
let String(value_property) = &decoded.entries.first().unwrap().key else {
let ArrayValue::String(value_property) = &decoded.entries.first().unwrap().key else {
panic!("StrProperty!")
};
assert_eq!(value_property.value, "redstrate");
@ -84,13 +148,13 @@ mod tests {
];
let property = ArrayProperty {
key_name: "StrProperty".to_string(),
entries: vec![
ArrayEntry {
key: String(MapSubStrProperty {
value: "redstrate".to_string(),
}),
}
],
key_type: KeyType::String,
key_data: ArrayKeyData::String(),
entries: vec![ArrayEntry {
key: ArrayValue::String(StringMapKey {
value: "redstrate".to_string(),
}),
}],
};
let mut buffer: Vec<u8> = Vec::new();
@ -101,4 +165,171 @@ mod tests {
assert_eq!(expected_data, &buffer[..]);
}
#[test]
fn read_complex_array() {
// From Persistent.sav
let data = [
0x5f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74,
0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x6c,
0x6f, 0x74, 0x73, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x0e, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54,
0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61,
0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x0b, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x50, 0x6f, 0x74, 0x69,
0x6f, 0x6e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00,
0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74,
0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50,
0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x49, 0x74, 0x65, 0x6d, 0x5f, 0x50, 0x6f,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x74,
0x69, 0x6f, 0x6e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11,
0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65,
0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75,
0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61,
0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f,
0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00,
0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74,
0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50,
0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00,
0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69,
0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65,
0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e,
0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72,
0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00,
0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d,
0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d,
0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65,
0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73,
0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74,
0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69,
0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00,
0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79,
0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00,
0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73,
0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d,
0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00,
0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50,
0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70,
0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72,
0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73,
0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65,
0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05,
0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72,
0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65,
0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f,
0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79,
0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50,
0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70,
0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e,
0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41,
0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e,
0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e,
0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00,
0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54,
0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61,
0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65,
0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00,
0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61,
0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f,
0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00,
0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61,
0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00,
0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54,
0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d,
0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e,
0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72,
0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e,
0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11,
0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65,
0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75,
0x63, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61,
0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f,
0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00,
0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74,
0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50,
0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00,
0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69,
0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x79, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65,
0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e,
0x61, 0x6d, 0x65, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72,
0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00,
0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x11, 0x00, 0x00, 0x00, 0x50, 0x72, 0x69, 0x6d,
0x61, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x00, 0x0d,
0x00, 0x00, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
0x79, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65,
0x00,
];
let mut cursor = Cursor::new(data);
let decoded = ArrayProperty::read_le(&mut cursor).unwrap();
assert_eq!(decoded.key_name, "StructProperty");
assert_eq!(decoded.entries.len(), 10);
}
}

View file

@ -26,12 +26,8 @@ mod tests {
#[test]
fn write_false() {
let expected_data: [u8; 10] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
];
let property = BoolProperty {
value: false
};
let expected_data: [u8; 10] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
let property = BoolProperty { value: false };
let mut buffer: Vec<u8> = Vec::new();
{
@ -52,12 +48,8 @@ mod tests {
#[test]
fn write_true() {
let expected_data: [u8; 10] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00
];
let property = BoolProperty {
value: true
};
let expected_data: [u8; 10] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00];
let property = BoolProperty { value: true };
let mut buffer: Vec<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::{BinRead, BinWrite};
pub(crate) fn read_bool_from<T: From<u8> + PartialEq>(x: T) -> bool {
x == T::from(1u8)
}
pub(crate) fn write_bool_as<T: From<u8>>(x: &bool) -> T {
if *x {
T::from(1u8)
} else {
T::from(0u8)
}
if *x { T::from(1u8) } else { T::from(0u8) }
}
#[binrw::parser(reader, endian)]
@ -52,7 +48,6 @@ pub(crate) fn write_string_with_length(string: &String) -> BinResult<()> {
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;

View file

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

View file

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

View file

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

View file

@ -1,16 +1,21 @@
pub mod array_property;
pub mod bool_property;
mod build_data;
mod common;
pub mod float_property;
mod guid;
pub mod int_property;
mod linear_color;
pub mod map_property;
mod name_property;
mod primary_asset_id;
mod primary_asset_type;
pub mod set_property;
pub mod str_property;
pub mod struct_property;
mod structs;
mod guid;
use binrw::helpers::{until, until_eof};
use binrw::helpers::until_eof;
use crate::array_property::ArrayProperty;
use crate::bool_property::BoolProperty;
@ -21,12 +26,12 @@ use crate::map_property::MapProperty;
use crate::set_property::SetProperty;
use crate::str_property::StrProperty;
use crate::struct_property::StructProperty;
use binrw::binrw;
use binrw::{BinRead, BinResult, binrw};
// Used in ArrayProperty exclusively, but could be used instead of magic above
#[binrw]
#[derive(Debug)]
#[br(import { magic: &str })]
#[br(import { magic: &str, name: &str })]
pub enum Property {
#[br(pre_assert("NameProperty" == magic))]
Name(StrProperty),
@ -45,7 +50,10 @@ pub enum Property {
#[br(pre_assert("MapProperty" == magic))]
Map(MapProperty),
#[br(pre_assert("SetProperty" == magic))]
Set(SetProperty),
Set {
#[br(args(name))]
value: SetProperty,
},
}
#[binrw]
@ -60,15 +68,31 @@ pub struct Entry {
#[br(if(name != "None"))]
pub type_name: String,
#[br(if(name != "None"), args { magic: &type_name })]
#[br(if(name != "None"), args { magic: &type_name, name: &name })]
pub r#type: Option<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]
#[derive(Debug)]
pub struct TaggedObject {
pub size_in_bytes: u32,
#[br(parse_with = until(|entry: &Entry| entry.name == "None"))]
//#[br(parse_with = custom_tagged_object_parser, args(size_in_bytes))]
//#[br(parse_with = until(|entry: &Entry| entry.name == "None"))]
#[br(parse_with = until_eof)]
pub entries: Vec<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::structs::PrimaryAssetNameProperty;
use binrw::helpers::until_exclusive;
use binrw::{BinRead, BinResult, binrw};
use crate::guid::Guid;
// A struct without a name
#[binrw]
#[derive(Debug)]
pub struct AnonymousStruct {
#[br(parse_with = until_exclusive(|entry: &PrimaryAssetNameProperty| entry.property_name == "None"))]
fields: Vec<PrimaryAssetNameProperty>,
// parse until we can't parse no more. kind of a hack for how we run into the end of Persistent.Sav
#[binrw::parser(reader, endian)]
fn cc() -> BinResult<Vec<PrimaryAssetNameProperty>> {
let mut result = Vec::<PrimaryAssetNameProperty>::new();
loop {
if let Ok(str) = PrimaryAssetNameProperty::read_options(reader, endian, ()) {
result.push(str);
} else {
break;
}
}
Ok(result)
}
#[binrw]
#[derive(Debug)]
pub struct MapSubStructProperty {
#[br(temp)]
#[bw(ignore)]
pub unk_name_length: u32,
pub r#struct: Struct,
#[br(parse_with = cc)]
fields: Vec<PrimaryAssetNameProperty>,
}
#[binrw]
@ -34,7 +40,12 @@ pub struct StructMaybeKey {
#[bw(write_with = write_string_with_length)]
pub unk_type: String,
#[br(pad_before = 4)] // type length
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
pub struct_name: String,
#[br(args { magic: &struct_name })]
#[brw(pad_before = 17)]
pub r#struct: Struct,
}
@ -64,7 +75,7 @@ pub struct MapSubStrProperty {
#[derive(Debug)]
pub struct MapSubBoolProperty {
#[br(map = read_bool_from::<u8>)]
#[bw(ignore)]
#[bw(map = write_bool_as::<u8>)]
pub value: bool,
}
@ -129,6 +140,10 @@ pub enum MapKeyProperty {
SomeID(Guid),
#[br(pre_assert(*magic == KeyType::SomeID2))]
SomeID2(Guid),
#[br(pre_assert(*magic == KeyType::ArrayStruct))]
ArrayStruct(StructMaybeKey),
#[br(pre_assert(*magic == KeyType::Unknown2))]
SomeID3(Guid),
}
#[binrw]
@ -142,17 +157,24 @@ pub struct MapEntry {
pub value: MabSubProperty,
}
// TODO: im worried that set/array/map actually share same of the same values...
#[binrw]
#[brw(repr = u32)]
#[derive(Debug, PartialEq, Clone)]
pub enum KeyType {
None = 0x0,
String = 0x1,
SetStruct = 0x2,
SetStruct2 = 0x2f,
GUID = 0x3,
SomeID = 0x6,
SomeID2 = 0x10,
EnumAgain = 0x4,
Enum = 0x7,
StructMaybe = 0xC,
ArrayStruct = 0xA, // Only used in ArrayProperty
Unknown = 0x2E, // AcquiredItemBoxIds in Persistent.sav
Unknown2 = 0x33, // CharacterPersistentDataList in Persistent.sav
}
#[binrw::parser(reader, endian)]
@ -198,9 +220,9 @@ pub struct MapProperty {
pub value_name: String,
#[brw(pad_before = 5)]
pub key_type: KeyType,
pub map_key_type: KeyType,
#[br(parse_with = custom_parser, args(size_in_bytes, &key_type, &value_name))]
#[br(parse_with = custom_parser, args(size_in_bytes, &map_key_type, &value_name))]
pub entries: Vec<MapEntry>,
}
@ -251,15 +273,15 @@ mod tests {
let property = MapProperty {
key_name: "StrProperty".to_string(),
value_name: "StrProperty".to_string(),
key_type: KeyType::String,
entries: vec![
MapEntry {
key: MapKeyProperty::String(StringMapKey { value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string() }),
value: String(MapSubStrProperty {
value: "NAME 1".to_string(),
}),
}
],
map_key_type: KeyType::String,
entries: vec![MapEntry {
key: MapKeyProperty::String(StringMapKey {
value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string(),
}),
value: String(MapSubStrProperty {
value: "NAME 1".to_string(),
}),
}],
};
let mut buffer: Vec<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;
use binrw::binrw;
use crate::common::{read_string_with_length, write_string_with_length};
use crate::map_property::{KeyType, MapSubStrProperty};
use crate::struct_property::Struct;
use binrw::{BinRead, BinResult, binrw};
#[binrw]
#[derive(Debug)]
pub struct SetEntry {
#[br(parse_with = read_string_with_length)]
#[bw(ignore)]
pub unk_name: String,
#[br(parse_with = read_string_with_length)]
#[bw(ignore)]
pub unk_type: String,
#[br(args { magic: &unk_type })]
pub key: Property,
#[br(import { magic: &str, name: &str })]
pub enum SetValue {
// NOTE: the name checking is just a temporary workaround
#[br(pre_assert("StructProperty" == magic && name != "OpenedStrongBoxIds" && name != "AcquiredItemBoxIds"))]
Struct {
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
struct_type: String,
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
r#type: String,
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
#[br(pad_before = 8)]
struct_type_for_some_reason_again: String,
#[br(args { magic: &struct_type_for_some_reason_again })]
#[brw(pad_before = 17)]
r#struct: Struct,
},
#[br(pre_assert("StringProperty" == magic || "NameProperty" == magic))]
String(MapSubStrProperty),
#[br(pre_assert("StructProperty" == magic && name == "AcquiredItemBoxIds"))]
Unknown { unk: [u8; 736] },
#[br(pre_assert("StructProperty" == magic && name == "OpenedStrongBoxIds"))]
Unknown2 { unk: [u8; 64] },
}
#[binrw]
#[derive(Debug)]
pub struct SetProperty {
pub unk: u32,
#[br(import(value_type: &str, key_type: &str))]
pub struct SetEntry {
#[br(args { magic: value_type, name: key_type })]
pub key: SetValue,
}
#[br(pad_before = 4, parse_with = read_string_with_length)]
#[bw(ignore)]
#[binrw::parser(reader, endian)]
fn custom_parser(size_in_bytes: u32, value_type: &str, key_type: &str) -> BinResult<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,
#[br(pad_before = 5)]
pub num_set_entries: u32,
#[brw(pad_before = 5)]
pub key_type: KeyType,
#[br(count = num_set_entries)]
#[br(parse_with = custom_parser, args(size_in_bytes, &key_name, &name))]
pub entries: Vec<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

View file

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

View file

@ -1,7 +1,7 @@
use crate::Property;
use crate::build_data::DABuildDataStruct;
use crate::common::{read_string_with_length, write_string_with_length};
use binrw::binrw;
use crate::common::read_string_with_length;
use crate::guid::Guid;
#[binrw]
#[derive(Debug)]
@ -27,80 +27,208 @@ pub struct DACharacterCommonStatusStruct {
pub unk: [u8; 17],
}
// TODO: replace all usage of this with StructField
#[binrw]
#[derive(Debug)]
pub struct PrimaryAssetNameProperty {
#[br(parse_with = read_string_with_length)]
#[bw(ignore)]
#[bw(write_with = write_string_with_length)]
pub property_name: String,
#[br(parse_with = read_string_with_length)]
#[bw(ignore)]
#[bw(write_with = write_string_with_length)]
#[br(if(property_name != "None"))]
pub type_name: String,
#[br(if(property_name != "None"))]
#[br(args { magic: &type_name})]
#[br(args { magic: &type_name, name: &property_name})]
pub key: Option<Box<Property>>,
}
// TODO: allow specializing into structs for StructProperty, and so on
#[binrw]
#[derive(Debug)]
pub struct CarryCountProperty {
#[br(import { name: &str, r#type: &str })]
pub struct StructField {
#[br(parse_with = read_string_with_length)]
#[bw(ignore)]
#[bw(write_with = write_string_with_length)]
#[br(assert(property_name == name))]
pub property_name: String,
#[br(args { magic: &property_name})]
pub key: Option<Box<Property>>,
}
#[br(parse_with = read_string_with_length)]
#[bw(write_with = write_string_with_length)]
#[br(assert(type_name == r#type))]
pub type_name: String,
#[binrw]
#[derive(Debug)]
pub struct PrimaryAssetIdStruct {
#[br(pad_before = 17)]
asset: PrimaryAssetNameProperty,
#[br(if(property_name != "None"))]
#[br(args { magic: &type_name, name: &property_name })]
pub key: Option<Box<Property>>,
}
#[binrw]
#[derive(Debug)]
pub struct DAModuleItemDataStruct {
#[br(pad_before = 17)]
#[br(pad_after = 9)] // none
pub module_level: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct DABuildDataStruct {
pub unk: [u8; 17],
}
#[binrw]
#[derive(Debug)]
pub struct DAAssembleIdDataStruct {
pub unk: [u8; 17],
}
#[binrw]
#[derive(Debug)]
pub struct GuidStruct {
#[br(pad_before = 17)]
pub guid: Guid
pub hanger: PrimaryAssetNameProperty,
pub headset: PrimaryAssetNameProperty,
pub mobility: PrimaryAssetNameProperty,
pub thruster: PrimaryAssetNameProperty,
pub utility: PrimaryAssetNameProperty,
pub primary_front_weapon: PrimaryAssetNameProperty,
pub secondary_front_weapon: PrimaryAssetNameProperty,
pub left_rear_weapon: PrimaryAssetNameProperty,
pub right_rear_weapon: PrimaryAssetNameProperty,
// has none at the end
#[br(pad_after = 9)]
pub coloring_data: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct DAMachineColoringDataStruct {
pub unk: [u8; 17],
pub hanger: PrimaryAssetNameProperty,
pub headset: PrimaryAssetNameProperty,
pub mobility: PrimaryAssetNameProperty,
pub thruster: PrimaryAssetNameProperty,
pub utility: PrimaryAssetNameProperty,
pub primary_front_weapon: PrimaryAssetNameProperty,
pub secondary_front_weapon: PrimaryAssetNameProperty,
pub left_rear_weapon: PrimaryAssetNameProperty,
// has none at the end
#[br(pad_after = 9)]
pub right_rear_weapon: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct DAHumanoidColoringDataStruct {
pub skin: PrimaryAssetNameProperty,
pub hair_base: PrimaryAssetNameProperty,
pub hair_gradation: PrimaryAssetNameProperty,
pub hair_highlight: PrimaryAssetNameProperty,
pub head_option: PrimaryAssetNameProperty,
pub eye_l: PrimaryAssetNameProperty,
pub eye_r: PrimaryAssetNameProperty,
pub body_main: PrimaryAssetNameProperty,
pub body_sub1: PrimaryAssetNameProperty,
pub body_sub2: PrimaryAssetNameProperty,
// has none at the end
#[br(pad_after = 9)]
pub body_sub3: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct DAModuleColorStruct {
pub unk: [u8; 17],
pub main: PrimaryAssetNameProperty,
pub sub: PrimaryAssetNameProperty,
pub inner: PrimaryAssetNameProperty,
// has none at the end
#[br(pad_after = 9)]
pub glow: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct LinearColorStruct {
pub unk: [u8; 33],
pub struct DATriggerDataStruct {
pub unk: [u8; 319], // trigger weapon config in game
}
#[binrw]
#[derive(Debug)]
pub struct DACustomizeAssetIdDataStruct {
pub body: PrimaryAssetNameProperty,
pub face: PrimaryAssetNameProperty,
pub front_hair: PrimaryAssetNameProperty,
pub back_hair: PrimaryAssetNameProperty,
pub coloring_data: PrimaryAssetNameProperty,
pub figure_data: PrimaryAssetNameProperty,
pub inverse_face_mesh: PrimaryAssetNameProperty,
pub inverse_front_hair_mesh: PrimaryAssetNameProperty,
// has none at the end
#[brw(pad_after = 9)]
pub inverse_back_hair_mesh: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct DAHumanoidFigureData {
pub bust_up: PrimaryAssetNameProperty,
pub fat_up: PrimaryAssetNameProperty,
pub arm_up: PrimaryAssetNameProperty,
pub leg_up: PrimaryAssetNameProperty,
// has none at the end
#[brw(pad_after = 9)]
pub waist_up: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct DATuningDataStruct {
#[brw(pad_after = 9)]
pub granted_tuning_point_list: PrimaryAssetNameProperty,
}
#[binrw]
#[derive(Debug)]
pub struct SavedBuildData {
pub build_data: DABuildDataStruct,
}
#[binrw]
#[derive(Debug)]
pub struct DATuningPointData {
#[br(args { name: "TuningPoint", r#type: "IntProperty" })]
tuning_point: StructField,
#[br(args { name: "MaxTuningPoint", r#type: "IntProperty" })]
#[brw(pad_after = 9)] // none
max_tuning_point: StructField,
}
#[binrw]
#[derive(Debug)]
pub struct TransformStruct {
#[br(args { name: "Rotation", r#type: "StructProperty" })]
rotation: StructField,
#[br(args { name: "Translation", r#type: "StructProperty" })]
translation: StructField,
#[br(args { name: "Scale3D", r#type: "StructProperty" })]
#[brw(pad_after = 9)] // none
scale: StructField,
}
#[binrw]
#[derive(Debug)]
pub struct QuatStruct {
// TODO: check if w is actually in front or in the back, this is a guess
pub w: f32,
pub x: f32,
pub y: f32,
pub z: f32,
}
#[binrw]
#[derive(Debug)]
pub struct VectorStruct {
pub x: f32,
pub y: f32,
pub z: f32,
}

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::io::Cursor;
use std::path::PathBuf;
use binrw::{BinRead, BinWrite};
use ireko::TaggedSerialization;
#[test]
fn roundtrip_localprofile() {
@ -31,3 +31,31 @@ fn roundtrip_localprofile() {
// Ensure our written version is the same as retail
assert_eq!(new_data.as_slice(), &data[..]);
}
#[test]
fn roundtrip_slot() {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("tests/resources");
d.push("Slot.bin");
let mut data = read(d).unwrap();
let mut cursor = Cursor::new(&mut data);
let local_profile = TaggedSerialization::read_le(&mut cursor).unwrap();
let tagged_object = &local_profile.objs[0];
assert_eq!(tagged_object.size_in_bytes, 900);
tagged_object.entry("Players").unwrap();
tagged_object.entry("Level").unwrap();
// TODO: check values
let mut new_data: Vec<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[..]);
}