diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs index fed5d4207..11366e969 100644 --- a/Dalamud/Game/Gui/GameGui.cs +++ b/Dalamud/Game/Gui/GameGui.cs @@ -2,7 +2,6 @@ using System; using System.Numerics; using System.Runtime.InteropServices; -using Dalamud.Game.Gui.Addons; using Dalamud.Game.Gui.FlyText; using Dalamud.Game.Gui.PartyFinder; using Dalamud.Game.Gui.Toast; @@ -24,10 +23,7 @@ namespace Dalamud.Game.Gui private readonly GameGuiAddressResolver address; private readonly GetMatrixSingletonDelegate getMatrixSingleton; - private readonly GetUIObjectDelegate getUIObject; private readonly ScreenToWorldNativeDelegate screenToWorldNative; - private readonly GetUIObjectByNameDelegate getUIObjectByName; - private readonly GetUiModuleDelegate getUiModule; private readonly GetAgentModuleDelegate getAgentModule; private readonly Hook setGlobalBgmHook; @@ -62,7 +58,6 @@ namespace Dalamud.Game.Gui Log.Verbose($"HandleItemHover address 0x{this.address.HandleItemHover.ToInt64():X}"); Log.Verbose($"HandleItemOut address 0x{this.address.HandleItemOut.ToInt64():X}"); Log.Verbose($"HandleImm address 0x{this.address.HandleImm.ToInt64():X}"); - Log.Verbose($"GetUIObject address 0x{this.address.GetUIObject.ToInt64():X}"); Log.Verbose($"GetAgentModule address 0x{this.address.GetAgentModule.ToInt64():X}"); this.Chat = new ChatGui(this.address.ChatManager, scanner, dalamud); @@ -80,44 +75,23 @@ namespace Dalamud.Game.Gui this.handleImmHook = new Hook(this.address.HandleImm, this.HandleImmDetour); - this.getUIObject = Marshal.GetDelegateForFunctionPointer(this.address.GetUIObject); - this.getMatrixSingleton = Marshal.GetDelegateForFunctionPointer(this.address.GetMatrixSingleton); this.screenToWorldNative = Marshal.GetDelegateForFunctionPointer(this.address.ScreenToWorld); this.toggleUiHideHook = new Hook(this.address.ToggleUiHide, this.ToggleUiHideDetour); - this.GetBaseUIObject = Marshal.GetDelegateForFunctionPointer(this.address.GetBaseUIObject); - this.getUIObjectByName = Marshal.GetDelegateForFunctionPointer(this.address.GetUIObjectByName); - - this.getUiModule = Marshal.GetDelegateForFunctionPointer(this.address.GetUIModule); this.getAgentModule = Marshal.GetDelegateForFunctionPointer(this.address.GetAgentModule); } // Marshaled delegates - /// - /// The delegate type of the native method that gets the Client::UI::UIModule address. - /// - /// The Client::UI::UIModule address. - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate IntPtr GetBaseUIObjectDelegate(); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate IntPtr GetMatrixSingletonDelegate(); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr GetUIObjectDelegate(); - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate bool ScreenToWorldNativeDelegate(float* camPos, float* clipPos, float rayDistance, float* worldPos, int* unknown); - [UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Ansi)] - private delegate IntPtr GetUIObjectByNameDelegate(IntPtr thisPtr, string uiName, int index); - - private delegate IntPtr GetUiModuleDelegate(IntPtr basePtr); - private delegate IntPtr GetAgentModuleDelegate(IntPtr uiModule); // Hooked delegates @@ -154,12 +128,6 @@ namespace Dalamud.Game.Gui /// public event EventHandler OnUiHideToggled; - /// - /// Gets a callable delegate for the GetBaseUIObject game method. - /// - /// The Client::UI::UIModule address. - public GetBaseUIObjectDelegate GetBaseUIObject { get; } - /// /// Gets the instance. /// @@ -213,19 +181,19 @@ namespace Dalamud.Game.Gui /// True if there were no errors and it could open the map. public bool OpenMapWithMapLink(MapLinkPayload mapLink) { - var uiObjectPtr = this.getUIObject(); + var uiModule = this.GetUIModule(); - if (uiObjectPtr.Equals(IntPtr.Zero)) + if (uiModule == IntPtr.Zero) { Log.Error("OpenMapWithMapLink: Null pointer returned from getUIObject()"); return false; } - this.getUIMapObject = this.address.GetVirtualFunction(uiObjectPtr, 0, 8); + this.getUIMapObject = this.address.GetVirtualFunction(uiModule, 0, 8); - var uiMapObjectPtr = this.getUIMapObject(uiObjectPtr); + var uiMapObjectPtr = this.getUIMapObject(uiModule); - if (uiMapObjectPtr.Equals(IntPtr.Zero)) + if (uiMapObjectPtr == IntPtr.Zero) { Log.Error("OpenMapWithMapLink: Null pointer returned from GetUIMapObject()"); return false; @@ -408,37 +376,40 @@ namespace Dalamud.Game.Gui /// Gets a pointer to the game's UI module. /// /// IntPtr pointing to UI module. - public IntPtr GetUIModule() => this.getUiModule(this.dalamud.Framework.Address.BaseAddress); - - /// - /// Gets the pointer to the UI Object with the given name and index. - /// - /// Name of UI to find. - /// Index of UI to find (1-indexed). - /// IntPtr.Zero if unable to find UI, otherwise IntPtr pointing to the start of the UI Object. - public IntPtr GetUiObjectByName(string name, int index) + public unsafe IntPtr GetUIModule() { - var baseUi = this.GetBaseUIObject(); - if (baseUi == IntPtr.Zero) return IntPtr.Zero; - var baseUiProperties = Marshal.ReadIntPtr(baseUi, 0x20); - if (baseUiProperties == IntPtr.Zero) return IntPtr.Zero; - return this.getUIObjectByName(baseUiProperties, name, index); + var framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance(); + if (framework == null) + return IntPtr.Zero; + + var uiModule = framework->GetUiModule(); + if (uiModule == null) + return IntPtr.Zero; + + return (IntPtr)uiModule; } /// - /// Gets an Addon by it's internal name. + /// Gets the pointer to the Addon with the given name and index. /// - /// The addon name. - /// The index of the addon, starting at 1. - /// The native memory representation of the addon, if it exists. - public Addon GetAddonByName(string name, int index) + /// Name of addon to find. + /// Index of addon to find (1-indexed). + /// IntPtr.Zero if unable to find UI, otherwise IntPtr pointing to the start of the addon. + public unsafe IntPtr GetAddonByName(string name, int index) { - var address = this.GetUiObjectByName(name, index); + var atkStage = FFXIVClientStructs.FFXIV.Component.GUI.AtkStage.GetSingleton(); + if (atkStage == null) + return IntPtr.Zero; - if (address == IntPtr.Zero) - return null; + var unitMgr = atkStage->RaptureAtkUnitManager; + if (unitMgr == null) + return IntPtr.Zero; - return new Addon(address); + var addon = unitMgr->GetAddonByName(name, index); + if (addon == null) + return IntPtr.Zero; + + return (IntPtr)addon; } /// @@ -448,7 +419,7 @@ namespace Dalamud.Game.Gui /// A pointer to the agent interface. public IntPtr FindAgentInterface(string addonName) { - var addon = this.dalamud.Framework.Gui.GetUiObjectByName(addonName, 1); + var addon = this.GetAddonByName(addonName, 1); return this.FindAgentInterface(addon); } @@ -457,7 +428,14 @@ namespace Dalamud.Game.Gui /// /// The addon address. /// A pointer to the agent interface. - public IntPtr FindAgentInterface(IntPtr addon) + public unsafe IntPtr FindAgentInterface(void* addon) => this.FindAgentInterface((IntPtr)addon); + + /// + /// Find the agent associated with an addon, if possible. + /// + /// The addon address. + /// A pointer to the agent interface. + public unsafe IntPtr FindAgentInterface(IntPtr addon) { if (addon == IntPtr.Zero) return IntPtr.Zero; @@ -474,9 +452,10 @@ namespace Dalamud.Game.Gui return IntPtr.Zero; } - var id = Marshal.ReadInt16(addon, 0x1CE); + var unitBase = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)addon; + var id = unitBase->ParentID; if (id == 0) - id = Marshal.ReadInt16(addon, 0x1CC); + id = unitBase->ID; if (id == 0) return IntPtr.Zero; diff --git a/Dalamud/Game/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Gui/GameGuiAddressResolver.cs index b68ea9496..52e98df6c 100644 --- a/Dalamud/Game/Gui/GameGuiAddressResolver.cs +++ b/Dalamud/Game/Gui/GameGuiAddressResolver.cs @@ -57,11 +57,6 @@ namespace Dalamud.Game.Gui /// public IntPtr HandleImm { get; private set; } - /// - /// Gets the address of the native GetUIObject method. - /// - public IntPtr GetUIObject { get; private set; } - /// /// Gets the address of the native GetMatrixSingleton method. /// @@ -77,21 +72,6 @@ namespace Dalamud.Game.Gui /// public IntPtr ToggleUiHide { get; private set; } - /// - /// Gets the address of the native Client::UI::UIModule getter method. - /// - public IntPtr GetBaseUIObject { get; private set; } - - /// - /// Gets the address of the native GetUIObjectByName method. - /// - public IntPtr GetUIObjectByName { get; private set; } - - /// - /// Gets the address of the native GetUIModule method. - /// - public IntPtr GetUIModule { get; private set; } - /// /// Gets the address of the native GetAgentModule method. /// @@ -106,13 +86,9 @@ namespace Dalamud.Game.Gui this.HandleActionHover = sig.ScanText("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 83 F8 0F"); this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F"); this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09"); - this.GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9"); this.GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??"); this.ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1"); this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??"); - this.GetBaseUIObject = sig.ScanText("E8 ?? ?? ?? ?? 41 B8 01 00 00 00 48 8D 15 ?? ?? ?? ?? 48 8B 48 20 E8 ?? ?? ?? ?? 48 8B CF"); - this.GetUIObjectByName = sig.ScanText("E8 ?? ?? ?? ?? 48 8B CF 48 89 87 ?? ?? 00 00 E8 ?? ?? ?? ?? 41 B8 01 00 00 00"); - this.GetUIModule = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 85 C0 75 2D"); var uiModuleVtableSig = sig.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 4C 89 61 28"); this.GetAgentModule = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size);