mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 02:54:36 +00:00
Don't store oodle as a global
This commit is contained in:
parent
95b4f35b0d
commit
c84be27763
5 changed files with 37 additions and 30 deletions
|
@ -22,11 +22,11 @@ type OodleLZ_Decompress = unsafe extern "win64" fn(
|
|||
threadPhase: u32,
|
||||
) -> i32;
|
||||
|
||||
pub fn decompress() -> OodleDecompress {
|
||||
pub fn decompress() -> Result<OodleDecompress, Box<dyn std::error::Error>> {
|
||||
#[cfg(windows)]
|
||||
return windows_oodle::decompress_wrapper_windows;
|
||||
return Ok(windows_oodle::decompress_wrapper_windows);
|
||||
#[cfg(unix)]
|
||||
return linux_oodle::oodle_loader_linux();
|
||||
return Ok(linux_oodle::oodle_loader_linux());
|
||||
}
|
||||
|
||||
fn call_decompress(comp_buf: &[u8], raw_buf: &mut [u8], decompress: OodleLZ_Decompress) -> i32 {
|
||||
|
|
|
@ -10,6 +10,7 @@ edition.workspace = true
|
|||
default = ["compression", "encryption"]
|
||||
compression = ["dep:flate2", "dep:zstd"]
|
||||
oodle = []
|
||||
oodle_loader = ["dep:oodle_loader"]
|
||||
encryption = ["dep:aes"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -17,10 +18,10 @@ byteorder = "1.4"
|
|||
aes = { workspace = true, optional = true }
|
||||
flate2 = { version = "1.0", optional = true }
|
||||
zstd = { version = "0.12", optional = true }
|
||||
oodle_loader = { path = "../oodle_loader", optional = true}
|
||||
thiserror = "1.0"
|
||||
sha1 = { workspace = true }
|
||||
strum = { workspace = true }
|
||||
once_cell = "1.18"
|
||||
|
||||
[dev-dependencies]
|
||||
base64 = { workspace = true }
|
||||
|
|
|
@ -306,6 +306,7 @@ impl Entry {
|
|||
version: Version,
|
||||
compression: &[Compression],
|
||||
#[allow(unused)] key: &super::Key,
|
||||
#[allow(unused)] oodle: &super::Oodle,
|
||||
buf: &mut W,
|
||||
) -> Result<(), super::Error> {
|
||||
reader.seek(io::SeekFrom::Start(self.offset))?;
|
||||
|
@ -375,10 +376,11 @@ impl Entry {
|
|||
}
|
||||
}
|
||||
#[cfg(feature = "oodle")]
|
||||
Some(Compression::Oodle) => unsafe {
|
||||
let Some(ref oodle) = super::OODLE else {
|
||||
return Err(super::Error::OodleFailed);
|
||||
};
|
||||
Some(Compression::Oodle) => {
|
||||
let oodle = match oodle {
|
||||
crate::Oodle::Some(getter) => getter().map_err(|_| super::Error::OodleFailed),
|
||||
crate::Oodle::None => Err(super::Error::OodleFailed),
|
||||
}?;
|
||||
let mut decompressed = vec![0; self.uncompressed as usize];
|
||||
|
||||
let mut compress_offset = 0;
|
||||
|
@ -408,7 +410,7 @@ impl Entry {
|
|||
"Oodle decompression length mismatch"
|
||||
);
|
||||
buf.write_all(&decompressed)?;
|
||||
},
|
||||
}
|
||||
#[cfg(not(feature = "oodle"))]
|
||||
Some(Compression::Oodle) => return Err(super::Error::Oodle),
|
||||
#[cfg(not(feature = "compression"))]
|
||||
|
|
|
@ -10,10 +10,13 @@ pub use {error::*, pak::*};
|
|||
pub const MAGIC: u32 = 0x5A6F12E1;
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
static mut OODLE: Option<once_cell::sync::Lazy<OodleDecompress>> = None;
|
||||
mod oodle {
|
||||
pub type OodleGetter = fn() -> Result<OodleDecompress, Box<dyn std::error::Error>>;
|
||||
pub type OodleDecompress = fn(comp_buf: &[u8], raw_buf: &mut [u8]) -> i32;
|
||||
}
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
type OodleDecompress = fn(comp_buf: &[u8], raw_buf: &mut [u8]) -> i32;
|
||||
#[cfg(feature = "oodle_loader")]
|
||||
pub use oodle_loader;
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
|
@ -127,10 +130,11 @@ pub enum Compression {
|
|||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) enum Key {
|
||||
#[cfg(feature = "encryption")]
|
||||
Some(aes::Aes256),
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
|
@ -141,13 +145,10 @@ impl From<aes::Aes256> for Key {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
pub(crate) enum Oodle<'func> {
|
||||
Some(&'func OodleDecompress),
|
||||
None,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "oodle"))]
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) enum Oodle {
|
||||
#[cfg(feature = "oodle")]
|
||||
Some(oodle::OodleGetter),
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
|
|
@ -4,16 +4,15 @@ use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
|||
use std::collections::BTreeMap;
|
||||
use std::io::{self, Read, Seek, Write};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct PakBuilder {
|
||||
key: super::Key,
|
||||
oodle: super::Oodle,
|
||||
}
|
||||
|
||||
impl PakBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
key: super::Key::None,
|
||||
}
|
||||
Self::default()
|
||||
}
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn key(mut self, key: aes::Aes256) -> Self {
|
||||
|
@ -21,19 +20,19 @@ impl PakBuilder {
|
|||
self
|
||||
}
|
||||
#[cfg(feature = "oodle")]
|
||||
pub fn oodle(self, oodle: fn() -> super::OodleDecompress) -> Self {
|
||||
unsafe { super::OODLE = Some(once_cell::sync::Lazy::new(oodle)) }
|
||||
pub fn oodle(mut self, oodle_getter: super::oodle::OodleGetter) -> Self {
|
||||
self.oodle = super::Oodle::Some(oodle_getter);
|
||||
self
|
||||
}
|
||||
pub fn reader<R: Read + Seek>(self, reader: &mut R) -> Result<PakReader, super::Error> {
|
||||
PakReader::new_any_inner(reader, self.key)
|
||||
PakReader::new_any_inner(reader, self.key, self.oodle)
|
||||
}
|
||||
pub fn reader_with_version<R: Read + Seek>(
|
||||
self,
|
||||
reader: &mut R,
|
||||
version: super::Version,
|
||||
) -> Result<PakReader, super::Error> {
|
||||
PakReader::new_inner(reader, version, self.key)
|
||||
PakReader::new_inner(reader, version, self.key, self.oodle)
|
||||
}
|
||||
pub fn writer<W: Write + Seek>(
|
||||
self,
|
||||
|
@ -50,6 +49,7 @@ impl PakBuilder {
|
|||
pub struct PakReader {
|
||||
pak: Pak,
|
||||
key: super::Key,
|
||||
oodle: super::Oodle,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -128,13 +128,14 @@ impl PakReader {
|
|||
fn new_any_inner<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
key: super::Key,
|
||||
oodle: super::Oodle,
|
||||
) -> Result<Self, super::Error> {
|
||||
use std::fmt::Write;
|
||||
let mut log = "\n".to_owned();
|
||||
|
||||
for ver in Version::iter() {
|
||||
match Pak::read(&mut *reader, ver, &key) {
|
||||
Ok(pak) => return Ok(Self { pak, key }),
|
||||
Ok(pak) => return Ok(Self { pak, key, oodle }),
|
||||
Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?,
|
||||
}
|
||||
}
|
||||
|
@ -145,8 +146,9 @@ impl PakReader {
|
|||
reader: &mut R,
|
||||
version: super::Version,
|
||||
key: super::Key,
|
||||
oodle: super::Oodle,
|
||||
) -> Result<Self, super::Error> {
|
||||
Pak::read(reader, version, &key).map(|pak| Self { pak, key })
|
||||
Pak::read(reader, version, &key).map(|pak| Self { pak, key, oodle })
|
||||
}
|
||||
|
||||
pub fn version(&self) -> super::Version {
|
||||
|
@ -183,6 +185,7 @@ impl PakReader {
|
|||
self.pak.version,
|
||||
&self.pak.compression,
|
||||
&self.key,
|
||||
&self.oodle,
|
||||
writer,
|
||||
),
|
||||
None => Err(super::Error::MissingEntry(path.to_owned())),
|
||||
|
|
Loading…
Reference in a new issue