mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
fix: ContextMenu adjustments to new client structs
This commit is contained in:
parent
ebe35095f5
commit
47a096a252
6 changed files with 80 additions and 29 deletions
|
|
@ -2,12 +2,13 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Dalamud.Game.Gui.ContextMenus.OldStructs;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using Dalamud.IoC;
|
using Dalamud.IoC;
|
||||||
using Dalamud.IoC.Internal;
|
using Dalamud.IoC.Internal;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
|
@ -38,7 +39,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private unsafe AgentContextInterface* currentAgentContextInterface;
|
private unsafe OldAgentContextInterface* currentAgentContextInterface;
|
||||||
|
|
||||||
private IntPtr currentSubContextMenuTitle;
|
private IntPtr currentSubContextMenuTitle;
|
||||||
|
|
||||||
|
|
@ -67,15 +68,15 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
|
|
||||||
#region Delegates
|
#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 ContextMenuOpenedDelegate(AddonContextMenu* addonContextMenu, int menuSize, AtkValue* atkValueArgs);
|
||||||
|
|
||||||
private unsafe delegate bool ContextMenuItemSelectedDelegate(AddonContextMenu* addonContextMenu, int selectedIndex, byte a3);
|
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
|
#endregion
|
||||||
|
|
||||||
|
|
@ -108,7 +109,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
this.subContextMenuOpenedHook.Enable();
|
this.subContextMenuOpenedHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static unsafe bool IsInventoryContext(AgentContextInterface* agentContextInterface)
|
private static unsafe bool IsInventoryContext(OldAgentContextInterface* agentContextInterface)
|
||||||
{
|
{
|
||||||
return agentContextInterface == AgentInventoryContext.Instance();
|
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;
|
this.currentAgentContextInterface = agentContextInterface;
|
||||||
return this.contextMenuOpeningHook!.Original(a1, a2, a3, a4, a5, agentContextInterface, a7, a8);
|
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);
|
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)
|
if (this.openSubContextMenu == null || this.selectedOpenSubContextMenuItem == null)
|
||||||
{
|
{
|
||||||
|
|
@ -274,7 +275,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
this.ContextMenuOpenedImplementation(addonContextMenu, ref atkValueCount, ref atkValues);
|
this.ContextMenuOpenedImplementation(addonContextMenu, ref atkValueCount, ref atkValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(AddonContextMenu* addonContextMenu, AgentContextInterface* agentContextInterface, string? title, ContextMenus.ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable<ContextMenuItem> initialContextMenuItems)
|
private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(AddonContextMenu* addonContextMenu, OldAgentContextInterface* agentContextInterface, string? title, ContextMenus.ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable<ContextMenuItem> initialContextMenuItems)
|
||||||
{
|
{
|
||||||
var parentAddonName = this.GetParentAddonName(&addonContextMenu->AtkUnitBase);
|
var parentAddonName = this.GetParentAddonName(&addonContextMenu->AtkUnitBase);
|
||||||
|
|
||||||
|
|
@ -285,11 +286,11 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
if (IsInventoryContext(agentContextInterface))
|
if (IsInventoryContext(agentContextInterface))
|
||||||
{
|
{
|
||||||
var agentInventoryContext = (AgentInventoryContext*)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
|
else
|
||||||
{
|
{
|
||||||
var agentContext = (AgentContext*)agentContextInterface;
|
var agentContext = (OldAgentContext*)agentContextInterface;
|
||||||
|
|
||||||
uint? id = agentContext->GameObjectId;
|
uint? id = agentContext->GameObjectId;
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Dalamud.Game.Gui.ContextMenus.OldStructs;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
|
@ -18,7 +18,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
/// <param name="agent">The agent associated with the context menu.</param>
|
/// <param name="agent">The agent associated with the context menu.</param>
|
||||||
/// <param name="parentAddonName">The the name of the parent addon associated with the context menu.</param>
|
/// <param name="parentAddonName">The the name of the parent addon associated with the context menu.</param>
|
||||||
/// <param name="items">The items in the context menu.</param>
|
/// <param name="items">The items in the context menu.</param>
|
||||||
public ContextMenuOpenedArgs(AddonContextMenu* addon, AgentContextInterface* agent, string? parentAddonName, IEnumerable<ContextMenuItem> items)
|
public ContextMenuOpenedArgs(AddonContextMenu* addon, OldAgentContextInterface* agent, string? parentAddonName, IEnumerable<ContextMenuItem> items)
|
||||||
{
|
{
|
||||||
this.Addon = addon;
|
this.Addon = addon;
|
||||||
this.Agent = agent;
|
this.Agent = agent;
|
||||||
|
|
@ -34,7 +34,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the agent associated with the context menu.
|
/// Gets the agent associated with the context menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public AgentContextInterface* Agent { get; }
|
public OldAgentContextInterface* Agent { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the parent addon associated with the context menu.
|
/// Gets the name of the parent addon associated with the context menu.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Dalamud.Game.Gui.ContextMenus.OldStructs;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal unsafe class ContextMenuReaderWriter
|
internal unsafe class ContextMenuReaderWriter
|
||||||
{
|
{
|
||||||
private readonly AgentContextInterface* agentContextInterface;
|
private readonly OldAgentContextInterface* agentContextInterface;
|
||||||
|
|
||||||
private int atkValueCount;
|
private int atkValueCount;
|
||||||
private AtkValue* atkValues;
|
private AtkValue* atkValues;
|
||||||
|
|
@ -30,7 +30,7 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
/// <param name="agentContextInterface">The AgentContextInterface to act upon.</param>
|
/// <param name="agentContextInterface">The AgentContextInterface to act upon.</param>
|
||||||
/// <param name="atkValueCount">The number of ATK values to consider.</param>
|
/// <param name="atkValueCount">The number of ATK values to consider.</param>
|
||||||
/// <param name="atkValues">Pointer to the array of ATK values.</param>
|
/// <param name="atkValues">Pointer to the array of ATK values.</param>
|
||||||
public ContextMenuReaderWriter(AgentContextInterface* agentContextInterface, int atkValueCount, AtkValue* atkValues)
|
public ContextMenuReaderWriter(OldAgentContextInterface* agentContextInterface, int atkValueCount, AtkValue* atkValues)
|
||||||
{
|
{
|
||||||
PluginLog.Warning($"{(IntPtr)atkValues:X}");
|
PluginLog.Warning($"{(IntPtr)atkValues:X}");
|
||||||
|
|
||||||
|
|
@ -306,17 +306,17 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
byte action;
|
byte action;
|
||||||
if (this.IsInventoryContext)
|
if (this.IsInventoryContext)
|
||||||
{
|
{
|
||||||
var actions = &((AgentInventoryContext*)this.agentContextInterface)->Actions;
|
var actions = &((AgentInventoryContext*)this.agentContextInterface)->EventIdArray;
|
||||||
action = *(actions + contextMenuItemAtkValueBaseIndex);
|
action = *actions[contextMenuItemAtkValueBaseIndex];
|
||||||
}
|
}
|
||||||
else if (this.StructLayout is SubContextMenuStructLayout.Alternate)
|
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);
|
action = (byte)*(redButtonActions + contextMenuItemIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var actions = &((AgentContext*)this.agentContextInterface)->Items->Actions;
|
var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions;
|
||||||
action = *(actions + contextMenuItemAtkValueBaseIndex);
|
action = *(actions + contextMenuItemAtkValueBaseIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,27 +438,27 @@ namespace Dalamud.Game.Gui.ContextMenus
|
||||||
|
|
||||||
if (this.IsInventoryContext)
|
if (this.IsInventoryContext)
|
||||||
{
|
{
|
||||||
var actions = &((AgentInventoryContext*)this.agentContextInterface)->Actions;
|
var actions = &((AgentInventoryContext*)this.agentContextInterface)->EventIdArray;
|
||||||
*(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action;
|
*actions[this.FirstContextMenuItemIndex + contextMenuItemIndex] = action;
|
||||||
}
|
}
|
||||||
else if (this.StructLayout is SubContextMenuStructLayout.Alternate && this.FirstUnhandledAction != null)
|
else if (this.StructLayout is SubContextMenuStructLayout.Alternate && this.FirstUnhandledAction != null)
|
||||||
{
|
{
|
||||||
// Some weird placeholder goes here
|
// 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);
|
*(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = (byte)(this.FirstUnhandledAction.Value + contextMenuItemIndex);
|
||||||
|
|
||||||
// Make sure there's one of these function pointers for every item.
|
// 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.
|
// 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);
|
*(unkFunctionPointers + this.FirstContextMenuItemIndex + contextMenuItemIndex) = *(unkFunctionPointers + this.FirstContextMenuItemIndex);
|
||||||
|
|
||||||
// The real action goes here
|
// The real action goes here
|
||||||
var redButtonActions = &((AgentContext*)this.agentContextInterface)->Items->RedButtonActions;
|
var redButtonActions = &((OldAgentContext*)this.agentContextInterface)->Items->RedButtonActions;
|
||||||
*(redButtonActions + contextMenuItemIndex) = action;
|
*(redButtonActions + contextMenuItemIndex) = action;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var actions = &((AgentContext*)this.agentContextInterface)->Items->Actions;
|
var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions;
|
||||||
*(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action;
|
*(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
33
Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs
Normal file
33
Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -412,7 +412,7 @@ namespace Dalamud.Game.Gui
|
||||||
var unitBase = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)addon;
|
var unitBase = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)addon;
|
||||||
var id = unitBase->ParentID;
|
var id = unitBase->ParentID;
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
id = unitBase->IDu;
|
id = unitBase->ID;
|
||||||
|
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue