From 3964da39159818cdc0fc8c268e0e0626c2a33c4a Mon Sep 17 00:00:00 2001 From: Loskh <1020612624@qq.com> Date: Tue, 30 Dec 2025 23:26:32 +0800 Subject: [PATCH 1/3] update sqpack --- .../Client/System/File/FileDescriptor.cs | 2 +- .../FFXIV/Client/System/File/FileInterface.cs | 33 ++++++++++++ .../FFXIV/Client/System/File/FileThread.cs | 4 +- .../FFXIV/Client/System/File/SqPackHeader.cs | 24 +++++++++ .../Client/System/File/SqPackIndexHeader.cs | 28 ++++++++++ .../FFXIV/Client/System/File/SqPackManager.cs | 52 +++++++++++++++++++ 6 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 FFXIVClientStructs/FFXIV/Client/System/File/FileInterface.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/System/File/SqPackHeader.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/System/File/SqPackIndexHeader.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs b/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs index ec5df4ed22..b2a44310b7 100644 --- a/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs +++ b/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs @@ -8,7 +8,7 @@ public unsafe partial struct FileDescriptor { [FieldOffset(0x8)] public byte* FileBuffer; [FieldOffset(0x10)] public ulong FileLength; [FieldOffset(0x18)] public ulong CurrentFileOffset; - [FieldOffset(0x30)] public void* FileInterface; // Client::System::File::FileInterface + [FieldOffset(0x30)] public FileInterface* FileInterface; // Client::System::File::FileInterface [FieldOffset(0x60)] public FileDescriptor* Previous; // believe its a queue [FieldOffset(0x68)] public FileDescriptor* Next; [FieldOffset(0x70), FixedSizeArray(isString: true)] internal FixedSizeArray260 _filePath; diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/FileInterface.cs b/FFXIVClientStructs/FFXIV/Client/System/File/FileInterface.cs new file mode 100644 index 0000000000..40d41e882b --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/FileInterface.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; + +[GenerateInterop] +[StructLayout(LayoutKind.Explicit, Size = 0x230)] +public unsafe partial struct FileInterface { + [FieldOffset(0x10)] public nint FileHandle; + [FieldOffset(0x20)] public bool IsOpen; + + [MemberFunction("E8 ?? ?? ?? ?? 33 F6 45 32 F6")] + public partial void Ctor(); + + [MemberFunction("E8 ?? ?? ?? ?? 0F B6 C8 3C 01"), GenerateStringOverloads] + public partial sbyte Open(CStringPointer filePath,int openMode); + + [MemberFunction("E8 ?? ?? ?? ?? 8B 05 ?? ?? ?? ?? EB 18")] + public partial sbyte Close(); + + [MemberFunction("E8 ?? ?? ?? ?? 89 1F 33 C0")] + public partial sbyte Read(void* buffer,ulong size); + + [MemberFunction("E8 ?? ?? ?? ?? 48 8B 44 24 ?? 48 03 E8")] + public partial sbyte ReadWithOffset(void* buffer, ulong size, ulong offset); + + [MemberFunction("E8 ?? ?? ?? ?? 41 3A C7 75 0E")] + public partial sbyte Write(void* buffer, ulong size); + + [MemberFunction("E8 ?? ?? ?? ?? 49 2B C6")] + public partial ulong GetFileSize(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs b/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs index bd095f0566..35b28cf75b 100644 --- a/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs +++ b/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs @@ -3,7 +3,9 @@ namespace FFXIVClientStructs.FFXIV.Client.System.File; // Client::System::File::FileThread // Client::System::Threading::Thread // Client::System::Common::NonCopyable +[GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x2518)] -public unsafe struct FileThread { +public unsafe partial struct FileThread { [FieldOffset(0x0008)] public void* SecurityAttributes; // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventa + [FieldOffset(0x0028), FixedSizeArray] internal FixedSizeArray20> _sqPackManagers; } diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackHeader.cs b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackHeader.cs new file mode 100644 index 0000000000..552c8078f8 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackHeader.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; +// https://github.com/NotAdam/Lumina/blob/12d0e8d418d8dc49f04e6bee1d06bae2905232c6/src/Lumina/Data/Structs/SqPackHeader.cs +public enum PlatformId : byte { + Win32, + PS3, + PS4, + PS5, + Lys // Xbox +} + +[GenerateInterop] +[StructLayout(LayoutKind.Explicit, Size = 0x400)] +public partial struct SqPackHeader { + [FieldOffset(0x000)] internal FixedSizeArray8 Magic; + [FieldOffset(0x008)] public PlatformId PlatformId; + //[FieldOffset(0x009)] internal byte[] Unknown; + [FieldOffset(0x00C)] public uint Size; + [FieldOffset(0x010)] public uint Version; + [FieldOffset(0x014)] public uint Type; +} diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackIndexHeader.cs b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackIndexHeader.cs new file mode 100644 index 0000000000..91b0504cf5 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackIndexHeader.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; + +//https://github.com/NotAdam/Lumina/blob/12d0e8d418d8dc49f04e6bee1d06bae2905232c6/src/Lumina/Data/Structs/SqPackIndexHeader.cs +[StructLayout(LayoutKind.Explicit, Size = 0x400)] +public unsafe struct SqPackIndexHeader { + [FieldOffset(0x000)] public uint Size; + [FieldOffset(0x004)] public uint Version; + [FieldOffset(0x008)] public uint IndexDataOffset; + [FieldOffset(0x00C)] public uint IndexDataSize; + [FieldOffset(0x010)] public fixed byte IndexDataHash[64]; + [FieldOffset(0x050)] public uint NumberOfDataFile; + [FieldOffset(0x054)] public uint SynonymDataOffset; + [FieldOffset(0x058)] public uint SynonymDataSize; + [FieldOffset(0x05C)] public fixed byte SynonymDataHash[64]; + [FieldOffset(0x09C)] public uint EmptyBlockDataOffset; + [FieldOffset(0x0A0)] public uint EmptyBlockDataSize; + [FieldOffset(0x0A4)] public fixed byte EmptyBlockDataHash[64]; + [FieldOffset(0x0E4)] public uint DirIndexDataOffset; + [FieldOffset(0x0E8)] public uint DirIndexDataSize; + [FieldOffset(0x0EC)] public fixed byte DirIndexDataHash[64]; + [FieldOffset(0x12C)] public uint IndexType; + [FieldOffset(0x130)] internal fixed byte Reserved[656]; + [FieldOffset(0x3C0)] public fixed byte SelfHash[64]; +} diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs new file mode 100644 index 0000000000..a8358a3532 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FFXIVClientStructs.FFXIV.Client.System.Resource; +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; + +[GenerateInterop] +[StructLayout(LayoutKind.Explicit, Size = 0xA80)] +public unsafe partial struct SqPackManager { + [FieldOffset(0x000)] public FileManager* FileManager; + [FieldOffset(0x014)] public SqPackIndexHeader IndexHeader; + [FieldOffset(0x414)] public SqPackHeader SqPackHeader; + [FieldOffset(0x814)] public ResourceCategory ResourceCategory; + [FieldOffset(0x818)] public int PackId; + [FieldOffset(0x81C)] public uint DataCount; + [FieldOffset(0x820)] public uint SynonymDataCount; + [FieldOffset(0x824)] public uint DirIndexDataCount; + [FieldOffset(0x834)] public uint FileSize; + [FieldOffset(0x840)] public FileAccessPath FilePath; + + [FieldOffset(0xA50)] public void* IndexData; + [FieldOffset(0xA58)] public void* SynonymData; + [FieldOffset(0xA60)] public void* DirIndexData; + [FieldOffset(0xA88), FixedSizeArray] internal FixedSizeArray10> _dataFiles; + [FieldOffset(0xAD8)] public FileInterface* IndexFile; + [FieldOffset(0xAE8)] public void* GetOffset; + + [MemberFunction("E8 ?? ?? ?? ?? EB 03 49 8B C7 48 89 03 48 83 C3 08")] + public partial void Ctor(); + + [MemberFunction("E8 ?? ?? ?? ?? 49 8D 55 70 49 8B CF")] + public partial bool LoadIndexFile(ResourceCategory category, int packId); + + [MemberFunction("48 89 6C 24 ?? 56 57 41 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 8B 69 64")] + public partial bool LoadDataFiles(); + + [MemberFunction("E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 44 38 69 20")] + public partial ulong GetSqPackPath(FileAccessPath* path, int fileId, ResourceCategory category, int packId, byte* platform, byte* a7); + + [MemberFunction("40 55 41 54 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 80 79 0A 00")] + public partial bool GetOffsetFromIndex(CStringPointer path, uint* offset, uint* fileId); + + [MemberFunction("40 53 55 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B EA"), GenerateStringOverloads] + public partial bool GetOffsetFromIndex2(CStringPointer path, uint* offset, uint* fileId); + + [StaticAddress("48 8D 0D ?? ?? ?? ?? 80 3C 08 ?? 0F 85", 3, isPointer: true)] + public static partial byte* GetIndex2Table(); +} + + From d4ffef11472320f3065ea00599be9c0db4e5bb07 Mon Sep 17 00:00:00 2001 From: Loskh <1020612624@qq.com> Date: Tue, 30 Dec 2025 23:38:00 +0800 Subject: [PATCH 2/3] update data.yaml --- ida/data.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ida/data.yml b/ida/data.yml index ce71cf5fd7..3e0e790fc9 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -5102,6 +5102,14 @@ classes: - ea: 0x142096A60 vfuncs: 0: Dtor + funcs: + 0x14045DAC0: ctor + 0x14045DB60: Open + 0x14045DF80: Close + 0x14045DCF0: Read + 0x14045DDA0: ReadWithOffset + 0x14045DE50: Write + 0x14045DF40: GetFileSize Client::System::File::FileThread: vtbls: - ea: 0x142096A80 @@ -5129,6 +5137,14 @@ classes: 0x1400D4370: Copy 0x140095180: SetPathUtf8String 0x140094950: Dtor + Client::System::File::SqPackManager: + funcs: + 0x1417CD170: ctor + 0x1417CD4A0: LoadIndexFile + 0x1417CD8B0: LoadDataFiles + 0x1417CCD40: GetSqPackPath + 0x1417CDA10: GetOffsetFromIndex + 0x1417CDC70: GetOffsetFromIndex2 Client::System::Resource::Handle::ResourceHandle: vtbls: - ea: 0x142078258 From c135344fc2aa4253982eac5248966d57e0c0772e Mon Sep 17 00:00:00 2001 From: Loskh <1020612624@qq.com> Date: Tue, 30 Dec 2025 23:51:57 +0800 Subject: [PATCH 3/3] fix SqPackManager size --- FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs index a8358a3532..d4df8193f1 100644 --- a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs +++ b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs @@ -7,7 +7,7 @@ namespace FFXIVClientStructs.FFXIV.Client.System.File; [GenerateInterop] -[StructLayout(LayoutKind.Explicit, Size = 0xA80)] +[StructLayout(LayoutKind.Explicit, Size = 0xAF0)] public unsafe partial struct SqPackManager { [FieldOffset(0x000)] public FileManager* FileManager; [FieldOffset(0x014)] public SqPackIndexHeader IndexHeader;