diff --git a/PalettePlus/Interop/Hooks.cs b/PalettePlus/Interop/Hooks.cs index e2cf997..d9226ff 100644 --- a/PalettePlus/Interop/Hooks.cs +++ b/PalettePlus/Interop/Hooks.cs @@ -1,11 +1,12 @@ using System; -using System.Runtime.InteropServices; -using System.Collections.Generic; using System.Linq; +using System.Collections.Generic; using Dalamud.Hooking; using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Utility.Signatures; +using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using CSGameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject; using PalettePlus.Structs; @@ -14,70 +15,49 @@ using PalettePlus.Palettes; namespace PalettePlus.Interop { - internal static class Hooks { - private const string QWordSig = "4C 8B C0 48 8B 0D ?? ?? ?? ??"; - private const string UpdateColorsSig = "E8 ?? ?? ?? ?? B2 FF 48 8B CB"; - private const string GenerateColorsSig = "48 8B C4 4C 89 40 18 48 89 50 10 55 53"; - private const string EnableDrawSig = "E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9 74 33 45 33 C0"; - private const string CopyCharaSig = "E8 ?? ?? ?? ?? 0F B6 9F ?? ?? ?? ?? 48 8D 8F"; - private const string UpdateCharaSig = "E8 ?? ?? ?? ?? 83 BF ?? ?? ?? ?? ?? 75 34"; - + internal class Hooks { internal static Dictionary ActorCopy = new(); - internal static nint UnknownQWord; - - internal unsafe delegate nint UpdateColorsDelegate(Model* a1); + [Signature("E8 ?? ?? ?? ?? B2 FF 48 8B CB")] internal static UpdateColorsDelegate UpdateColors = null!; - //internal static Hook UpdateColorsHook = null!; - - internal unsafe delegate nint GenerateColorsDelegate(IntPtr a1, ModelShader* model, ModelShader* decal, byte* customize); + internal unsafe delegate nint UpdateColorsDelegate(Model* a1); + + [Signature("48 8B C4 4C 89 40 18 48 89 50 10 55 53")] internal static GenerateColorsDelegate GenerateColors = null!; + internal unsafe delegate nint GenerateColorsDelegate(CharacterUtility* a1, ModelShader* model, ModelShader* decal, byte* customize); + [Signature("E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9 74 33 45 33 C0", DetourName = nameof(EnableDrawDetour))] + private Hook EnableDrawHook = null!; private unsafe delegate nint EnableDrawDelegate(CSGameObject* a1); - private static Hook EnableDrawHook = null!; - - private delegate nint CopyCharaDelegate(nint to, nint from, uint unk); - private static Hook CopyCharaHook = null!; - - private delegate nint UpdateCharaDelegate(nint drawObj, nint data, char skipEquip); - private static Hook UpdateCharaHook = null!; - - internal unsafe static void Init() { - UnknownQWord = *(IntPtr*)PluginServices.SigScanner.GetStaticAddressFromSig(QWordSig); - - var updateColors = PluginServices.SigScanner.ScanText(UpdateColorsSig); - UpdateColors = Marshal.GetDelegateForFunctionPointer(updateColors); - //UpdateColorsHook = Hook.FromAddress(updateColors, UpdateColorsDetour); - //UpdateColorsHook.Enable(); - - var generateColors = PluginServices.SigScanner.ScanText(GenerateColorsSig); - GenerateColors = Marshal.GetDelegateForFunctionPointer(generateColors); - - EnableDrawHook = PluginServices.Hooks.HookFromSignature(EnableDrawSig, EnableDrawDetour); - EnableDrawHook.Enable(); - - CopyCharaHook = PluginServices.Hooks.HookFromSignature(CopyCharaSig, CopyCharaDetour); - CopyCharaHook.Enable(); - - UpdateCharaHook = PluginServices.Hooks.HookFromSignature(UpdateCharaSig, UpdateCharaDetour); - UpdateCharaHook.Enable(); - } - internal static void Dispose() { - //UpdateColorsHook.Disable(); - //UpdateColorsHook.Dispose(); + [Signature("E8 ?? ?? ?? ?? 0F B6 9F ?? ?? ?? ?? 48 8D 8F", DetourName = nameof(CopyCharaDetour))] + private Hook CopyCharaHook = null!; + private unsafe delegate nint CopyCharaDelegate(CharaSetup* to, nint from, uint unk); + + [Signature("E8 ?? ?? ?? ?? 83 BF ?? ?? ?? ?? ?? 75 34", DetourName = nameof(UpdateCharaDetour))] + private Hook UpdateCharaHook = null!; + private delegate bool UpdateCharaDelegate(nint drawObj, nint data, char skipEquip); + + internal void Init() { + PluginServices.Hooks.InitializeFromAttributes(this); + + this.EnableDrawHook.Enable(); + this.CopyCharaHook.Enable(); + this.UpdateCharaHook.Enable(); + } - EnableDrawHook.Disable(); - EnableDrawHook.Dispose(); + internal void Dispose() { + this.EnableDrawHook.Disable(); + this.EnableDrawHook.Dispose(); - CopyCharaHook.Disable(); - CopyCharaHook.Dispose(); + this.CopyCharaHook.Disable(); + this.CopyCharaHook.Dispose(); - UpdateCharaHook.Disable(); - UpdateCharaHook.Dispose(); + this.UpdateCharaHook.Disable(); + this.UpdateCharaHook.Dispose(); } - private unsafe static nint EnableDrawDetour(CSGameObject* a1) { + private unsafe nint EnableDrawDetour(CSGameObject* a1) { var c1 = ((byte)a1->TargetableStatus & 0x80) != 0; var c2 = (a1->RenderFlags & 0x2000000) == 0; var isNew = !(c1 && c2); @@ -97,11 +77,13 @@ private unsafe static nint EnableDrawDetour(CSGameObject* a1) { return exec; } - private static nint CopyCharaDetour(nint to, nint from, uint unk) { + private unsafe nint CopyCharaDetour(CharaSetup* to, nint from, uint unk) { var exec = CopyCharaHook.Original(to, from, unk); try { - var toObj = PluginServices.ObjectTable.CreateObjectReference(to) as Character; + var toAddr = to != null ? (nint)to->Character : nint.Zero; + + var toObj = PluginServices.ObjectTable.CreateObjectReference(toAddr) as Character; var fromObj = PluginServices.ObjectTable.CreateObjectReference(from) as Character; if (toObj != null && fromObj != null && toObj.ObjectIndex >= 200 && toObj.ObjectIndex < 240) { PluginServices.Log.Verbose($"Copying from {fromObj.ObjectIndex} to {toObj.ObjectIndex}"); @@ -114,7 +96,7 @@ private static nint CopyCharaDetour(nint to, nint from, uint unk) { return exec; } - private unsafe static nint UpdateCharaDetour(nint drawObj, nint data, char skipEquip) { + private unsafe bool UpdateCharaDetour(nint drawObj, nint data, char skipEquip) { try { var owner = GetOwner(drawObj); var palette = owner != null ? GetPalette(owner) : null; @@ -143,7 +125,7 @@ private unsafe static nint UpdateCharaDetour(nint drawObj, nint data, char skipE return UpdateCharaHook.Original(drawObj, data, skipEquip); } - private unsafe static Character? GetOwner(nint drawObj) { + private unsafe Character? GetOwner(nint drawObj) { var charas = PluginServices.ObjectTable .Where(obj => obj is Character) .Cast(); @@ -157,7 +139,7 @@ private unsafe static nint UpdateCharaDetour(nint drawObj, nint data, char skipE return null; } - private static Palette? GetPalette(Character chara) { + private Palette? GetPalette(Character chara) { if (!chara.IsValidForPalette()) return null; diff --git a/PalettePlus/PalettePlus.cs b/PalettePlus/PalettePlus.cs index 8517353..a98d844 100644 --- a/PalettePlus/PalettePlus.cs +++ b/PalettePlus/PalettePlus.cs @@ -14,12 +14,15 @@ public sealed class PalettePlus : IDalamudPlugin { public static Configuration Config { get; internal set; } = null!; + private Hooks Hooks; + public PalettePlus(DalamudPluginInterface api) { PluginServices.Init(api); Configuration.LoadConfig(); - Hooks.Init(); + this.Hooks = new Hooks(); + this.Hooks.Init(); IpcProvider.Init(); @@ -43,7 +46,7 @@ public PalettePlus(DalamudPluginInterface api) { public void Dispose() { IpcProvider.Dispose(); - Hooks.Dispose(); + this.Hooks.Dispose(); PluginServices.Interface.UiBuilder.Draw -= PluginGui.Windows.Draw; diff --git a/PalettePlus/Structs/Model.cs b/PalettePlus/Structs/Model.cs index 14a8015..b4c9a94 100644 --- a/PalettePlus/Structs/Model.cs +++ b/PalettePlus/Structs/Model.cs @@ -49,7 +49,7 @@ public unsafe ParamContainer GenerateColorValues() { decal.Pointers[i] = (ulong)decal.Parameters; } - Interop.Hooks.GenerateColors!(Interop.Hooks.UnknownQWord, &model, &decal, custom); + Interop.Hooks.GenerateColors(CharacterUtility.Instance(), &model, &decal, custom); } }