improve code quality. currently working on world decoding

This commit is contained in:
mykola2312 2023-08-22 09:54:29 +03:00
parent 907ea77b4b
commit 6edd70ecf5
2 changed files with 31 additions and 37 deletions

View file

@ -1,42 +1,16 @@
use std::env;
use std::str;
use std::fs;
use inflate::inflate_bytes_zlib;
use std::path::Path;
pub mod save;
use save::Save;
fn main() {
let args: Vec<_> = env::args().collect();
let save_path = args.get(1).unwrap();
let out_path = match args.get(2) {
/*let out_path = match args.get(2) {
Some(path) => path,
None => "out.bin"
};
};*/
let save_buf = fs::read(save_path).unwrap();
let size = save_buf.len();
let mut offset = size;
for i in (0..size - 7).rev() {
let header = match str::from_utf8(&save_buf[i..i+7]) {
Ok(header) => header,
Err(_) => continue
};
if header == "<world>" {
offset = i;
break;
}
}
if offset == size {
panic!("Didn't find any world header");
} else {
println!("Found offset 0x{:x}", offset);
}
// offset+0x13 - deflate
match inflate_bytes_zlib(&save_buf[offset+0x13..]) {
Ok(out_buf) => fs::write(out_path, &out_buf).expect("out_buf"),
Err(e) => panic!("{}", e)
};
let save = Save::load(Path::new(save_path)).expect("load save");
dbg!(save);
}

View file

@ -5,29 +5,39 @@ use anyhow::anyhow;
use anyhow::Result;
use inflate::inflate_bytes_zlib;
struct World {
#[derive(Debug)]
pub struct World {
offset: usize,
size: usize,
data: Vec<u8>
}
impl World {
const DATA_OFFSET: usize = 0x13;
fn decode(raw: &[u8], offset: usize, size: usize) -> Result<Self> {
let data = inflate_bytes_zlib(&raw[offset..offset+size])
let data_offset = offset + World::DATA_OFFSET;
let data = inflate_bytes_zlib(&raw[data_offset..data_offset+size])
.map_err(|e| anyhow!(e))?;
Ok(Self { offset, size, data })
}
pub fn dump(&self, path: &Path) -> Result<()> {
Ok(fs::write(path, &self.data)?)
}
}
struct Save {
#[derive(Debug)]
pub struct Save {
raw: Vec<u8>,
worlds: Vec<World>
}
impl Save {
fn load(path: &Path) -> Result<Self> {
pub fn load(path: &Path) -> Result<Self> {
let raw = fs::read(path)?;
let file_end = raw.len() - 1;
let mut offsets: Vec<usize> = Vec::new();
for i in 0..raw.len()-7 {
let keyword = match str::from_utf8(&raw[i..i+7]) {
@ -40,6 +50,16 @@ impl Save {
}
}
Ok(Self { raw, worlds: Vec::new() })
let mut worlds: Vec<World> = Vec::new();
for i in offsets.chunks(2) {
let offset = i[0];
let size = i.get(1).unwrap_or(&file_end);
match World::decode(&raw, offset, *size) {
Ok(world) => worlds.push(world),
Err(e) => println!("world 0x{:x} decode error {}", offset, e)
};
}
Ok(Self { raw, worlds })
}
}