mirror of
https://github.com/redstrate/Physis.git
synced 2025-04-19 17:36:50 +00:00
Re-arrange SqPack-related formats into their own submodule
This is to make way for another dat module (for the stuff under the user folder.) This kind of re-organization was inevitable anyway, and I gave the structs new SqPack-y names to fit their new home.
This commit is contained in:
parent
591c5f55ed
commit
b54ee74802
7 changed files with 102 additions and 101 deletions
|
@ -8,13 +8,12 @@ use std::path::PathBuf;
|
|||
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use crate::sqpack::{IndexEntry, SqPackData, SqPackIndex};
|
||||
use crate::ByteBuffer;
|
||||
use crate::common::{Language, Platform, read_version};
|
||||
use crate::dat::DatFile;
|
||||
use crate::exd::EXD;
|
||||
use crate::exh::EXH;
|
||||
use crate::exl::EXL;
|
||||
use crate::index::{IndexEntry, IndexFile};
|
||||
use crate::patch::{PatchError, ZiPatch};
|
||||
use crate::repository::{Category, Repository, string_to_category};
|
||||
|
||||
|
@ -26,7 +25,7 @@ pub struct GameData {
|
|||
/// Repositories in the game directory.
|
||||
pub repositories: Vec<Repository>,
|
||||
|
||||
index_files: HashMap<String, IndexFile>,
|
||||
index_files: HashMap<String, SqPackIndex>,
|
||||
}
|
||||
|
||||
fn is_valid(path: &str) -> bool {
|
||||
|
@ -125,7 +124,7 @@ impl GameData {
|
|||
self.repositories.sort();
|
||||
}
|
||||
|
||||
fn get_dat_file(&self, path: &str, chunk: u8, data_file_id: u32) -> Option<DatFile> {
|
||||
fn get_dat_file(&self, path: &str, chunk: u8, data_file_id: u32) -> Option<SqPackData> {
|
||||
let (repository, category) = self.parse_repository_category(path).unwrap();
|
||||
|
||||
let dat_path: PathBuf = [
|
||||
|
@ -137,7 +136,7 @@ impl GameData {
|
|||
.iter()
|
||||
.collect();
|
||||
|
||||
DatFile::from_existing(dat_path.to_str()?)
|
||||
SqPackData::from_existing(dat_path.to_str()?)
|
||||
}
|
||||
|
||||
/// Checks if a file located at `path` exists.
|
||||
|
@ -395,13 +394,13 @@ impl GameData {
|
|||
|
||||
fn cache_index_file(&mut self, filename: &str) {
|
||||
if !self.index_files.contains_key(filename) {
|
||||
if let Some(index_file) = IndexFile::from_existing(filename) {
|
||||
if let Some(index_file) = SqPackIndex::from_existing(filename) {
|
||||
self.index_files.insert(filename.to_string(), index_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_index_file(&self, filename: &str) -> Option<&IndexFile> {
|
||||
fn get_index_file(&self, filename: &str) -> Option<&SqPackIndex> {
|
||||
self.index_files.get(filename)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,14 +20,10 @@ pub mod repository;
|
|||
/// Handling and updating data in the "boot" directory, which contains the launcher files.
|
||||
pub mod bootdata;
|
||||
|
||||
/// Common methods and structures relating to the SqPack data format.
|
||||
/// SqPack file formats - including Db, Data and Index/Index2 files.
|
||||
pub mod sqpack;
|
||||
|
||||
/// Reading and writing SqPack index files.
|
||||
pub mod index;
|
||||
|
||||
mod compression;
|
||||
mod dat;
|
||||
|
||||
/// Reading model (MDL) files.
|
||||
pub mod model;
|
||||
|
@ -157,7 +153,4 @@ pub mod existing_dirs;
|
|||
/// Reading patch lists
|
||||
pub mod patchlist;
|
||||
|
||||
/// Reading SQDB files
|
||||
pub mod sqdb;
|
||||
|
||||
mod bcn;
|
||||
|
|
24
src/dat.rs → src/sqpack/data.rs
Executable file → Normal file
24
src/dat.rs → src/sqpack/data.rs
Executable file → Normal file
|
@ -46,17 +46,17 @@ struct TextureLodBlock {
|
|||
}
|
||||
|
||||
pub trait AnyNumberType<'a>:
|
||||
BinRead<Args<'a> = ()> + BinWrite<Args<'a> = ()> + std::ops::AddAssign + Copy + Default + 'static
|
||||
BinRead<Args<'a> = ()> + BinWrite<Args<'a> = ()> + std::ops::AddAssign + Copy + Default + 'static
|
||||
{
|
||||
}
|
||||
|
||||
impl<'a, T> AnyNumberType<'a> for T where
|
||||
T: BinRead<Args<'a> = ()>
|
||||
+ BinWrite<Args<'a> = ()>
|
||||
+ std::ops::AddAssign
|
||||
+ Copy
|
||||
+ Default
|
||||
+ 'static
|
||||
T: BinRead<Args<'a> = ()>
|
||||
+ BinWrite<Args<'a> = ()>
|
||||
+ std::ops::AddAssign
|
||||
+ Copy
|
||||
+ Default
|
||||
+ 'static
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ pub struct BlockHeader {
|
|||
pub compression: CompressionMode,
|
||||
}
|
||||
|
||||
pub struct DatFile {
|
||||
pub struct SqPackData {
|
||||
file: std::fs::File,
|
||||
}
|
||||
|
||||
|
@ -191,10 +191,10 @@ fn to_u8_slice(slice: &mut [u16]) -> &mut [u8] {
|
|||
unsafe { std::slice::from_raw_parts_mut(slice.as_mut_ptr().cast::<u8>(), byte_len) }
|
||||
}
|
||||
|
||||
impl DatFile {
|
||||
impl SqPackData {
|
||||
/// Creates a new reference to an existing dat file.
|
||||
pub fn from_existing(path: &str) -> Option<DatFile> {
|
||||
Some(DatFile {
|
||||
pub fn from_existing(path: &str) -> Option<Self> {
|
||||
Some(Self {
|
||||
file: std::fs::File::open(path).ok()?,
|
||||
})
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ mod tests {
|
|||
d.push("resources/tests");
|
||||
d.push("random");
|
||||
|
||||
let mut dat = crate::dat::DatFile::from_existing(d.to_str().unwrap()).unwrap();
|
||||
let mut dat = SqPackData::from_existing(d.to_str().unwrap()).unwrap();
|
||||
|
||||
let empty_file_info = FileInfo {
|
||||
size: 0,
|
|
@ -42,7 +42,7 @@ pub struct SQDBEntry {
|
|||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
#[brw(little)]
|
||||
pub struct SQDB {
|
||||
pub struct SqPackDatabase {
|
||||
sqpack_header: SqPackHeader,
|
||||
|
||||
header: SQDBHeader,
|
||||
|
@ -51,10 +51,10 @@ pub struct SQDB {
|
|||
entries: Vec<SQDBEntry>,
|
||||
}
|
||||
|
||||
impl SQDB {
|
||||
impl SqPackDatabase {
|
||||
/// Reads an existing SQDB file
|
||||
pub fn from_existing(buffer: ByteSpan) -> Option<Self> {
|
||||
let mut cursor = Cursor::new(buffer);
|
||||
SQDB::read(&mut cursor).ok()
|
||||
Self::read(&mut cursor).ok()
|
||||
}
|
||||
}
|
10
src/index.rs → src/sqpack/index.rs
Executable file → Normal file
10
src/index.rs → src/sqpack/index.rs
Executable file → Normal file
|
@ -149,7 +149,7 @@ pub struct IndexEntry {
|
|||
|
||||
#[binrw]
|
||||
#[br(little)]
|
||||
pub struct IndexFile {
|
||||
pub struct SqPackIndex {
|
||||
sqpack_header: SqPackHeader,
|
||||
|
||||
#[br(seek_before = SeekFrom::Start(sqpack_header.size.into()))]
|
||||
|
@ -164,8 +164,8 @@ pub struct IndexFile {
|
|||
pub data_entries: Vec<DataEntry>,
|
||||
|
||||
/*#[br(seek_before = SeekFrom::Start(index_header.unknown_descriptor.offset.into()))]
|
||||
#[br(count = index_header.unknown_descriptor.size / 16)]
|
||||
pub unknown_entries: Vec<IndexHashTableEntry>,*/
|
||||
* #[br(count = index_header.unknown_descriptor.size / 16)]
|
||||
* pub unknown_entries: Vec<IndexHashTableEntry>,*/
|
||||
#[br(seek_before = SeekFrom::Start(index_header.folder_descriptor.offset.into()))]
|
||||
#[br(count = index_header.folder_descriptor.size / 16)]
|
||||
pub folder_entries: Vec<FolderEntry>,
|
||||
|
@ -173,7 +173,7 @@ pub struct IndexFile {
|
|||
|
||||
const CRC: Jamcrc = Jamcrc::new();
|
||||
|
||||
impl IndexFile {
|
||||
impl SqPackIndex {
|
||||
/// Creates a new reference to an existing index file.
|
||||
pub fn from_existing(path: &str) -> Option<Self> {
|
||||
let mut index_file = std::fs::File::open(path).ok()?;
|
||||
|
@ -252,7 +252,7 @@ mod tests {
|
|||
d.push("random");
|
||||
|
||||
// Feeding it invalid data should not panic
|
||||
IndexFile::from_existing(d.to_str().unwrap());
|
||||
SqPackIndex::from_existing(d.to_str().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
21
src/sqpack.rs → src/sqpack/mod.rs
Executable file → Normal file
21
src/sqpack.rs → src/sqpack/mod.rs
Executable file → Normal file
|
@ -4,16 +4,25 @@
|
|||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
|
||||
use binrw::{BinRead, BinWrite, binrw};
|
||||
use data::{BlockHeader, CompressionMode};
|
||||
|
||||
use crate::common::{Platform, Region};
|
||||
use crate::compression::no_header_decompress;
|
||||
use crate::dat::{BlockHeader, CompressionMode};
|
||||
|
||||
mod data;
|
||||
pub use data::SqPackData;
|
||||
|
||||
mod db;
|
||||
pub use db::SqPackDatabase;
|
||||
|
||||
mod index;
|
||||
pub use index::{SqPackIndex, IndexEntry};
|
||||
|
||||
/// The type of this SqPack file.
|
||||
#[binrw]
|
||||
#[brw(repr = u8)]
|
||||
#[derive(Debug)]
|
||||
enum SqPackFileType {
|
||||
pub(crate) enum SqPackFileType {
|
||||
/// FFXIV Explorer says "SQDB", whatever that is.
|
||||
SQDB = 0x0,
|
||||
/// Dat files.
|
||||
|
@ -25,7 +34,7 @@ enum SqPackFileType {
|
|||
#[binrw]
|
||||
#[brw(magic = b"SqPack\0\0")]
|
||||
#[derive(Debug)]
|
||||
pub struct SqPackHeader {
|
||||
pub(crate) struct SqPackHeader {
|
||||
#[brw(pad_size_to = 4)]
|
||||
platform_id: Platform,
|
||||
pub size: u32,
|
||||
|
@ -48,7 +57,7 @@ pub struct SqPackHeader {
|
|||
sha1_hash: [u8; 20],
|
||||
}
|
||||
|
||||
pub fn read_data_block<T: Read + Seek>(mut buf: T, starting_position: u64) -> Option<Vec<u8>> {
|
||||
pub(crate) fn read_data_block<T: Read + Seek>(mut buf: T, starting_position: u64) -> Option<Vec<u8>> {
|
||||
buf.seek(SeekFrom::Start(starting_position)).ok()?;
|
||||
|
||||
let block_header = BlockHeader::read(&mut buf).unwrap();
|
||||
|
@ -78,7 +87,7 @@ pub fn read_data_block<T: Read + Seek>(mut buf: T, starting_position: u64) -> Op
|
|||
}
|
||||
|
||||
/// A fixed version of read_data_block accounting for differing compressed block sizes in ZiPatch files.
|
||||
pub fn read_data_block_patch<T: Read + Seek>(mut buf: T) -> Option<Vec<u8>> {
|
||||
pub(crate) fn read_data_block_patch<T: Read + Seek>(mut buf: T) -> Option<Vec<u8>> {
|
||||
let block_header = BlockHeader::read(&mut buf).unwrap();
|
||||
|
||||
match block_header.compression {
|
||||
|
@ -115,7 +124,7 @@ pub fn read_data_block_patch<T: Read + Seek>(mut buf: T) -> Option<Vec<u8>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn write_data_block_patch<T: Write + Seek>(mut writer: T, data: Vec<u8>) {
|
||||
pub(crate) fn write_data_block_patch<T: Write + Seek>(mut writer: T, data: Vec<u8>) {
|
||||
let new_file_size: usize = (data.len() + 143) & 0xFFFFFF80;
|
||||
|
||||
// This only adds uncompressed data for now, to simplify implementation
|
|
@ -6,14 +6,14 @@ use std::fs::read;
|
|||
|
||||
use physis::common::Platform;
|
||||
use physis::fiin::FileInfo;
|
||||
use physis::index;
|
||||
use physis::sqpack::SqPackIndex;
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(not(feature = "retail_game_testing"), ignore)]
|
||||
fn test_index_read() {
|
||||
let game_dir = env::var("FFXIV_GAME_DIR").unwrap();
|
||||
|
||||
index::IndexFile::from_existing(
|
||||
SqPackIndex::from_existing(
|
||||
format!("{}/game/sqpack/ffxiv/000000.win32.index", game_dir).as_str(),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue