mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
remove automatic download
This commit is contained in:
parent
6bd3be3aca
commit
6680e7871b
3 changed files with 61 additions and 148 deletions
|
@ -9,7 +9,7 @@ edition.workspace = true
|
||||||
[features]
|
[features]
|
||||||
default = ["compression", "encryption"]
|
default = ["compression", "encryption"]
|
||||||
compression = ["dep:flate2", "dep:zstd"]
|
compression = ["dep:flate2", "dep:zstd"]
|
||||||
oodle = ["dep:libloading", "dep:ureq", "dep:once_cell", "dep:hex-literal", "dep:hex"]
|
oodle = []
|
||||||
encryption = ["dep:aes"]
|
encryption = ["dep:aes"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -20,11 +20,6 @@ zstd = { version = "0.12", optional = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
sha1 = "0.10.5"
|
sha1 = "0.10.5"
|
||||||
strum = { workspace = true }
|
strum = { workspace = true }
|
||||||
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]
|
[dev-dependencies]
|
||||||
base64 = { workspace = true }
|
base64 = { workspace = true }
|
||||||
|
|
|
@ -375,112 +375,52 @@ impl Entry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "oodle")]
|
#[cfg(feature = "oodle")]
|
||||||
Some(Compression::Oodle) => {
|
Some(Compression::Oodle) => unsafe {
|
||||||
#[cfg(not(target_os = "windows"))]
|
// #[allow(non_snake_case)]
|
||||||
return Err(super::Error::Oodle);
|
// #[allow(clippy::type_complexity)]
|
||||||
|
// let OodleLZ_Decompress = lib.get(b"OodleLZ_Decompress").unwrap();
|
||||||
|
let mut decompressed = vec![0; self.uncompressed as usize];
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
let mut compress_offset = 0;
|
||||||
unsafe {
|
let mut decompress_offset = 0;
|
||||||
use std::ops::Deref;
|
let block_count = ranges.len();
|
||||||
let lib = match OODLE.deref() {
|
for range in ranges {
|
||||||
Ok(lib) => Ok(lib),
|
let decomp = if block_count == 1 {
|
||||||
Err(e) => Err(super::Error::Other(e.to_string())),
|
self.uncompressed as usize
|
||||||
}?;
|
} else {
|
||||||
|
(self.compression_block_size as usize)
|
||||||
/*
|
.min(self.uncompressed as usize - compress_offset)
|
||||||
let set_printf: libloading::Symbol<
|
};
|
||||||
unsafe extern "C" fn(
|
let buffer = &mut data[range];
|
||||||
unsafe extern "C" fn(
|
let out = OodleLZ_Decompress(
|
||||||
i32,
|
buffer.as_mut_ptr(),
|
||||||
*const std::ffi::c_char,
|
buffer.len(),
|
||||||
i32,
|
decompressed.as_mut_ptr().offset(decompress_offset),
|
||||||
*const std::ffi::c_char,
|
decomp,
|
||||||
...
|
1,
|
||||||
) -> std::ffi::c_int,
|
1,
|
||||||
),
|
0, //verbose 3
|
||||||
> = lib.get(b"OodleCore_Plugins_SetPrintf").unwrap();
|
0,
|
||||||
|
0,
|
||||||
pub unsafe extern "C" fn printf(
|
0,
|
||||||
a: i32,
|
0,
|
||||||
b: *const std::ffi::c_char,
|
std::ptr::null_mut(),
|
||||||
c: i32,
|
0,
|
||||||
str: *const std::ffi::c_char,
|
3,
|
||||||
mut args: ...
|
|
||||||
) -> std::ffi::c_int {
|
|
||||||
use printf_compat::{format, output};
|
|
||||||
let mut s = String::new();
|
|
||||||
let bytes_written = format(str, args.as_va_list(), output::fmt_write(&mut s));
|
|
||||||
print!("[OODLE]: {}", s);
|
|
||||||
bytes_written
|
|
||||||
}
|
|
||||||
|
|
||||||
set_printf(printf);
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
let OodleLZ_Decompress: libloading::Symbol<
|
|
||||||
extern "C" fn(
|
|
||||||
compBuf: *mut u8,
|
|
||||||
compBufSize: usize,
|
|
||||||
rawBuf: *mut u8,
|
|
||||||
rawLen: usize,
|
|
||||||
fuzzSafe: u32,
|
|
||||||
checkCRC: u32,
|
|
||||||
verbosity: u32,
|
|
||||||
decBufBase: u64,
|
|
||||||
decBufSize: usize,
|
|
||||||
fpCallback: u64,
|
|
||||||
callbackUserData: u64,
|
|
||||||
decoderMemory: *mut u8,
|
|
||||||
decoderMemorySize: usize,
|
|
||||||
threadPhase: u32,
|
|
||||||
) -> i32,
|
|
||||||
> = lib.get(b"OodleLZ_Decompress").unwrap();
|
|
||||||
|
|
||||||
let mut decompressed = vec![0; self.uncompressed as usize];
|
|
||||||
|
|
||||||
let mut compress_offset = 0;
|
|
||||||
let mut decompress_offset = 0;
|
|
||||||
let block_count = ranges.len();
|
|
||||||
for range in ranges {
|
|
||||||
let decomp = if block_count == 1 {
|
|
||||||
self.uncompressed as usize
|
|
||||||
} else {
|
|
||||||
(self.compression_block_size as usize)
|
|
||||||
.min(self.uncompressed as usize - compress_offset)
|
|
||||||
};
|
|
||||||
let buffer = &mut data[range];
|
|
||||||
let out = OodleLZ_Decompress(
|
|
||||||
buffer.as_mut_ptr(),
|
|
||||||
buffer.len(),
|
|
||||||
decompressed.as_mut_ptr().offset(decompress_offset),
|
|
||||||
decomp,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0, //verbose 3
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
std::ptr::null_mut(),
|
|
||||||
0,
|
|
||||||
3,
|
|
||||||
);
|
|
||||||
if out == 0 {
|
|
||||||
return Err(super::Error::DecompressionFailed(Compression::Oodle));
|
|
||||||
}
|
|
||||||
compress_offset += self.compression_block_size as usize;
|
|
||||||
decompress_offset += out as isize;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
decompress_offset, self.uncompressed as isize,
|
|
||||||
"Oodle decompression length mismatch"
|
|
||||||
);
|
);
|
||||||
buf.write_all(&decompressed)?;
|
if out == 0 {
|
||||||
|
return Err(super::Error::DecompressionFailed(Compression::Oodle));
|
||||||
|
}
|
||||||
|
compress_offset += self.compression_block_size as usize;
|
||||||
|
decompress_offset += out as isize;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
assert_eq!(
|
||||||
|
decompress_offset, self.uncompressed as isize,
|
||||||
|
"Oodle decompression length mismatch"
|
||||||
|
);
|
||||||
|
buf.write_all(&decompressed)?;
|
||||||
|
},
|
||||||
#[cfg(not(feature = "oodle"))]
|
#[cfg(not(feature = "oodle"))]
|
||||||
Some(Compression::Oodle) => return Err(super::Error::Oodle),
|
Some(Compression::Oodle) => return Err(super::Error::Oodle),
|
||||||
#[cfg(not(feature = "compression"))]
|
#[cfg(not(feature = "compression"))]
|
||||||
|
@ -491,42 +431,6 @@ impl Entry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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};
|
|
||||||
|
|
||||||
let oodle = std::env::current_exe()?.with_file_name("oo2core_9_win64.dll");
|
|
||||||
if !oodle.exists() {
|
|
||||||
let mut data = vec![];
|
|
||||||
ureq::get("https://cdn.discordapp.com/attachments/817251677086285848/992648087371792404/oo2core_9_win64.dll")
|
|
||||||
.call().map_err(Box::new)?
|
|
||||||
.into_reader().read_to_end(&mut data)?;
|
|
||||||
|
|
||||||
std::fs::write(&oodle, data)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut hasher = Sha1::new();
|
|
||||||
hasher.update(std::fs::read(&oodle)?);
|
|
||||||
let hash = hasher.finalize();
|
|
||||||
(hash[..] == OODLE_HASH).then_some(()).ok_or_else(|| {
|
|
||||||
super::Error::Other(format!(
|
|
||||||
"oodle hash mismatch expected: {} got: {} ",
|
|
||||||
hex::encode(OODLE_HASH),
|
|
||||||
hex::encode(hash)
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
unsafe { libloading::Library::new(oodle) }.map_err(|_| super::Error::OodleFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_entry() {
|
fn test_entry() {
|
||||||
|
|
|
@ -7,11 +7,25 @@ mod pak;
|
||||||
|
|
||||||
pub use {error::*, 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;
|
pub const MAGIC: u32 = 0x5A6F12E1;
|
||||||
|
|
||||||
|
type DECOMPRESS = fn(
|
||||||
|
compBuf: *mut u8,
|
||||||
|
compBufSize: usize,
|
||||||
|
rawBuf: *mut u8,
|
||||||
|
rawLen: usize,
|
||||||
|
fuzzSafe: u32,
|
||||||
|
checkCRC: u32,
|
||||||
|
verbosity: u32,
|
||||||
|
decBufBase: u64,
|
||||||
|
decBufSize: usize,
|
||||||
|
fpCallback: u64,
|
||||||
|
callbackUserData: u64,
|
||||||
|
decoderMemory: *mut u8,
|
||||||
|
decoderMemorySize: usize,
|
||||||
|
threadPhase: u32,
|
||||||
|
) -> i32;
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
|
|
Loading…
Reference in a new issue