2022-07-19 19:29:41 -04:00
|
|
|
use binrw::binrw;
|
|
|
|
use binrw::BinRead;
|
2022-10-17 19:23:45 -04:00
|
|
|
use modular_bitfield::prelude::*;
|
2022-08-16 11:52:07 -04:00
|
|
|
use std::io::SeekFrom;
|
2022-08-09 22:37:40 -04:00
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
#[brw(repr = u8)]
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
enum PlatformId {
|
|
|
|
Windows,
|
|
|
|
PS3,
|
|
|
|
PS4,
|
|
|
|
}
|
2022-07-19 19:29:41 -04:00
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
#[br(magic = b"SqPack")]
|
|
|
|
pub struct SqPackHeader {
|
|
|
|
#[br(pad_before = 2)]
|
|
|
|
platform_id: PlatformId,
|
|
|
|
#[br(pad_before = 3)]
|
|
|
|
size: u32,
|
|
|
|
version: u32,
|
|
|
|
file_type: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
pub struct SqPackIndexHeader {
|
|
|
|
size: u32,
|
|
|
|
file_type: u32,
|
|
|
|
index_data_offset: u32,
|
|
|
|
index_data_size: u32,
|
|
|
|
}
|
|
|
|
|
2022-10-17 19:23:45 -04:00
|
|
|
#[bitfield]
|
2022-07-19 19:29:41 -04:00
|
|
|
#[binrw]
|
2022-10-17 19:23:45 -04:00
|
|
|
#[br(map = Self::from_bytes)]
|
2022-07-19 19:29:41 -04:00
|
|
|
pub struct IndexHashBitfield {
|
2022-10-17 19:23:45 -04:00
|
|
|
pub size: B1,
|
|
|
|
pub data_file_id: B3,
|
|
|
|
pub offset: B28,
|
2022-07-19 19:29:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
pub struct IndexHashTableEntry {
|
|
|
|
pub(crate) hash: u64,
|
|
|
|
#[br(pad_after = 4)]
|
|
|
|
pub(crate) bitfield: IndexHashBitfield,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct IndexEntry {
|
|
|
|
pub hash: u64,
|
|
|
|
pub data_file_id: u8,
|
|
|
|
pub offset: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw]
|
2022-10-13 16:03:46 -04:00
|
|
|
#[br(little)]
|
2022-07-19 19:29:41 -04:00
|
|
|
pub struct IndexFile {
|
|
|
|
sqpack_header: SqPackHeader,
|
|
|
|
|
|
|
|
#[br(seek_before = SeekFrom::Start(sqpack_header.size.into()))]
|
|
|
|
index_header: SqPackIndexHeader,
|
|
|
|
|
|
|
|
#[br(seek_before = SeekFrom::Start(index_header.index_data_offset.into()))]
|
2022-08-09 19:35:14 -04:00
|
|
|
#[br(count = index_header.index_data_size / 16)]
|
2022-07-19 19:29:41 -04:00
|
|
|
pub entries: Vec<IndexHashTableEntry>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IndexFile {
|
2022-08-14 23:38:49 -04:00
|
|
|
/// Creates a new reference to an existing index file.
|
2022-07-19 19:29:41 -04:00
|
|
|
pub fn from_existing(path: &str) -> Option<IndexFile> {
|
2022-08-09 22:43:04 -04:00
|
|
|
let mut index_file = std::fs::File::open(path).ok()?;
|
2022-07-19 19:29:41 -04:00
|
|
|
|
2022-08-09 20:05:11 -04:00
|
|
|
IndexFile::read(&mut index_file).ok()
|
2022-07-19 19:29:41 -04:00
|
|
|
}
|
2022-08-16 11:52:07 -04:00
|
|
|
}
|