From 47a096a252d981b00fe62e890f09494298c8cb75 Mon Sep 17 00:00:00 2001 From: goaaats Date: Wed, 13 Apr 2022 03:53:24 +0200 Subject: [PATCH] fix: ContextMenu adjustments to new client structs --- Dalamud/Game/Gui/ContextMenus/ContextMenu.cs | 25 +++++++------- .../Gui/ContextMenus/ContextMenuOpenedArgs.cs | 6 ++-- .../ContextMenus/ContextMenuReaderWriter.cs | 26 +++++++-------- .../OldStructs/OldAgentContext.cs | 33 +++++++++++++++++++ .../OldStructs/OldAgentContextInterface.cs | 17 ++++++++++ Dalamud/Game/Gui/GameGui.cs | 2 +- 6 files changed, 80 insertions(+), 29 deletions(-) create mode 100644 Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs create mode 100644 Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContextInterface.cs diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenu.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenu.cs index 44307b48a..3d02634ab 100644 --- a/Dalamud/Game/Gui/ContextMenus/ContextMenu.cs +++ b/Dalamud/Game/Gui/ContextMenus/ContextMenu.cs @@ -2,12 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; - +using Dalamud.Game.Gui.ContextMenus.OldStructs; using Dalamud.Hooking; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Logging; using Dalamud.Memory; +using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; @@ -38,7 +39,7 @@ namespace Dalamud.Game.Gui.ContextMenus #endregion - private unsafe AgentContextInterface* currentAgentContextInterface; + private unsafe OldAgentContextInterface* currentAgentContextInterface; private IntPtr currentSubContextMenuTitle; @@ -67,15 +68,15 @@ namespace Dalamud.Game.Gui.ContextMenus #region Delegates - private unsafe delegate bool OpenSubContextMenuDelegate(AgentContext* agentContext); + private unsafe delegate bool OpenSubContextMenuDelegate(OldAgentContext* agentContext); - private unsafe delegate IntPtr ContextMenuOpeningDelegate(IntPtr a1, IntPtr a2, IntPtr a3, uint a4, IntPtr a5, AgentContextInterface* agentContextInterface, IntPtr a7, ushort a8); + private unsafe delegate IntPtr ContextMenuOpeningDelegate(IntPtr a1, IntPtr a2, IntPtr a3, uint a4, IntPtr a5, OldAgentContextInterface* agentContextInterface, IntPtr a7, ushort a8); private unsafe delegate bool ContextMenuOpenedDelegate(AddonContextMenu* addonContextMenu, int menuSize, AtkValue* atkValueArgs); private unsafe delegate bool ContextMenuItemSelectedDelegate(AddonContextMenu* addonContextMenu, int selectedIndex, byte a3); - private unsafe delegate bool SubContextMenuOpeningDelegate(AgentContext* agentContext); + private unsafe delegate bool SubContextMenuOpeningDelegate(OldAgentContext* agentContext); #endregion @@ -108,7 +109,7 @@ namespace Dalamud.Game.Gui.ContextMenus this.subContextMenuOpenedHook.Enable(); } - private static unsafe bool IsInventoryContext(AgentContextInterface* agentContextInterface) + private static unsafe bool IsInventoryContext(OldAgentContextInterface* agentContextInterface) { return agentContextInterface == AgentInventoryContext.Instance(); } @@ -121,7 +122,7 @@ namespace Dalamud.Game.Gui.ContextMenus } } - private unsafe IntPtr ContextMenuOpeningDetour(IntPtr a1, IntPtr a2, IntPtr a3, uint a4, IntPtr a5, AgentContextInterface* agentContextInterface, IntPtr a7, ushort a8) + private unsafe IntPtr ContextMenuOpeningDetour(IntPtr a1, IntPtr a2, IntPtr a3, uint a4, IntPtr a5, OldAgentContextInterface* agentContextInterface, IntPtr a7, ushort a8) { this.currentAgentContextInterface = agentContextInterface; return this.contextMenuOpeningHook!.Original(a1, a2, a3, a4, a5, agentContextInterface, a7, a8); @@ -212,12 +213,12 @@ namespace Dalamud.Game.Gui.ContextMenus } } - private unsafe bool SubContextMenuOpeningDetour(AgentContext* agentContext) + private unsafe bool SubContextMenuOpeningDetour(OldAgentContext* agentContext) { return this.SubContextMenuOpeningImplementation(agentContext) || this.subContextMenuOpeningHook.Original(agentContext); } - private unsafe bool SubContextMenuOpeningImplementation(AgentContext* agentContext) + private unsafe bool SubContextMenuOpeningImplementation(OldAgentContext* agentContext) { if (this.openSubContextMenu == null || this.selectedOpenSubContextMenuItem == null) { @@ -274,7 +275,7 @@ namespace Dalamud.Game.Gui.ContextMenus this.ContextMenuOpenedImplementation(addonContextMenu, ref atkValueCount, ref atkValues); } - private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(AddonContextMenu* addonContextMenu, AgentContextInterface* agentContextInterface, string? title, ContextMenus.ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable initialContextMenuItems) + private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(AddonContextMenu* addonContextMenu, OldAgentContextInterface* agentContextInterface, string? title, ContextMenus.ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable initialContextMenuItems) { var parentAddonName = this.GetParentAddonName(&addonContextMenu->AtkUnitBase); @@ -285,11 +286,11 @@ namespace Dalamud.Game.Gui.ContextMenus if (IsInventoryContext(agentContextInterface)) { var agentInventoryContext = (AgentInventoryContext*)agentContextInterface; - inventoryItemContext = new InventoryItemContext(agentInventoryContext->InventoryItemId, agentInventoryContext->InventoryItemCount, agentInventoryContext->InventoryItemIsHighQuality); + inventoryItemContext = new InventoryItemContext(agentInventoryContext->TargetDummyItem.ItemID, agentInventoryContext->TargetDummyItem.Quantity, agentInventoryContext->TargetDummyItem.Flags.HasFlag(InventoryItem.ItemFlags.HQ)); } else { - var agentContext = (AgentContext*)agentContextInterface; + var agentContext = (OldAgentContext*)agentContextInterface; uint? id = agentContext->GameObjectId; if (id == 0) diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedArgs.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedArgs.cs index 05293bacd..4ecc3e4b9 100644 --- a/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedArgs.cs +++ b/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedArgs.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; - +using Dalamud.Game.Gui.ContextMenus.OldStructs; using Dalamud.Game.Text.SeStringHandling; using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI.Agent; @@ -18,7 +18,7 @@ namespace Dalamud.Game.Gui.ContextMenus /// The agent associated with the context menu. /// The the name of the parent addon associated with the context menu. /// The items in the context menu. - public ContextMenuOpenedArgs(AddonContextMenu* addon, AgentContextInterface* agent, string? parentAddonName, IEnumerable items) + public ContextMenuOpenedArgs(AddonContextMenu* addon, OldAgentContextInterface* agent, string? parentAddonName, IEnumerable items) { this.Addon = addon; this.Agent = agent; @@ -34,7 +34,7 @@ namespace Dalamud.Game.Gui.ContextMenus /// /// Gets the agent associated with the context menu. /// - public AgentContextInterface* Agent { get; } + public OldAgentContextInterface* Agent { get; } /// /// Gets the name of the parent addon associated with the context menu. diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuReaderWriter.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuReaderWriter.cs index 16f24365d..75310d7d7 100644 --- a/Dalamud/Game/Gui/ContextMenus/ContextMenuReaderWriter.cs +++ b/Dalamud/Game/Gui/ContextMenus/ContextMenuReaderWriter.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Runtime.InteropServices; - +using Dalamud.Game.Gui.ContextMenus.OldStructs; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Logging; using Dalamud.Memory; @@ -19,7 +19,7 @@ namespace Dalamud.Game.Gui.ContextMenus /// internal unsafe class ContextMenuReaderWriter { - private readonly AgentContextInterface* agentContextInterface; + private readonly OldAgentContextInterface* agentContextInterface; private int atkValueCount; private AtkValue* atkValues; @@ -30,7 +30,7 @@ namespace Dalamud.Game.Gui.ContextMenus /// The AgentContextInterface to act upon. /// The number of ATK values to consider. /// Pointer to the array of ATK values. - public ContextMenuReaderWriter(AgentContextInterface* agentContextInterface, int atkValueCount, AtkValue* atkValues) + public ContextMenuReaderWriter(OldAgentContextInterface* agentContextInterface, int atkValueCount, AtkValue* atkValues) { PluginLog.Warning($"{(IntPtr)atkValues:X}"); @@ -306,17 +306,17 @@ namespace Dalamud.Game.Gui.ContextMenus byte action; if (this.IsInventoryContext) { - var actions = &((AgentInventoryContext*)this.agentContextInterface)->Actions; - action = *(actions + contextMenuItemAtkValueBaseIndex); + var actions = &((AgentInventoryContext*)this.agentContextInterface)->EventIdArray; + action = *actions[contextMenuItemAtkValueBaseIndex]; } else if (this.StructLayout is SubContextMenuStructLayout.Alternate) { - var redButtonActions = &((AgentContext*)this.agentContextInterface)->Items->RedButtonActions; + var redButtonActions = &((OldAgentContext*)this.agentContextInterface)->Items->RedButtonActions; action = (byte)*(redButtonActions + contextMenuItemIndex); } else { - var actions = &((AgentContext*)this.agentContextInterface)->Items->Actions; + var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions; action = *(actions + contextMenuItemAtkValueBaseIndex); } @@ -438,27 +438,27 @@ namespace Dalamud.Game.Gui.ContextMenus if (this.IsInventoryContext) { - var actions = &((AgentInventoryContext*)this.agentContextInterface)->Actions; - *(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action; + var actions = &((AgentInventoryContext*)this.agentContextInterface)->EventIdArray; + *actions[this.FirstContextMenuItemIndex + contextMenuItemIndex] = action; } else if (this.StructLayout is SubContextMenuStructLayout.Alternate && this.FirstUnhandledAction != null) { // Some weird placeholder goes here - var actions = &((AgentContext*)this.agentContextInterface)->Items->Actions; + var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions; *(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = (byte)(this.FirstUnhandledAction.Value + contextMenuItemIndex); // Make sure there's one of these function pointers for every item. // The function needs to be the same, so we just copy the first one into every index. - var unkFunctionPointers = &((AgentContext*)this.agentContextInterface)->Items->UnkFunctionPointers; + var unkFunctionPointers = &((OldAgentContext*)this.agentContextInterface)->Items->UnkFunctionPointers; *(unkFunctionPointers + this.FirstContextMenuItemIndex + contextMenuItemIndex) = *(unkFunctionPointers + this.FirstContextMenuItemIndex); // The real action goes here - var redButtonActions = &((AgentContext*)this.agentContextInterface)->Items->RedButtonActions; + var redButtonActions = &((OldAgentContext*)this.agentContextInterface)->Items->RedButtonActions; *(redButtonActions + contextMenuItemIndex) = action; } else { - var actions = &((AgentContext*)this.agentContextInterface)->Items->Actions; + var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions; *(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action; } diff --git a/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs b/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs new file mode 100644 index 000000000..d0c59b616 --- /dev/null +++ b/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs @@ -0,0 +1,33 @@ +using System.Runtime.InteropServices; + +using FFXIVClientStructs.FFXIV.Client.System.String; +using FFXIVClientStructs.FFXIV.Client.UI.Agent; +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace Dalamud.Game.Gui.ContextMenus.OldStructs; + +// TODO: This is transplanted from client structs before the rework. Need to take some time to sort all of this out soon. + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct OldAgentContext +{ + public static OldAgentContext* Instance() => (OldAgentContext*)FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Context); + + [FieldOffset(0x0)] public AgentInterface AgentInterface; + [FieldOffset(0x0)] public OldAgentContextInterface AgentContextInterface; + [FieldOffset(0xD18)] public unsafe OldAgentContextMenuItems* Items; + [FieldOffset(0xE08)] public Utf8String GameObjectName; + [FieldOffset(0xEE0)] public ulong GameObjectContentId; + [FieldOffset(0xEF0)] public uint GameObjectId; + [FieldOffset(0xF00)] public ushort GameObjectWorldId; +} + +[StructLayout(LayoutKind.Explicit)] +public struct OldAgentContextMenuItems +{ + [FieldOffset(0x0)] public ushort AtkValueCount; + [FieldOffset(0x8)] public AtkValue AtkValues; + [FieldOffset(0x428)] public byte Actions; + [FieldOffset(0x450)] public ulong UnkFunctionPointers; + [FieldOffset(0x598)] public ulong RedButtonActions; +} diff --git a/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContextInterface.cs b/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContextInterface.cs new file mode 100644 index 000000000..2dde22dfb --- /dev/null +++ b/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContextInterface.cs @@ -0,0 +1,17 @@ +using System.Runtime.InteropServices; + +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace Dalamud.Game.Gui.ContextMenus.OldStructs; + +// TODO: This is transplanted from client structs before the rework. Need to take some time to sort all of this out soon. + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct OldAgentContextInterface +{ + [FieldOffset(0x0)] public AgentInterface AgentInterface; + [FieldOffset(0x670)] public unsafe byte SelectedIndex; + [FieldOffset(0x690)] public byte* Unk1; + [FieldOffset(0xD08)] public byte* SubContextMenuTitle; + [FieldOffset(0x1740)] public bool IsSubContextMenu; +} diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs index 94e195ef0..5638f8b50 100644 --- a/Dalamud/Game/Gui/GameGui.cs +++ b/Dalamud/Game/Gui/GameGui.cs @@ -412,7 +412,7 @@ namespace Dalamud.Game.Gui var unitBase = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)addon; var id = unitBase->ParentID; if (id == 0) - id = unitBase->IDu; + id = unitBase->ID; if (id == 0) return IntPtr.Zero;