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,
|
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
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,
|
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,
|
||||||
|
|
14
src/entry.rs
14
src/entry.rs
|
@ -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 {
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
29
src/pak.rs
29
src/pak.rs
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue