From ee48ea0166171e5437a5d5731a069aeb6aabc99f Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Fri, 22 Nov 2024 00:43:36 +0100 Subject: [PATCH] Some stashed changes already applied. --- Penumbra/Collections/ModCollection.cs | 1 + .../Hooks/ResourceLoading/ResourceLoader.cs | 8 ++++---- .../{TexMdlService.cs => RsfService.cs} | 4 ++-- .../Interop/PathResolving/PathDataHandler.cs | 5 +++++ .../Interop/Processing/ImcFilePostProcessor.cs | 3 ++- Penumbra/UI/ResourceWatcher/Record.cs | 14 +++++++++++--- Penumbra/UI/ResourceWatcher/ResourceWatcher.cs | 2 +- .../UI/ResourceWatcher/ResourceWatcherTable.cs | 18 +++++++++++++++++- Penumbra/UI/Tabs/Debug/AtchDrawer.cs | 15 ++++++++------- Penumbra/UI/Tabs/Debug/DebugTab.cs | 8 ++++---- 10 files changed, 55 insertions(+), 23 deletions(-) rename Penumbra/Interop/Hooks/ResourceLoading/{TexMdlService.cs => RsfService.cs} (96%) diff --git a/Penumbra/Collections/ModCollection.cs b/Penumbra/Collections/ModCollection.cs index eb5ab46a..db9c19cb 100644 --- a/Penumbra/Collections/ModCollection.cs +++ b/Penumbra/Collections/ModCollection.cs @@ -57,6 +57,7 @@ public string AnonymizedName public int ChangeCounter { get; private set; } public uint ImcChangeCounter { get; set; } + public uint AtchChangeCounter { get; set; } /// Increment the number of changes in the effective file list. public int IncrementCounter() diff --git a/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs b/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs index 442bac15..47f96d98 100644 --- a/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs @@ -15,18 +15,18 @@ public unsafe class ResourceLoader : IDisposable, IService { private readonly ResourceService _resources; private readonly FileReadService _fileReadService; - private readonly TexMdlScdService _texMdlScdService; + private readonly RsfService _rsfService; private readonly PapHandler _papHandler; private readonly Configuration _config; private ResolveData _resolvedData = ResolveData.Invalid; public event Action? PapRequested; - public ResourceLoader(ResourceService resources, FileReadService fileReadService, TexMdlScdService texMdlScdService, Configuration config) + public ResourceLoader(ResourceService resources, FileReadService fileReadService, RsfService rsfService, Configuration config) { _resources = resources; _fileReadService = fileReadService; - _texMdlScdService = texMdlScdService; + _rsfService = rsfService; _config = config; ResetResolvePath(); @@ -140,7 +140,7 @@ private void ResourceHandler(ref ResourceCategory category, ref ResourceType typ return; } - _texMdlScdService.AddCrc(type, resolvedPath); + _rsfService.AddCrc(type, resolvedPath); // Replace the hash and path with the correct one for the replacement. hash = ComputeHash(resolvedPath.Value.InternalName, parameters); var oldPath = path; diff --git a/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs b/Penumbra/Interop/Hooks/ResourceLoading/RsfService.cs similarity index 96% rename from Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs rename to Penumbra/Interop/Hooks/ResourceLoading/RsfService.cs index b43f1ed5..7ac1563f 100644 --- a/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/RsfService.cs @@ -11,7 +11,7 @@ namespace Penumbra.Interop.Hooks.ResourceLoading; -public unsafe class TexMdlScdService : IDisposable, IRequiredService +public unsafe class RsfService : IDisposable, IRequiredService { /// /// We need to be able to obtain the requested LoD level. @@ -43,7 +43,7 @@ public byte GetLod(TextureResourceHandle* handle) private readonly LodService _lodService; - public TexMdlScdService(IGameInteropProvider interop) + public RsfService(IGameInteropProvider interop) { interop.InitializeFromAttributes(this); _lodService = new LodService(interop); diff --git a/Penumbra/Interop/PathResolving/PathDataHandler.cs b/Penumbra/Interop/PathResolving/PathDataHandler.cs index 9410ff98..5439151f 100644 --- a/Penumbra/Interop/PathResolving/PathDataHandler.cs +++ b/Penumbra/Interop/PathResolving/PathDataHandler.cs @@ -44,6 +44,11 @@ public static FullPath CreateTmb(CiByteString path, ModCollection collection) public static FullPath CreateAvfx(CiByteString path, ModCollection collection) => CreateBase(path, collection); + /// Create the encoding path for an ATCH file. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static FullPath CreateAtch(CiByteString path, ModCollection collection) + => new($"|{collection.LocalId.Id}_{collection.AtchChangeCounter}_{DiscriminatorString}|{path}"); + /// Create the encoding path for a MTRL file. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static FullPath CreateMtrl(CiByteString path, ModCollection collection, Utf8GamePath originalPath) diff --git a/Penumbra/Interop/Processing/ImcFilePostProcessor.cs b/Penumbra/Interop/Processing/ImcFilePostProcessor.cs index 33a3941a..a3233cfb 100644 --- a/Penumbra/Interop/Processing/ImcFilePostProcessor.cs +++ b/Penumbra/Interop/Processing/ImcFilePostProcessor.cs @@ -1,3 +1,4 @@ +using Dalamud.Game.ClientState.JobGauge.Types; using Penumbra.Api.Enums; using Penumbra.Collections.Manager; using Penumbra.Interop.PathResolving; @@ -24,7 +25,7 @@ public unsafe void PostProcess(ResourceHandle* resource, CiByteString originalGa return; file.Replace(resource); - Penumbra.Log.Information( + Penumbra.Log.Verbose( $"[ResourceLoader] Loaded {originalGamePath} from file and replaced with IMC from collection {collection.AnonymizedName}."); } } diff --git a/Penumbra/UI/ResourceWatcher/Record.cs b/Penumbra/UI/ResourceWatcher/Record.cs index b69d9944..7338e5a9 100644 --- a/Penumbra/UI/ResourceWatcher/Record.cs +++ b/Penumbra/UI/ResourceWatcher/Record.cs @@ -3,6 +3,7 @@ using Penumbra.Enums; using Penumbra.Interop.Structs; using Penumbra.String; +using Penumbra.String.Classes; namespace Penumbra.UI.ResourceWatcher; @@ -24,14 +25,16 @@ internal unsafe struct Record public ModCollection? Collection; public ResourceHandle* Handle; public ResourceTypeFlag ResourceType; - public ResourceCategoryFlag Category; + public ulong Crc64; public uint RefCount; + public ResourceCategoryFlag Category; public RecordType RecordType; public OptionalBool Synchronously; public OptionalBool ReturnValue; public OptionalBool CustomLoad; public LoadState LoadState; + public static Record CreateRequest(CiByteString path, bool sync) => new() { @@ -49,6 +52,7 @@ public static Record CreateRequest(CiByteString path, bool sync) CustomLoad = OptionalBool.Null, AssociatedGameObject = string.Empty, LoadState = LoadState.None, + Crc64 = 0, }; public static Record CreateDefaultLoad(CiByteString path, ResourceHandle* handle, ModCollection collection, string associatedGameObject) @@ -70,15 +74,16 @@ public static Record CreateDefaultLoad(CiByteString path, ResourceHandle* handle CustomLoad = false, AssociatedGameObject = associatedGameObject, LoadState = handle->LoadState, + Crc64 = 0, }; } - public static Record CreateLoad(CiByteString path, CiByteString originalPath, ResourceHandle* handle, ModCollection collection, + public static Record CreateLoad(FullPath path, CiByteString originalPath, ResourceHandle* handle, ModCollection collection, string associatedGameObject) => new() { Time = DateTime.UtcNow, - Path = path.IsOwned ? path : path.Clone(), + Path = path.InternalName.IsOwned ? path.InternalName : path.InternalName.Clone(), OriginalPath = originalPath.IsOwned ? originalPath : originalPath.Clone(), Collection = collection, Handle = handle, @@ -91,6 +96,7 @@ public static Record CreateLoad(CiByteString path, CiByteString originalPath, Re CustomLoad = true, AssociatedGameObject = associatedGameObject, LoadState = handle->LoadState, + Crc64 = path.Crc64, }; public static Record CreateDestruction(ResourceHandle* handle) @@ -112,6 +118,7 @@ public static Record CreateDestruction(ResourceHandle* handle) CustomLoad = OptionalBool.Null, AssociatedGameObject = string.Empty, LoadState = handle->LoadState, + Crc64 = 0, }; } @@ -132,5 +139,6 @@ public static Record CreateFileLoad(CiByteString path, ResourceHandle* handle, b CustomLoad = custom, AssociatedGameObject = string.Empty, LoadState = handle->LoadState, + Crc64 = 0, }; } diff --git a/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs b/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs index 6f1ce9cf..d432e97e 100644 --- a/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs +++ b/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs @@ -250,7 +250,7 @@ private unsafe void OnResourceLoaded(ResourceHandle* handle, Utf8GamePath path, var record = manipulatedPath == null ? Record.CreateDefaultLoad(path.Path, handle, data.ModCollection, Name(data)) - : Record.CreateLoad(manipulatedPath.Value.InternalName, path.Path, handle, data.ModCollection, Name(data)); + : Record.CreateLoad(manipulatedPath.Value, path.Path, handle, data.ModCollection, Name(data)); if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record)) _newRecords.Enqueue(record); } diff --git a/Penumbra/UI/ResourceWatcher/ResourceWatcherTable.cs b/Penumbra/UI/ResourceWatcher/ResourceWatcherTable.cs index 2bb71b87..88b7120d 100644 --- a/Penumbra/UI/ResourceWatcher/ResourceWatcherTable.cs +++ b/Penumbra/UI/ResourceWatcher/ResourceWatcherTable.cs @@ -29,7 +29,8 @@ public ResourceWatcherTable(EphemeralConfig config, IReadOnlyCollection new HandleColumn { Label = "Resource" }, new LoadStateColumn { Label = "State" }, new RefCountColumn { Label = "#Ref" }, - new DateColumn { Label = "Time" } + new DateColumn { Label = "Time" }, + new Crc64Column { Label = "Crc64" } ) { } @@ -144,6 +145,21 @@ public override void DrawColumn(Record item, int _) => ImGui.TextUnformatted($"{item.Time.ToLongTimeString()}.{item.Time.Millisecond:D4}"); } + private sealed class Crc64Column : ColumnString + { + public override float Width + => UiBuilder.MonoFont.GetCharAdvance('0') * 17; + + public override unsafe string ToName(Record item) + => item.Crc64 != 0 ? $"{item.Crc64:X16}" : string.Empty; + + public override unsafe void DrawColumn(Record item, int _) + { + using var font = ImRaii.PushFont(UiBuilder.MonoFont, item.Handle != null); + ImUtf8.Text(ToName(item)); + } + } + private sealed class CollectionColumn : ColumnString { diff --git a/Penumbra/UI/Tabs/Debug/AtchDrawer.cs b/Penumbra/UI/Tabs/Debug/AtchDrawer.cs index 3e407e99..d9058083 100644 --- a/Penumbra/UI/Tabs/Debug/AtchDrawer.cs +++ b/Penumbra/UI/Tabs/Debug/AtchDrawer.cs @@ -2,6 +2,7 @@ using OtterGui; using OtterGui.Text; using Penumbra.GameData.Files; +using Penumbra.GameData.Files.AtchStructs; namespace Penumbra.UI.Tabs.Debug; @@ -18,27 +19,27 @@ public static void Draw(AtchFile file) ImGui.SameLine(); using (ImUtf8.Group()) { - ImUtf8.Text($"{file.Entries.Count}"); - if (file.Entries.Count == 0) + ImUtf8.Text($"{file.Points.Count}"); + if (file.Points.Count == 0) { ImUtf8.Text("0"u8); return; } - ImUtf8.Text($"{file.Entries[0].States.Count}"); + ImUtf8.Text($"{file.Points[0].Entries.Length}"); } - foreach (var (entry, index) in file.Entries.WithIndex()) + foreach (var (entry, index) in file.Points.WithIndex()) { using var id = ImUtf8.PushId(index); - using var tree = ImUtf8.TreeNode($"{index:D3}: {entry.Name.Span}"); + using var tree = ImUtf8.TreeNode($"{index:D3}: {entry.Type.ToName()}"); if (tree) { ImUtf8.TreeNode(entry.Accessory ? "Accessory"u8 : "Weapon"u8, ImGuiTreeNodeFlags.Bullet | ImGuiTreeNodeFlags.Leaf).Dispose(); - foreach (var (state, i) in entry.States.WithIndex()) + foreach (var (state, i) in entry.Entries.WithIndex()) { id.Push(i); - using var t = ImUtf8.TreeNode(state.Bone.Span); + using var t = ImUtf8.TreeNode(state.Bone); if (t) { ImUtf8.TreeNode($"Scale: {state.Scale}", ImGuiTreeNodeFlags.Bullet | ImGuiTreeNodeFlags.Leaf).Dispose(); diff --git a/Penumbra/UI/Tabs/Debug/DebugTab.cs b/Penumbra/UI/Tabs/Debug/DebugTab.cs index 28911b05..fc735d04 100644 --- a/Penumbra/UI/Tabs/Debug/DebugTab.cs +++ b/Penumbra/UI/Tabs/Debug/DebugTab.cs @@ -104,7 +104,7 @@ public class DebugTab : Window, ITab, IUiService private readonly CrashHandlerPanel _crashHandlerPanel; private readonly TexHeaderDrawer _texHeaderDrawer; private readonly HookOverrideDrawer _hookOverrides; - private readonly TexMdlScdService _texMdlScdService; + private readonly RsfService _rsfService; public DebugTab(PerformanceTracker performance, Configuration config, CollectionManager collectionManager, ObjectManager objects, IClientState clientState, IDataManager dataManager, @@ -115,7 +115,7 @@ public DebugTab(PerformanceTracker performance, Configuration config, Collection CutsceneService cutsceneService, ModImportManager modImporter, ImportPopup importPopup, FrameworkManager framework, TextureManager textureManager, ShaderReplacementFixer shaderReplacementFixer, RedrawService redraws, DictEmote emotes, Diagnostics diagnostics, IpcTester ipcTester, CrashHandlerPanel crashHandlerPanel, TexHeaderDrawer texHeaderDrawer, - HookOverrideDrawer hookOverrides, TexMdlScdService texMdlScdService) + HookOverrideDrawer hookOverrides, RsfService rsfService) : base("Penumbra Debug Window", ImGuiWindowFlags.NoCollapse) { IsOpen = true; @@ -153,7 +153,7 @@ public DebugTab(PerformanceTracker performance, Configuration config, Collection _crashHandlerPanel = crashHandlerPanel; _texHeaderDrawer = texHeaderDrawer; _hookOverrides = hookOverrides; - _texMdlScdService = texMdlScdService; + _rsfService = rsfService; _objects = objects; _clientState = clientState; _dataManager = dataManager; @@ -1087,7 +1087,7 @@ private unsafe void DrawCrcCache() ImUtf8.TableSetupColumn("Type"u8, ImGuiTableColumnFlags.WidthFixed, 5 * UiBuilder.MonoFont.GetCharAdvance('0')); ImGui.TableHeadersRow(); - foreach (var (hash, type) in _texMdlScdService.CustomCache) + foreach (var (hash, type) in _rsfService.CustomCache) { ImGui.TableNextColumn(); ImUtf8.Text($"{hash:X16}");