mirror of
https://github.com/NinjaCheetah/rustii.git
synced 2025-06-06 15:31:02 -04:00
U8 archive unpacking command now functional
This commit is contained in:
parent
884657268b
commit
7cef25d8f0
@ -19,18 +19,18 @@ pub enum U8Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct U8Node {
|
pub struct U8Node {
|
||||||
node_type: u8,
|
pub node_type: u8,
|
||||||
name_offset: u32, // This is really type u24, so the most significant byte will be ignored.
|
pub name_offset: u32, // This is really type u24, so the most significant byte will be ignored.
|
||||||
data_offset: u32,
|
pub data_offset: u32,
|
||||||
size: u32,
|
pub size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct U8Archive {
|
pub struct U8Archive {
|
||||||
u8_nodes: Vec<U8Node>,
|
pub u8_nodes: Vec<U8Node>,
|
||||||
file_names: Vec<String>,
|
pub file_names: Vec<String>,
|
||||||
file_data: Vec<Vec<u8>>,
|
pub file_data: Vec<Vec<u8>>,
|
||||||
root_node_offset: u32,
|
root_node_offset: u32,
|
||||||
header_size: u32,
|
header_size: u32,
|
||||||
data_offset: u32,
|
data_offset: u32,
|
||||||
|
@ -37,8 +37,59 @@ pub fn unpack_u8_archive(input: &str, output: &str) -> Result<()> {
|
|||||||
if !in_path.exists() {
|
if !in_path.exists() {
|
||||||
bail!("Source U8 archive \"{}\" could not be found.", input);
|
bail!("Source U8 archive \"{}\" could not be found.", input);
|
||||||
}
|
}
|
||||||
let u8_data = u8::U8Archive::from_bytes(&fs::read(in_path)?)?;
|
let out_path = PathBuf::from(output);
|
||||||
println!("{:?}", u8_data);
|
if out_path.exists() {
|
||||||
fs::write(Path::new(output), u8_data.to_bytes()?)?;
|
if !out_path.is_dir() {
|
||||||
|
bail!("A file already exists with the specified directory name!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fs::create_dir(&out_path).with_context(|| format!("The output directory \"{}\" could not be created.", out_path.display()))?;
|
||||||
|
}
|
||||||
|
let u8_archive = u8::U8Archive::from_bytes(&fs::read(in_path).with_context(|| format!("Failed to open U8 archive \"{}\" for reading.", in_path.display()))?)?;
|
||||||
|
// This stores the path we're actively writing files to.
|
||||||
|
let mut current_dir = out_path.clone();
|
||||||
|
// This is the order of directory nodes we've traversed down.
|
||||||
|
let mut parent_dirs: Vec<u32> = Vec::from([0]);
|
||||||
|
for i in 0..u8_archive.u8_nodes.len() {
|
||||||
|
match u8_archive.u8_nodes[i].node_type {
|
||||||
|
1 => {
|
||||||
|
// Code for a directory node.
|
||||||
|
if u8_archive.u8_nodes[i].name_offset != 0 {
|
||||||
|
// If we're already at the correct level, make a new directory and push it to
|
||||||
|
// the parent_dirs vec.
|
||||||
|
if u8_archive.u8_nodes[i].data_offset == *parent_dirs.last().unwrap() {
|
||||||
|
current_dir = current_dir.join(&u8_archive.file_names[i]);
|
||||||
|
if !current_dir.exists() {
|
||||||
|
fs::create_dir(¤t_dir).with_context(|| format!("Failed to create directory \"{}\".", current_dir.display()))?;
|
||||||
|
}
|
||||||
|
parent_dirs.push(i as u32);
|
||||||
|
}
|
||||||
|
// Otherwise, go back up the path until we're at the correct level.
|
||||||
|
else {
|
||||||
|
while u8_archive.u8_nodes[i].data_offset != *parent_dirs.last().unwrap() {
|
||||||
|
parent_dirs.pop();
|
||||||
|
}
|
||||||
|
parent_dirs.push(i as u32);
|
||||||
|
current_dir = out_path.clone();
|
||||||
|
// Rebuild current working directory, and make sure all directories in the
|
||||||
|
// path exist.
|
||||||
|
for dir in &parent_dirs {
|
||||||
|
current_dir = current_dir.join(&u8_archive.file_names[*dir as usize]);
|
||||||
|
if !current_dir.exists() {
|
||||||
|
fs::create_dir(¤t_dir).with_context(|| format!("Failed to create directory \"{}\".", current_dir.display()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
0 => {
|
||||||
|
// Code for a file node.
|
||||||
|
fs::write(current_dir.join(&u8_archive.file_names[i]), &u8_archive.file_data[i])
|
||||||
|
.with_context(|| format!("Failed to write file \"{}\" in directory \"{}\".", u8_archive.file_names[i], current_dir.display()))?;
|
||||||
|
},
|
||||||
|
_ => bail!("Node at index {} has an invalid type! U8 archive cannot be unpacked.", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("Successfully unpacked U8 archive to directory \"{}\"!", out_path.display());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user