Created
July 29, 2019 08:28
-
-
Save andrewmd5/e2caf1ff81157f7e804239896a338712 to your computer and use it in GitHub Desktop.
Tiny Rust program to parse a knytt.bin file, printing its contents.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashMap; | |
use std::fs::File; | |
use std::io::Read; | |
fn main() -> std::io::Result<()> { | |
if let Ok(mut file) = | |
File::open("E:/Knytt Stories/Test/Drakkan - Training Groundv3rev.knytt.bin") | |
{ | |
let mut files = HashMap::new(); | |
let mut data: Vec<u8> = Vec::new(); | |
let bin_size = file.read_to_end(&mut data)?; | |
let mut offset = 0; | |
let mut root_directory = String::from(""); | |
//checks for the Knytt Stories header | |
if data[0] as char == 'N' && data[1] as char == 'F' { | |
offset = 2; //read two chars, move up by two. | |
//builds the root directory name until an invalid char is reached. | |
while data[offset - 1] as u8 != 0 { | |
root_directory.push(data[offset] as char); | |
offset += 1; | |
} | |
//there is a weird int here, just skip it. | |
offset += 4; | |
//start looping from the file | |
while offset < bin_size { | |
//there is another header each section we skip | |
offset += 2; // skip other header' | |
let mut file_name = String::from(""); | |
//builds the file name until an invalid char is reached. | |
while data[offset - 1] as u8 != 0 { | |
let file_character = data[offset] as char; | |
file_name.push(if file_character == '\\' { | |
'/' | |
} else { | |
file_character | |
}); | |
offset += 1; | |
} | |
//assembles the file size from a compressed int. | |
let file_size = data[offset] as u32 | |
+ data[offset + 1] as u32 * 256 | |
+ data[offset + 2] as u32 * 65536 | |
+ data[offset + 3] as u32 * 16777216; | |
offset += 4; //as if we read an int, move up four bytes. | |
files.insert(file_name, file_size); | |
offset += file_size as usize; //let's pretend we're actually reading the file data. | |
} | |
for (k, v) in files.iter() { | |
println!( | |
"File Name {root}->{file}{size}", | |
root = root_directory, | |
file = k, | |
size = v | |
); | |
} | |
} | |
} | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment