feat: add HoveredItem data to Dalamud.Game.Internal.Gui.GameGui

This commit is contained in:
goat 2020-04-02 19:59:51 +09:00
parent 1e00a33577
commit 6b2c531eed
2 changed files with 42 additions and 2 deletions

View file

@ -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<SetGlobalBgmDelegate> setGlobalBgmHook;
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr HandleItemHoverDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4);
private readonly Hook<HandleItemHoverDelegate> handleItemHoverHook;
/// <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
/// </summary>
public ulong HoveredItem { get; set; }
/// <summary>
/// Event that is fired when the currently hovered item changes.
/// </summary>
public EventHandler<ulong> 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<SetGlobalBgmDelegate>(Address.SetGlobalBgm,
new SetGlobalBgmDelegate(HandleSetGlobalBgmDetour),
this);
this.handleItemHoverHook =
new Hook<HandleItemHoverDelegate>(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();
}
}
}

View file

@ -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 ?? ?? ?? ??");
}
}
}