mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
add compression and oodle features
This commit is contained in:
parent
03dd3a63ed
commit
f2c2255d53
6 changed files with 40 additions and 15 deletions
|
@ -6,19 +6,24 @@ license.workspace = true
|
|||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["compression"]
|
||||
compression = ["dep:flate2", "dep:zstd"]
|
||||
oodle = ["dep:libloading", "dep:ureq", "dep:once_cell", "dep:hex-literal", "dep:hex"]
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.4"
|
||||
aes = "0.8"
|
||||
flate2 = "1.0"
|
||||
flate2 = { version = "1.0", optional = true }
|
||||
zstd = { version = "0.12", optional = true }
|
||||
thiserror = "1.0"
|
||||
sha1 = "0.10.5"
|
||||
strum = { workspace = true }
|
||||
libloading = "0.7.4"
|
||||
ureq = "2.6.2"
|
||||
hex-literal = "0.4.1"
|
||||
hex = { workspace = true }
|
||||
once_cell = "1.17.1"
|
||||
zstd = "0.12.3"
|
||||
libloading = { version = "0.7", optional = true }
|
||||
ureq = { version = "2.6", optional = true }
|
||||
once_cell = { version = "1.17", optional = true}
|
||||
hex-literal = { version = "0.4", optional = true }
|
||||
hex = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
base64 = { workspace = true }
|
||||
|
|
|
@ -350,6 +350,7 @@ impl Entry {
|
|||
None => vec![0..data.len()],
|
||||
};
|
||||
|
||||
#[cfg(feature = "compression")]
|
||||
macro_rules! decompress {
|
||||
($decompressor: ty) => {
|
||||
for range in ranges {
|
||||
|
@ -359,14 +360,18 @@ impl Entry {
|
|||
}
|
||||
|
||||
match self.compression.map(|c| compression[c as usize]) {
|
||||
None => buf.write_all(&data)?,
|
||||
None | Some(Compression::None) => buf.write_all(&data)?,
|
||||
#[cfg(feature = "compression")]
|
||||
Some(Compression::Zlib) => decompress!(flate2::read::ZlibDecoder<&[u8]>),
|
||||
#[cfg(feature = "compression")]
|
||||
Some(Compression::Gzip) => decompress!(flate2::read::GzDecoder<&[u8]>),
|
||||
#[cfg(feature = "compression")]
|
||||
Some(Compression::Zstd) => {
|
||||
for range in ranges {
|
||||
io::copy(&mut zstd::stream::read::Decoder::new(&data[range])?, buf)?;
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "oodle")]
|
||||
Some(Compression::Oodle) => {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
return Err(super::Error::Oodle);
|
||||
|
@ -472,18 +477,25 @@ impl Entry {
|
|||
buf.write_all(&decompressed)?;
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
#[cfg(not(feature = "oodle"))]
|
||||
Some(Compression::Oodle) => return Err(super::Error::Oodle),
|
||||
#[cfg(not(feature = "compression"))]
|
||||
_ => return Err(super::Error::Compression),
|
||||
}
|
||||
buf.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
use once_cell::sync::Lazy;
|
||||
#[cfg(feature = "oodle")]
|
||||
static OODLE: Lazy<Result<libloading::Library, String>> =
|
||||
Lazy::new(|| get_oodle().map_err(|e| e.to_string()));
|
||||
#[cfg(feature = "oodle")]
|
||||
static OODLE_HASH: [u8; 20] = hex_literal::hex!("4bcc73614cb8fd2b0bce8d0f91ee5f3202d9d624");
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
fn get_oodle() -> Result<libloading::Library, super::Error> {
|
||||
use sha1::{Digest, Sha1};
|
||||
|
||||
|
|
|
@ -9,6 +9,13 @@ pub enum Error {
|
|||
#[error("expect 256 bit AES key as base64 or hex string")]
|
||||
Aes,
|
||||
|
||||
// feature errors
|
||||
#[error("enable the compression feature to read compressed paks")]
|
||||
Compression,
|
||||
|
||||
#[error("enable the oodle feature to read oodle paks")]
|
||||
Oodle,
|
||||
|
||||
// std errors
|
||||
#[error("io error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
@ -22,6 +29,7 @@ pub enum Error {
|
|||
#[error("utf16 conversion: {0}")]
|
||||
Utf16(#[from] std::string::FromUtf16Error),
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
#[error("ureq error: {0}")]
|
||||
Ureq(#[from] Box<ureq::Error>), // boxed because ureq::Error is quite large
|
||||
|
||||
|
@ -35,9 +43,6 @@ pub enum Error {
|
|||
#[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)]
|
||||
Magic(u32),
|
||||
|
||||
#[error("Oodle compression only supported on Windows (or WINE)")]
|
||||
Oodle,
|
||||
|
||||
#[error("Could not load oo2core_9_win64.dll")]
|
||||
OodleFailed,
|
||||
|
||||
|
@ -72,7 +77,7 @@ pub enum Error {
|
|||
OsString(std::ffi::OsString),
|
||||
|
||||
#[error("{0}version unsupported or is encrypted (possibly missing --aes-key?)")]
|
||||
UnsuportedOrEncrypted(String),
|
||||
UnsupportedOrEncrypted(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
|
|
|
@ -7,6 +7,9 @@ mod pak;
|
|||
|
||||
pub use {error::*, pak::*};
|
||||
|
||||
#[cfg(all(feature = "oodle", not(target_os = "windows")))]
|
||||
compile_error!("Oodle compression only supported on Windows (or WINE)");
|
||||
|
||||
pub const MAGIC: u32 = 0x5A6F12E1;
|
||||
|
||||
#[derive(
|
||||
|
|
|
@ -96,7 +96,7 @@ impl PakReader {
|
|||
Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?,
|
||||
}
|
||||
}
|
||||
Err(super::Error::UnsuportedOrEncrypted(log))
|
||||
Err(super::Error::UnsupportedOrEncrypted(log))
|
||||
}
|
||||
|
||||
pub fn new<R: Read + Seek>(
|
||||
|
|
|
@ -19,6 +19,6 @@ indicatif = { version = "0.17.3", features = ["rayon"] }
|
|||
path-clean = "0.1.0"
|
||||
path-slash = "0.2.1"
|
||||
rayon = "1.6.1"
|
||||
repak = { version = "0.1.7", path = "../repak" }
|
||||
repak = { version = "0.1.7", path = "../repak", features = ["oodle"] }
|
||||
sha2 = "0.10.7"
|
||||
strum = { workspace = true }
|
||||
|
|
Loading…
Reference in a new issue