diff --git a/Cargo.toml b/Cargo.toml index 9897587..a775799 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ edition = "2021" [dependencies] byteorder = "*" strum = { version = "*", features = ["derive"] } +hashbrown = "*" thiserror = "*" [profile.release] diff --git a/src/entry.rs b/src/entry.rs index 9712d6f..4f6fe27 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -4,7 +4,6 @@ use super::{Compression, ReadExt, Version}; #[derive(Debug)] pub struct Entry { - pub name: String, pub offset: u64, pub compressed: u64, pub uncompressed: u64, @@ -12,6 +11,8 @@ pub struct Entry { pub timestamp: Option, pub hash: [u8; 20], pub compression_blocks: Option>, + pub encrypted: bool, + pub block_uncompressed: Option, } impl Entry { @@ -19,27 +20,34 @@ impl Entry { reader: &mut R, version: super::Version, ) -> Result { - let name = reader.read_string()?; let offset = reader.read_u64::()?; let compressed = reader.read_u64::()?; let uncompressed = reader.read_u64::()?; let compression_method = match reader.read_u32::()? { - 0x01 => Compression::Zlib, - 0x10 => Compression::ZlibBiasMemory, - 0x20 => Compression::ZlibBiasMemory, + 0x01 | 0x10 | 0x20 => Compression::Zlib, _ => Compression::None, }; Ok(Self { - name, offset, compressed, uncompressed, compression_method, - timestamp: (version == Version::Initial).then_some(reader.read_u64::()?), + timestamp: match version == Version::Initial { + true => Some(reader.read_u64::()?), + false => None, + }, hash: reader.read_guid()?, - compression_blocks: (version >= Version::CompressionEncryption - && compression_method != Compression::None) - .then_some(reader.read_array(Block::new)?), + compression_blocks: match version >= Version::CompressionEncryption + && compression_method != Compression::None + { + true => Some(reader.read_array(Block::new)?), + false => None, + }, + encrypted: version >= Version::CompressionEncryption && reader.read_bool()?, + block_uncompressed: match version >= Version::CompressionEncryption { + true => Some(reader.read_u32::()?), + false => None, + }, }) } } diff --git a/src/footer.rs b/src/footer.rs index b491a65..50ba5f5 100644 --- a/src/footer.rs +++ b/src/footer.rs @@ -7,13 +7,13 @@ use super::{Compression, ReadExt, Version}; #[derive(Debug)] pub struct Footer { pub encryption_uuid: Option, - pub encrypted: Option, + pub encrypted: bool, pub magic: u32, pub version: Version, pub offset: u64, pub size: u64, pub hash: [u8; 20], - pub frozen: Option, + pub frozen: bool, pub compression: Option>, } @@ -24,19 +24,13 @@ impl Footer { true => Some(reader.read_u128::()?), false => None, }, - encrypted: match version >= Version::IndexEncryption { - true => Some(reader.read_bool()?), - false => None, - }, + encrypted: version >= Version::IndexEncryption && reader.read_bool()?, magic: reader.read_u32::()?, version: Version::from_repr(reader.read_u32::()?).unwrap_or(version), offset: reader.read_u64::()?, size: reader.read_u64::()?, hash: reader.read_guid()?, - frozen: match version == Version::FrozenIndex { - true => Some(reader.read_bool()?), - false => None, - }, + frozen: version == Version::FrozenIndex && reader.read_bool()?, compression: match version >= Version::FNameBasedCompression { true => { let mut compression = diff --git a/src/index.rs b/src/index.rs deleted file mode 100644 index 4404bae..0000000 --- a/src/index.rs +++ /dev/null @@ -1,36 +0,0 @@ -use super::{ReadExt, Version}; - -#[derive(Debug)] -pub enum Index { - WithoutPathHash(IndexV1), - WithPathHash, -} - -impl Index { - pub fn new(reader: &mut R, version: Version) -> Result { - Ok(match version < Version::PathHashIndex { - true => Index::WithoutPathHash(IndexV1::new(reader, version)?), - false => Index::WithPathHash, - }) - } -} - -#[derive(Debug)] -pub struct IndexV1 { - pub mount_point: String, - pub entries: Vec, -} - -impl IndexV1 { - pub fn new( - reader: &mut R, - version: super::Version, - ) -> Result { - Ok(Self { - mount_point: reader.read_string()?, - entries: reader.read_array(|reader| super::Entry::new(reader, version))?, - }) - } -} - -pub struct IndexV2 {} diff --git a/src/lib.rs b/src/lib.rs index c486864..c8f70d7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,10 +3,9 @@ mod entry; mod error; mod ext; mod footer; -mod index; mod pak; -pub use {entry::*, error::*, ext::*, footer::*, index::*, pak::*}; +pub use {entry::*, error::*, ext::*, footer::*, pak::*}; pub const MAGIC: u32 = 0x5A6F12E1; @@ -40,8 +39,6 @@ pub enum Compression { #[default] None, Zlib, - ZlibBiasMemory, - ZlibBiasSpeed, Gzip, Oodle, } diff --git a/src/pak.rs b/src/pak.rs index 69e06f4..06f8417 100644 --- a/src/pak.rs +++ b/src/pak.rs @@ -1,12 +1,15 @@ use std::io; +use super::ReadExt; +use byteorder::{ReadBytesExt, LE}; + use super::Version; #[derive(Debug)] pub struct Pak { pub version: Version, pub footer: super::Footer, - pub index: super::Index, + pub mount_point: String, } impl Pak { @@ -17,11 +20,18 @@ impl Pak { reader.seek(io::SeekFrom::End(-footer_size(&version)))?; let footer = super::Footer::new(&mut reader, version)?; reader.seek(io::SeekFrom::Start(footer.offset))?; - let index = super::Index::new(&mut reader, version)?; + let mount_point = reader.read_string()?; + let mut entries = hashbrown::HashMap::with_capacity(reader.read_u32::()? as usize); + for _ in 0..entries.capacity() { + entries.insert( + reader.read_string()?, + super::Entry::new(&mut reader, version)?, + ); + } Ok(Self { version, footer, - index, + mount_point, }) } }