ok read is broken but now iter impl is there

This commit is contained in:
spuds 2023-01-14 14:20:00 +00:00
parent cf98aa3a60
commit 97469c58ae
6 changed files with 53 additions and 24 deletions

View file

@ -4,8 +4,8 @@ fn main() -> Result<(), un_pak::Error> {
un_pak::Version::CompressionEncryption, un_pak::Version::CompressionEncryption,
None, None,
)?; )?;
for file in pak.entries.keys() { for file in pak.files() {
println!("{file}") println!("{file}");
} }
Ok(()) Ok(())
} }

14
examples/unpack.rs Normal file
View file

@ -0,0 +1,14 @@
fn main() -> Result<(), un_pak::Error> {
let mut pak = un_pak::Pak::new(
std::io::BufReader::new(std::io::Cursor::new(include_bytes!("rando_p.pak"))),
un_pak::Version::CompressionEncryption,
None,
)?;
for file in pak.files() {
match pak.get(&file).expect("file should be in pak") {
Ok(data) => std::fs::write(&file, data)?,
Err(e) => eprintln!("{e}"),
}
}
Ok(())
}

View file

@ -7,8 +7,12 @@ fn main() -> Result<(), un_pak::Error> {
ver, ver,
None, None,
) { ) {
Ok(un_pak::Pak { version, .. }) | Err(un_pak::Error::Version { version, .. }) => { Ok(pak) => {
println!("{}", version); println!("{}", pak.version());
break;
}
Err(un_pak::Error::Version { version, .. }) => {
println!("{version}");
break; break;
} }
_ => continue, _ => continue,

View file

@ -72,19 +72,21 @@ impl Entry {
) -> Result<Vec<u8>, super::Error> { ) -> Result<Vec<u8>, super::Error> {
let mut buf = io::BufWriter::new(Vec::with_capacity(self.uncompressed as usize)); let mut buf = io::BufWriter::new(Vec::with_capacity(self.uncompressed as usize));
reader.seek(io::SeekFrom::Start(self.offset))?; reader.seek(io::SeekFrom::Start(self.offset))?;
Entry::new(reader, version)?;
let mut data = reader.read_len(match self.encrypted { let mut data = reader.read_len(match self.encrypted {
// add alignment (aes block size: 16) then zero out alignment bits // add alignment (aes block size: 16) then zero out alignment bits
true => (self.compressed + 15) & !17, true => (self.compressed + 15) & !17,
false => self.compressed, false => self.compressed,
} as usize)?; } as usize)?;
if self.encrypted { if self.encrypted {
if let Some(key) = key { let Some(key) = key else {
use aes::cipher::BlockDecrypt; return Err(super::Error::Encrypted);
for block in data.chunks_mut(16) { };
key.decrypt_block(aes::Block::from_mut_slice(block)) use aes::cipher::BlockDecrypt;
} for block in data.chunks_mut(16) {
data.truncate(self.compressed as usize); key.decrypt_block(aes::Block::from_mut_slice(block))
} }
data.truncate(self.compressed as usize);
} }
use io::Write; use io::Write;
match self.compression { match self.compression {

View file

@ -14,16 +14,18 @@ pub enum Error {
Utf16(#[from] std::string::FromUtf16Error), Utf16(#[from] std::string::FromUtf16Error),
#[error("bufwriter dereference: {0}")] #[error("bufwriter dereference: {0}")]
IntoInner(#[from] std::io::IntoInnerError<std::io::BufWriter<Vec<u8>>>), IntoInner(#[from] std::io::IntoInnerError<std::io::BufWriter<Vec<u8>>>),
#[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)]
// crate errors // crate errors
#[error("got {0}, which is not a boolean")]
Bool(u8),
#[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)]
Magic(u32), Magic(u32),
#[error("used version {used} but pak is version {version}")] #[error("used version {used} but pak is version {version}")]
Version { Version {
used: super::Version, used: super::Version,
version: super::Version, version: super::Version,
}, },
#[error("got {0}, which is not a boolean")] #[error("pak is encrypted but no key was provided")]
Bool(u8), Encrypted,
#[error("{0}")] #[error("{0}")]
Other(String), Other(String),
} }

View file

@ -27,18 +27,17 @@ impl<R: io::Read + io::Seek> Pak<R> {
let mut key = None; let mut key = None;
// decrypt index if needed // decrypt index if needed
if footer.encrypted { if footer.encrypted {
if let Some(hash) = key_hash { let Some(hash) = key_hash else {
use aes::cipher::{BlockDecrypt, KeyInit}; return Err(super::Error::Encrypted);
match aes::Aes256Dec::new_from_slice(hash) { };
Ok(decrypter) => { use aes::cipher::{BlockDecrypt, KeyInit};
for chunk in index.chunks_mut(16) { let Ok(decrypter)= aes::Aes256Dec::new_from_slice(hash) else {
decrypter.decrypt_block(aes::Block::from_mut_slice(chunk)) return Err(super::Error::Aes)
} };
key = Some(decrypter); for chunk in index.chunks_mut(16) {
} decrypter.decrypt_block(aes::Block::from_mut_slice(chunk))
Err(_) => return Err(super::Error::Aes),
}
} }
key = Some(decrypter);
} }
let mut index = io::Cursor::new(index); let mut index = io::Cursor::new(index);
let mount_point = index.read_string()?; let mount_point = index.read_string()?;
@ -72,4 +71,12 @@ impl<R: io::Read + io::Seek> Pak<R> {
.get(path) .get(path)
.map(|entry| entry.read(&mut self.reader, self.version, self.key.as_ref())) .map(|entry| entry.read(&mut self.reader, self.version, self.key.as_ref()))
} }
pub fn files(&self) -> std::vec::IntoIter<String> {
self.entries
.keys()
.cloned()
.collect::<Vec<String>>()
.into_iter()
}
} }