diff --git a/repak/src/entry.rs b/repak/src/entry.rs index dc05d84..184dee6 100644 --- a/repak/src/entry.rs +++ b/repak/src/entry.rs @@ -307,6 +307,7 @@ impl Entry { compression: &[Compression], #[allow(unused)] key: &super::Key, buf: &mut W, + #[allow(unused)] oodle: super::Oodle, ) -> Result<(), super::Error> { reader.seek(io::SeekFrom::Start(self.offset))?; Entry::read(reader, version)?; @@ -376,9 +377,9 @@ impl Entry { } #[cfg(feature = "oodle")] Some(Compression::Oodle) => unsafe { - // #[allow(non_snake_case)] - // #[allow(clippy::type_complexity)] - // let OodleLZ_Decompress = lib.get(b"OodleLZ_Decompress").unwrap(); + let super::Oodle::Some(oodle) = oodle else { + return Err(super::Error::OodleFailed); + }; let mut decompressed = vec![0; self.uncompressed as usize]; let mut compress_offset = 0; @@ -392,7 +393,7 @@ impl Entry { .min(self.uncompressed as usize - compress_offset) }; let buffer = &mut data[range]; - let out = OodleLZ_Decompress( + let out = oodle( buffer.as_mut_ptr(), buffer.len(), decompressed.as_mut_ptr().offset(decompress_offset), @@ -415,7 +416,7 @@ impl Entry { decompress_offset += out as isize; } - assert_eq!( + debug_assert_eq!( decompress_offset, self.uncompressed as isize, "Oodle decompression length mismatch" ); diff --git a/repak/src/error.rs b/repak/src/error.rs index 29a7642..f023917 100644 --- a/repak/src/error.rs +++ b/repak/src/error.rs @@ -16,14 +16,7 @@ pub enum Error { #[error("enable the encryption feature to read encrypted paks")] Encryption, - #[cfg_attr( - windows, - error("enable the oodle feature to read Oodle compressed paks") - )] - #[cfg_attr( - not(windows), - error("Oodle compression only supported on Windows (or WINE)") - )] + #[error("enable the oodle feature to read Oodle compressed paks")] Oodle, // std errors @@ -39,10 +32,6 @@ pub enum Error { #[error("utf16 conversion: {0}")] Utf16(#[from] std::string::FromUtf16Error), - #[cfg(feature = "oodle")] - #[error("ureq error: {0}")] - Ureq(#[from] Box), // boxed because ureq::Error is quite large - #[error("bufwriter dereference: {0}")] IntoInner(#[from] std::io::IntoInnerError>>), @@ -53,7 +42,7 @@ pub enum Error { #[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)] Magic(u32), - #[error("Could not load oo2core_9_win64.dll")] + #[error("pointer to OodleLZ_Decompress was not provided")] OodleFailed, #[error("No entry found at {0}")] diff --git a/repak/src/lib.rs b/repak/src/lib.rs index 18f942e..eabf15c 100644 --- a/repak/src/lib.rs +++ b/repak/src/lib.rs @@ -151,3 +151,14 @@ impl From for Key { Self::Some(value) } } + +#[cfg(feature = "oodle")] +pub(crate) enum Oodle<'func> { + Some(&'func DECOMPRESS), + None, +} + +#[cfg(not(feature = "oodle"))] +pub(crate) enum Oodle { + None, +} diff --git a/repak/src/pak.rs b/repak/src/pak.rs index 0452a84..bdaf5b8 100644 --- a/repak/src/pak.rs +++ b/repak/src/pak.rs @@ -180,6 +180,18 @@ impl PakReader { Ok(data) } + #[cfg(feature = "oodle")] + pub fn get_with_oodle( + &self, + path: &str, + reader: &mut R, + oodle: &super::DECOMPRESS, + ) -> Result, super::Error> { + let mut data = Vec::new(); + self.read_file_with_oodle(path, reader, &mut data, oodle)?; + Ok(data) + } + pub fn read_file( &self, path: &str, @@ -193,6 +205,28 @@ impl PakReader { &self.pak.compression, &self.key, writer, + super::Oodle::None, + ), + None => Err(super::Error::MissingEntry(path.to_owned())), + } + } + + #[cfg(feature = "oodle")] + pub fn read_file_with_oodle( + &self, + path: &str, + reader: &mut R, + writer: &mut W, + oodle: &super::DECOMPRESS, + ) -> Result<(), super::Error> { + match self.pak.index.entries().get(path) { + Some(entry) => entry.read_file( + reader, + self.pak.version, + &self.pak.compression, + &self.key, + writer, + super::Oodle::Some(oodle), ), None => Err(super::Error::MissingEntry(path.to_owned())), }