improve code quality. currently working on world decoding
This commit is contained in:
parent
907ea77b4b
commit
6edd70ecf5
2 changed files with 31 additions and 37 deletions
38
src/main.rs
38
src/main.rs
|
|
@ -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);
|
||||
}
|
||||
30
src/save.rs
30
src/save.rs
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue