mirror of
https://github.com/G2-Games/lbee-utils.git
synced 2025-04-19 23:32:55 -05:00
Made code more maintainable, fixed bugs
This commit is contained in:
parent
1a9a05b004
commit
9e49b22b23
2 changed files with 75 additions and 52 deletions
|
@ -257,7 +257,7 @@ impl Pak {
|
||||||
debug!("remainder {}", remainder);
|
debug!("remainder {}", remainder);
|
||||||
debug!("block_offset {} - expected offset {}", block_offset, entry.offset);
|
debug!("block_offset {} - expected offset {}", block_offset, entry.offset);
|
||||||
output.write_all(&entry.data)?;
|
output.write_all(&entry.data)?;
|
||||||
output.write_all(&vec![0u8; remainder as usize])?;
|
output.write_all(&vec![0u8; remainder])?;
|
||||||
block_offset += block_size as u32;
|
block_offset += block_size as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +331,23 @@ impl Pak {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn replace_by_id(
|
||||||
|
&mut self,
|
||||||
|
id: u32,
|
||||||
|
replacement_bytes: &[u8],
|
||||||
|
) -> Result<(), PakError> {
|
||||||
|
let entry = self.get_entry_by_id(id);
|
||||||
|
let index = if let Some(entry) = entry {
|
||||||
|
entry.index
|
||||||
|
} else {
|
||||||
|
return Err(PakError::IndexError)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.replace(index, replacement_bytes)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the header information from the PAK
|
/// Get the header information from the PAK
|
||||||
pub fn header(&self) -> &Header {
|
pub fn header(&self) -> &Header {
|
||||||
&self.header
|
&self.header
|
||||||
|
@ -350,7 +367,7 @@ impl Pak {
|
||||||
self.entries
|
self.entries
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|e|
|
.find(|e|
|
||||||
e.name.as_ref().is_some_and(|n| n == &name)
|
e.name.as_ref().is_some_and(|n| n == name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +381,6 @@ impl Pak {
|
||||||
self.entries
|
self.entries
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| e.name.as_ref()
|
.any(|e| e.name.as_ref()
|
||||||
.is_some_and(|n| n == &name))
|
.is_some_and(|n| n == name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
use clap::{error::ErrorKind, Error, Parser, Subcommand};
|
use clap::{error::{Error, ErrorKind}, Parser, Subcommand};
|
||||||
use luca_pak::Pak;
|
use luca_pak::Pak;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
@ -31,10 +31,16 @@ enum Commands {
|
||||||
|
|
||||||
/// The name of the file within the PAK you wish to replace.
|
/// The name of the file within the PAK you wish to replace.
|
||||||
/// If not provided, the filename will be used.
|
/// If not provided, the filename will be used.
|
||||||
/// Icompatible with batch mode.
|
/// Incompatible with batch mode, and ID.
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
|
|
||||||
|
/// The ID of the file within the PAK you wish to replace.
|
||||||
|
/// If not provided, the filename will be used.
|
||||||
|
/// Incompatible with batch mode, and name.
|
||||||
|
#[arg(short, long)]
|
||||||
|
id: Option<u32>,
|
||||||
|
|
||||||
/// File or folder to use as a replacement
|
/// File or folder to use as a replacement
|
||||||
#[arg(value_name = "REPLACEMENT")]
|
#[arg(value_name = "REPLACEMENT")]
|
||||||
replacement: PathBuf,
|
replacement: PathBuf,
|
||||||
|
@ -48,44 +54,34 @@ enum Commands {
|
||||||
fn main() {
|
fn main() {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
if !cli.input.is_file() {
|
let mut pak = match Pak::open(&cli.input) {
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
Ok(pak) => pak,
|
||||||
"The input file/folder provided is not a file\n",
|
Err(err) => fmt_error(&format!("Could not open PAK file: {}", err)).exit()
|
||||||
).exit()
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let mut pak = Pak::open(&cli.input).unwrap();
|
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::Extract { output } => {
|
Commands::Extract { output } => {
|
||||||
if !output.is_dir() {
|
if output.exists() && !output.is_dir() {
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
fmt_error("The output given was not a directory").exit()
|
||||||
"The output given was not a directory\n",
|
} else if !output.exists() {
|
||||||
).exit()
|
fs::create_dir(&output).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
for entry in pak.entries() {
|
for entry in pak.entries() {
|
||||||
entry.save(&output).unwrap();
|
entry.save(&output).unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Commands::Replace { batch, name, replacement, output } => {
|
Commands::Replace { batch, name, id, replacement, output } => {
|
||||||
if !output.is_file() {
|
if id.is_some() && name.is_some() {
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
fmt_error("Cannot use ID and name together").exit()
|
||||||
"Replacement output must be a file\n",
|
|
||||||
).exit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if batch {
|
if batch {
|
||||||
if name.is_some() {
|
if name.is_some() || id.is_some() {
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
fmt_error("Cannot use name or ID with batch").exit()
|
||||||
"Cannot use name with batch\n",
|
|
||||||
).exit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !replacement.is_dir() {
|
if !replacement.is_dir() {
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
fmt_error("Batch replacement must be a directory").exit()
|
||||||
"Batch replacement must be a directory\n",
|
|
||||||
).exit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for entry in fs::read_dir(replacement).unwrap() {
|
for entry in fs::read_dir(replacement).unwrap() {
|
||||||
|
@ -97,23 +93,21 @@ fn main() {
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
dbg!(&search_name);
|
let parsed_id: Option<u32> = search_name.parse().ok();
|
||||||
|
|
||||||
// Read in the replacement file to a vec
|
// Read in the replacement file to a vec
|
||||||
let rep_data: Vec<u8> = std::fs::read(entry.path()).unwrap();
|
let rep_data: Vec<u8> = std::fs::read(entry.path()).unwrap();
|
||||||
if let Err(err) = pak.replace_by_name(search_name, &rep_data) {
|
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
// Try replacing by name, if that fails, replace by parsed ID
|
||||||
format!("Failed to replace file in PAK: {}\n", err),
|
if pak.replace_by_name(search_name, &rep_data).is_err() {
|
||||||
).exit()
|
fmt_error("Could not replace entry in PAK: Could not find name").print().unwrap()
|
||||||
|
} else if parsed_id.is_some() && pak.replace_by_id(parsed_id.unwrap(), &rep_data).is_err() {
|
||||||
|
fmt_error("Could not replace entry in PAK: ID is invalid").print().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pak.save(&output).unwrap();
|
|
||||||
} else {
|
} else {
|
||||||
if !replacement.is_file() {
|
if !replacement.is_file() {
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
fmt_error("Replacement input must be a file").exit()
|
||||||
"Replacement input must be a file\n",
|
|
||||||
).exit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let search_name = if let Some(name) = name {
|
let search_name = if let Some(name) = name {
|
||||||
|
@ -126,24 +120,36 @@ fn main() {
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let search_id = if id.is_some() {
|
||||||
|
id
|
||||||
|
} else if let Ok(id) = search_name.parse::<u32>() {
|
||||||
|
Some(id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
// Read in the replacement file to a vec
|
// Read in the replacement file to a vec
|
||||||
let rep_data: Vec<u8> = std::fs::read(replacement).unwrap();
|
let rep_data: Vec<u8> = std::fs::read(replacement).unwrap();
|
||||||
if let Err(err) = pak.replace_by_name(search_name, &rep_data) {
|
if id.is_some() {
|
||||||
Error::raw(ErrorKind::ValueValidation,
|
if pak.replace_by_id(search_id.unwrap(), &rep_data).is_err() {
|
||||||
format!("Failed to replace file in PAK: {}\n", err),
|
fmt_error("Could not replace entry in PAK: ID is invalid").exit()
|
||||||
).exit()
|
}
|
||||||
|
} else if pak.replace_by_name(search_name, &rep_data).is_err() {
|
||||||
|
fmt_error("Could not replace entry in PAK: Could not find name").exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
pak.save(&output).unwrap();
|
pak.save(&output).unwrap();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
pak.save(&output).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/*
|
|
||||||
let rep_cz_data: Vec<u8> = std::fs::read("en_manual01_Linkto_2_6.cz1").unwrap();
|
#[inline(always)]
|
||||||
pak.replace(4, &rep_cz_data).unwrap();
|
fn fmt_error(message: &str) -> Error {
|
||||||
|
Error::raw(
|
||||||
let mut output = BufWriter::new(File::create("MANUAL-modified.PAK").unwrap());
|
ErrorKind::ValueValidation,
|
||||||
pak.encode(&mut output).unwrap();
|
format!("{}\n", message),
|
||||||
*/
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue