mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
ok read is broken but now iter impl is there
This commit is contained in:
parent
cf98aa3a60
commit
97469c58ae
6 changed files with 53 additions and 24 deletions
|
@ -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
14
examples/unpack.rs
Normal 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(())
|
||||
}
|
|
@ -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,
|
||||
|
|
14
src/entry.rs
14
src/entry.rs
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
29
src/pak.rs
29
src/pak.rs
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue