From 5abbd8b1101090afba2729cfbbf4adeeb673e615 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 17 Jul 2024 18:34:03 +0200 Subject: [PATCH] Hook UpdateRender despite per-frame calls. --- Penumbra.GameData | 2 +- Penumbra/Interop/Hooks/Meta/GetEqpIndirect.cs | 37 ------------------- .../{GetEqpIndirect2.cs => UpdateRender.cs} | 15 +++----- 3 files changed, 6 insertions(+), 48 deletions(-) delete mode 100644 Penumbra/Interop/Hooks/Meta/GetEqpIndirect.cs rename Penumbra/Interop/Hooks/Meta/{GetEqpIndirect2.cs => UpdateRender.cs} (55%) diff --git a/Penumbra.GameData b/Penumbra.GameData index 94df458d..c5ad1f3a 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit 94df458dfb2a704a611fa77d955808284aeb23ac +Subproject commit c5ad1f3ae9818baa446327bdcf49fac65088c703 diff --git a/Penumbra/Interop/Hooks/Meta/GetEqpIndirect.cs b/Penumbra/Interop/Hooks/Meta/GetEqpIndirect.cs deleted file mode 100644 index 8bd49500..00000000 --- a/Penumbra/Interop/Hooks/Meta/GetEqpIndirect.cs +++ /dev/null @@ -1,37 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using OtterGui.Services; -using Penumbra.Collections; -using Penumbra.GameData; -using Penumbra.Interop.PathResolving; - -namespace Penumbra.Interop.Hooks.Meta; - -public sealed unsafe class GetEqpIndirect : FastHook -{ - private readonly CollectionResolver _collectionResolver; - private readonly MetaState _metaState; - - public GetEqpIndirect(HookManager hooks, CollectionResolver collectionResolver, MetaState metaState) - { - _collectionResolver = collectionResolver; - _metaState = metaState; - Task = hooks.CreateHook("Get EQP Indirect", Sigs.GetEqpIndirect, Detour, HookSettings.MetaParentHooks); - } - - public delegate void Delegate(DrawObject* drawObject); - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - private void Detour(DrawObject* drawObject) - { - // Shortcut because this is also called all the time. - // Same thing is checked at the beginning of the original function. - if ((*(byte*)((nint)drawObject + Offsets.GetEqpIndirectSkip1) & 1) == 0 || *(ulong*)((nint)drawObject + Offsets.GetEqpIndirectSkip2) == 0) - return; - - Penumbra.Log.Excessive($"[Get EQP Indirect] Invoked on {(nint)drawObject:X}."); - var collection = _collectionResolver.IdentifyCollection(drawObject, true); - _metaState.EqpCollection.Push(collection); - Task.Result.Original(drawObject); - _metaState.EqpCollection.Pop(); - } -} diff --git a/Penumbra/Interop/Hooks/Meta/GetEqpIndirect2.cs b/Penumbra/Interop/Hooks/Meta/UpdateRender.cs similarity index 55% rename from Penumbra/Interop/Hooks/Meta/GetEqpIndirect2.cs rename to Penumbra/Interop/Hooks/Meta/UpdateRender.cs index e90674a8..95cc0e15 100644 --- a/Penumbra/Interop/Hooks/Meta/GetEqpIndirect2.cs +++ b/Penumbra/Interop/Hooks/Meta/UpdateRender.cs @@ -1,20 +1,20 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using OtterGui.Services; -using Penumbra.GameData; using Penumbra.Interop.PathResolving; namespace Penumbra.Interop.Hooks.Meta; -public sealed unsafe class GetEqpIndirect2 : FastHook +/// The actual function is inlined, so we need to hook its only callsite: Human.UpdateRender instead. +public sealed unsafe class UpdateRender : FastHook { private readonly CollectionResolver _collectionResolver; private readonly MetaState _metaState; - public GetEqpIndirect2(HookManager hooks, CollectionResolver collectionResolver, MetaState metaState) + public UpdateRender(HookManager hooks, CollectionResolver collectionResolver, MetaState metaState, CharacterBaseVTables vTables) { _collectionResolver = collectionResolver; _metaState = metaState; - Task = hooks.CreateHook("Get EQP Indirect 2", Sigs.GetEqpIndirect2, Detour, HookSettings.MetaParentHooks); + Task = hooks.CreateHook("Human.UpdateRender", vTables.HumanVTable[4], Detour, HookSettings.MetaParentHooks); } public delegate void Delegate(DrawObject* drawObject); @@ -22,12 +22,7 @@ public sealed unsafe class GetEqpIndirect2 : FastHook [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private void Detour(DrawObject* drawObject) { - // Shortcut because this is also called all the time. - // Same thing is checked at the beginning of the original function. - if (((*(uint*)((nint)drawObject + Offsets.GetEqpIndirect2Skip) >> 0x12) & 1) == 0) - return; - - Penumbra.Log.Excessive($"[Get EQP Indirect 2] Invoked on {(nint)drawObject:X}."); + Penumbra.Log.Excessive($"[Human.UpdateRender] Invoked on {(nint)drawObject:X}."); var collection = _collectionResolver.IdentifyCollection(drawObject, true); _metaState.EqpCollection.Push(collection); Task.Result.Original(drawObject);