From bd43533a4a0d6d82a05c4b6d549e49cfb8dec81d Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Fri, 21 Jul 2023 15:56:31 +0400 Subject: [PATCH] No need to track network condition changes, use the UI for everything --- Craftimizer/Utils/Hooks.cs | 73 ++++++++++++++------------------------ 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/Craftimizer/Utils/Hooks.cs b/Craftimizer/Utils/Hooks.cs index 1807544..ee16b9d 100644 --- a/Craftimizer/Utils/Hooks.cs +++ b/Craftimizer/Utils/Hooks.cs @@ -1,72 +1,51 @@ -using Craftimizer.Simulator; +using Craftimizer.Simulator.Actions; using Dalamud.Hooking; using Dalamud.Logging; using Dalamud.Utility.Signatures; +using FFXIVClientStructs.FFXIV.Client.Game; using System; +using ActionType = Craftimizer.Simulator.Actions.ActionType; +using CSActionType = FFXIVClientStructs.FFXIV.Client.Game.ActionType; +using Condition = Craftimizer.Simulator.Condition; +using Craftimizer.Plugin; +using ActionUtils = Craftimizer.Plugin.ActionUtils; namespace Craftimizer.Utils; -public sealed class Hooks : IDisposable +public sealed unsafe class Hooks : IDisposable { - public class ConditionUpdatedEventArgs : EventArgs - { - public Condition Condition { get; } + public delegate void OnActionUsedDelegate(ActionType action); - public ConditionUpdatedEventArgs(Condition condition) - { - Condition = condition; - } - } + public event OnActionUsedDelegate? OnActionUsed; - public event EventHandler? OnConditionUpdated; + public delegate bool UseActionDelegate(ActionManager* manager, CSActionType actionType, uint actionId, ulong targetId, uint param, uint useType, int pvp, nint a8); - public delegate void ActorControlSelfPrototype(uint entityId, uint type, uint a3, uint a4, uint a5, uint source, uint a7, uint a8, ulong a9, byte flag); - - // https://github.com/Kouzukii/ffxiv-deathrecap/blob/1298e75c5e15a6596e8678e85b8f1bde926051bf/Events/CombatEventCapture.cs#L82 - [Signature("E8 ?? ?? ?? ?? 0F B7 0B 83 E9 64", DetourName = nameof(ActorControlSelfDetour))] - public readonly Hook ActorControlSelfHook = null!; + public readonly Hook UseActionHook = null!; public Hooks() { - SignatureHelper.Initialise(this); - ActorControlSelfHook.Enable(); + UseActionHook = Hook.FromAddress((nint)ActionManager.MemberFunctionPointers.UseAction, UseActionDetour); + UseActionHook.Enable(); } - private bool HandleCondition(uint type, uint a3, uint a4) + private bool UseActionDetour(ActionManager* manager, CSActionType actionType, uint actionId, ulong targetId, uint param, uint useType, int pvp, nint a8) { - // Crafting related or something? - if (type != 300) - return false; - - // Condition update - if (a3 != 9) - return false; - - // Invalid condition - if (a4 < 2) + var canCast = manager->GetActionStatus(actionType, actionId) == 0; + var ret = UseActionHook.Original(manager, actionType, actionId, targetId, param, useType, pvp, a8); + if (canCast && ret && (actionType == CSActionType.CraftAction || actionType == CSActionType.Spell)) { - PluginLog.LogError($"Invalid condition {a4}"); - return false; + var classJob = ClassJobUtils.GetClassJobFromIdx((byte)(Service.ClientState.LocalPlayer?.ClassJob.Id ?? 0)); + if (classJob != null) { + var simActionType = ActionUtils.GetActionTypeFromId(actionId, classJob.Value, actionType == CSActionType.CraftAction); + if (simActionType != null) + OnActionUsed?.Invoke(simActionType.Value); + } } - - var condition = (Condition)(1 << ((int)a4 - 2)); - - OnConditionUpdated?.Invoke(this, new(condition)); - return true; - } - - private void ActorControlSelfDetour(uint entityId, uint type, uint a3, uint a4, uint a5, uint source, uint a7, uint a8, ulong a9, byte flag) - { - ActorControlSelfHook.Original(entityId, type, a3, a4, a5, source, a7, a8, a9, flag); - - if (HandleCondition(type, a3, a4)) - return; - - //PluginLog.LogDebug($"{entityId} {type} {a3} {a4} {a5} {a7} {a8} {a9} {flag}"); + return ret; } public void Dispose() { - ActorControlSelfHook.Dispose(); + UseActionHook.Dispose(); } }