From 9fb80907811f1fac339410ba60ce6384c40195a2 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 3 Jul 2024 17:29:49 +0200 Subject: [PATCH] Current state. --- OtterGui | 2 +- Penumbra.GameData | 2 +- Penumbra/Api/Api/GameStateApi.cs | 2 +- .../Cache/CollectionCacheManager.cs | 2 +- .../Collections/Cache/CustomResourceCache.cs | 2 +- Penumbra/Communication/MtrlShpkLoaded.cs | 2 +- Penumbra/Interop/Hooks/HookSettings.cs | 18 ++- .../Hooks/Objects/CharacterBaseDestructor.cs | 2 +- .../Hooks/Objects/CharacterDestructor.cs | 2 +- .../Interop/Hooks/Objects/CopyCharacter.cs | 2 +- .../Hooks/Objects/CreateCharacterBase.cs | 2 +- Penumbra/Interop/Hooks/Objects/EnableDraw.cs | 2 +- .../Interop/Hooks/Objects/WeaponReload.cs | 2 +- .../PreBoneDeformerReplacer.cs | 24 ++-- .../PostProcessing}/ShaderReplacementFixer.cs | 20 ++-- .../ResourceLoading/CreateFileWHook.cs | 5 +- .../ResourceLoading/FileReadService.cs | 11 +- .../ResourceLoading/ResourceLoader.cs | 26 ++-- .../ResourceLoading/ResourceManagerService.cs | 6 +- .../ResourceLoading/ResourceService.cs | 13 +- .../ResourceLoading/TexMdlService.cs | 113 +++++++++++------- .../Hooks/Resources/ApricotResourceLoad.cs | 2 +- .../Interop/Hooks/Resources/LoadMtrlShpk.cs | 2 +- .../Interop/Hooks/Resources/LoadMtrlTex.cs | 2 +- .../Hooks/Resources/ResolvePathHooksBase.cs | 3 +- .../Resources/ResourceHandleDestructor.cs | 2 +- Penumbra/Interop/PathResolving/MetaState.cs | 2 +- .../Interop/PathResolving/PathResolver.cs | 2 +- .../Interop/PathResolving/SubfileHelper.cs | 2 +- .../Processing/FilePostProcessService.cs | 2 +- .../Interop/ResourceTree/ResolveContext.cs | 2 +- Penumbra/Interop/ResourceTree/ResourceTree.cs | 30 +++-- Penumbra/Interop/Services/DecalReverter.cs | 2 +- Penumbra/Penumbra.cs | 2 +- Penumbra/Penumbra.csproj | 1 - Penumbra/Services/CrashHandlerService.cs | 2 +- .../UI/ResourceWatcher/ResourceWatcher.cs | 2 +- Penumbra/UI/Tabs/Debug/DebugTab.cs | 3 +- Penumbra/UI/Tabs/ResourceTab.cs | 2 +- 39 files changed, 186 insertions(+), 139 deletions(-) rename Penumbra/Interop/{Services => Hooks/PostProcessing}/PreBoneDeformerReplacer.cs (81%) rename Penumbra/Interop/{Services => Hooks/PostProcessing}/ShaderReplacementFixer.cs (91%) rename Penumbra/Interop/{ => Hooks}/ResourceLoading/CreateFileWHook.cs (97%) rename Penumbra/Interop/{ => Hooks}/ResourceLoading/FileReadService.cs (92%) rename Penumbra/Interop/{ => Hooks}/ResourceLoading/ResourceLoader.cs (93%) rename Penumbra/Interop/{ => Hooks}/ResourceLoading/ResourceManagerService.cs (93%) rename Penumbra/Interop/{ => Hooks}/ResourceLoading/ResourceService.cs (95%) rename Penumbra/Interop/{ => Hooks}/ResourceLoading/TexMdlService.cs (60%) diff --git a/OtterGui b/OtterGui index 437ef65c..c2738e1d 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 437ef65c6464c54c8f40196dd2428da901d73aab +Subproject commit c2738e1d42974cddbe5a31238c6ed236a831d17d diff --git a/Penumbra.GameData b/Penumbra.GameData index 3a97e5ae..066637ab 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit 3a97e5aeee3b7375b333c1add5305d0ce80cbf83 +Subproject commit 066637abe05c659b79d84f52e6db33487498f433 diff --git a/Penumbra/Api/Api/GameStateApi.cs b/Penumbra/Api/Api/GameStateApi.cs index becb55ee..b035c886 100644 --- a/Penumbra/Api/Api/GameStateApi.cs +++ b/Penumbra/Api/Api/GameStateApi.cs @@ -2,8 +2,8 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using OtterGui.Services; using Penumbra.Api.Enums; using Penumbra.Collections; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.PathResolving; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Structs; using Penumbra.Services; using Penumbra.String.Classes; diff --git a/Penumbra/Collections/Cache/CollectionCacheManager.cs b/Penumbra/Collections/Cache/CollectionCacheManager.cs index 44c12856..80d4cf1d 100644 --- a/Penumbra/Collections/Cache/CollectionCacheManager.cs +++ b/Penumbra/Collections/Cache/CollectionCacheManager.cs @@ -5,7 +5,7 @@ using Penumbra.Api; using Penumbra.Api.Enums; using Penumbra.Collections.Manager; using Penumbra.Communication; -using Penumbra.Interop.ResourceLoading; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Meta; using Penumbra.Mods; using Penumbra.Mods.Groups; diff --git a/Penumbra/Collections/Cache/CustomResourceCache.cs b/Penumbra/Collections/Cache/CustomResourceCache.cs index 46c28393..e63f8637 100644 --- a/Penumbra/Collections/Cache/CustomResourceCache.cs +++ b/Penumbra/Collections/Cache/CustomResourceCache.cs @@ -1,6 +1,6 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource; using Penumbra.Api.Enums; -using Penumbra.Interop.ResourceLoading; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.SafeHandles; using Penumbra.String.Classes; diff --git a/Penumbra/Communication/MtrlShpkLoaded.cs b/Penumbra/Communication/MtrlShpkLoaded.cs index 8aab0e0e..9d3597a8 100644 --- a/Penumbra/Communication/MtrlShpkLoaded.cs +++ b/Penumbra/Communication/MtrlShpkLoaded.cs @@ -10,7 +10,7 @@ public sealed class MtrlShpkLoaded() : EventWrapper + /// ShaderReplacementFixer = 0, } } diff --git a/Penumbra/Interop/Hooks/HookSettings.cs b/Penumbra/Interop/Hooks/HookSettings.cs index 6d511a28..ed4eb669 100644 --- a/Penumbra/Interop/Hooks/HookSettings.cs +++ b/Penumbra/Interop/Hooks/HookSettings.cs @@ -1,8 +1,14 @@ -namespace Penumbra.Interop.Hooks; - +namespace Penumbra.Interop.Hooks; + public static class HookSettings { - public const bool MetaEntryHooks = false; - public const bool MetaParentHooks = false; - public const bool VfxIdentificationHooks = false; -} + public const bool AllHooks = true; + + public const bool ObjectHooks = false && AllHooks; + public const bool ReplacementHooks = true && AllHooks; + public const bool ResourceHooks = false && AllHooks; + public const bool MetaEntryHooks = false && AllHooks; + public const bool MetaParentHooks = false && AllHooks; + public const bool VfxIdentificationHooks = false && AllHooks; + public const bool PostProcessingHooks = false && AllHooks; +} diff --git a/Penumbra/Interop/Hooks/Objects/CharacterBaseDestructor.cs b/Penumbra/Interop/Hooks/Objects/CharacterBaseDestructor.cs index e01a6550..c67bb9f3 100644 --- a/Penumbra/Interop/Hooks/Objects/CharacterBaseDestructor.cs +++ b/Penumbra/Interop/Hooks/Objects/CharacterBaseDestructor.cs @@ -19,7 +19,7 @@ public sealed unsafe class CharacterBaseDestructor : EventWrapperPtr _task = hooks.CreateHook(Name, Address, Detour, true); + => _task = hooks.CreateHook(Name, Address, Detour, HookSettings.ObjectHooks); private readonly Task> _task; diff --git a/Penumbra/Interop/Hooks/Objects/CharacterDestructor.cs b/Penumbra/Interop/Hooks/Objects/CharacterDestructor.cs index 6e10c5e3..618d0bd7 100644 --- a/Penumbra/Interop/Hooks/Objects/CharacterDestructor.cs +++ b/Penumbra/Interop/Hooks/Objects/CharacterDestructor.cs @@ -19,7 +19,7 @@ public sealed unsafe class CharacterDestructor : EventWrapperPtr _task = hooks.CreateHook(Name, Sigs.CharacterDestructor, Detour, true); + => _task = hooks.CreateHook(Name, Sigs.CharacterDestructor, Detour, HookSettings.ObjectHooks); private readonly Task> _task; diff --git a/Penumbra/Interop/Hooks/Objects/CopyCharacter.cs b/Penumbra/Interop/Hooks/Objects/CopyCharacter.cs index 20c96f56..663209ae 100644 --- a/Penumbra/Interop/Hooks/Objects/CopyCharacter.cs +++ b/Penumbra/Interop/Hooks/Objects/CopyCharacter.cs @@ -15,7 +15,7 @@ public sealed unsafe class CopyCharacter : EventWrapperPtr _task = hooks.CreateHook(Name, Address, Detour, true); + => _task = hooks.CreateHook(Name, Address, Detour, HookSettings.ObjectHooks); private readonly Task> _task; diff --git a/Penumbra/Interop/Hooks/Objects/CreateCharacterBase.cs b/Penumbra/Interop/Hooks/Objects/CreateCharacterBase.cs index 299f312a..56b3d853 100644 --- a/Penumbra/Interop/Hooks/Objects/CreateCharacterBase.cs +++ b/Penumbra/Interop/Hooks/Objects/CreateCharacterBase.cs @@ -16,7 +16,7 @@ public sealed unsafe class CreateCharacterBase : EventWrapperPtr _task = hooks.CreateHook(Name, Address, Detour, true); + => _task = hooks.CreateHook(Name, Address, Detour, HookSettings.ObjectHooks); private readonly Task> _task; diff --git a/Penumbra/Interop/Hooks/Objects/EnableDraw.cs b/Penumbra/Interop/Hooks/Objects/EnableDraw.cs index 267b4711..8b701fe5 100644 --- a/Penumbra/Interop/Hooks/Objects/EnableDraw.cs +++ b/Penumbra/Interop/Hooks/Objects/EnableDraw.cs @@ -17,7 +17,7 @@ public sealed unsafe class EnableDraw : IHookService public EnableDraw(HookManager hooks, GameState state) { _state = state; - _task = hooks.CreateHook("Enable Draw", Sigs.EnableDraw, Detour, true); + _task = hooks.CreateHook("Enable Draw", Sigs.EnableDraw, Detour, HookSettings.ObjectHooks); } private delegate void Delegate(GameObject* gameObject); diff --git a/Penumbra/Interop/Hooks/Objects/WeaponReload.cs b/Penumbra/Interop/Hooks/Objects/WeaponReload.cs index fec0a13f..da31840f 100644 --- a/Penumbra/Interop/Hooks/Objects/WeaponReload.cs +++ b/Penumbra/Interop/Hooks/Objects/WeaponReload.cs @@ -16,7 +16,7 @@ public sealed unsafe class WeaponReload : EventWrapperPtr _task = hooks.CreateHook(Name, Address, Detour, true); + => _task = hooks.CreateHook(Name, Address, Detour, HookSettings.ObjectHooks); private readonly Task> _task; diff --git a/Penumbra/Interop/Services/PreBoneDeformerReplacer.cs b/Penumbra/Interop/Hooks/PostProcessing/PreBoneDeformerReplacer.cs similarity index 81% rename from Penumbra/Interop/Services/PreBoneDeformerReplacer.cs rename to Penumbra/Interop/Hooks/PostProcessing/PreBoneDeformerReplacer.cs index 9f553257..903484ea 100644 --- a/Penumbra/Interop/Services/PreBoneDeformerReplacer.cs +++ b/Penumbra/Interop/Hooks/PostProcessing/PreBoneDeformerReplacer.cs @@ -4,12 +4,13 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.System.Resource; using OtterGui.Services; using Penumbra.Api.Enums; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.PathResolving; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.SafeHandles; using Penumbra.String.Classes; +using CharacterUtility = Penumbra.Interop.Services.CharacterUtility; -namespace Penumbra.Interop.Services; +namespace Penumbra.Interop.Hooks.PostProcessing; public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredService { @@ -29,17 +30,16 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi private readonly IFramework _framework; public PreBoneDeformerReplacer(CharacterUtility utility, CollectionResolver collectionResolver, ResourceLoader resourceLoader, - IGameInteropProvider interop, IFramework framework, CharacterBaseVTables vTables) + HookManager hooks, IFramework framework, CharacterBaseVTables vTables) { - interop.InitializeFromAttributes(this); - _utility = utility; - _collectionResolver = collectionResolver; - _resourceLoader = resourceLoader; - _framework = framework; - _humanSetupScalingHook = interop.HookFromAddress(vTables.HumanVTable[57], SetupScaling); - _humanCreateDeformerHook = interop.HookFromAddress(vTables.HumanVTable[91], CreateDeformer); - _humanSetupScalingHook.Enable(); - _humanCreateDeformerHook.Enable(); + _utility = utility; + _collectionResolver = collectionResolver; + _resourceLoader = resourceLoader; + _framework = framework; + _humanSetupScalingHook = hooks.CreateHook("HumanSetupScaling", vTables.HumanVTable[58], SetupScaling, + HookSettings.PostProcessingHooks).Result; + _humanCreateDeformerHook = hooks.CreateHook("HumanCreateDeformer", vTables.HumanVTable[101], + CreateDeformer, HookSettings.PostProcessingHooks).Result; } public void Dispose() diff --git a/Penumbra/Interop/Services/ShaderReplacementFixer.cs b/Penumbra/Interop/Hooks/PostProcessing/ShaderReplacementFixer.cs similarity index 91% rename from Penumbra/Interop/Services/ShaderReplacementFixer.cs rename to Penumbra/Interop/Hooks/PostProcessing/ShaderReplacementFixer.cs index 95e70b45..b27ca4c5 100644 --- a/Penumbra/Interop/Services/ShaderReplacementFixer.cs +++ b/Penumbra/Interop/Hooks/PostProcessing/ShaderReplacementFixer.cs @@ -1,6 +1,4 @@ using Dalamud.Hooking; -using Dalamud.Plugin.Services; -using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Graphics.Render; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; @@ -10,9 +8,11 @@ using Penumbra.Communication; using Penumbra.GameData; using Penumbra.Interop.Hooks.Resources; using Penumbra.Services; +using CharacterUtility = Penumbra.Interop.Services.CharacterUtility; using CSModelRenderer = FFXIVClientStructs.FFXIV.Client.Graphics.Render.ModelRenderer; +using ModelRenderer = Penumbra.Interop.Services.ModelRenderer; -namespace Penumbra.Interop.Services; +namespace Penumbra.Interop.Hooks.PostProcessing; public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredService { @@ -29,8 +29,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic private readonly Hook _humanOnRenderMaterialHook; - [Signature(Sigs.ModelRendererOnRenderMaterial, DetourName = nameof(ModelRendererOnRenderMaterialDetour))] - private readonly Hook _modelRendererOnRenderMaterialHook = null!; + private readonly Hook _modelRendererOnRenderMaterialHook; private readonly ResourceHandleDestructor _resourceHandleDestructor; private readonly CommunicatorService _communicator; @@ -59,19 +58,18 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic => _moddedCharacterGlassShpkCount; public ShaderReplacementFixer(ResourceHandleDestructor resourceHandleDestructor, CharacterUtility utility, ModelRenderer modelRenderer, - CommunicatorService communicator, IGameInteropProvider interop, CharacterBaseVTables vTables) + CommunicatorService communicator, HookManager hooks, CharacterBaseVTables vTables) { - interop.InitializeFromAttributes(this); _resourceHandleDestructor = resourceHandleDestructor; _utility = utility; _modelRenderer = modelRenderer; _communicator = communicator; - _humanOnRenderMaterialHook = - interop.HookFromAddress(vTables.HumanVTable[62], OnRenderHumanMaterial); + _humanOnRenderMaterialHook = hooks.CreateHook("Human.OnRenderMaterial", vTables.HumanVTable[62], + OnRenderHumanMaterial, HookSettings.PostProcessingHooks).Result; + _modelRendererOnRenderMaterialHook = hooks.CreateHook("ModelRenderer.OnRenderMaterial", + Sigs.ModelRendererOnRenderMaterial, ModelRendererOnRenderMaterialDetour, HookSettings.PostProcessingHooks).Result; _communicator.MtrlShpkLoaded.Subscribe(OnMtrlShpkLoaded, MtrlShpkLoaded.Priority.ShaderReplacementFixer); _resourceHandleDestructor.Subscribe(OnResourceHandleDestructor, ResourceHandleDestructor.Priority.ShaderReplacementFixer); - _humanOnRenderMaterialHook.Enable(); - _modelRendererOnRenderMaterialHook.Enable(); } public void Dispose() diff --git a/Penumbra/Interop/ResourceLoading/CreateFileWHook.cs b/Penumbra/Interop/Hooks/ResourceLoading/CreateFileWHook.cs similarity index 97% rename from Penumbra/Interop/ResourceLoading/CreateFileWHook.cs rename to Penumbra/Interop/Hooks/ResourceLoading/CreateFileWHook.cs index bde640d2..a8ac0608 100644 --- a/Penumbra/Interop/ResourceLoading/CreateFileWHook.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/CreateFileWHook.cs @@ -5,7 +5,7 @@ using Penumbra.String; using Penumbra.String.Classes; using Penumbra.String.Functions; -namespace Penumbra.Interop.ResourceLoading; +namespace Penumbra.Interop.Hooks.ResourceLoading; /// /// To allow XIV to load files of arbitrary path length, @@ -19,7 +19,8 @@ public unsafe class CreateFileWHook : IDisposable, IRequiredService public CreateFileWHook(IGameInteropProvider interop) { _createFileWHook = interop.HookFromImport(null, "KERNEL32.dll", "CreateFileW", 0, CreateFileWDetour); - _createFileWHook.Enable(); + if (HookSettings.ReplacementHooks) + _createFileWHook.Enable(); } /// diff --git a/Penumbra/Interop/ResourceLoading/FileReadService.cs b/Penumbra/Interop/Hooks/ResourceLoading/FileReadService.cs similarity index 92% rename from Penumbra/Interop/ResourceLoading/FileReadService.cs rename to Penumbra/Interop/Hooks/ResourceLoading/FileReadService.cs index 5edba790..199525fb 100644 --- a/Penumbra/Interop/ResourceLoading/FileReadService.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/FileReadService.cs @@ -6,16 +6,17 @@ using Penumbra.GameData; using Penumbra.Interop.Structs; using Penumbra.Util; -namespace Penumbra.Interop.ResourceLoading; +namespace Penumbra.Interop.Hooks.ResourceLoading; public unsafe class FileReadService : IDisposable, IRequiredService { public FileReadService(PerformanceTracker performance, ResourceManagerService resourceManager, IGameInteropProvider interop) { _resourceManager = resourceManager; - _performance = performance; + _performance = performance; interop.InitializeFromAttributes(this); - _readSqPackHook.Enable(); + if (HookSettings.ReplacementHooks) + _readSqPackHook.Enable(); } /// Invoked when a file is supposed to be read from SqPack. @@ -49,7 +50,7 @@ public unsafe class FileReadService : IDisposable, IRequiredService _readSqPackHook.Dispose(); } - private readonly PerformanceTracker _performance; + private readonly PerformanceTracker _performance; private readonly ResourceManagerService _resourceManager; private delegate byte ReadSqPackPrototype(nint resourceManager, SeFileDescriptor* pFileDesc, int priority, bool isSync); @@ -60,7 +61,7 @@ public unsafe class FileReadService : IDisposable, IRequiredService private byte ReadSqPackDetour(nint resourceManager, SeFileDescriptor* fileDescriptor, int priority, bool isSync) { using var performance = _performance.Measure(PerformanceType.ReadSqPack); - byte? ret = null; + byte? ret = null; _lastFileThreadResourceManager.Value = resourceManager; ReadSqPack?.Invoke(fileDescriptor, ref priority, ref isSync, ref ret); _lastFileThreadResourceManager.Value = nint.Zero; diff --git a/Penumbra/Interop/ResourceLoading/ResourceLoader.cs b/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs similarity index 93% rename from Penumbra/Interop/ResourceLoading/ResourceLoader.cs rename to Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs index 4a423993..5cac2f32 100644 --- a/Penumbra/Interop/ResourceLoading/ResourceLoader.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs @@ -9,27 +9,27 @@ using Penumbra.String; using Penumbra.String.Classes; using FileMode = Penumbra.Interop.Structs.FileMode; -namespace Penumbra.Interop.ResourceLoading; +namespace Penumbra.Interop.Hooks.ResourceLoading; public unsafe class ResourceLoader : IDisposable, IService { private readonly ResourceService _resources; private readonly FileReadService _fileReadService; - private readonly TexMdlService _texMdlService; + private readonly TexMdlService _texMdlService; private ResolveData _resolvedData = ResolveData.Invalid; public ResourceLoader(ResourceService resources, FileReadService fileReadService, TexMdlService texMdlService) { - _resources = resources; + _resources = resources; _fileReadService = fileReadService; - _texMdlService = texMdlService; + _texMdlService = texMdlService; ResetResolvePath(); - _resources.ResourceRequested += ResourceHandler; + _resources.ResourceRequested += ResourceHandler; _resources.ResourceHandleIncRef += IncRefProtection; _resources.ResourceHandleDecRef += DecRefProtection; - _fileReadService.ReadSqPack += ReadSqPackDetour; + _fileReadService.ReadSqPack += ReadSqPackDetour; } /// Load a resource for a given path and a specific collection. @@ -80,10 +80,10 @@ public unsafe class ResourceLoader : IDisposable, IService public void Dispose() { - _resources.ResourceRequested -= ResourceHandler; + _resources.ResourceRequested -= ResourceHandler; _resources.ResourceHandleIncRef -= IncRefProtection; _resources.ResourceHandleDecRef -= DecRefProtection; - _fileReadService.ReadSqPack -= ReadSqPackDetour; + _fileReadService.ReadSqPack -= ReadSqPackDetour; } private void ResourceHandler(ref ResourceCategory category, ref ResourceType type, ref int hash, ref Utf8GamePath path, @@ -112,7 +112,7 @@ public unsafe class ResourceLoader : IDisposable, IService // Replace the hash and path with the correct one for the replacement. hash = ComputeHash(resolvedPath.Value.InternalName, parameters); var oldPath = path; - path = p; + path = p; returnValue = _resources.GetOriginalResource(sync, category, type, hash, path.Path, parameters); ResourceLoaded?.Invoke(returnValue, oldPath, resolvedPath.Value, data); } @@ -140,12 +140,12 @@ public unsafe class ResourceLoader : IDisposable, IService } var path = ByteString.FromSpanUnsafe(actualPath, gamePath.Path.IsNullTerminated, gamePath.Path.IsAsciiLowerCase, gamePath.Path.IsAscii); - fileDescriptor->ResourceHandle->FileNameData = path.Path; + fileDescriptor->ResourceHandle->FileNameData = path.Path; fileDescriptor->ResourceHandle->FileNameLength = path.Length; MtrlForceSync(fileDescriptor, ref isSync); returnValue = DefaultLoadResource(path, fileDescriptor, priority, isSync, data); // Return original resource handle path so that they can be loaded separately. - fileDescriptor->ResourceHandle->FileNameData = gamePath.Path.Path; + fileDescriptor->ResourceHandle->FileNameData = gamePath.Path.Path; fileDescriptor->ResourceHandle->FileNameLength = gamePath.Path.Length; } @@ -165,7 +165,7 @@ public unsafe class ResourceLoader : IDisposable, IService // Ensure that the file descriptor has its wchar_t array on aligned boundary even if it has to be odd. var fd = stackalloc char[0x11 + 0x0B + 14]; fileDescriptor->FileDescriptor = (byte*)fd + 1; - CreateFileWHook.WritePtr(fd + 0x11, gamePath.Path, gamePath.Length); + CreateFileWHook.WritePtr(fd + 0x11, gamePath.Path, gamePath.Length); CreateFileWHook.WritePtr(&fileDescriptor->Utf16FileName, gamePath.Path, gamePath.Length); // Use the SE ReadFile function. @@ -206,7 +206,7 @@ public unsafe class ResourceLoader : IDisposable, IService return; _incMode.Value = true; - returnValue = _resources.IncRef(handle); + returnValue = _resources.IncRef(handle); _incMode.Value = false; } diff --git a/Penumbra/Interop/ResourceLoading/ResourceManagerService.cs b/Penumbra/Interop/Hooks/ResourceLoading/ResourceManagerService.cs similarity index 93% rename from Penumbra/Interop/ResourceLoading/ResourceManagerService.cs rename to Penumbra/Interop/Hooks/ResourceLoading/ResourceManagerService.cs index 0479d2a6..1bff80ba 100644 --- a/Penumbra/Interop/ResourceLoading/ResourceManagerService.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/ResourceManagerService.cs @@ -8,7 +8,7 @@ using OtterGui.Services; using Penumbra.Api.Enums; using Penumbra.GameData; -namespace Penumbra.Interop.ResourceLoading; +namespace Penumbra.Interop.Hooks.ResourceLoading; public unsafe class ResourceManagerService : IRequiredService { @@ -23,10 +23,10 @@ public unsafe class ResourceManagerService : IRequiredService public ResourceHandle* FindResource(ResourceCategory cat, ResourceType ext, uint crc32) { ref var manager = ref *ResourceManager; - var catIdx = (uint)cat >> 0x18; + var catIdx = (uint)cat >> 0x18; cat = (ResourceCategory)(ushort)cat; ref var category = ref manager.ResourceGraph->Containers[(int)cat]; - var extMap = FindInMap(category.CategoryMaps[(int)catIdx].Value, (uint)ext); + var extMap = FindInMap(category.CategoryMaps[(int)catIdx].Value, (uint)ext); if (extMap == null) return null; diff --git a/Penumbra/Interop/ResourceLoading/ResourceService.cs b/Penumbra/Interop/Hooks/ResourceLoading/ResourceService.cs similarity index 95% rename from Penumbra/Interop/ResourceLoading/ResourceService.cs rename to Penumbra/Interop/Hooks/ResourceLoading/ResourceService.cs index d623d72d..0b00452b 100644 --- a/Penumbra/Interop/ResourceLoading/ResourceService.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/ResourceService.cs @@ -12,7 +12,7 @@ using Penumbra.String.Classes; using Penumbra.Util; using CSResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle; -namespace Penumbra.Interop.ResourceLoading; +namespace Penumbra.Interop.Hooks.ResourceLoading; public unsafe class ResourceService : IDisposable, IRequiredService { @@ -24,16 +24,19 @@ public unsafe class ResourceService : IDisposable, IRequiredService _performance = performance; _resourceManager = resourceManager; interop.InitializeFromAttributes(this); - _getResourceSyncHook.Enable(); - _getResourceAsyncHook.Enable(); _incRefHook = interop.HookFromAddress( (nint)CSResourceHandle.MemberFunctionPointers.IncRef, ResourceHandleIncRefDetour); - _incRefHook.Enable(); _decRefHook = interop.HookFromAddress( (nint)CSResourceHandle.MemberFunctionPointers.DecRef, ResourceHandleDecRefDetour); - _decRefHook.Enable(); + if (HookSettings.ReplacementHooks) + { + _getResourceSyncHook.Enable(); + _getResourceAsyncHook.Enable(); + _incRefHook.Enable(); + _decRefHook.Enable(); + } } public ResourceHandle* GetResource(ResourceCategory category, ResourceType type, ByteString path) diff --git a/Penumbra/Interop/ResourceLoading/TexMdlService.cs b/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs similarity index 60% rename from Penumbra/Interop/ResourceLoading/TexMdlService.cs rename to Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs index a2b43c64..28ad7aa4 100644 --- a/Penumbra/Interop/ResourceLoading/TexMdlService.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs @@ -1,109 +1,138 @@ using Dalamud.Hooking; using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; -using FFXIVClientStructs.FFXIV.Client.LayoutEngine; -using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; +using Lumina.Excel.GeneratedSheets2; using OtterGui.Services; using Penumbra.Api.Enums; using Penumbra.GameData; +using Penumbra.Interop.Structs; using Penumbra.String.Classes; +using FileMode = Penumbra.Interop.Structs.FileMode; +using ResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle; -namespace Penumbra.Interop.ResourceLoading; +namespace Penumbra.Interop.Hooks.ResourceLoading; public unsafe class TexMdlService : IDisposable, IRequiredService { /// Custom ulong flag to signal our files as opposed to SE files. public static readonly nint CustomFileFlag = new(0xDEADBEEF); - + /// /// We need to keep a list of all CRC64 hash values of our replaced Mdl and Tex files, /// i.e. CRC32 of filename in the lower bytes, CRC32 of parent path in the upper bytes. /// public IReadOnlySet CustomFileCrc => _customFileCrc; - + public TexMdlService(IGameInteropProvider interop) { interop.InitializeFromAttributes(this); - //_checkFileStateHook.Enable(); - //_loadTexFileExternHook.Enable(); - //_loadMdlFileExternHook.Enable(); + if (HookSettings.ReplacementHooks) + { + _checkFileStateHook.Enable(); + _loadMdlFileExternHook.Enable(); + _textureSomethingHook.Enable(); + _vf32Hook.Enable(); + //_loadTexFileExternHook.Enable(); + } } - + /// Add CRC64 if the given file is a model or texture file and has an associated path. public void AddCrc(ResourceType type, FullPath? path) { - if (path.HasValue && type is ResourceType.Mdl or ResourceType.Tex) + if (path.HasValue && type is ResourceType.Mdl) _customFileCrc.Add(path.Value.Crc64); } - + /// Add a fixed CRC64 value. public void AddCrc(ulong crc64) => _customFileCrc.Add(crc64); - + public void Dispose() { - //_checkFileStateHook.Dispose(); + _checkFileStateHook.Dispose(); //_loadTexFileExternHook.Dispose(); - //_loadMdlFileExternHook.Dispose(); + _textureSomethingHook.Dispose(); + _loadMdlFileExternHook.Dispose(); + _vf32Hook.Dispose(); } - - private readonly HashSet _customFileCrc = new(); - + + private readonly HashSet _customFileCrc = []; + private delegate nint CheckFileStatePrototype(nint unk1, ulong crc64); - + + private delegate nint TextureSomethingDelegate(TextureResourceHandle* handle, int lod, SeFileDescriptor* descriptor); + [Signature(Sigs.CheckFileState, DetourName = nameof(CheckFileStateDetour))] private readonly Hook _checkFileStateHook = null!; - + + [Signature("E8 ?? ?? ?? ?? 0F B6 C8 EB ?? 4C 8B 83", DetourName = nameof(TextureSomethingDetour))] + private readonly Hook _textureSomethingHook = null!; + + private nint TextureSomethingDetour(TextureResourceHandle* handle, int lod, SeFileDescriptor* descriptor) + { + //Penumbra.Log.Information($"SomethingDetour {handle->Handle.FileName()}"); + //if (!handle->Handle.GamePath(out var path) || !path.IsRooted()) + return _textureSomethingHook.Original(handle, lod, descriptor); + + descriptor->FileMode = FileMode.LoadUnpackedResource; + return _loadTexFileLocal.Invoke((ResourceHandle*)handle, lod, (nint)descriptor, true); + } + /// /// The function that checks a files CRC64 to determine whether it is 'protected'. /// We use it to check against our stored CRC64s and if it corresponds, we return the custom flag. /// private nint CheckFileStateDetour(nint ptr, ulong crc64) => _customFileCrc.Contains(crc64) ? CustomFileFlag : _checkFileStateHook.Original(ptr, crc64); - - + + private delegate byte LoadTexFileLocalDelegate(ResourceHandle* handle, int unk1, nint unk2, bool unk3); - + /// We use the local functions for our own files in the extern hook. [Signature(Sigs.LoadTexFileLocal)] private readonly LoadTexFileLocalDelegate _loadTexFileLocal = null!; - + private delegate byte LoadMdlFileLocalPrototype(ResourceHandle* handle, nint unk1, bool unk2); - + /// We use the local functions for our own files in the extern hook. [Signature(Sigs.LoadMdlFileLocal)] private readonly LoadMdlFileLocalPrototype _loadMdlFileLocal = null!; - - + + private delegate byte LoadTexFileExternPrototype(ResourceHandle* handle, int unk1, nint unk2, bool unk3, nint unk4); + + private delegate byte TexResourceHandleVf32Prototype(TextureResourceHandle* handle, SeFileDescriptor* descriptor, byte unk2); + + [Signature("40 53 55 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9", DetourName = nameof(Vf32Detour))] + private readonly Hook _vf32Hook = null!; - private delegate byte TexResourceHandleVf32Prototype(ResourceHandle* handle, nint unk1, byte unk2); - - //[Signature("40 53 55 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9", DetourName = nameof(Vf32Detour))] - //private readonly Hook _vf32Hook = null!; - // - //private byte Vf32Detour(ResourceHandle* handle, nint unk1, byte unk2) - //{ - // var ret = _vf32Hook.Original(handle, unk1, unk2); - // return _loadTexFileLocal() - //} - + private byte Vf32Detour(TextureResourceHandle* handle, SeFileDescriptor* descriptor, byte unk2) + { + //if (handle->Handle.GamePath(out var path) && path.IsRooted()) + //{ + // Penumbra.Log.Information($"Replacing {descriptor->FileMode} with {FileMode.LoadSqPackResource} in VF32 for {path}."); + // descriptor->FileMode = FileMode.LoadSqPackResource; + //} + + var ret = _vf32Hook.Original(handle, descriptor, unk2); + return ret; + } + //[Signature(Sigs.LoadTexFileExtern, DetourName = nameof(LoadTexFileExternDetour))] //private readonly Hook _loadTexFileExternHook = null!; - + /// We hook the extern functions to just return the local one if given the custom flag as last argument. //private byte LoadTexFileExternDetour(ResourceHandle* resourceHandle, int unk1, nint unk2, bool unk3, nint ptr) // => ptr.Equals(CustomFileFlag) // ? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3) // : _loadTexFileExternHook.Original(resourceHandle, unk1, unk2, unk3, ptr); - public delegate byte LoadMdlFileExternPrototype(ResourceHandle* handle, nint unk1, bool unk2, nint unk3); - - + + [Signature(Sigs.LoadMdlFileExtern, DetourName = nameof(LoadMdlFileExternDetour))] private readonly Hook _loadMdlFileExternHook = null!; - + /// We hook the extern functions to just return the local one if given the custom flag as last argument. private byte LoadMdlFileExternDetour(ResourceHandle* resourceHandle, nint unk1, bool unk2, nint ptr) => ptr.Equals(CustomFileFlag) diff --git a/Penumbra/Interop/Hooks/Resources/ApricotResourceLoad.cs b/Penumbra/Interop/Hooks/Resources/ApricotResourceLoad.cs index 2e5698a3..511e842f 100644 --- a/Penumbra/Interop/Hooks/Resources/ApricotResourceLoad.cs +++ b/Penumbra/Interop/Hooks/Resources/ApricotResourceLoad.cs @@ -11,7 +11,7 @@ public sealed unsafe class ApricotResourceLoad : FastHook("Load Apricot Resource", Sigs.ApricotResourceLoad, Detour, true); + Task = hooks.CreateHook("Load Apricot Resource", Sigs.ApricotResourceLoad, Detour, HookSettings.ResourceHooks); } public delegate byte Delegate(ResourceHandle* handle, nint unk1, byte unk2); diff --git a/Penumbra/Interop/Hooks/Resources/LoadMtrlShpk.cs b/Penumbra/Interop/Hooks/Resources/LoadMtrlShpk.cs index 5ef3bf37..8447762b 100644 --- a/Penumbra/Interop/Hooks/Resources/LoadMtrlShpk.cs +++ b/Penumbra/Interop/Hooks/Resources/LoadMtrlShpk.cs @@ -14,7 +14,7 @@ public sealed unsafe class LoadMtrlShpk : FastHook { _gameState = gameState; _communicator = communicator; - Task = hooks.CreateHook("Load Material Shaders", Sigs.LoadMtrlShpk, Detour, true); + Task = hooks.CreateHook("Load Material Shaders", Sigs.LoadMtrlShpk, Detour, HookSettings.ResourceHooks); } public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle); diff --git a/Penumbra/Interop/Hooks/Resources/LoadMtrlTex.cs b/Penumbra/Interop/Hooks/Resources/LoadMtrlTex.cs index 14a011ea..7bc3c7b0 100644 --- a/Penumbra/Interop/Hooks/Resources/LoadMtrlTex.cs +++ b/Penumbra/Interop/Hooks/Resources/LoadMtrlTex.cs @@ -11,7 +11,7 @@ public sealed unsafe class LoadMtrlTex : FastHook public LoadMtrlTex(HookManager hooks, GameState gameState) { _gameState = gameState; - Task = hooks.CreateHook("Load Material Textures", Sigs.LoadMtrlTex, Detour, true); + Task = hooks.CreateHook("Load Material Textures", Sigs.LoadMtrlTex, Detour, HookSettings.ResourceHooks); } public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle); diff --git a/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs b/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs index a7e82b72..8fa6d861 100644 --- a/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs +++ b/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs @@ -59,7 +59,8 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable _resolveVfxPathHook = Create( $"{name}.{nameof(ResolveVfx)}", hooks, vTable[93], type, ResolveVfx, ResolveVfxHuman); _resolveEidPathHook = Create( $"{name}.{nameof(ResolveEid)}", hooks, vTable[94], ResolveEid); // @formatter:on - Enable(); + if (HookSettings.ResourceHooks) + Enable(); } public void Enable() diff --git a/Penumbra/Interop/Hooks/Resources/ResourceHandleDestructor.cs b/Penumbra/Interop/Hooks/Resources/ResourceHandleDestructor.cs index ac3f504a..cd4a53c4 100644 --- a/Penumbra/Interop/Hooks/Resources/ResourceHandleDestructor.cs +++ b/Penumbra/Interop/Hooks/Resources/ResourceHandleDestructor.cs @@ -23,7 +23,7 @@ public sealed unsafe class ResourceHandleDestructor : EventWrapperPtr _task = hooks.CreateHook(Name, Sigs.ResourceHandleDestructor, Detour, true); + => _task = hooks.CreateHook(Name, Sigs.ResourceHandleDestructor, Detour, HookSettings.ResourceHooks); private readonly Task> _task; diff --git a/Penumbra/Interop/PathResolving/MetaState.cs b/Penumbra/Interop/PathResolving/MetaState.cs index 5eacbfb0..e709c210 100644 --- a/Penumbra/Interop/PathResolving/MetaState.cs +++ b/Penumbra/Interop/PathResolving/MetaState.cs @@ -4,12 +4,12 @@ using OtterGui.Services; using Penumbra.Collections; using Penumbra.Api.Enums; using Penumbra.GameData.Structs; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Services; using Penumbra.Services; using Penumbra.String.Classes; using CharacterUtility = Penumbra.Interop.Services.CharacterUtility; using Penumbra.Interop.Hooks.Objects; +using Penumbra.Interop.Hooks.ResourceLoading; namespace Penumbra.Interop.PathResolving; diff --git a/Penumbra/Interop/PathResolving/PathResolver.cs b/Penumbra/Interop/PathResolving/PathResolver.cs index cc3e0e9b..49035dc8 100644 --- a/Penumbra/Interop/PathResolving/PathResolver.cs +++ b/Penumbra/Interop/PathResolving/PathResolver.cs @@ -3,8 +3,8 @@ using OtterGui.Services; using Penumbra.Api.Enums; using Penumbra.Collections; using Penumbra.Collections.Manager; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.Processing; -using Penumbra.Interop.ResourceLoading; using Penumbra.String.Classes; using Penumbra.Util; diff --git a/Penumbra/Interop/PathResolving/SubfileHelper.cs b/Penumbra/Interop/PathResolving/SubfileHelper.cs index 44a152f0..836cf731 100644 --- a/Penumbra/Interop/PathResolving/SubfileHelper.cs +++ b/Penumbra/Interop/PathResolving/SubfileHelper.cs @@ -1,8 +1,8 @@ using OtterGui.Services; using Penumbra.Api.Enums; using Penumbra.Collections; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.Hooks.Resources; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Structs; using Penumbra.String.Classes; diff --git a/Penumbra/Interop/Processing/FilePostProcessService.cs b/Penumbra/Interop/Processing/FilePostProcessService.cs index 0dc62b3d..bba53c94 100644 --- a/Penumbra/Interop/Processing/FilePostProcessService.cs +++ b/Penumbra/Interop/Processing/FilePostProcessService.cs @@ -1,7 +1,7 @@ using System.Collections.Frozen; using OtterGui.Services; using Penumbra.Api.Enums; -using Penumbra.Interop.ResourceLoading; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.Structs; using Penumbra.String; diff --git a/Penumbra/Interop/ResourceTree/ResolveContext.cs b/Penumbra/Interop/ResourceTree/ResolveContext.cs index ca8836b0..a852a4cc 100644 --- a/Penumbra/Interop/ResourceTree/ResolveContext.cs +++ b/Penumbra/Interop/ResourceTree/ResolveContext.cs @@ -9,8 +9,8 @@ using Penumbra.Collections; using Penumbra.GameData.Data; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; +using Penumbra.Interop.Hooks.PostProcessing; using Penumbra.Interop.PathResolving; -using Penumbra.Interop.Services; using Penumbra.String; using Penumbra.String.Classes; using Penumbra.UI; diff --git a/Penumbra/Interop/ResourceTree/ResourceTree.cs b/Penumbra/Interop/ResourceTree/ResourceTree.cs index b8bad84a..810c946d 100644 --- a/Penumbra/Interop/ResourceTree/ResourceTree.cs +++ b/Penumbra/Interop/ResourceTree/ResourceTree.cs @@ -5,7 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; using Penumbra.GameData.Data; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; -using Penumbra.Interop.Services; +using Penumbra.Interop.Hooks.PostProcessing; using Penumbra.UI; using CustomizeData = FFXIVClientStructs.FFXIV.Client.Game.Character.CustomizeData; using CustomizeIndex = Dalamud.Game.ClientState.Objects.Enums.CustomizeIndex; @@ -31,7 +31,8 @@ public class ResourceTree public CustomizeData CustomizeData; public GenderRace RaceCode; - public ResourceTree(string name, string anonymizedName, int gameObjectIndex, nint gameObjectAddress, nint drawObjectAddress, bool localPlayerRelated, bool playerRelated, bool networked, string collectionName, string anonymizedCollectionName) + public ResourceTree(string name, string anonymizedName, int gameObjectIndex, nint gameObjectAddress, nint drawObjectAddress, + bool localPlayerRelated, bool playerRelated, bool networked, string collectionName, string anonymizedCollectionName) { Name = name; AnonymizedName = anonymizedName; @@ -61,9 +62,10 @@ public class ResourceTree var human = modelType == CharacterBase.ModelType.Human ? (Human*)model : null; var equipment = modelType switch { - CharacterBase.ModelType.Human => new ReadOnlySpan(&human->Head, 10), - CharacterBase.ModelType.DemiHuman => new ReadOnlySpan(Unsafe.AsPointer(ref character->DrawData.EquipmentModelIds[0]), 10), - _ => ReadOnlySpan.Empty, + CharacterBase.ModelType.Human => new ReadOnlySpan(&human->Head, 10), + CharacterBase.ModelType.DemiHuman => new ReadOnlySpan( + Unsafe.AsPointer(ref character->DrawData.EquipmentModelIds[0]), 10), + _ => ReadOnlySpan.Empty, }; ModelId = character->CharacterData.ModelCharaId; CustomizeData = character->DrawData.CustomizeData; @@ -112,15 +114,17 @@ public class ResourceTree { if (baseSubObject->GetObjectType() != FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType.CharacterBase) continue; + var subObject = (CharacterBase*)baseSubObject; if (subObject->GetModelType() != CharacterBase.ModelType.Weapon) continue; - var weapon = (Weapon*)subObject; + + var weapon = (Weapon*)subObject; // This way to tell apart MainHand and OffHand is not always accurate, but seems good enough for what we're doing with it. var slot = weaponIndex > 0 ? EquipSlot.OffHand : EquipSlot.MainHand; - var equipment = new CharacterArmor(weapon->ModelSetId, (byte)weapon->Variant, (byte)weapon->ModelUnknown); + var equipment = new CharacterArmor(weapon->ModelSetId, (byte)weapon->Variant, new StainIds(weapon->Stain1, weapon->Stain2)); var weaponType = weapon->SecondaryId; var genericContext = globalContext.CreateContext(subObject, 0xFFFFFFFFu, slot, equipment, weaponType); @@ -152,6 +156,7 @@ public class ResourceTree ++weaponIndex; } + Nodes.InsertRange(0, weaponNodes); } @@ -167,10 +172,11 @@ public class ResourceTree { if (globalContext.WithUiData) { - pbdNode = pbdNode.Clone(); + pbdNode = pbdNode.Clone(); pbdNode.FallbackName = "Racial Deformer"; - pbdNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization; + pbdNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization; } + Nodes.Add(pbdNode); } } @@ -184,10 +190,11 @@ public class ResourceTree { if (globalContext.WithUiData) { - decalNode = decalNode.Clone(); + decalNode = decalNode.Clone(); decalNode.FallbackName = "Face Decal"; decalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization; } + Nodes.Add(decalNode); } @@ -200,10 +207,11 @@ public class ResourceTree { if (globalContext.WithUiData) { - legacyDecalNode = legacyDecalNode.Clone(); + legacyDecalNode = legacyDecalNode.Clone(); legacyDecalNode.FallbackName = "Legacy Body Decal"; legacyDecalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization; } + Nodes.Add(legacyDecalNode); } } diff --git a/Penumbra/Interop/Services/DecalReverter.cs b/Penumbra/Interop/Services/DecalReverter.cs index 17d8d2e0..21b51fd2 100644 --- a/Penumbra/Interop/Services/DecalReverter.cs +++ b/Penumbra/Interop/Services/DecalReverter.cs @@ -1,7 +1,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource; using Penumbra.Api.Enums; using Penumbra.Collections; -using Penumbra.Interop.ResourceLoading; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.String.Classes; namespace Penumbra.Interop.Services; diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs index b1ad0b78..9f2db2e6 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/Penumbra.cs @@ -8,7 +8,6 @@ using Penumbra.Api; using Penumbra.Api.Enums; using Penumbra.Collections; using Penumbra.Collections.Cache; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.PathResolving; using Penumbra.Services; using Penumbra.Interop.Services; @@ -22,6 +21,7 @@ using Penumbra.GameData.Enums; using Penumbra.UI; using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager; using System.Xml.Linq; +using Penumbra.Interop.Hooks.ResourceLoading; namespace Penumbra; diff --git a/Penumbra/Penumbra.csproj b/Penumbra/Penumbra.csproj index ed5c5e30..2e53bd22 100644 --- a/Penumbra/Penumbra.csproj +++ b/Penumbra/Penumbra.csproj @@ -37,7 +37,6 @@ $(AppData)\XIVLauncher\addon\Hooks\dev\ - H:\Projects\FFPlugins\Dalamud\bin\Release\ diff --git a/Penumbra/Services/CrashHandlerService.cs b/Penumbra/Services/CrashHandlerService.cs index 25c6cf57..9103b29c 100644 --- a/Penumbra/Services/CrashHandlerService.cs +++ b/Penumbra/Services/CrashHandlerService.cs @@ -7,8 +7,8 @@ using Penumbra.Communication; using Penumbra.CrashHandler; using Penumbra.CrashHandler.Buffers; using Penumbra.GameData.Actors; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.PathResolving; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Structs; using Penumbra.String; using Penumbra.String.Classes; diff --git a/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs b/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs index c53f1b8e..935f11e3 100644 --- a/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs +++ b/Penumbra/UI/ResourceWatcher/ResourceWatcher.cs @@ -8,8 +8,8 @@ using Penumbra.Api.Enums; using Penumbra.Collections; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Interop.Hooks.Resources; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Structs; using Penumbra.Services; using Penumbra.String; diff --git a/Penumbra/UI/Tabs/Debug/DebugTab.cs b/Penumbra/UI/Tabs/Debug/DebugTab.cs index 41f28ab9..9a03f384 100644 --- a/Penumbra/UI/Tabs/Debug/DebugTab.cs +++ b/Penumbra/UI/Tabs/Debug/DebugTab.cs @@ -25,7 +25,6 @@ using Penumbra.GameData.Interop; using Penumbra.Import.Structs; using Penumbra.Import.Textures; using Penumbra.Interop.PathResolving; -using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Services; using Penumbra.Interop.Structs; using Penumbra.Mods; @@ -40,6 +39,8 @@ using CharacterUtility = Penumbra.Interop.Services.CharacterUtility; using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager; using ImGuiClip = OtterGui.ImGuiClip; using Penumbra.Api.IpcTester; +using Penumbra.Interop.Hooks.PostProcessing; +using Penumbra.Interop.Hooks.ResourceLoading; namespace Penumbra.UI.Tabs.Debug; diff --git a/Penumbra/UI/Tabs/ResourceTab.cs b/Penumbra/UI/Tabs/ResourceTab.cs index 14d4ed41..a4dbba2f 100644 --- a/Penumbra/UI/Tabs/ResourceTab.cs +++ b/Penumbra/UI/Tabs/ResourceTab.cs @@ -8,7 +8,7 @@ using OtterGui; using OtterGui.Raii; using OtterGui.Services; using OtterGui.Widgets; -using Penumbra.Interop.ResourceLoading; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.String.Classes; namespace Penumbra.UI.Tabs;