mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Add events based on AgentUpdateFlag
This commit is contained in:
parent
116e8aadbc
commit
0b6f3b8bcf
3 changed files with 103 additions and 18 deletions
|
|
@ -43,6 +43,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
private readonly Hook<HandleImmDelegate> handleImmHook;
|
private readonly Hook<HandleImmDelegate> handleImmHook;
|
||||||
private readonly Hook<RaptureAtkModule.Delegates.SetUiVisibility> setUiVisibilityHook;
|
private readonly Hook<RaptureAtkModule.Delegates.SetUiVisibility> setUiVisibilityHook;
|
||||||
private readonly Hook<Utf8String.Delegates.Ctor_FromSequence> utf8StringFromSequenceHook;
|
private readonly Hook<Utf8String.Delegates.Ctor_FromSequence> utf8StringFromSequenceHook;
|
||||||
|
private readonly Hook<RaptureAtkModule.Delegates.Update> raptureAtkModuleUpdateHook;
|
||||||
|
|
||||||
[ServiceManager.ServiceConstructor]
|
[ServiceManager.ServiceConstructor]
|
||||||
private GameGui(TargetSigScanner sigScanner)
|
private GameGui(TargetSigScanner sigScanner)
|
||||||
|
|
@ -65,6 +66,10 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
|
|
||||||
this.utf8StringFromSequenceHook = Hook<Utf8String.Delegates.Ctor_FromSequence>.FromAddress(Utf8String.Addresses.Ctor_FromSequence.Value, this.Utf8StringFromSequenceDetour);
|
this.utf8StringFromSequenceHook = Hook<Utf8String.Delegates.Ctor_FromSequence>.FromAddress(Utf8String.Addresses.Ctor_FromSequence.Value, this.Utf8StringFromSequenceDetour);
|
||||||
|
|
||||||
|
this.raptureAtkModuleUpdateHook = Hook<RaptureAtkModule.Delegates.Update>.FromFunctionPointerVariable(
|
||||||
|
new(&RaptureAtkModule.StaticVirtualTablePointer->Update),
|
||||||
|
this.RaptureAtkModuleUpdateDetour);
|
||||||
|
|
||||||
this.handleItemHoverHook.Enable();
|
this.handleItemHoverHook.Enable();
|
||||||
this.handleItemOutHook.Enable();
|
this.handleItemOutHook.Enable();
|
||||||
this.handleImmHook.Enable();
|
this.handleImmHook.Enable();
|
||||||
|
|
@ -72,6 +77,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
this.handleActionHoverHook.Enable();
|
this.handleActionHoverHook.Enable();
|
||||||
this.handleActionOutHook.Enable();
|
this.handleActionOutHook.Enable();
|
||||||
this.utf8StringFromSequenceHook.Enable();
|
this.utf8StringFromSequenceHook.Enable();
|
||||||
|
this.raptureAtkModuleUpdateHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooked delegates
|
// Hooked delegates
|
||||||
|
|
@ -88,6 +94,18 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event EventHandler<HoveredAction>? HoveredActionChanged;
|
public event EventHandler<HoveredAction>? HoveredActionChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action InventoryUpdate;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action ActionBarUpdate;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action UnlocksUpdate;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action MainCommandEnabledStateUpdate;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool GameUiHidden { get; private set; }
|
public bool GameUiHidden { get; private set; }
|
||||||
|
|
||||||
|
|
@ -238,6 +256,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
this.handleActionHoverHook.Dispose();
|
this.handleActionHoverHook.Dispose();
|
||||||
this.handleActionOutHook.Dispose();
|
this.handleActionOutHook.Dispose();
|
||||||
this.utf8StringFromSequenceHook.Dispose();
|
this.utf8StringFromSequenceHook.Dispose();
|
||||||
|
this.raptureAtkModuleUpdateHook.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -362,6 +381,34 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
|
|
||||||
return thisPtr; // this function shouldn't need to return but the original asm moves this into rax before returning so be safe?
|
return thisPtr; // this function shouldn't need to return but the original asm moves this into rax before returning so be safe?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RaptureAtkModuleUpdateDetour(RaptureAtkModule* thisPtr, float delta)
|
||||||
|
{
|
||||||
|
// The game clears the AgentUpdateFlag in the original function, but it also updates agents in it too.
|
||||||
|
// We'll make a copy of the flags, so that we can fire events after the agents have been updated.
|
||||||
|
|
||||||
|
var agentUpdateFlag = thisPtr->AgentUpdateFlag;
|
||||||
|
|
||||||
|
this.raptureAtkModuleUpdateHook.Original(thisPtr, delta);
|
||||||
|
|
||||||
|
if (agentUpdateFlag != RaptureAtkModule.AgentUpdateFlags.None)
|
||||||
|
{
|
||||||
|
if (agentUpdateFlag.HasFlag(RaptureAtkModule.AgentUpdateFlags.InventoryUpdate) ||
|
||||||
|
agentUpdateFlag.HasFlag(RaptureAtkModule.AgentUpdateFlags.RetainerMarketInventoryUpdate) ||
|
||||||
|
agentUpdateFlag.HasFlag(RaptureAtkModule.AgentUpdateFlags.HousingInventoryUpdate) ||
|
||||||
|
agentUpdateFlag.HasFlag(RaptureAtkModule.AgentUpdateFlags.ContentInventoryUpdate))
|
||||||
|
this.InventoryUpdate.InvokeSafely();
|
||||||
|
|
||||||
|
if (agentUpdateFlag.HasFlag(RaptureAtkModule.AgentUpdateFlags.ActionBarUpdate))
|
||||||
|
this.ActionBarUpdate.InvokeSafely();
|
||||||
|
|
||||||
|
if (agentUpdateFlag.HasFlag(RaptureAtkModule.AgentUpdateFlags.UnlocksUpdate))
|
||||||
|
this.UnlocksUpdate.InvokeSafely();
|
||||||
|
|
||||||
|
if (agentUpdateFlag.HasFlag(RaptureAtkModule.AgentUpdateFlags.MainCommandEnabledStateUpdate))
|
||||||
|
this.MainCommandEnabledStateUpdate.InvokeSafely();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -385,6 +432,10 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
|
||||||
this.gameGuiService.UiHideToggled += this.UiHideToggledForward;
|
this.gameGuiService.UiHideToggled += this.UiHideToggledForward;
|
||||||
this.gameGuiService.HoveredItemChanged += this.HoveredItemForward;
|
this.gameGuiService.HoveredItemChanged += this.HoveredItemForward;
|
||||||
this.gameGuiService.HoveredActionChanged += this.HoveredActionForward;
|
this.gameGuiService.HoveredActionChanged += this.HoveredActionForward;
|
||||||
|
this.gameGuiService.InventoryUpdate += this.InventoryUpdateForward;
|
||||||
|
this.gameGuiService.ActionBarUpdate += this.ActionBarUpdateForward;
|
||||||
|
this.gameGuiService.UnlocksUpdate += this.UnlocksUpdateForward;
|
||||||
|
this.gameGuiService.MainCommandEnabledStateUpdate += this.MainCommandEnabledStateUpdateForward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
@ -396,6 +447,18 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event EventHandler<HoveredAction>? HoveredActionChanged;
|
public event EventHandler<HoveredAction>? HoveredActionChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action InventoryUpdate;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action ActionBarUpdate;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action UnlocksUpdate;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event Action MainCommandEnabledStateUpdate;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool GameUiHidden => this.gameGuiService.GameUiHidden;
|
public bool GameUiHidden => this.gameGuiService.GameUiHidden;
|
||||||
|
|
||||||
|
|
@ -415,6 +478,10 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
|
||||||
this.gameGuiService.UiHideToggled -= this.UiHideToggledForward;
|
this.gameGuiService.UiHideToggled -= this.UiHideToggledForward;
|
||||||
this.gameGuiService.HoveredItemChanged -= this.HoveredItemForward;
|
this.gameGuiService.HoveredItemChanged -= this.HoveredItemForward;
|
||||||
this.gameGuiService.HoveredActionChanged -= this.HoveredActionForward;
|
this.gameGuiService.HoveredActionChanged -= this.HoveredActionForward;
|
||||||
|
this.gameGuiService.InventoryUpdate -= this.InventoryUpdateForward;
|
||||||
|
this.gameGuiService.ActionBarUpdate -= this.ActionBarUpdateForward;
|
||||||
|
this.gameGuiService.UnlocksUpdate -= this.UnlocksUpdateForward;
|
||||||
|
this.gameGuiService.MainCommandEnabledStateUpdate -= this.MainCommandEnabledStateUpdateForward;
|
||||||
|
|
||||||
this.UiHideToggled = null;
|
this.UiHideToggled = null;
|
||||||
this.HoveredItemChanged = null;
|
this.HoveredItemChanged = null;
|
||||||
|
|
@ -466,4 +533,12 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
|
||||||
private void HoveredItemForward(object sender, ulong itemId) => this.HoveredItemChanged?.Invoke(sender, itemId);
|
private void HoveredItemForward(object sender, ulong itemId) => this.HoveredItemChanged?.Invoke(sender, itemId);
|
||||||
|
|
||||||
private void HoveredActionForward(object sender, HoveredAction hoverAction) => this.HoveredActionChanged?.Invoke(sender, hoverAction);
|
private void HoveredActionForward(object sender, HoveredAction hoverAction) => this.HoveredActionChanged?.Invoke(sender, hoverAction);
|
||||||
|
|
||||||
|
private void InventoryUpdateForward() => this.InventoryUpdate.InvokeSafely();
|
||||||
|
|
||||||
|
private void ActionBarUpdateForward() => this.ActionBarUpdate.InvokeSafely();
|
||||||
|
|
||||||
|
private void UnlocksUpdateForward() => this.UnlocksUpdate.InvokeSafely();
|
||||||
|
|
||||||
|
private void MainCommandEnabledStateUpdateForward() => this.MainCommandEnabledStateUpdate.InvokeSafely();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,14 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
using Dalamud.Game.Gui;
|
||||||
using Dalamud.Game.Inventory.InventoryEventArgTypes;
|
using Dalamud.Game.Inventory.InventoryEventArgTypes;
|
||||||
using Dalamud.Hooking;
|
|
||||||
using Dalamud.IoC;
|
using Dalamud.IoC;
|
||||||
using Dalamud.IoC.Internal;
|
using Dalamud.IoC.Internal;
|
||||||
using Dalamud.Logging.Internal;
|
using Dalamud.Logging.Internal;
|
||||||
using Dalamud.Plugin.Internal;
|
using Dalamud.Plugin.Internal;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.Inventory;
|
namespace Dalamud.Game.Inventory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -33,7 +31,8 @@ internal class GameInventory : IInternalDisposableService
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly Framework framework = Service<Framework>.Get();
|
private readonly Framework framework = Service<Framework>.Get();
|
||||||
|
|
||||||
private readonly Hook<RaptureAtkModuleUpdateDelegate> raptureAtkModuleUpdateHook;
|
[ServiceManager.ServiceDependency]
|
||||||
|
private readonly GameGui gameGui = Service<GameGui>.Get();
|
||||||
|
|
||||||
private readonly GameInventoryType[] inventoryTypes;
|
private readonly GameInventoryType[] inventoryTypes;
|
||||||
private readonly GameInventoryItem[]?[] inventoryItems;
|
private readonly GameInventoryItem[]?[] inventoryItems;
|
||||||
|
|
@ -47,18 +46,9 @@ internal class GameInventory : IInternalDisposableService
|
||||||
this.inventoryTypes = Enum.GetValues<GameInventoryType>();
|
this.inventoryTypes = Enum.GetValues<GameInventoryType>();
|
||||||
this.inventoryItems = new GameInventoryItem[this.inventoryTypes.Length][];
|
this.inventoryItems = new GameInventoryItem[this.inventoryTypes.Length][];
|
||||||
|
|
||||||
unsafe
|
this.gameGui.InventoryUpdate += this.OnInventoryUpdate;
|
||||||
{
|
|
||||||
this.raptureAtkModuleUpdateHook = Hook<RaptureAtkModuleUpdateDelegate>.FromFunctionPointerVariable(
|
|
||||||
new(&RaptureAtkModule.StaticVirtualTablePointer->Update),
|
|
||||||
this.RaptureAtkModuleUpdateDetour);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.raptureAtkModuleUpdateHook.Enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe delegate void RaptureAtkModuleUpdateDelegate(RaptureAtkModule* ram, float f1);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
{
|
{
|
||||||
|
|
@ -68,7 +58,7 @@ internal class GameInventory : IInternalDisposableService
|
||||||
this.subscribersPendingChange.Clear();
|
this.subscribersPendingChange.Clear();
|
||||||
this.subscribersChanged = false;
|
this.subscribersChanged = false;
|
||||||
this.framework.Update -= this.OnFrameworkUpdate;
|
this.framework.Update -= this.OnFrameworkUpdate;
|
||||||
this.raptureAtkModuleUpdateHook.Dispose();
|
this.gameGui.InventoryUpdate -= this.OnInventoryUpdate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,10 +309,9 @@ internal class GameInventory : IInternalDisposableService
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void RaptureAtkModuleUpdateDetour(RaptureAtkModule* ram, float f1)
|
private void OnInventoryUpdate()
|
||||||
{
|
{
|
||||||
this.inventoriesMightBeChanged |= ram->AgentUpdateFlag != 0;
|
this.inventoriesMightBeChanged |= true;
|
||||||
this.raptureAtkModuleUpdateHook.Original(ram, f1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,27 @@ public unsafe interface IGameGui
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<HoveredAction> HoveredActionChanged;
|
public event EventHandler<HoveredAction> HoveredActionChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is fired when the inventory has been updated.
|
||||||
|
/// </summary>
|
||||||
|
event Action InventoryUpdate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when the action bar needs to be updated, e.g. after changing Class/Job,
|
||||||
|
/// updating Gear Sets, modifying Macros, or executing a hotbar slot.
|
||||||
|
/// </summary>
|
||||||
|
event Action ActionBarUpdate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is fired when collectibles, content or systems were unlocked.
|
||||||
|
/// </summary>
|
||||||
|
event Action UnlocksUpdate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is fired when the enable state of MainCommands has been updated.
|
||||||
|
/// </summary>
|
||||||
|
event Action MainCommandEnabledStateUpdate;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the game UI is hidden.
|
/// Gets a value indicating whether the game UI is hidden.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue