2
0
mirror of https://github.com/dpethes/rerogue.git synced 2025-06-07 18:58:32 +02:00

add bundle unpacker

This commit is contained in:
dpethes 2015-01-25 17:03:47 +01:00
parent ce9c38a111
commit b867d6891a
3 changed files with 111 additions and 0 deletions

4
bundle_pack/Cargo.lock generated Normal file
View File

@ -0,0 +1,4 @@
[root]
name = "bundle_pack"
version = "0.0.1"

5
bundle_pack/Cargo.toml Normal file
View File

@ -0,0 +1,5 @@
[package]
name = "bundle_pack"
version = "0.0.1"
authors = ["dpethes <dejvu@email.cz>"]

102
bundle_pack/src/main.rs Normal file
View File

@ -0,0 +1,102 @@
#![allow(unstable)]
extern crate core;
extern crate collections;
use std::io::File;
use std::os;
use collections::string::String;
struct FileEntry {
filename: String,
length: u32,
offset: u32
}
fn unpack_bundle(fpath: &Path) {
// check file magic
let mut f = File::open(fpath).unwrap();
let mut magic = String::new();
for i in 0..4 {
let c:u8 = f.read_u8().unwrap();
magic.push(c as char);
}
println!("Magic: {}", magic);
// file data size (= filesize - 8)
let asize = f.read_be_u32().unwrap();
println!("Archive size: {}", asize);
// bundle header
let mut bheader = String::new();
for i in 0..4 {
let c:u8 = f.read_u8().unwrap();
bheader.push(c as char);
}
let bsize = f.read_be_u32().unwrap();
println!("Bundle header: {} size: {}", bheader, bsize);
// skip padding
f.seek(65570, std::io::SeekStyle::SeekCur);
// read file entries
let file_entries = (bsize - 65570) / 252;
println!("File entries: {}", file_entries);
let mut files = Vec::new();
for i in 0..file_entries {
let mut fname = String::new();
let input_fname = f.read_exact(200).unwrap();
for byte in input_fname.iter() {
let c = byte ^ 0xAA;
if c == 0 {
break;
}
fname.push(c as char);
}
let fsize = f.read_le_u32().unwrap();
let foffset = f.read_le_u32().unwrap();
println!("File name: {} offset: {} size: {}", fname, foffset, fsize);
f.read_exact(44).unwrap();
let file = FileEntry {filename: fname, length: fsize, offset: foffset};
files.push(file);
}
// bundle data
let mut bdata = String::new();
for i in 0..4 {
let c:u8 = f.read_u8().unwrap();
bdata.push(c as char);
}
let bdata_size = f.read_be_u32().unwrap();
println!("Bundle data: {} size: {}", bdata, bdata_size);
// unpack files
let base_pos = f.tell().unwrap();
for file in files.iter() {
let mut split = file.filename.split_str("\\");
let vec: Vec<&str> = split.collect();
let last = vec[vec.len() - 1];
println!("File name: {} offset: {} size: {}", last, file.offset, file.length);
let fpos = base_pos + file.offset as u64;
f.seek((fpos as i64), std::io::SeekStyle::SeekSet);
let databytes = f.read_exact(file.length as usize).unwrap();
let mut fdest = File::create(&Path::new(last));
fdest.write(databytes.as_slice());
}
}
fn main() {
let args = os::args();
if args.len() < 2 {
println!("No input specified!"); //first param = path
unpack_bundle(&Path::new("BUNDLE.000")); //debug - remove
} else {
println!("Trying to parse file {0}", args[1]);
let ref fpath = args[1];
unpack_bundle(&Path::new(fpath));
}
print!("Done.");
}