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;
|
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 anyhow::Result;
|
||||||
use inflate::inflate_bytes_zlib;
|
use inflate::inflate_bytes_zlib;
|
||||||
use deflate::deflate_bytes_zlib;
|
use deflate::deflate_bytes_zlib;
|
||||||
|
use crate::fot::raw::Raw;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct World {
|
pub struct World {
|
||||||
|
|
@ -93,7 +94,8 @@ impl Save {
|
||||||
file.write(&world.encode())?;
|
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 END: usize = 0xD1B1E; //0xD1B1E;
|
||||||
const SIZE: usize = 0x38088;
|
const SIZE: usize = 0x38088;
|
||||||
//let world = self.worlds.last().unwrap();
|
//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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue