mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 10:54:38 +00:00
WIP pak init refactor
This commit is contained in:
parent
0b5bded4b4
commit
461bc66c30
4 changed files with 54 additions and 60 deletions
|
@ -6,7 +6,7 @@ pub use {list::list, unpack::unpack, version::version};
|
|||
fn load_pak(
|
||||
path: String,
|
||||
key: Option<String>,
|
||||
) -> Result<unpak::Pak<std::io::BufReader<std::fs::File>>, unpak::Error> {
|
||||
) -> Result<unpak::PakReader<std::io::BufReader<std::fs::File>>, unpak::Error> {
|
||||
use aes::cipher::KeyInit;
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
let key = key
|
||||
|
@ -21,17 +21,5 @@ fn load_pak(
|
|||
})
|
||||
.transpose()?;
|
||||
|
||||
for ver in unpak::Version::iter() {
|
||||
match unpak::Pak::new(
|
||||
std::io::BufReader::new(std::fs::OpenOptions::new().read(true).open(&path)?),
|
||||
ver,
|
||||
key.clone(),
|
||||
) {
|
||||
Ok(pak) => {
|
||||
return Ok(pak);
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
Err(unpak::Error::Other("version unsupported"))
|
||||
unpak::PakReader::new_any( std::io::BufReader::new(std::fs::OpenOptions::new().read(true).open(&path)?), key)
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ pub enum Version {
|
|||
|
||||
// strum shouldn't need to be installed by users
|
||||
impl Version {
|
||||
pub fn iter() -> VersionIter {
|
||||
<Version as strum::IntoEnumIterator>::iter()
|
||||
pub fn iter() -> std::iter::Rev<VersionIter> {
|
||||
<Version as strum::IntoEnumIterator>::iter().rev()
|
||||
}
|
||||
|
||||
pub fn size(self) -> i64 {
|
||||
|
|
47
src/pak.rs
47
src/pak.rs
|
@ -3,12 +3,16 @@ use hashbrown::HashMap;
|
|||
use std::io::{self, Seek};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pak<R: io::Read + io::Seek> {
|
||||
pub struct PakReader<R: io::Read + io::Seek> {
|
||||
pak: Pak,
|
||||
reader: R,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct Pak {
|
||||
version: Version,
|
||||
mount_point: String,
|
||||
key: Option<aes::Aes256Dec>,
|
||||
index: Index,
|
||||
reader: R,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -52,12 +56,34 @@ fn decrypt(key: &Option<aes::Aes256Dec>, bytes: &mut [u8]) -> Result<(), super::
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: io::Read + io::Seek> Pak<R> {
|
||||
impl<R: io::Read + io::Seek> PakReader<R> {
|
||||
pub fn new_any(
|
||||
mut reader: R,
|
||||
key: Option<aes::Aes256Dec>,
|
||||
) -> Result<Self, super::Error> {
|
||||
for ver in Version::iter() {
|
||||
match PakReader::new(
|
||||
&mut reader,
|
||||
ver,
|
||||
key.clone(),
|
||||
) {
|
||||
Ok(pak) => {
|
||||
return Ok(PakReader {
|
||||
pak,
|
||||
reader,
|
||||
});
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
Err(super::Error::Other("version unsupported"))
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
mut reader: R,
|
||||
version: super::Version,
|
||||
key: Option<aes::Aes256Dec>,
|
||||
) -> Result<Self, super::Error> {
|
||||
) -> Result<Pak, super::Error> {
|
||||
use super::ext::ReadExt;
|
||||
use byteorder::{ReadBytesExt, LE};
|
||||
// read footer to get index, encryption & compression info
|
||||
|
@ -174,21 +200,20 @@ impl<R: io::Read + io::Seek> Pak<R> {
|
|||
Index::V1(IndexV1 { entries })
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
Ok(Pak {
|
||||
version,
|
||||
mount_point,
|
||||
key,
|
||||
index,
|
||||
reader,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn version(&self) -> super::Version {
|
||||
self.version
|
||||
self.pak.version
|
||||
}
|
||||
|
||||
pub fn mount_point(&self) -> &str {
|
||||
&self.mount_point
|
||||
&self.pak.mount_point
|
||||
}
|
||||
|
||||
pub fn get(&mut self, path: &str) -> Result<Vec<u8>, super::Error> {
|
||||
|
@ -198,14 +223,14 @@ impl<R: io::Read + io::Seek> Pak<R> {
|
|||
}
|
||||
|
||||
pub fn read<W: io::Write>(&mut self, path: &str, writer: &mut W) -> Result<(), super::Error> {
|
||||
match self.index.entries().get(path) {
|
||||
Some(entry) => entry.read(&mut self.reader, self.version, self.key.as_ref(), writer),
|
||||
match self.pak.index.entries().get(path) {
|
||||
Some(entry) => entry.read(&mut self.reader, self.pak.version, self.pak.key.as_ref(), writer),
|
||||
None => Err(super::Error::Other("no file found at given path")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn files(&self) -> std::vec::IntoIter<String> {
|
||||
self.index
|
||||
self.pak.index
|
||||
.entries()
|
||||
.keys()
|
||||
.cloned()
|
||||
|
|
|
@ -1,38 +1,7 @@
|
|||
fn load_pak(
|
||||
bytes: &[u8],
|
||||
key: Option<String>,
|
||||
) -> Result<unpak::Pak<std::io::Cursor<&[u8]>>, unpak::Error> {
|
||||
use aes::cipher::KeyInit;
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
let key = key
|
||||
.map(|k| {
|
||||
general_purpose::STANDARD
|
||||
.decode(k)
|
||||
.as_ref()
|
||||
.map_err(|_| unpak::Error::Base64)
|
||||
.and_then(|bytes| {
|
||||
aes::Aes256Dec::new_from_slice(bytes).map_err(|_| unpak::Error::Aes)
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
for ver in unpak::Version::iter() {
|
||||
match unpak::Pak::new(std::io::Cursor::new(bytes), ver, key.clone()) {
|
||||
Ok(pak) => {
|
||||
return Ok(pak);
|
||||
}
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(unpak::Error::Other("version unsupported"))
|
||||
}
|
||||
use paste::paste;
|
||||
|
||||
static AES_KEY: &str = "lNJbw660IOC+kU7cnVQ1oeqrXyhk4J6UAZrCBbcnp94=";
|
||||
|
||||
use paste::paste;
|
||||
|
||||
macro_rules! matrix_test {
|
||||
( ($($version:literal $exp_version:expr),* $(,)?), $compress:tt, $encrypt:tt, $encryptindex:tt ) => {
|
||||
$( compress!($version, $exp_version, $compress, $encrypt, $encryptindex); )*
|
||||
|
@ -57,7 +26,19 @@ macro_rules! encryptindex {
|
|||
paste! {
|
||||
#[test]
|
||||
fn [< test_version_ $version $compress $encrypt $encryptindex >]() {
|
||||
let mut pak = load_pak(include_bytes!(concat!("packs/pack_", $version, $compress, $encrypt, $encryptindex, ".pak")), Some(AES_KEY.to_string())).unwrap();
|
||||
use aes::cipher::KeyInit;
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
let key = general_purpose::STANDARD
|
||||
.decode(AES_KEY)
|
||||
.as_ref()
|
||||
.map_err(|_| unpak::Error::Base64)
|
||||
.and_then(|bytes| {
|
||||
aes::Aes256Dec::new_from_slice(bytes).map_err(|_| unpak::Error::Aes)
|
||||
}).unwrap();
|
||||
let mut pak = unpak::PakReader::new_any(
|
||||
std::io::Cursor::new(include_bytes!(concat!("packs/pack_", $version, $compress, $encrypt, $encryptindex, ".pak"))),
|
||||
Some(key),
|
||||
).unwrap();
|
||||
assert_eq!(pak.mount_point(), "../mount/point/root/");
|
||||
assert_eq!(pak.version(), $exp_version);
|
||||
use std::collections::HashSet;
|
||||
|
|
Loading…
Reference in a new issue