From 6b2c531eed44dc112bda68d92dc94584bad15dbb Mon Sep 17 00:00:00 2001 From: goat Date: Thu, 2 Apr 2020 19:59:51 +0900 Subject: [PATCH] feat: add HoveredItem data to Dalamud.Game.Internal.Gui.GameGui --- Dalamud/Game/Internal/Gui/GameGui.cs | 41 ++++++++++++++++++- .../Internal/Gui/GameGuiAddressResolver.cs | 3 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Dalamud/Game/Internal/Gui/GameGui.cs b/Dalamud/Game/Internal/Gui/GameGui.cs index 370341300..6444c0374 100644 --- a/Dalamud/Game/Internal/Gui/GameGui.cs +++ b/Dalamud/Game/Internal/Gui/GameGui.cs @@ -12,9 +12,23 @@ namespace Dalamud.Game.Internal.Gui { [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr SetGlobalBgmDelegate(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6); - private readonly Hook setGlobalBgmHook; + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + private delegate IntPtr HandleItemHoverDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4); + private readonly Hook handleItemHoverHook; + + /// + /// The item ID that is currently hovered by the player. 0 when no item is hovered. + /// If > 1.000.000, subtract 1.000.000 and treat it as HQ + /// + public ulong HoveredItem { get; set; } + + /// + /// Event that is fired when the currently hovered item changes. + /// + public EventHandler HoveredItemChanged { get; set; } + public GameGui(IntPtr baseAddress, SigScanner scanner, Dalamud dalamud) { Address = new GameGuiAddressResolver(baseAddress); Address.Setup(scanner); @@ -23,6 +37,7 @@ namespace Dalamud.Game.Internal.Gui { Log.Verbose("GameGuiManager address {Address}", Address.BaseAddress); Log.Verbose("SetGlobalBgm address {Address}", Address.SetGlobalBgm); + Log.Verbose("HandleItemHover address {Address}", Address.HandleItemHover); Chat = new ChatGui(Address.ChatManager, scanner, dalamud); @@ -30,6 +45,10 @@ namespace Dalamud.Game.Internal.Gui { new Hook(Address.SetGlobalBgm, new SetGlobalBgmDelegate(HandleSetGlobalBgmDetour), this); + this.handleItemHoverHook = + new Hook(Address.HandleItemHover, + new HandleItemHoverDelegate(HandleItemHoverDetour), + this); } private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) { @@ -40,16 +59,36 @@ namespace Dalamud.Game.Internal.Gui { return retVal; } + private IntPtr HandleItemHoverDetour(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4) { + var retVal = this.handleItemHoverHook.Original(hoverState, a2, a3, a4); + + if (retVal.ToInt64() == 22) { + var itemId = (ulong)Marshal.ReadInt32(hoverState, 0x130); + + try { + HoveredItemChanged?.Invoke(this, itemId); + } catch (Exception e) { + Log.Error(e, "Could not dispatch HoveredItemChanged event."); + } + + Log.Verbose("HoverItemId: {0}", itemId); + } + + return retVal; + } + public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0); public void Enable() { Chat.Enable(); this.setGlobalBgmHook.Enable(); + this.handleItemHoverHook.Enable(); } public void Dispose() { Chat.Dispose(); this.setGlobalBgmHook.Dispose(); + this.handleItemHoverHook.Dispose(); } } } diff --git a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs index c0127e8d4..091543c56 100644 --- a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs +++ b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs @@ -9,6 +9,7 @@ namespace Dalamud.Game.Internal.Gui { public IntPtr ChatManager { get; private set; } public IntPtr SetGlobalBgm { get; private set; } + public IntPtr HandleItemHover { get; set; } public GameGuiAddressResolver(IntPtr baseAddress) { BaseAddress = baseAddress; @@ -24,8 +25,8 @@ namespace Dalamud.Game.Internal.Gui { } protected override void Setup64Bit(SigScanner sig) { - //SetGlobalBgm = sig.ScanText("4C 8B 15 ?? ?? ?? ?? 4D 85 D2 74 58 41 83 7A ?? ?? 76 51 4D 8B 92 ?? ?? ?? ?? 0F B6 44 24 ?? 49 81 C2 ?? ?? ?? ?? 66 41 89 4A ?? 33 C9 41 88 52 30 41 89 4A 14 66 41 89 4A ?? 41 88 42 12 49 89 4A 38 41 89 4A 40 49 89 4A 48 41 38 4A 30 74 14 8B 44 24 28 41 89 42 40 45 89 42 38"); SetGlobalBgm = sig.ScanText("4C 8B 15 ?? ?? ?? ?? 4D 85 D2 74 58"); + HandleItemHover = sig.ScanText("E8 ?? ?? ?? ?? 48 8B 5C 24 ?? 48 89 AE ?? ?? ?? ??"); } } }