From b4587ea71b6b809e4dccc27e930bf7c0b9eaf361 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 10 Mar 2022 10:11:31 -0500 Subject: [PATCH] Add index file parser --- CMakeLists.txt | 4 ++- include/indexparser.h | 62 ++++++++++++++++++++++++++++++++++++++++ src/indexparser.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 include/indexparser.h create mode 100644 src/indexparser.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 12eded0..6b6db51 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,9 @@ set(SRC src/fiinparser.cpp include/fiinparser.h include/headline.h - src/headline.cpp) + src/headline.cpp + include/indexparser.h + src/indexparser.cpp) include(FetchContent) diff --git a/include/indexparser.h b/include/indexparser.h new file mode 100644 index 0000000..6c506e5 --- /dev/null +++ b/include/indexparser.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include +#include + +// these are methods dedicated to reading ".index" and ".index2" files +// major thanks to xiv.dev for providing the struct definitions + +enum PlatformId : uint8_t +{ + Win32, + PS3, + PS4 +}; + +// https://github.com/SapphireServer/Sapphire/blob/develop/deps/datReader/SqPack.cpp#L5 +struct SqPackHeader +{ + char magic[0x8]; + PlatformId platformId; + uint8_t padding0[3]; + uint32_t size; + uint32_t version; + uint32_t type; +}; + +struct SqPackIndexHeader +{ + uint32_t size; + uint32_t type; + uint32_t indexDataOffset; + uint32_t indexDataSize; +}; + +struct IndexHashTableEntry +{ + uint64_t hash; + uint32_t unknown : 1; + uint32_t dataFileId : 3; + uint32_t offset : 28; + uint32_t _padding; +}; + +struct Index2HashTableEntry +{ + uint32_t hash; + uint32_t unknown : 1; + uint32_t dataFileId : 3; + uint32_t offset : 28; +}; + +template +struct IndexFile { + SqPackHeader packHeader; + SqPackIndexHeader indexHeader; + + std::vector entries; +}; + +IndexFile readIndexFile(const std::string_view path); +IndexFile readIndex2File(const std::string_view path); \ No newline at end of file diff --git a/src/indexparser.cpp b/src/indexparser.cpp new file mode 100644 index 0000000..f5095eb --- /dev/null +++ b/src/indexparser.cpp @@ -0,0 +1,66 @@ +#include "indexparser.h" + +#include +#include + +template +void commonParseSqPack(FILE* file, IndexFile index) { + fread(&index.packHeader, sizeof index.packHeader, 1, file); + + // data starts at size + fseek(file, index.packHeader.size, SEEK_SET); + + // read index header + fread(&index.indexHeader, sizeof index.indexHeader, 1, file); + + // version should be 1? + qInfo() << index.packHeader.version; + + fseek(file, index.indexHeader.indexDataOffset, SEEK_SET); + + qInfo() << "size: " << index.indexHeader.indexDataSize; +} + +IndexFile readIndexFile(const std::string_view path) { + FILE* file = fopen(path.data(), "rb"); + if(!file) { + qInfo() << "Failed to read file info " << path.data(); + return {}; + } + + IndexFile index; + commonParseSqPack(file, index); + + for(int i = 0; i < index.indexHeader.indexDataSize; i++) { + IndexHashTableEntry entry; + fread(&entry, sizeof entry, 1, file); + + qInfo() << entry.hash; + qInfo() << entry.dataFileId; + qInfo() << entry.offset; + } + + return index; +} + +IndexFile readIndex2File(const std::string_view path) { + FILE* file = fopen(path.data(), "rb"); + if(!file) { + qInfo() << "Failed to read file info " << path.data(); + return {}; + } + + IndexFile index; + commonParseSqPack(file, index); + + for(int i = 0; i < index.indexHeader.indexDataSize; i++) { + Index2HashTableEntry entry; + fread(&entry, sizeof entry, 1, file); + + qInfo() << entry.hash; + qInfo() << entry.dataFileId; + qInfo() << entry.offset; + } + + return index; +} \ No newline at end of file