implemented EntityList decoding and encoding. But decoding has some bugs that needs to be fixed

This commit is contained in:
mykola2312 2023-09-04 07:14:07 +03:00
parent 4e8cc4a5e8
commit 5ea616cd44
6 changed files with 52 additions and 49 deletions

View file

@ -8,9 +8,9 @@ pub trait Decoder: Sized {
fn get_enc_size(&self) -> usize; fn get_enc_size(&self) -> usize;
} }
pub trait DecoderCtx<Ctx>: Sized { pub trait DecoderCtx<DCtx, ECtx>: Sized {
fn decode(raw: &Raw, offset: usize, size: usize, ctx: Ctx) -> Result<Self>; fn decode(raw: &Raw, offset: usize, size: usize, ctx: DCtx) -> Result<Self>;
fn encode(&self, ctx: Ctx) -> Result<Raw>; fn encode(&self, ctx: ECtx) -> Result<Raw>;
fn get_enc_size(&self) -> usize; fn get_enc_size(&self) -> usize;
} }

View file

@ -14,7 +14,7 @@ pub struct Entity {
enc_size: usize, enc_size: usize,
} }
impl DecoderCtx<&mut EntityList> for Entity { impl DecoderCtx<&mut EntityList, &EntityList> for Entity {
fn decode(raw: &Raw, offset: usize, _: usize, ctx: &mut EntityList) -> Result<Self> { fn decode(raw: &Raw, offset: usize, _: usize, ctx: &mut EntityList) -> Result<Self> {
let mut rd = ReadStream::new(raw, offset); let mut rd = ReadStream::new(raw, offset);
Ok(match ctx.get_entity_encoding() { Ok(match ctx.get_entity_encoding() {
@ -45,11 +45,10 @@ impl DecoderCtx<&mut EntityList> for Entity {
}) })
} }
fn encode(&self, ctx: &mut EntityList) -> Result<Raw> { fn encode(&self, ctx: &EntityList) -> Result<Raw> {
let mut wd = WriteStream::new(self.get_enc_size()); let mut wd = WriteStream::new(self.get_enc_size());
match ctx.get_entity_encoding() { match ctx.get_entity_encoding() {
EntityEncoding::File => { EntityEncoding::File => {
wd.write(ctx.get_entity_tag())?;
wd.write(ctx.get_type_name(self.type_idx))?; wd.write(ctx.get_type_name(self.type_idx))?;
wd.write(&self.esh)?; wd.write(&self.esh)?;
} }

View file

@ -21,8 +21,8 @@ pub struct EntityList {
unk1: u32, unk1: u32,
enc_size: usize, enc_size: usize,
types: Vec<FString>, pub types: Vec<FString>,
entities: Vec<Entity> pub entities: Vec<Entity>
} }
impl EntityList { impl EntityList {
@ -51,7 +51,7 @@ impl EntityList {
} }
} }
impl DecoderCtx<EntityEncoding> for EntityList { impl DecoderCtx<EntityEncoding,EntityEncoding> for EntityList {
fn decode(raw: &Raw, offset: usize, size: usize, ctx: EntityEncoding) -> Result<Self> { fn decode(raw: &Raw, offset: usize, size: usize, ctx: EntityEncoding) -> Result<Self> {
let mut rd = ReadStream::new(raw, offset); let mut rd = ReadStream::new(raw, offset);
let mut ent_list = EntityList { let mut ent_list = EntityList {
@ -84,15 +84,16 @@ impl DecoderCtx<EntityEncoding> for EntityList {
EntityEncoding::World => { EntityEncoding::World => {
ent_list.entity_file_tag = Some(rd.read(0)?); ent_list.entity_file_tag = Some(rd.read(0)?);
let n = rd.read_u32()?; let type_count = rd.read_u32()?;
for _ in 0..n { for _ in 0..type_count {
ent_list.types.push(rd.read(0)?); ent_list.types.push(rd.read(0)?);
} }
let m = rd.read_u16()?; let ent_count = rd.read_u16()?;
ent_list.unk1 = rd.read_u32()?; ent_list.unk1 = rd.read_u32()?;
for _ in 0..m { for i in 1..ent_count {
let ent: Entity = rd.read_opt(0, &mut ent_list)?; let ent: Entity = rd.read_opt(0, &mut ent_list)?;
println!("ok read {}", i);
ent_list.entities.push(ent); ent_list.entities.push(ent);
} }
@ -103,7 +104,30 @@ impl DecoderCtx<EntityEncoding> for EntityList {
} }
fn encode(&self, ctx: EntityEncoding) -> Result<Raw> { fn encode(&self, ctx: EntityEncoding) -> Result<Raw> {
todo!(); let mut wd = WriteStream::new(self.get_enc_size());
match ctx {
EntityEncoding::File => {
for ent in self.entities.iter() {
wd.write(self.get_entity_tag())?;
wd.write_opt(ent, &self)?;
}
},
EntityEncoding::World => {
wd.write(self.entity_file_tag.as_ref().unwrap())?;
wd.write_u32(self.types.len() as u32)?;
for type_name in self.types.iter() {
wd.write(type_name)?;
}
wd.write_u16(self.entities.len() as u16)?;
wd.write_u32(self.unk1)?;
for ent in self.entities.iter() {
wd.write_opt(ent, &self)?;
}
}
}
Ok(wd.into_raw(0, 0))
} }
fn get_enc_size(&self) -> usize { fn get_enc_size(&self) -> usize {

View file

@ -7,7 +7,6 @@ use byteorder::{ByteOrder, LittleEndian};
use std::path::Path; use std::path::Path;
use std::str; use std::str;
#[derive(Debug)]
pub struct Save { pub struct Save {
pub raw: Raw, pub raw: Raw,
pub world: World, pub world: World,

View file

@ -46,7 +46,7 @@ impl<'a> ReadStream<'a> {
// read_opt - decode with optional paramters. required for complex structure // read_opt - decode with optional paramters. required for complex structure
// with different origins (save / entfile) like entities // with different origins (save / entfile) like entities
pub fn read_opt<T: DecoderCtx<Ctx>, Ctx>(&mut self, size: usize, ctx: Ctx) -> Result<T> { pub fn read_opt<T: DecoderCtx<DCtx, ECtx>, DCtx, ECtx>(&mut self, size: usize, ctx: DCtx) -> Result<T> {
let val = T::decode(&self.raw, self.offset(), size, ctx)?; let val = T::decode(&self.raw, self.offset(), size, ctx)?;
self.skip(val.get_enc_size()); self.skip(val.get_enc_size());
Ok(val) Ok(val)
@ -112,6 +112,13 @@ impl WriteStream {
self.buf.get_mut().extend(bytes.iter()); self.buf.get_mut().extend(bytes.iter());
} }
pub fn write_opt<T: DecoderCtx<DCtx, ECtx>, DCtx, ECtx>(&mut self, val: &T, ctx: ECtx) -> Result<()> {
let mut raw = val.encode(ctx)?;
self.skip(raw.mem.len());
self.buf.get_mut().append(&mut raw.mem);
Ok(())
}
pub fn write<T: Decoder>(&mut self, val: &T) -> Result<()> { pub fn write<T: Decoder>(&mut self, val: &T) -> Result<()> {
let mut raw = val.encode()?; let mut raw = val.encode()?;
self.skip(raw.mem.len()); self.skip(raw.mem.len());

View file

@ -1,6 +1,6 @@
use super::decoder::Decoder; use super::decoder::Decoder;
use super::esh::ESH;
use super::fstring::FString; use super::fstring::FString;
use super::entitylist::{EntityList, EntityEncoding};
use super::raw::Raw; use super::raw::Raw;
use super::sgd::SGD; use super::sgd::SGD;
use super::ssg::SSG; use super::ssg::SSG;
@ -13,7 +13,6 @@ use deflate::deflate_bytes_zlib;
use inflate::inflate_bytes_zlib; use inflate::inflate_bytes_zlib;
use std::io::Cursor; use std::io::Cursor;
#[derive(Debug)]
pub struct World { pub struct World {
pub tag: Tag, pub tag: Tag,
pub uncompressed_size: u32, pub uncompressed_size: u32,
@ -23,6 +22,8 @@ pub struct World {
pub mission: FString, pub mission: FString,
pub sgd: SGD, pub sgd: SGD,
pub ssg: SSG, pub ssg: SSG,
pub ents: EntityList
} }
impl World { impl World {
@ -30,37 +31,7 @@ impl World {
const WORLD_HDR_LEN: usize = 0x13; const WORLD_HDR_LEN: usize = 0x13;
pub fn test(&self) -> Result<()> { pub fn test(&self) -> Result<()> {
let mut rd = ReadStream::new(&self.data, 0x1038); println!("read {} ents", self.ents.entities.len());
let _: Tag = rd.read(0)?;
let n = rd.read_u32()? as usize;
let mut types: Vec<FString> = Vec::with_capacity(n);
for i in 0..n {
let ent_type: FString = rd.read(0)?;
println!("{}\t{}", i, &ent_type);
types.push(ent_type);
}
let esh_count = rd.read_u16()?;
let unk1 = rd.read_u32()?;
dbg!(esh_count);
for i in 1..esh_count {
let unk2 = rd.read_u32()?;
let type_idx = rd.read_u16()?;
if type_idx == 0xFFFF {
continue;
}
let name = &types[type_idx as usize];
println!(
"offset {:x} idx {} unk1 {} name {}",
rd.offset(),
i,
unk2,
name
);
let _: ESH = rd.read(0)?;
}
Ok(()) Ok(())
} }
@ -88,6 +59,8 @@ impl Decoder for World {
let sgd: SGD = rd.read(0)?; let sgd: SGD = rd.read(0)?;
let ssg: SSG = rd.read(0)?; let ssg: SSG = rd.read(0)?;
let ents: EntityList = rd.read_opt(0, EntityEncoding::World)?;
Ok(World { Ok(World {
tag, tag,
uncompressed_size, uncompressed_size,
@ -95,6 +68,7 @@ impl Decoder for World {
mission, mission,
sgd, sgd,
ssg, ssg,
ents
}) })
} }