implement assemble_file function which assembles, or to be more accurate - patches file on the fly
This commit is contained in:
parent
5aa3b9738c
commit
8787394a26
3 changed files with 70 additions and 2 deletions
|
|
@ -1 +1,2 @@
|
|||
mod raw;
|
||||
pub mod save;
|
||||
50
src/fot/raw.rs
Normal file
50
src/fot/raw.rs
Normal file
|
|
@ -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<Block> with already encoded data to patch file
|
||||
|
||||
pub struct Raw {
|
||||
pub offset: usize,
|
||||
pub size: usize,
|
||||
pub mem: Vec<u8>
|
||||
}
|
||||
|
||||
impl Raw {
|
||||
pub fn load_file(path: &Path) -> Result<Raw> {
|
||||
let mem = fs::read(path)?;
|
||||
|
||||
Ok(Self { offset: 0, size: mem.len(), mem })
|
||||
}
|
||||
|
||||
pub fn assemble_file(&self, path: &Path, blocks: Vec<Raw>) -> 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(())
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Raw> = 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(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue