encryption uuid isn't the only thing :/

This commit is contained in:
spuds 2023-01-06 19:54:48 +00:00
parent 38ed23a5bc
commit 39ea548d57
No known key found for this signature in database
GPG key ID: 0B6CA6068E827C8F
7 changed files with 38 additions and 32 deletions

View file

@ -1,15 +1,18 @@
fn main() -> Result<(), un_pak::Error> { fn main() -> Result<(), un_pak::Error> {
for version in un_pak::Version::iter().rev() { let path = std::env::args().nth(1).unwrap_or_default();
for version in un_pak::Version::iter() {
print!("{version} - ");
match un_pak::Pak::new( match un_pak::Pak::new(
version, version,
std::io::BufReader::new(std::io::Cursor::new(include_bytes!("rando_p.pak"))), std::io::BufReader::new(std::fs::OpenOptions::new().read(true).open(&path)?),
) { ) {
Ok(_) => { Ok(pak) => {
print!("{:#?}", pak);
println!("parsed successfully!"); println!("parsed successfully!");
return Ok(());
} }
Err(e) => println!("{e}"), Err(e) => println!("{e}"),
} }
} }
Err(un_pak::Error::Other("no version can parse".to_string())) std::thread::sleep_ms(10000);
Ok(())
} }

View file

