diff --git a/src/fot.rs b/src/fot.rs index 8889875..8e7a391 100644 --- a/src/fot.rs +++ b/src/fot.rs @@ -1 +1,2 @@ +mod raw; pub mod save; \ No newline at end of file diff --git a/src/fot/raw.rs b/src/fot/raw.rs new file mode 100644 index 0000000..470ffdc --- /dev/null +++ b/src/fot/raw.rs @@ -0,0 +1,50 @@ +use std::io::Write; +use std::str; +use std::fs; +use std::fs::OpenOptions; +use std::path::Path; +use anyhow::Result; + +// I can use traits to dynamically implement encode/decode for every header +// or I can just pass Vec with already encoded data to patch file + +pub struct Raw { + pub offset: usize, + pub size: usize, + pub mem: Vec +} + +impl Raw { + pub fn load_file(path: &Path) -> Result { + let mem = fs::read(path)?; + + Ok(Self { offset: 0, size: mem.len(), mem }) + } + + pub fn assemble_file(&self, path: &Path, blocks: Vec) -> Result<()> { + let mut file = OpenOptions::new() + .create(true).truncate(true).write(true).open(path)?; + + let mut sorted = blocks; + sorted.sort_by(|a, b| a.offset.cmp(&b.offset)); + + let file_end = self.size; + let mut prev_end: usize = 0; + for block in sorted.iter() { + // prev + file.write(&self.mem[prev_end..block.offset])?; + // data + file.write(&block.mem)?; + // padding + if block.size > block.mem.len() { + file.write(&vec![0; block.size - block.mem.len()])?; + } + prev_end = block.offset + block.size; + } + if prev_end < file_end { + file.write(&self.mem[prev_end..file_end])?; + } + + Ok(()) + } +} \ No newline at end of file diff --git a/src/fot/save.rs b/src/fot/save.rs index f799d5a..9d3d7c2 100644 --- a/src/fot/save.rs +++ b/src/fot/save.rs @@ -7,6 +7,7 @@ use anyhow::anyhow; use anyhow::Result; use inflate::inflate_bytes_zlib; use deflate::deflate_bytes_zlib; +use crate::fot::raw::Raw; #[derive(Debug)] pub struct World { @@ -93,7 +94,8 @@ impl Save { file.write(&world.encode())?; }*/ - const START: usize = 0x99A84; + // determine world block size be next campaign + /*const START: usize = 0x99A84; const END: usize = 0xD1B1E; //0xD1B1E; const SIZE: usize = 0x38088; //let world = self.worlds.last().unwrap(); @@ -111,7 +113,22 @@ impl Save { } } - file.write(&self.raw[END+1..])?; + file.write(&self.raw[END+1..])?;*/ + + let raw = Raw { offset: 0, size: self.raw.len(), mem: self.raw.clone() }; + + const START: usize = 0x99A84; + const END: usize = 0xD1B1E; //0xD1B1E; + const SIZE: usize = 0x38088; + //let world = self.worlds.last().unwrap(); + let world = World::decode(&self.raw, START, END - START)?; + let enc = world.encode(); + + let mut blocks: Vec = Vec::new(); + blocks.push(Raw {offset: START, size: 0x13, mem: self.raw[START..START+0x13].to_vec()}); + blocks.push(Raw {offset: START+0x13, size: SIZE, mem: enc}); + + raw.assemble_file(path, blocks)?; Ok(()) }