diff --git a/luca_pak/src/lib.rs b/luca_pak/src/lib.rs index ce88517..3a98d97 100644 --- a/luca_pak/src/lib.rs +++ b/luca_pak/src/lib.rs @@ -25,6 +25,9 @@ pub enum PakError { #[error("Malformed header information")] HeaderError, + + #[error("Index not found")] + IndexError, } /// A full PAK file with a header and its contents @@ -196,7 +199,10 @@ impl Pak { }) } - pub fn encode(&self, mut output: &mut T) -> Result<(), PakError> { + pub fn encode( + &self, + mut output: &mut T + ) -> Result<(), PakError> { let mut block_offset = 0; self.header.write_into(&mut output)?; @@ -250,6 +256,34 @@ impl Pak { Ok(()) } + pub fn replace( + &mut self, + index: usize, + replacement_bytes: &[u8] + ) -> Result<(), PakError> { + let block_size = self.header().block_size(); + + let replaced_entry = if let Some(entry) = self.entries.get_mut(index) { + entry + } else { + return Err(PakError::IndexError) + }; + + // Replace the entry data + replaced_entry.data = replacement_bytes.to_vec(); + replaced_entry.length = replaced_entry.data.len() as u32; + + let mut next_offset = replaced_entry.offset + replaced_entry.length.div_ceil(block_size); + + for entry in self.entries.iter_mut().skip(index + 1) { + entry.offset = next_offset; + + next_offset = entry.offset + entry.length.div_ceil(block_size); + } + + Ok(()) + } + /// Get the header information from the PAK pub fn header(&self) -> &Header { &self.header diff --git a/luca_pak/src/main.rs b/luca_pak/src/main.rs index 97184b9..ff26529 100644 --- a/luca_pak/src/main.rs +++ b/luca_pak/src/main.rs @@ -1,4 +1,4 @@ -use std::{fs::File, io::BufWriter}; +use std::{fs::File, io::{BufWriter, Read}}; use luca_pak::Pak; fn main() { @@ -38,14 +38,19 @@ fn main() { } */ - let pak = Pak::open("MANUAL.PAK").unwrap(); - println!("{:#?}", pak.header()); + let mut pak = Pak::open("MANUAL.PAK").unwrap(); + //println!("{:#?}", pak.header()); //println!("{:#032b}", pak.header().flags().0); + /* for (i, entry) in pak.entries().iter().enumerate() { - //println!("{i:03}: {:06.2} kB - {}", entry.len() as f32 / 1_000.0, entry.name().as_ref().unwrap()); + println!("{i:03}: {:06.2} kB - {}", entry.len() as f32 / 1_000.0, entry.name().as_ref().unwrap()); entry.save("./output/").unwrap(); } + */ + + let rep_cz_data: Vec = std::fs::read("en_manual01_Linkto_2_6").unwrap(); + pak.replace(4, &rep_cz_data).unwrap(); let mut output = BufWriter::new(File::create("MANUAL-modified.PAK").unwrap()); pak.encode(&mut output).unwrap();