1use bitflags::bitflags;
20use getset::*;
21use serde_derive::{Serialize, Deserialize};
22
23use std::{fmt, fmt::Display};
24
25use crate::binary::{ReadBytes, WriteBytes};
26use crate::error::{Result, RLibError};
27use crate::files::{DecodeableExtraData, Decodeable, EncodeableExtraData, Encodeable};
28
29pub const EXTENSIONS: [&str; 6] = [
31 ".csc", ".ccd", ".esf", ".save", ".save_multiplayer", ".twc", ];
38
39pub const SIGNATURE_CAAB: &[u8; 4] = &[0xCA, 0xAB, 0x00, 0x00];
41pub const SIGNATURE_CBAB: &[u8; 4] = &[0xCB, 0xAB, 0x00, 0x00];
42pub const SIGNATURE_CEAB: &[u8; 4] = &[0xCE, 0xAB, 0x00, 0x00];
43pub const SIGNATURE_CFAB: &[u8; 4] = &[0xCF, 0xAB, 0x00, 0x00];
44
45mod caab;
46mod cbab;
47mod utils;
48
49#[cfg(test)] mod esf_test;
50
51pub const INVALID: u8 = 0x00;
57
58const BOOL: u8 = 0x01;
60const I8: u8 = 0x02;
61const I16: u8 = 0x03;
62const I32: u8 = 0x04;
63const I64: u8 = 0x05;
64const U8: u8 = 0x06;
65const U16: u8 = 0x07;
66const U32: u8 = 0x08;
67const U64: u8 = 0x09;
68const F32: u8 = 0x0a;
69const F64: u8 = 0x0b;
70const COORD_2D: u8 = 0x0c;
71const COORD_3D: u8 = 0x0d;
72const UTF16: u8 = 0x0e;
73const ASCII: u8 = 0x0f;
74const ANGLE: u8 = 0x10;
75
76const BOOL_TRUE: u8 = 0x12;
78const BOOL_FALSE: u8 = 0x13;
79const U32_ZERO: u8 = 0x14;
80const U32_ONE: u8 = 0x15;
81const U32_BYTE: u8 = 0x16;
82const U32_16BIT: u8 = 0x17;
83const U32_24BIT: u8 = 0x18;
84const I32_ZERO: u8 = 0x19;
85const I32_BYTE: u8 = 0x1a;
86const I32_16BIT: u8 = 0x1b;
87const I32_24BIT: u8 = 0x1c;
88const F32_ZERO: u8 = 0x1d;
89
90const UNKNOWN_21: u8 = 0x21;
92const UNKNOWN_23: u8 = 0x23;
93const UNKNOWN_24: u8 = 0x24;
94const UNKNOWN_25: u8 = 0x25;
95
96const UNKNOWN_26: u8 = 0x26;
98
99const BOOL_ARRAY: u8 = 0x41;
101const I8_ARRAY: u8 = 0x42;
102const I16_ARRAY: u8 = 0x43;
103const I32_ARRAY: u8 = 0x44;
104const I64_ARRAY: u8 = 0x45;
105const U8_ARRAY: u8 = 0x46;
106const U16_ARRAY: u8 = 0x47;
107const U32_ARRAY: u8 = 0x48;
108const U64_ARRAY: u8 = 0x49;
109const F32_ARRAY: u8 = 0x4a;
110const F64_ARRAY: u8 = 0x4b;
111const COORD_2D_ARRAY: u8 = 0x4c;
112const COORD_3D_ARRAY: u8 = 0x4d;
113const UTF16_ARRAY: u8 = 0x4e;
114const ASCII_ARRAY: u8 = 0x4f;
115const ANGLE_ARRAY: u8 = 0x50;
116
117const BOOL_TRUE_ARRAY: u8 = 0x52; const BOOL_FALSE_ARRAY: u8 = 0x53; const U32_ZERO_ARRAY: u8 = 0x54; const U32_ONE_ARRAY: u8 = 0x55; const U32_BYTE_ARRAY: u8 = 0x56;
123const U32_16BIT_ARRAY: u8 = 0x57;
124const U32_24BIT_ARRAY: u8 = 0x58;
125const I32_ZERO_ARRAY: u8 = 0x59; const I32_BYTE_ARRAY: u8 = 0x5a;
127const I32_16BIT_ARRAY: u8 = 0x5b;
128const I32_24BIT_ARRAY: u8 = 0x5c;
129const F32_ZERO_ARRAY: u8 = 0x5d; const COMPRESSED_TAGS: [&str; 1] = ["CAMPAIGN_ENV"];
132const COMPRESSED_DATA_TAG: &str = "COMPRESSED_DATA";
133const COMPRESSED_DATA_INFO_TAG: &str = "COMPRESSED_DATA_INFO";
134
135bitflags! {
137
138 #[derive(PartialEq, Clone, Copy, Default, Debug, Serialize, Deserialize)]
140 pub struct RecordNodeFlags: u8 {
141
142 const IS_RECORD_NODE = 0b1000_0000;
144
145 const HAS_NESTED_BLOCKS = 0b0100_0000;
147
148 const HAS_NON_OPTIMIZED_INFO = 0b0010_0000;
150 }
151}
152
153#[derive(Getters, Setters, PartialEq, Clone, Debug, Default, Serialize, Deserialize)]
159#[getset(get = "pub", set = "pub")]
160pub struct ESF {
161
162 signature: ESFSignature,
164
165 unknown_1: u32,
167
168 creation_date: u32,
170
171 root_node: NodeType,
173}
174
175#[derive(Eq, PartialEq, Clone, Copy, Debug, Default, Serialize, Deserialize)]
177pub enum ESFSignature {
178 #[default]CAAB,
179 CBAB,
180 CEAB,
181 CFAB
182}
183
184#[derive(PartialEq, Clone, Debug, Default, Serialize, Deserialize)]
188pub enum NodeType {
189
190 #[default]
192 Invalid,
193
194 Bool(BoolNode),
196 I8(i8),
197 I16(i16),
198 I32(I32Node),
199 I64(i64),
200 U8(u8),
201 U16(u16),
202 U32(U32Node),
203 U64(u64),
204 F32(F32Node),
205 F64(f64),
206 Coord2d(Coordinates2DNode),
207 Coord3d(Coordinates3DNode),
208 Utf16(String),
209 Ascii(String),
210 Angle(i16),
211
212 Unknown21(u32),
214 Unknown23(u8),
215 Unknown24(u16),
216 Unknown25(u32),
217 Unknown26(Vec<u8>),
218
219 BoolArray(Vec<bool>),
221 I8Array(Vec<u8>),
222 I16Array(Vec<i16>),
223 I32Array(VecI32Node),
224 I64Array(Vec<i64>),
225 U8Array(Vec<u8>),
226 U16Array(Vec<u16>),
227 U32Array(VecU32Node),
228 U64Array(Vec<u64>),
229 F32Array(Vec<f32>),
230 F64Array(Vec<f64>),
231 Coord2dArray(Vec<Coordinates2DNode>),
232 Coord3dArray(Vec<Coordinates3DNode>),
233 Utf16Array(Vec<String>),
234 AsciiArray(Vec<String>),
235 AngleArray(Vec<i16>),
236
237 Record(Box<RecordNode>),
239}
240
241#[derive(Getters, MutGetters, Setters, Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
243#[getset(get = "pub", get_mut = "pub", set = "pub")]
244pub struct BoolNode {
245 value: bool,
246 optimized: bool,
247}
248
249#[derive(Getters, MutGetters, Setters, Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
251#[getset(get = "pub", get_mut = "pub", set = "pub")]
252pub struct I32Node {
253 value: i32,
254 optimized: bool,
255}
256
257#[derive(Getters, MutGetters, Setters, Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
259#[getset(get = "pub", get_mut = "pub", set = "pub")]
260pub struct U32Node {
261 value: u32,
262 optimized: bool,
263}
264
265#[derive(Getters, MutGetters, Setters, PartialEq, Clone, Debug, Serialize, Deserialize)]
267#[getset(get = "pub", get_mut = "pub", set = "pub")]
268pub struct F32Node {
269 value: f32,
270 optimized: bool,
271}
272
273#[derive(Getters, MutGetters, Setters, Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
275#[getset(get = "pub", get_mut = "pub", set = "pub")]
276pub struct VecI32Node {
277 value: Vec<i32>,
278 optimized: bool,
279}
280
281#[derive(Getters, MutGetters, Setters, Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
283#[getset(get = "pub", get_mut = "pub", set = "pub")]
284pub struct VecU32Node {
285 value: Vec<u32>,
286 optimized: bool,
287}
288
289#[derive(Getters, MutGetters, Setters, PartialEq, Clone, Default, Debug, Serialize, Deserialize)]
291#[getset(get = "pub", get_mut = "pub", set = "pub")]
292pub struct Coordinates2DNode {
293 x: f32,
294 y: f32,
295}
296
297#[derive(Getters, MutGetters, Setters, PartialEq, Clone, Default, Debug, Serialize, Deserialize)]
299#[getset(get = "pub", get_mut = "pub", set = "pub")]
300pub struct Coordinates3DNode {
301 x: f32,
302 y: f32,
303 z: f32,
304}
305
306#[derive(Getters, MutGetters, Setters, PartialEq, Clone, Default, Debug, Serialize, Deserialize)]
308#[getset(get = "pub", get_mut = "pub", set = "pub")]
309pub struct RecordNode {
310
311 record_flags: RecordNodeFlags,
313
314 version: u8,
316
317 name: String,
319
320 children: Vec<Vec<NodeType>>
322}
323
324impl ESF {
330
331 pub fn clone_without_root_node(&self) -> Self {
333 Self {
334 signature: self.signature,
335 unknown_1: self.unknown_1,
336 creation_date: self.creation_date,
337 root_node: NodeType::Invalid,
338 }
339 }
340}
341
342impl NodeType {
344
345 pub fn clone_without_children(&self) -> Self {
347 match self {
348 Self::Record(node) => {
349 let mut new_node = RecordNode::default();
350 new_node.set_name(node.name().to_owned());
351 new_node.set_record_flags(*node.record_flags());
352 new_node.set_version(*node.version());
353
354 Self::Record(Box::new(new_node))
355 }
356
357 _ => self.clone()
358 }
359 }
360}
361
362impl Display for ESFSignature {
364 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
365 Display::fmt(match self {
366 Self::CAAB => "CAAB",
367 Self::CBAB => "CBAB",
368 Self::CEAB => "CEAB",
369 Self::CFAB => "CFAB",
370 }, f)
371 }
372}
373
374impl TryFrom<&str> for ESFSignature {
375 type Error = RLibError;
376
377 fn try_from(value: &str) -> Result<Self, Self::Error> {
378 match value {
379 "CAAB" => Ok(Self::CAAB),
380 "CBAB" => Ok(Self::CBAB),
381 "CEAB" => Ok(Self::CEAB),
382 "CFAB" => Ok(Self::CFAB),
383 _ => Err(RLibError::UnknownESFSignature(value.to_string())),
384 }
385 }
386}
387
388impl TryFrom<Vec<u8>> for ESFSignature {
389 type Error = RLibError;
390
391 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
392 match value.as_slice().try_into()? {
393 SIGNATURE_CAAB => Ok(Self::CAAB),
394 SIGNATURE_CBAB => Ok(Self::CBAB),
395 SIGNATURE_CEAB => Ok(Self::CEAB),
396 SIGNATURE_CFAB => Ok(Self::CFAB),
397 _ => Err(RLibError::UnknownESFSignatureBytes(value[0], value[1])),
398 }
399 }
400}
401
402impl From<ESFSignature> for Vec<u8> {
403 fn from(value: ESFSignature) -> Self {
404 match value {
405 ESFSignature::CAAB => SIGNATURE_CAAB.to_vec(),
406 ESFSignature::CBAB => SIGNATURE_CBAB.to_vec(),
407 ESFSignature::CEAB => SIGNATURE_CEAB.to_vec(),
408 ESFSignature::CFAB => SIGNATURE_CFAB.to_vec(),
409 }
410 }
411}
412
413impl Decodeable for ESF {
414
415 fn decode<R: ReadBytes>(data: &mut R, _extra_data: &Option<DecodeableExtraData>) -> Result<Self> {
416 let mut esf = Self::default();
417
418 let sig_bytes = data.read_slice(4, false)?;
419 esf.signature = ESFSignature::try_from(sig_bytes.to_vec())?;
420
421 match esf.signature {
422 ESFSignature::CAAB => Self::read_caab(&mut esf, data)?,
423 ESFSignature::CBAB => Self::read_cbab(&mut esf, data)?,
424 _ => return Err(RLibError::DecodingESFUnsupportedSignature(sig_bytes[0], sig_bytes[1])),
425 };
426
427 Ok(esf)
433 }
434}
435
436impl Encodeable for ESF {
437
438 fn encode<W: WriteBytes>(&mut self, buffer: &mut W, extra_data: &Option<EncodeableExtraData>) -> Result<()> {
439 let sig_bytes: Vec<u8> = Vec::from(self.signature);
440 buffer.write_all(&sig_bytes)?;
441
442 match self.signature {
443 ESFSignature::CAAB => self.save_caab(buffer, extra_data),
444 ESFSignature::CBAB => self.save_cbab(buffer, extra_data),
445 _ => Err(RLibError::EncodingESFUnsupportedSignature(self.signature.to_string())),
446 }
447 }
448}