From f307e48a0c75bccb0ce45fde3beed0824e617557 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 8 Mar 2025 09:56:43 -0500 Subject: [PATCH] Add support for reading SQDB files --- src/lib.rs | 3 +++ src/sqdb.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/sqpack.rs | 2 ++ 3 files changed, 65 insertions(+) create mode 100644 src/sqdb.rs diff --git a/src/lib.rs b/src/lib.rs index 5f50d89..0dec4ac 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -168,3 +168,6 @@ pub mod existing_dirs; /// Reading patch lists pub mod patchlist; + +/// Reading SQDB files +pub mod sqdb; diff --git a/src/sqdb.rs b/src/sqdb.rs new file mode 100644 index 0000000..33ce3eb --- /dev/null +++ b/src/sqdb.rs @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: 2025 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +use std::io::Cursor; + +use crate::common_file_operations::read_string; +use crate::common_file_operations::write_string; +use crate::sqpack::SqPackHeader; +use crate::ByteSpan; +use binrw::helpers::until_eof; +use binrw::BinRead; +use binrw::binrw; + +#[binrw] +#[derive(Debug)] +pub struct SQDBHeader { + size: u32, + #[br(pad_after = 1016)] // nothing + unk: u32, +} + +// 264 bytes +#[binrw] +#[derive(Debug)] +pub struct SQDBEntry { + #[br(pad_before = 4)] // 4 empty bytes + offset: u32, // TODO: just a guess, offset into what? + #[br(pad_after = 4)] // 4 more empty bytes + size: u32, // TODO: also a guess + + // Corresponds to SplitPath hash + filename_hash: u32, + path_hash: u32, + + // TODO: this is terrible, just read until string nul terminator + #[br(count = 240)] + #[br(map = read_string)] + #[bw(map = write_string)] + path: String, +} + +#[binrw] +#[derive(Debug)] +#[brw(little)] +pub struct SQDB { + sqpack_header: SqPackHeader, + + header: SQDBHeader, + + #[br(parse_with = until_eof)] + entries: Vec +} + +impl SQDB { + /// Reads an existing SQDB file + pub fn from_existing(buffer: ByteSpan) -> Option { + let mut cursor = Cursor::new(buffer); + SQDB::read(&mut cursor).ok() + } +} diff --git a/src/sqpack.rs b/src/sqpack.rs index f689e4d..2a8e444 100755 --- a/src/sqpack.rs +++ b/src/sqpack.rs @@ -12,6 +12,7 @@ use crate::dat::{BlockHeader, CompressionMode}; /// The type of this SqPack file. #[binrw] #[brw(repr = u8)] +#[derive(Debug)] enum SqPackFileType { /// FFXIV Explorer says "SQDB", whatever that is. SQDB = 0x0, @@ -23,6 +24,7 @@ enum SqPackFileType { #[binrw] #[brw(magic = b"SqPack\0\0")] +#[derive(Debug)] pub struct SqPackHeader { #[brw(pad_size_to = 4)] platform_id: Platform,