diff --git a/src/fot.rs b/src/fot.rs index 68e97ff..caf4488 100644 --- a/src/fot.rs +++ b/src/fot.rs @@ -1,4 +1,5 @@ mod decoder; +mod entity; mod esh; mod fstring; mod raw; diff --git a/src/fot/decoder.rs b/src/fot/decoder.rs index 6e31e59..b91806d 100644 --- a/src/fot/decoder.rs +++ b/src/fot/decoder.rs @@ -3,13 +3,15 @@ use anyhow::Result; use std::str; pub trait Decoder: Sized { - fn decode(raw: &Raw, offset: usize, size: usize) -> Result; + type Opt; + fn decode(raw: &Raw, offset: usize, size: usize, opt: Option) -> Result; fn encode(&self) -> Result; fn get_enc_size(&self) -> usize; } impl Decoder for String { - fn decode(raw: &Raw, offset: usize, size: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, size: usize, _: Option<()>) -> Result { let str = &raw.mem[offset..]; match str.iter().position(|&c| c == 0) { Some(pos) => Ok(str::from_utf8(&str[..pos])?.to_string()), diff --git a/src/fot/entity.rs b/src/fot/entity.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/fot/esh.rs b/src/fot/esh.rs index e5c1cee..afda8dc 100644 --- a/src/fot/esh.rs +++ b/src/fot/esh.rs @@ -76,7 +76,8 @@ impl ESHValue { } impl Decoder for ESHValue { - fn decode(raw: &Raw, offset: usize, _: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result { let mut rd = ReadStream::new(raw, offset); let data_type = rd.read_u32()?; let data_size = rd.read_u32()?; @@ -248,7 +249,8 @@ pub struct ESH { } impl Decoder for ESH { - fn decode(raw: &Raw, offset: usize, _: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result { let mut rd = ReadStream::new(raw, offset); let tag: Tag = rd.read(0)?; diff --git a/src/fot/fstring.rs b/src/fot/fstring.rs index 439ba15..25ffc57 100644 --- a/src/fot/fstring.rs +++ b/src/fot/fstring.rs @@ -24,7 +24,8 @@ pub struct FString { } impl Decoder for FString { - fn decode(raw: &Raw, offset: usize, _: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result { let mut rdr = Cursor::new(&raw.mem[offset..]); let flen = rdr.read_u32::()? as usize; let len = flen & !(1 << 31); diff --git a/src/fot/save.rs b/src/fot/save.rs index 192adbf..82dd3a3 100644 --- a/src/fot/save.rs +++ b/src/fot/save.rs @@ -46,7 +46,7 @@ impl Save { return Err(anyhow!("Unable to determine world block size")); } - let world = World::decode(&raw, world_offset, world_size)?; + let world = World::decode(&raw, world_offset, world_size, None)?; Ok(Save { raw, world }) } diff --git a/src/fot/sgd.rs b/src/fot/sgd.rs index 7f5526e..8f27b7f 100644 --- a/src/fot/sgd.rs +++ b/src/fot/sgd.rs @@ -15,7 +15,8 @@ pub struct SGD { } impl Decoder for SGD { - fn decode(raw: &Raw, offset: usize, _: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result { let mut rd = ReadStream::new(raw, offset); let tag: Tag = rd.read(0)?; let unk1 = rd.read_bytes(0x48)?; diff --git a/src/fot/ssg.rs b/src/fot/ssg.rs index 86186fe..e66bb94 100644 --- a/src/fot/ssg.rs +++ b/src/fot/ssg.rs @@ -11,7 +11,8 @@ pub struct SSG { } impl Decoder for SSG { - fn decode(raw: &Raw, offset: usize, _: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result { let mut rd = ReadStream::new(raw, offset); let tag: Tag = rd.read(0)?; let unk1 = rd.read_bytes(0x14)?; diff --git a/src/fot/stream.rs b/src/fot/stream.rs index c85fcba..a7ab63e 100644 --- a/src/fot/stream.rs +++ b/src/fot/stream.rs @@ -43,8 +43,17 @@ impl<'a> ReadStream<'a> { // "size" is not required to be actual size, it's only // a hint for Decoder::decode. Most of the structures are // dynamically determining their decoding and encoding sizes + + // read_opt - decode with optional paramters. required for complex structure + // with different origins (save / entfile) like entities + pub fn read_opt(&mut self, size: usize, opt: T::Opt) -> Result { + let val = T::decode(&self.raw, self.offset(), size, Some(opt))?; + self.skip(val.get_enc_size()); + Ok(val) + } + pub fn read(&mut self, size: usize) -> Result { - let val = T::decode(&self.raw, self.offset(), size)?; + let val = T::decode(&self.raw, self.offset(), size, None)?; self.skip(val.get_enc_size()); Ok(val) } diff --git a/src/fot/tag.rs b/src/fot/tag.rs index b21e66f..1e9fea9 100644 --- a/src/fot/tag.rs +++ b/src/fot/tag.rs @@ -10,7 +10,8 @@ pub struct Tag { } impl Decoder for Tag { - fn decode(raw: &Raw, offset: usize, size: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, size: usize, _: Option<()>) -> Result { let mut rd = ReadStream::new(raw, offset); let name: String = rd.read(0)?; let version: String = rd.read(0)?; diff --git a/src/fot/world.rs b/src/fot/world.rs index 6902650..b5fb00d 100644 --- a/src/fot/world.rs +++ b/src/fot/world.rs @@ -52,7 +52,13 @@ impl World { } let name = &types[type_idx as usize]; - println!("offset {:x} idx {} unk1 {} name {}", rd.offset(), i, unk2, name); + println!( + "offset {:x} idx {} unk1 {} name {}", + rd.offset(), + i, + unk2, + name + ); let _: ESH = rd.read(0)?; } @@ -61,7 +67,8 @@ impl World { } impl Decoder for World { - fn decode(raw: &Raw, offset: usize, size: usize) -> Result { + type Opt = (); + fn decode(raw: &Raw, offset: usize, size: usize, _: Option<()>) -> Result { let mut enc = ReadStream::new(raw, offset); let tag: Tag = enc.read(Self::WORLD_TAG_LEN)?;