@ -2,6 +2,7 @@ use byteorder::{ReadBytesExt, LE};
use super::{Compression, ReadExt, Version}; use super::{Compression, ReadExt, Version};
#[derive(Debug)]
pub struct Entry { pub struct Entry {
pub name: String, pub name: String,
pub offset: u64, pub offset: u64,
@ -43,6 +44,7 @@ impl Entry {
} }
} }
#[derive(Debug)]
pub struct Block { pub struct Block {
/// start offset relative to the start of the entry header /// start offset relative to the start of the entry header
pub offset: u64, pub offset: u64,

View file

@ -1,19 +1,19 @@
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum Error { pub enum Error {
#[error("expected magic of {} but got {0}", super::MAGIC)] #[error("illegal file magic of {0}")]
MagicMismatch(u32), WrongMagic(u32),
#[error("parsed with {0} but pak was {0}")] #[error("used version {0} but pak is version {1}")]
VersionMismatch(super::Version, super::Version), WrongVersion(super::Version, super::Version),
#[error("expected 1 or 0 but got {0}")] #[error("couldn't convert {0} to boolean")]
BoolConversion(u8), BoolConv(u8),
#[error("reading file: {0}")] #[error("io error: {0}")]
IoError(#[from] std::io::Error), IoError(#[from] std::io::Error),
#[error("converting to enum: {0}")] #[error("enum conversion: {0}")]
StrumError(#[from] strum::ParseError), StrumConv(#[from] strum::ParseError),
#[error("converting to utf8: {0}")] #[error("utf8 conversion: {0}")]
Utf8Error(#[from] std::string::FromUtf8Error), Utf8Conv(#[from] std::string::FromUtf8Error),
#[error("converting to utf16: {0}")] #[error("utf16 conversion: {0}")]
Utf16Error(#[from] std::string::FromUtf16Error), Utf16Conv(#[from] std::string::FromUtf16Error),
#[error("{0}")] #[error("{0}")]
Other(String), Other(String),
} }

View file

@ -1,7 +1,5 @@
use byteorder::{ReadBytesExt, LE}; use byteorder::{ReadBytesExt, LE};
type R = dyn std::io::Read;
pub trait ReadExt { pub trait ReadExt {
fn read_bool(&mut self) -> Result<bool, super::Error>; fn read_bool(&mut self) -> Result<bool, super::Error>;
fn read_guid(&mut self) -> Result<[u8; 20], super::Error>; fn read_guid(&mut self) -> Result<[u8; 20], super::Error>;
@ -18,7 +16,7 @@ impl<R: std::io::Read> ReadExt for R {
match self.read_u8()? { match self.read_u8()? {
1 => Ok(true), 1 => Ok(true),
0 => Ok(false), 0 => Ok(false),
err => Err(super::Error::BoolConversion(err)), err => Err(super::Error::BoolConv(err)),
} }
} }
@ -43,8 +41,7 @@ impl<R: std::io::Read> ReadExt for R {
Ok(match self.read_i32::<LE>()? { Ok(match self.read_i32::<LE>()? {
size if size.is_positive() => String::from_utf8(self.read_len(size as usize)?)?, size if size.is_positive() => String::from_utf8(self.read_len(size as usize)?)?,
size if size.is_negative() => { size if size.is_negative() => {
let size = 2 * -size; let mut buf = Vec::with_capacity(-size as usize);
let mut buf = Vec::with_capacity(size as usize / 2);
for _ in 0..buf.capacity() { for _ in 0..buf.capacity() {
buf.push(self.read_u16::<LE>()?); buf.push(self.read_u16::<LE>()?);
} }

View file

@ -4,8 +4,9 @@ use byteorder::{ReadBytesExt, LE};
use super::{Compression, ReadExt, Version}; use super::{Compression, ReadExt, Version};
#[derive(Debug)]
pub struct Footer { pub struct Footer {
pub encryption_guid: Option<[u8; 20]>, pub encryption_uuid: Option<u128>,
pub encrypted: Option<bool>, pub encrypted: Option<bool>,
pub magic: u32, pub magic: u32,
pub version: Version, pub version: Version,
@ -19,8 +20,8 @@ pub struct Footer {
impl Footer { impl Footer {
pub fn new<R: std::io::Read>(reader: &mut R, version: &Version) -> Result<Self, super::Error> { pub fn new<R: std::io::Read>(reader: &mut R, version: &Version) -> Result<Self, super::Error> {
let footer = Footer { let footer = Footer {
encryption_guid: (version >= &Version::EncryptionKeyGuid) encryption_uuid: (version >= &Version::EncryptionKeyGuid)
.then_some(reader.read_guid()?), .then_some(reader.read_u128::<LE>()?),
encrypted: (version >= &Version::CompressionEncryption).then_some(reader.read_bool()?), encrypted: (version >= &Version::CompressionEncryption).then_some(reader.read_bool()?),
magic: reader.read_u32::<LE>()?, magic: reader.read_u32::<LE>()?,
version: Version::from_repr(reader.read_u32::<LE>()?).unwrap_or_default(), version: Version::from_repr(reader.read_u32::<LE>()?).unwrap_or_default(),
@ -51,10 +52,10 @@ impl Footer {
}), }),
}; };
if super::MAGIC != footer.magic { if super::MAGIC != footer.magic {
return Err(super::Error::MagicMismatch(footer.magic)); return Err(super::Error::WrongMagic(footer.magic));
} }
if version != &footer.version { if version != &footer.version {
return Err(super::Error::VersionMismatch(*version, footer.version)); return Err(super::Error::WrongVersion(*version, footer.version));
} }
Ok(footer) Ok(footer)
} }

View file

@ -1,19 +1,21 @@
use super::{ReadExt, Version}; use super::{ReadExt, Version};
#[derive(Debug)]
pub enum Index { pub enum Index {
WithoutPathHash(IndexV1), WithoutPathHash(IndexV1),
WithPathHash(IndexV2), WithPathHash,
} }
impl Index { impl Index {
pub fn new<R: std::io::Read>(reader: &mut R, version: &Version) -> Result<Self, super::Error> { pub fn new<R: std::io::Read>(reader: &mut R, version: &Version) -> Result<Self, super::Error> {
Ok(match version < &Version::PathHashIndex { Ok(match version < &Version::PathHashIndex {
true => Index::WithoutPathHash(IndexV1::new(reader, version)?), true => Index::WithoutPathHash(IndexV1::new(reader, version)?),
false => Index::WithPathHash(todo!()), false => Index::WithPathHash,
}) })
} }
} }
#[derive(Debug)]
pub struct IndexV1 { pub struct IndexV1 {
pub mount_point: String, pub mount_point: String,
pub entries: Vec<super::Entry>, pub entries: Vec<super::Entry>,

View file

@ -2,6 +2,7 @@ use std::io;
use super::Version; use super::Version;
#[derive(Debug)]
pub struct Pak { pub struct Pak {
pub version: Version, pub version: Version,
pub footer: super::Footer, pub footer: super::Footer,
@ -29,8 +30,8 @@ fn footer_size(version: &Version) -> i64 {
// (magic + version): u32 + (offset + size): u64 + hash: [u8; 20] // (magic + version): u32 + (offset + size): u64 + hash: [u8; 20]
let mut size = 4 + 4 + 8 + 8 + 20; let mut size = 4 + 4 + 8 + 8 + 20;
if version >= &Version::EncryptionKeyGuid { if version >= &Version::EncryptionKeyGuid {
// encryption guid: [u8; 20] // encryption uuid: u128
size += 20; size += 16;
} }
if version >= &Version::IndexEncryption { if version >= &Version::IndexEncryption {
// encrypted: bool // encrypted: bool