me3_coalesced_parser/
shared.rs1pub const ME3_MAGIC: u32 = 0x666D726D;
3pub const TLK_MAGIC: u32 = 0x006B6C54;
5
6pub type WChar = u16;
7pub type WString = Vec<u16>;
8
9#[derive(Debug, Hash, serde::Serialize, serde::Deserialize)]
11pub struct Tlk {
12 pub version: u32,
13 pub min_version: u32,
14
15 pub male_values: Vec<TlkString>,
17 pub female_values: Vec<TlkString>,
19}
20
21impl Tlk {
22 pub fn replace_male(&mut self, id: u32, value: WString) -> bool {
24 if let Some(entry) = self.male_values.iter_mut().find(|value| value.id == id) {
25 entry.value = value;
26 true
27 } else {
28 false
29 }
30 }
31
32 pub fn insert_male(&mut self, id: u32, value: WString) {
34 if self.replace_male(id, value.clone()) {
35 return;
36 }
37
38 self.male_values.push(TlkString { id, value })
39 }
40
41 pub fn replace_female(&mut self, id: u32, value: WString) -> bool {
43 if let Some(entry) = self.female_values.iter_mut().find(|value| value.id == id) {
44 entry.value = value;
45 true
46 } else {
47 false
48 }
49 }
50
51 pub fn insert_female(&mut self, id: u32, value: WString) {
53 if self.replace_female(id, value.clone()) {
54 return;
55 }
56
57 self.female_values.push(TlkString { id, value })
58 }
59
60 pub fn replace_male_utf8(&mut self, id: u32, value: String) -> bool {
62 if let Some(entry) = self.male_values.iter_mut().find(|value| value.id == id) {
63 entry.value = value.encode_utf16().collect();
64 true
65 } else {
66 false
67 }
68 }
69
70 pub fn insert_male_utf8(&mut self, id: u32, value: String) {
72 if self.replace_male_utf8(id, value.clone()) {
73 return;
74 }
75
76 self.male_values.push(TlkString {
77 id,
78 value: value.encode_utf16().collect(),
79 })
80 }
81
82 pub fn replace_female_utf8(&mut self, id: u32, value: String) -> bool {
84 if let Some(entry) = self.female_values.iter_mut().find(|value| value.id == id) {
85 entry.value = value.encode_utf16().collect();
86 true
87 } else {
88 false
89 }
90 }
91
92 pub fn insert_female_utf8(&mut self, id: u32, value: String) {
94 if self.replace_female_utf8(id, value.clone()) {
95 return;
96 }
97
98 self.female_values.push(TlkString {
99 id,
100 value: value.encode_utf16().collect(),
101 })
102 }
103}
104
105#[derive(Debug, Hash, serde::Serialize, serde::Deserialize)]
107pub struct TlkString {
108 pub id: u32,
110 pub value: WString,
112}
113
114#[derive(Debug, Hash, serde::Serialize, serde::Deserialize)]
116pub struct Coalesced {
117 pub version: u32,
119 pub files: Vec<CoalFile>,
121}
122
123#[derive(Debug, Hash, serde::Serialize, serde::Deserialize)]
125pub struct CoalFile {
126 pub path: String,
128 pub sections: Vec<Section>,
130}
131
132#[derive(Debug, Hash, serde::Serialize, serde::Deserialize)]
133pub struct Section {
134 pub name: String,
136 pub properties: Vec<Property>,
138}
139
140#[derive(Debug, Hash, serde::Serialize, serde::Deserialize)]
141pub struct Property {
142 pub name: String,
144 pub values: Vec<Value>,
146}
147
148#[derive(Debug, Hash, serde::Serialize, serde::Deserialize)]
149pub struct Value {
150 pub ty: ValueType,
152 pub text: Option<String>,
154}
155
156#[derive(Debug, Hash, serde::Serialize, serde::Deserialize, Clone, Copy)]
157#[repr(u8)]
158pub enum ValueType {
159 New = 0,
161 RemoveProperty = 1,
163 Add = 2,
165 AddUnique = 3,
167 Remove = 4,
169}
170
171pub struct UnknownValueType;
172
173impl TryFrom<u8> for ValueType {
174 type Error = UnknownValueType;
175
176 fn try_from(value: u8) -> Result<Self, Self::Error> {
177 Ok(match value {
178 0 => Self::New,
179 1 => Self::RemoveProperty,
180 2 => Self::Add,
181 3 => Self::AddUnique,
182 4 => Self::Remove,
183 _ => return Err(UnknownValueType),
184 })
185 }
186}
187
188pub(crate) fn invert_huffman_tree(pairs: &mut Vec<(i32, i32)>) {
194 let last_index = (pairs.len() - 1) as i32;
195
196 pairs.reverse();
198
199 for pair in pairs {
201 if pair.0 > -1 {
202 pair.0 = last_index - pair.0
203 }
204
205 if pair.1 > -1 {
206 pair.1 = last_index - pair.1
207 }
208 }
209}