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,
None,
)?;
for file in pak.entries.keys() {
println!("{file}")
for file in pak.files() {
println!("{file}");
}
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,
None,
) {
Ok(un_pak::Pak { version, .. }) | Err(un_pak::Error::Version { version, .. }) => {
println!("{}", version);
Ok(pak) => {
println!("{}", pak.version());
break;
}
Err(un_pak::Error::Version { version, .. }) => {
println!("{version}");
break;
}
_ => continue,

View file

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

View file

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

View file

@ -27,18 +27,17 @@ impl<R: io::Read + io::Seek> Pak<R> {
let mut key = None;
// decrypt index if needed
if footer.encrypted {
if let Some(hash) = key_hash {
use aes::cipher::{BlockDecrypt, KeyInit};
match aes::Aes256Dec::new_from_slice(hash) {
Ok(decrypter) => {
for chunk in index.chunks_mut(16) {
decrypter.decrypt_block(aes::Block::from_mut_slice(chunk))
}
key = Some(decrypter);
}
Err(_) => return Err(super::Error::Aes),
}
let Some(hash) = key_hash else {
return Err(super::Error::Encrypted);
};
use aes::cipher::{BlockDecrypt, KeyInit};
let Ok(decrypter)= aes::Aes256Dec::new_from_slice(hash) else {
return Err(super::Error::Aes)
};
for chunk in index.chunks_mut(16) {
decrypter.decrypt_block(aes::Block::from_mut_slice(chunk))
}
key = Some(decrypter);
}
let mut index = io::Cursor::new(index);
let mount_point = index.read_string()?;
@ -72,4 +71,12 @@ impl<R: io::Read + io::Seek> Pak<R> {
.get(path)
.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()
}
}