Skip to content

Commit

Permalink
Minor rework of sqpack stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
PassiveModding committed Jul 25, 2024
1 parent 09d4e09 commit 24f9357
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 61 deletions.
6 changes: 3 additions & 3 deletions Meddle/Meddle.UI/Windows/SqPackWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ private void BrowseCategory()
}


private (Category category, IndexHashTableEntry hash, SqPackFile file)[]? discoverResults;
private (Repository repo, Category category, IndexHashTableEntry hash, SqPackFile file)[]? discoverResults;

private void DrawFile()
{
Expand Down Expand Up @@ -506,8 +506,8 @@ private void DrawFile()
ImGui.Text("Discovered files:");
for (var i = 0; i < discoverResults.Length; i++)
{
var (category, sHash, sFile) = discoverResults[i];
var repoName = category.Repository?.Path.Split(Path.DirectorySeparatorChar).Last();
var (repository, category, sHash, sFile) = discoverResults[i];
var repoName = repository.Path.Split(Path.DirectorySeparatorChar).Last();
if (ImGui.Selectable($"[{i}] - {repoName} {sHash.Hash:X16}"))
{
selectedFile = (selectedFile!.Value.index, category, sHash, sFile);
Expand Down
85 changes: 45 additions & 40 deletions Meddle/Meddle.Utils/Files/SqPack/Category.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
using System.Collections.ObjectModel;
using System.IO.Compression;
using Meddle.Utils;

namespace Meddle.Utils.Files.SqPack;

public class Category
public class Category : IDisposable
{
public static readonly Dictionary< string, byte > CategoryNameToIdMap = new()
public static readonly Dictionary<string, byte> CategoryNameToIdMap = new()
{
{ "common", 0x00 },
{ "bgcommon", 0x01 },
{ "bg", 0x02 },
{ "cut", 0x03 },
{ "chara", 0x04 },
{ "shader", 0x05 },
{ "ui", 0x06 },
{ "sound", 0x07 },
{ "vfx", 0x08 },
{ "ui_script", 0x09 },
{ "exd", 0x0A },
{ "game_script", 0x0B },
{ "music", 0x0C },
{ "sqpack_test", 0x12 },
{ "debug", 0x13 },
{"common", 0x00},
{"bgcommon", 0x01},
{"bg", 0x02},
{"cut", 0x03},
{"chara", 0x04},
{"shader", 0x05},
{"ui", 0x06},
{"sound", 0x07},
{"vfx", 0x08},
{"ui_script", 0x09},
{"exd", 0x0A},
{"game_script", 0x0B},
{"music", 0x0C},
{"sqpack_test", 0x12},
{"debug", 0x13}
};

public static string? TryGetCategoryName(byte id)
Expand All @@ -31,17 +29,17 @@ public class Category
{
return CategoryNameToIdMap.First(x => x.Value == id).Key;
}

return null;
}

public byte Id { get; }

public bool FileExists(ulong hash)
{
return UnifiedIndexEntries.ContainsKey(hash);
}

public bool TryGetFile(ulong hash, FileType? fileType, out SqPackFile data)
{
if (!UnifiedIndexEntries.TryGetValue(hash, out var entry))
Expand All @@ -54,36 +52,36 @@ public bool TryGetFile(ulong hash, FileType? fileType, out SqPackFile data)
{
return TryGetFile(hash, out data);
}

var locData = SqPackUtil.ReadFile(entry.Offset, datFilePaths[entry.DataFileId], fileType.Value);
if (locData == null)
{
data = null!;
return false;
}

data = locData;
return true;
}

public bool TryGetFile(ulong hash, out SqPackFile data)
{
if (!UnifiedIndexEntries.TryGetValue(hash, out var entry))
{
data = null!;
return false;
}

data = SqPackUtil.ReadFile(entry.Offset, datFilePaths[entry.DataFileId]);
return true;
}

private readonly string[] datFilePaths;
public ReadOnlySpan<string> DatFilePaths => datFilePaths;
public readonly ReadOnlyDictionary<ulong, IndexHashTableEntry> UnifiedIndexEntries;
public ReadOnlyDictionary<ulong, IndexHashTableEntry> UnifiedIndexEntries { get; private set; }

public readonly bool Index;
public readonly bool Index2;
public Repository? Repository { get; set; }

// Take paths instead of file since it will eat all your ram
public Category(byte catId, byte[]? index, byte[]? index2, string[] datFilePaths)
Expand All @@ -98,7 +96,7 @@ public Category(byte catId, byte[]? index, byte[]? index2, string[] datFilePaths
throw new FileNotFoundException($"Dat file {dat} does not exist");
}
}

var unifiedEntries = new Dictionary<ulong, IndexHashTableEntry>();
if (index != null)
{
Expand All @@ -107,14 +105,15 @@ public Category(byte catId, byte[]? index, byte[]? index2, string[] datFilePaths
var dats = indexFile.IndexHeader.DataFileCount;
if (dats > datFilePaths.Length)
{
throw new Exception($"Not enough dat files provided for index, expected {dats} got {datFilePaths.Length}");
throw new Exception(
$"Not enough dat files provided for index, expected {dats} got {datFilePaths.Length}");
}
foreach(var entry in indexFile.Entries)

foreach (var entry in indexFile.Entries)
{
unifiedEntries[entry.Hash] = entry;
}
}
}

if (index2 != null)
{
Expand All @@ -123,19 +122,25 @@ public Category(byte catId, byte[]? index, byte[]? index2, string[] datFilePaths
var dats = index2File.IndexHeader.DataFileCount;
if (dats > datFilePaths.Length)
{
throw new Exception($"Not enough dat files provided for index2, expected {dats} got {datFilePaths.Length}");
throw new Exception(
$"Not enough dat files provided for index2, expected {dats} got {datFilePaths.Length}");
}
foreach(var entry in index2File.Entries)

foreach (var entry in index2File.Entries)
{
unifiedEntries[entry.Hash] = new IndexHashTableEntry()
unifiedEntries[entry.Hash] = new IndexHashTableEntry
{
Data = entry.Data,
Hash = entry.Hash
};
}
}

this.UnifiedIndexEntries = new ReadOnlyDictionary<ulong, IndexHashTableEntry>(unifiedEntries);

UnifiedIndexEntries = new ReadOnlyDictionary<ulong, IndexHashTableEntry>(unifiedEntries);
}

public void Dispose()
{
UnifiedIndexEntries = null!;
}
}
27 changes: 19 additions & 8 deletions Meddle/Meddle.Utils/Files/SqPack/Repository.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System.Globalization;
using System.Collections.ObjectModel;
using System.Globalization;

namespace Meddle.Utils.Files.SqPack;

public class Repository
public class Repository : IDisposable
{
public string Version { get; }
public int? ExpansionId { get; }
public string Path { get; }
public Dictionary<(byte category, byte expansion, byte chunk), Category> Categories { get; } = new();
public ReadOnlyDictionary<(byte category, byte expansion, byte chunk), Category> Categories { get; private set; }

public static string ParseVersion(DirectoryInfo info)
{
Expand Down Expand Up @@ -67,6 +68,7 @@ public Repository(string path)
// { XX } is the expansion id
// { XX} is the chunk id
var setGroups = allFiles.GroupBy(x => System.IO.Path.GetFileName(x)[..6]);
var categories = new Dictionary<(byte category, byte expansion, byte chunk), Category>();
foreach (var setGroup in setGroups)
{
var setId = setGroup.Key;
Expand All @@ -92,11 +94,20 @@ public Repository(string path)
var categoryId = byte.Parse(setId[..2], NumberStyles.HexNumber);
var expansionId = byte.Parse(setId[2..4], NumberStyles.HexNumber);
var chunkId = byte.Parse(setId[4..6], NumberStyles.HexNumber);
var cat = new Category(categoryId, index, index2, datFiles)
{
Repository = this
};
Categories[(categoryId, expansionId, chunkId)] = cat;
var cat = new Category(categoryId, index, index2, datFiles);
categories.Add((categoryId, expansionId, chunkId), cat);
}

Categories = new ReadOnlyDictionary<(byte category, byte expansion, byte chunk), Category>(categories);
}

public void Dispose()
{
foreach (var (_, category) in Categories)
{
category.Dispose();
}

Categories = null!;
}
}
30 changes: 20 additions & 10 deletions Meddle/Meddle.Utils/Files/SqPack/SqPack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

namespace Meddle.Utils.Files.SqPack;

public class SqPack
public class SqPack : IDisposable
{
private static readonly ActivitySource ActivitySource = new("Meddle.Utils.Files.SqPack");

private static uint[]? _crcTable;
public readonly IEnumerable<Repository> Repositories;
private static uint[]? CrcTable;
public IReadOnlyList<Repository> Repositories { get; private set; }

public SqPack(string path)
{
Expand Down Expand Up @@ -129,12 +129,12 @@ public bool FileExists(string path, out ParsedFilePath hash)
return null;
}

public (Category category, IndexHashTableEntry hash, SqPackFile file)[] GetFiles(string path)
public (Repository repo, Category category, IndexHashTableEntry hash, SqPackFile file)[] GetFiles(string path)
{
var hash = GetFileHash(path);
var categoryName = path.Split('/')[0];

var files = new List<(Category category, IndexHashTableEntry hash, SqPackFile file)>();
var files = new List<(Repository repo, Category category, IndexHashTableEntry hash, SqPackFile file)>();
byte? catId = null;
if (Category.CategoryNameToIdMap.TryGetValue(categoryName, out var id))
{
Expand All @@ -158,12 +158,12 @@ public bool FileExists(string path, out ParsedFilePath hash)
{
if (category.TryGetFile(hash.IndexHash, out var data))
{
files.Add((category, category.UnifiedIndexEntries[hash.IndexHash], data));
files.Add((repo, category, category.UnifiedIndexEntries[hash.IndexHash], data));
}

if (category.TryGetFile(hash.Index2Hash, out var data2))
{
files.Add((category, category.UnifiedIndexEntries[hash.Index2Hash], data2));
files.Add((repo, category, category.UnifiedIndexEntries[hash.Index2Hash], data2));
}
}
}
Expand All @@ -178,9 +178,9 @@ public static ParsedFilePath GetFileHash(string path)

private static uint[] GetCrcTable()
{
if (_crcTable != null)
if (CrcTable != null)
{
return _crcTable;
return CrcTable;
}

var table = new uint[16 * 256];
Expand All @@ -199,7 +199,7 @@ private static uint[] GetCrcTable()
}
}

_crcTable = table;
CrcTable = table;
return table;
}

Expand All @@ -216,4 +216,14 @@ public static uint GetHash(string value)
var ret = ~(crcLocal ^ uint.MaxValue);
return ret;
}

public void Dispose()
{
foreach (var repo in Repositories)
{
repo.Dispose();
}

Repositories = null!;
}
}

0 comments on commit 24f9357

Please sign in to comment.