Add HandleItemOut hook

Allows detecting when no more item is hovered and dispatch event
accordingly.
Also actually fill the HoveredItem property.
This commit is contained in:
Florian Maunier 2020-04-08 18:27:36 +02:00
parent e16b371ac3
commit a3e1e11737
No known key found for this signature in database
GPG key ID: 3919060DDEE2A555
2 changed files with 39 additions and 1 deletions

View file

@ -18,6 +18,10 @@ namespace Dalamud.Game.Internal.Gui {
private delegate IntPtr HandleItemHoverDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4);
private readonly Hook<HandleItemHoverDelegate> handleItemHoverHook;
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr HandleItemOutDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4);
private readonly Hook<HandleItemOutDelegate> handleItemOutHook;
/// <summary>
/// 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
@ -38,6 +42,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);
Log.Verbose("HandleItemOut address {Address}", Address.HandleItemOut);
Chat = new ChatGui(Address.ChatManager, scanner, dalamud);
@ -49,6 +54,11 @@ namespace Dalamud.Game.Internal.Gui {
new Hook<HandleItemHoverDelegate>(Address.HandleItemHover,
new HandleItemHoverDelegate(HandleItemHoverDetour),
this);
this.handleItemOutHook =
new Hook<HandleItemOutDelegate>(Address.HandleItemOut,
new HandleItemOutDelegate(HandleItemOutDetour),
this);
}
private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
@ -64,6 +74,7 @@ namespace Dalamud.Game.Internal.Gui {
if (retVal.ToInt64() == 22) {
var itemId = (ulong)Marshal.ReadInt32(hoverState, 0x130);
this.HoveredItem = itemId;
try {
HoveredItemChanged?.Invoke(this, itemId);
@ -77,18 +88,43 @@ namespace Dalamud.Game.Internal.Gui {
return retVal;
}
private IntPtr HandleItemOutDetour(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4)
{
var retVal = this.handleItemOutHook.Original(hoverState, a2, a3, a4);
if (a3 != IntPtr.Zero && a4 == 1) {
var a3Val = Marshal.ReadByte(a3, 0x8);
if (a3Val == 255) {
this.HoveredItem = 0ul;
try {
HoveredItemChanged?.Invoke(this, 0ul);
} catch (Exception e) {
Log.Error(e, "Could not dispatch HoveredItemChanged event.");
}
Log.Verbose("HoverItemId: 0");
}
}
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();
this.handleItemOutHook.Enable();
}
public void Dispose() {
Chat.Dispose();
this.setGlobalBgmHook.Dispose();
this.handleItemHoverHook.Dispose();
this.handleItemOutHook.Dispose();
}
}
}

View file

@ -10,7 +10,8 @@ namespace Dalamud.Game.Internal.Gui {
public IntPtr SetGlobalBgm { get; private set; }
public IntPtr HandleItemHover { get; set; }
public IntPtr HandleItemOut { get; set; }
public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress;
}
@ -27,6 +28,7 @@ namespace Dalamud.Game.Internal.Gui {
protected override void Setup64Bit(SigScanner sig) {
SetGlobalBgm = sig.ScanText("4C 8B 15 ?? ?? ?? ?? 4D 85 D2 74 58");
HandleItemHover = sig.ScanText("E8 ?? ?? ?? ?? 48 8B 5C 24 ?? 48 89 AE ?? ?? ?? ??");
HandleItemOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 4D");
}
}
}