diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenu.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenu.cs
deleted file mode 100644
index 0566b8107..000000000
--- a/Dalamud/Game/Gui/ContextMenus/ContextMenu.cs
+++ /dev/null
@@ -1,463 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using Dalamud.Configuration.Internal;
-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;
-using Serilog;
-
-using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Provides an interface to modify context menus.
- ///
- [PluginInterface]
- [InterfaceVersion("1.0")]
- [ServiceManager.BlockingEarlyLoadedService]
- public sealed class ContextMenu : IDisposable, IServiceType
- {
- private const int MaxContextMenuItemsPerContextMenu = 32;
-
- private readonly OpenSubContextMenuDelegate? openSubContextMenu;
-
- #region Hooks
-
- private readonly Hook contextMenuOpenedHook;
- private readonly Hook subContextMenuOpenedHook;
- private readonly Hook contextMenuItemSelectedHook;
- private readonly Hook contextMenuOpeningHook;
- private readonly Hook subContextMenuOpeningHook;
-
- #endregion
-
- private unsafe OldAgentContextInterface* currentAgentContextInterface;
-
- private IntPtr currentSubContextMenuTitle;
-
- private OpenSubContextMenuItem? selectedOpenSubContextMenuItem;
- private ContextMenuOpenedArgs? currentContextMenuOpenedArgs;
-
- [ServiceManager.ServiceConstructor]
- private ContextMenu(SigScanner sigScanner)
- {
- this.Address = new ContextMenuAddressResolver();
- this.Address.Setup(sigScanner);
-
- unsafe
- {
- this.openSubContextMenu = Marshal.GetDelegateForFunctionPointer(this.Address.OpenSubContextMenuPtr);
-
- this.contextMenuOpeningHook = Hook.FromAddress(this.Address.ContextMenuOpeningPtr, this.ContextMenuOpeningDetour);
- this.contextMenuOpenedHook = Hook.FromAddress(this.Address.ContextMenuOpenedPtr, this.ContextMenuOpenedDetour);
- this.contextMenuItemSelectedHook = Hook.FromAddress(this.Address.ContextMenuItemSelectedPtr, this.ContextMenuItemSelectedDetour);
- this.subContextMenuOpeningHook = Hook.FromAddress(this.Address.SubContextMenuOpeningPtr, this.SubContextMenuOpeningDetour);
- this.subContextMenuOpenedHook = Hook.FromAddress(this.Address.SubContextMenuOpenedPtr, this.SubContextMenuOpenedDetour);
- }
- }
-
- #region Delegates
-
- private unsafe delegate bool OpenSubContextMenuDelegate(OldAgentContext* agentContext);
-
- 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(OldAgentContext* agentContext);
-
- #endregion
-
- ///
- /// Occurs when a context menu is opened by the game.
- ///
- public event ContextMenus.ContextMenuOpenedDelegate? ContextMenuOpened;
-
- private ContextMenuAddressResolver Address { get; set; }
-
- ///
- void IDisposable.Dispose()
- {
- this.subContextMenuOpeningHook.Disable();
- this.contextMenuItemSelectedHook.Disable();
- this.subContextMenuOpenedHook.Disable();
- this.contextMenuOpenedHook.Disable();
- this.contextMenuOpeningHook.Disable();
- }
-
- private static unsafe bool IsInventoryContext(OldAgentContextInterface* agentContextInterface)
- {
- return agentContextInterface == AgentInventoryContext.Instance();
- }
-
- private static int GetContextMenuItemsHashCode(IEnumerable contextMenuItems)
- {
- unchecked
- {
- return contextMenuItems.Aggregate(17, (current, item) => (current * 23) + item.GetHashCode());
- }
- }
-
- [ServiceManager.CallWhenServicesReady]
- private void ContinueConstruction(GameGui gameGui)
- {
- if (!EnvironmentConfiguration.DalamudDoContextMenu)
- return;
-
- this.contextMenuOpeningHook.Enable();
- this.contextMenuOpenedHook.Enable();
- this.contextMenuItemSelectedHook.Enable();
- this.subContextMenuOpeningHook.Enable();
- this.subContextMenuOpenedHook.Enable();
- }
-
- 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);
- }
-
- private unsafe bool ContextMenuOpenedDetour(AddonContextMenu* addonContextMenu, int atkValueCount, AtkValue* atkValues)
- {
- try
- {
- this.ContextMenuOpenedImplementation(addonContextMenu, ref atkValueCount, ref atkValues);
- }
- catch (Exception ex)
- {
- PluginLog.Error(ex, "ContextMenuOpenedDetour");
- }
-
- return this.contextMenuOpenedHook.Original(addonContextMenu, atkValueCount, atkValues);
- }
-
- private unsafe void ContextMenuOpenedImplementation(AddonContextMenu* addonContextMenu, ref int atkValueCount, ref AtkValue* atkValues)
- {
- if (this.ContextMenuOpened == null
- || this.currentAgentContextInterface == null)
- {
- return;
- }
-
- var contextMenuReaderWriter = new ContextMenuReaderWriter(this.currentAgentContextInterface, atkValueCount, atkValues);
-
- // Check for a title.
- string? title = null;
- if (this.selectedOpenSubContextMenuItem != null)
- {
- title = this.selectedOpenSubContextMenuItem.Name.TextValue;
-
- // Write the custom title
- var titleAtkValue = &atkValues[1];
- fixed (byte* titlePtr = this.selectedOpenSubContextMenuItem.Name.Encode().NullTerminate())
- {
- titleAtkValue->SetString(titlePtr);
- }
- }
- else if (contextMenuReaderWriter.Title != null)
- {
- title = contextMenuReaderWriter.Title.TextValue;
- }
-
- // Determine which event to raise.
- var contextMenuOpenedDelegate = this.ContextMenuOpened;
-
- // this.selectedOpenSubContextMenuItem is OpenSubContextMenuItem openSubContextMenuItem
- if (this.selectedOpenSubContextMenuItem != null)
- {
- contextMenuOpenedDelegate = this.selectedOpenSubContextMenuItem.Opened;
- }
-
- // Get the existing items from the game.
- // TODO: For inventory sub context menus, we take only the last item -- the return item.
- // This is because we're doing a hack to spawn a Second Tier sub context menu and then appropriating it.
- var contextMenuItems = contextMenuReaderWriter.Read();
- if (contextMenuItems == null)
- return;
-
- if (IsInventoryContext(this.currentAgentContextInterface) && this.selectedOpenSubContextMenuItem != null)
- {
- contextMenuItems = contextMenuItems.TakeLast(1).ToArray();
- }
-
- var beforeHashCode = GetContextMenuItemsHashCode(contextMenuItems);
-
- // Raise the event and get the context menu changes.
- this.currentContextMenuOpenedArgs = this.NotifyContextMenuOpened(addonContextMenu, this.currentAgentContextInterface, title, contextMenuOpenedDelegate, contextMenuItems);
- if (this.currentContextMenuOpenedArgs == null)
- {
- return;
- }
-
- var afterHashCode = GetContextMenuItemsHashCode(this.currentContextMenuOpenedArgs.Items);
-
- PluginLog.Warning($"{beforeHashCode}={afterHashCode}");
-
- // Only write to memory if the items were actually changed.
- if (beforeHashCode != afterHashCode)
- {
- // Write the new changes.
- contextMenuReaderWriter.Write(this.currentContextMenuOpenedArgs.Items);
-
- // Update the addon.
- atkValueCount = *(&addonContextMenu->AtkValuesCount) = (ushort)contextMenuReaderWriter.AtkValueCount;
- atkValues = *(&addonContextMenu->AtkValues) = contextMenuReaderWriter.AtkValues;
- }
- }
-
- private unsafe bool SubContextMenuOpeningDetour(OldAgentContext* agentContext)
- {
- return this.SubContextMenuOpeningImplementation(agentContext) || this.subContextMenuOpeningHook.Original(agentContext);
- }
-
- private unsafe bool SubContextMenuOpeningImplementation(OldAgentContext* agentContext)
- {
- if (this.openSubContextMenu == null || this.selectedOpenSubContextMenuItem == null)
- {
- return false;
- }
-
- // The important things to make this work are:
- // 1. Allocate a temporary sub context menu title. The value doesn't matter, we'll set it later.
- // 2. Context menu item count must equal 1 to tell the game there is enough space for the "< Return" item.
- // 3. Atk value count must equal the index of the first context menu item.
- // This is enough to keep the base data, but excludes the context menu item data.
- // We want to exclude context menu item data in this function because the game sometimes includes garbage items which can cause problems.
- // After this function, the game adds the "< Return" item, and THEN we add our own items after that.
-
- this.openSubContextMenu(agentContext);
-
- // Allocate a new 1 byte title. This is required for the game to render the titled context menu style.
- // The actual value doesn't matter at this point, we'll set it later.
- MemoryHelper.GameFree(ref this.currentSubContextMenuTitle, (ulong)IntPtr.Size);
- this.currentSubContextMenuTitle = MemoryHelper.GameAllocateUi(1);
- *(&(&agentContext->AgentContextInterface)->SubContextMenuTitle) = (byte*)this.currentSubContextMenuTitle;
- *(byte*)this.currentSubContextMenuTitle = 0;
-
- // Expect at least 1 context menu item.
- (&agentContext->Items->AtkValues)[0].UInt = 1;
-
- // Expect a title. This isn't needed by the game, it's needed by ContextMenuReaderWriter which uses this to check if it's a context menu
- (&agentContext->Items->AtkValues)[1].ChangeType(ValueType.String);
-
- (&agentContext->Items->AtkValues)[1].String = (byte*)0;
-
- ContextMenuReaderWriter contextMenuReaderWriter = new ContextMenuReaderWriter(&agentContext->AgentContextInterface, agentContext->Items->AtkValueCount, &agentContext->Items->AtkValues);
- *(&agentContext->Items->AtkValueCount) = (ushort)contextMenuReaderWriter.FirstContextMenuItemIndex;
-
- return true;
- }
-
- private unsafe bool SubContextMenuOpenedDetour(AddonContextMenu* addonContextMenu, int atkValueCount, AtkValue* atkValues)
- {
- try
- {
- this.SubContextMenuOpenedImplementation(addonContextMenu, ref atkValueCount, ref atkValues);
- }
- catch (Exception ex)
- {
- PluginLog.Error(ex, "SubContextMenuOpenedDetour");
- }
-
- return this.subContextMenuOpenedHook.Original(addonContextMenu, atkValueCount, atkValues);
- }
-
- private unsafe void SubContextMenuOpenedImplementation(AddonContextMenu* addonContextMenu, ref int atkValueCount, ref AtkValue* atkValues)
- {
- this.ContextMenuOpenedImplementation(addonContextMenu, ref atkValueCount, ref atkValues);
- }
-
- private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(AddonContextMenu* addonContextMenu, OldAgentContextInterface* agentContextInterface, string? title, ContextMenus.ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable initialContextMenuItems)
- {
- var parentAddonName = this.GetParentAddonName(&addonContextMenu->AtkUnitBase);
-
- Log.Warning($"AgentContextInterface at: {new IntPtr(agentContextInterface):X}");
-
- InventoryItemContext? inventoryItemContext = null;
- GameObjectContext? gameObjectContext = null;
- if (IsInventoryContext(agentContextInterface))
- {
- var agentInventoryContext = (AgentInventoryContext*)agentContextInterface;
- inventoryItemContext = new InventoryItemContext(agentInventoryContext->TargetDummyItem.ItemID, agentInventoryContext->TargetDummyItem.Quantity, agentInventoryContext->TargetDummyItem.Flags.HasFlag(InventoryItem.ItemFlags.HQ));
- }
- else
- {
- var agentContext = (OldAgentContext*)agentContextInterface;
-
- uint? id = agentContext->GameObjectId;
- if (id == 0)
- {
- id = null;
- }
-
- ulong? contentId = agentContext->GameObjectContentId;
- if (contentId == 0)
- {
- contentId = null;
- }
-
- var name = MemoryHelper.ReadSeStringNullTerminated((IntPtr)agentContext->GameObjectName.StringPtr).TextValue;
- if (string.IsNullOrEmpty(name))
- {
- name = null;
- }
-
- ushort? worldId = agentContext->GameObjectWorldId;
- if (worldId == 0)
- {
- worldId = null;
- }
-
- if (id != null
- || contentId != null
- || name != null
- || worldId != null)
- {
- gameObjectContext = new GameObjectContext(id, contentId, name, worldId);
- }
- }
-
- // Temporarily remove the < Return item, for UX we should enforce that it is always last in the list.
- var lastContextMenuItem = initialContextMenuItems.LastOrDefault();
- if (lastContextMenuItem is GameContextMenuItem gameContextMenuItem && gameContextMenuItem.SelectedAction == 102)
- {
- initialContextMenuItems = initialContextMenuItems.SkipLast(1);
- }
-
- var contextMenuOpenedArgs = new ContextMenuOpenedArgs(addonContextMenu, agentContextInterface, parentAddonName, initialContextMenuItems)
- {
- Title = title,
- InventoryItemContext = inventoryItemContext,
- GameObjectContext = gameObjectContext,
- };
-
- try
- {
- contextMenuOpenedDelegate.Invoke(contextMenuOpenedArgs);
- }
- catch (Exception ex)
- {
- PluginLog.LogError(ex, "NotifyContextMenuOpened");
- return null;
- }
-
- // Readd the < Return item
- if (lastContextMenuItem is GameContextMenuItem gameContextMenuItem1 && gameContextMenuItem1.SelectedAction == 102)
- {
- contextMenuOpenedArgs.Items.Add(lastContextMenuItem);
- }
-
- foreach (var contextMenuItem in contextMenuOpenedArgs.Items.ToArray())
- {
- // TODO: Game doesn't support nested sub context menus, but we might be able to.
- if (contextMenuItem is OpenSubContextMenuItem && contextMenuOpenedArgs.Title != null)
- {
- contextMenuOpenedArgs.Items.Remove(contextMenuItem);
- PluginLog.Warning($"Context menu '{contextMenuOpenedArgs.Title}' item '{contextMenuItem}' has been removed because nested sub context menus are not supported.");
- }
- }
-
- if (contextMenuOpenedArgs.Items.Count > MaxContextMenuItemsPerContextMenu)
- {
- PluginLog.LogWarning($"Context menu requesting {contextMenuOpenedArgs.Items.Count} of max {MaxContextMenuItemsPerContextMenu} items. Resizing list to compensate.");
- contextMenuOpenedArgs.Items.RemoveRange(MaxContextMenuItemsPerContextMenu, contextMenuOpenedArgs.Items.Count - MaxContextMenuItemsPerContextMenu);
- }
-
- return contextMenuOpenedArgs;
- }
-
- private unsafe bool ContextMenuItemSelectedDetour(AddonContextMenu* addonContextMenu, int selectedIndex, byte a3)
- {
- try
- {
- this.ContextMenuItemSelectedImplementation(addonContextMenu, selectedIndex);
- }
- catch (Exception ex)
- {
- PluginLog.Error(ex, "ContextMenuItemSelectedDetour");
- }
-
- return this.contextMenuItemSelectedHook.Original(addonContextMenu, selectedIndex, a3);
- }
-
- private unsafe void ContextMenuItemSelectedImplementation(AddonContextMenu* addonContextMenu, int selectedIndex)
- {
- if (this.currentContextMenuOpenedArgs == null || selectedIndex == -1)
- {
- this.currentContextMenuOpenedArgs = null;
- this.selectedOpenSubContextMenuItem = null;
- return;
- }
-
- // Read the selected item directly from the game
- ContextMenuReaderWriter contextMenuReaderWriter = new ContextMenuReaderWriter(this.currentAgentContextInterface, addonContextMenu->AtkValuesCount, addonContextMenu->AtkValues);
- var gameContextMenuItems = contextMenuReaderWriter.Read();
- if (gameContextMenuItems == null)
- return;
-
- var gameSelectedItem = gameContextMenuItems.ElementAtOrDefault(selectedIndex);
-
- // This should be impossible
- if (gameSelectedItem == null)
- {
- this.currentContextMenuOpenedArgs = null;
- this.selectedOpenSubContextMenuItem = null;
- return;
- }
-
- // Match it with the items we already know about based on its name.
- // We can get into a state where we have a game item we don't recognize when another plugin has added one.
- var selectedItem = this.currentContextMenuOpenedArgs.Items.FirstOrDefault(item => item.Name.Encode().SequenceEqual(gameSelectedItem.Name.Encode()));
-
- this.selectedOpenSubContextMenuItem = null;
- if (selectedItem is CustomContextMenuItem customContextMenuItem)
- {
- try
- {
- var customContextMenuItemSelectedArgs = new CustomContextMenuItemSelectedArgs(this.currentContextMenuOpenedArgs, customContextMenuItem);
- customContextMenuItem.ItemSelected(customContextMenuItemSelectedArgs);
- }
- catch (Exception ex)
- {
- PluginLog.LogError(ex, "ContextMenuItemSelectedImplementation");
- }
- }
- else if (selectedItem is OpenSubContextMenuItem openSubContextMenuItem)
- {
- this.selectedOpenSubContextMenuItem = openSubContextMenuItem;
- }
-
- this.currentContextMenuOpenedArgs = null;
- }
-
- private unsafe string? GetParentAddonName(AtkUnitBase* addonInterface)
- {
- var parentAddonId = addonInterface->ContextMenuParentID;
- if (parentAddonId == 0)
- {
- return null;
- }
-
- var atkStage = AtkStage.GetSingleton();
- var parentAddon = atkStage->RaptureAtkUnitManager->GetAddonById(parentAddonId);
- return Marshal.PtrToStringUTF8(new IntPtr(parentAddon->Name));
- }
-
- private unsafe AtkUnitBase* GetAddonFromAgent(AgentInterface* agentInterface)
- {
- return agentInterface->AddonId == 0 ? null : AtkStage.GetSingleton()->RaptureAtkUnitManager->GetAddonById((ushort)agentInterface->AddonId);
- }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuAddressResolver.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuAddressResolver.cs
deleted file mode 100644
index 6bd0f6f72..000000000
--- a/Dalamud/Game/Gui/ContextMenus/ContextMenuAddressResolver.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Address resolver for context menu functions.
- ///
- public class ContextMenuAddressResolver : BaseAddressResolver
- {
- private const string SigOpenSubContextMenu = "E8 ?? ?? ?? ?? 44 39 A3 ?? ?? ?? ?? 0F 86";
- private const string SigContextMenuOpening = "E8 ?? ?? ?? ?? 0F B7 C0 48 83 C4 60";
- private const string SigContextMenuOpened = "48 8B C4 57 41 56 41 57 48 81 EC";
- private const string SigContextMenuItemSelected = "48 89 5C 24 ?? 55 57 41 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 44 24 ?? 80 B9";
- private const string SigSubContextMenuOpening = "E8 ?? ?? ?? ?? 44 39 A3 ?? ?? ?? ?? 0F 84";
- private const string SigSubContextMenuOpened = "48 8B C4 57 41 55 41 56 48 81 EC";
-
- ///
- /// Gets the OpenSubContextMenu function address.
- ///
- public IntPtr OpenSubContextMenuPtr { get; private set; }
-
- ///
- /// Gets the ContextMenuOpening function address.
- ///
- public IntPtr ContextMenuOpeningPtr { get; private set; }
-
- ///
- /// Gets the ContextMenuOpened function address.
- ///
- public IntPtr ContextMenuOpenedPtr { get; private set; }
-
- ///
- /// Gets the ContextMenuItemSelected function address.
- ///
- public IntPtr ContextMenuItemSelectedPtr { get; private set; }
-
- ///
- /// Gets the SubContextMenuOpening function address.
- ///
- public IntPtr SubContextMenuOpeningPtr { get; private set; }
-
- ///
- /// Gets the SubContextMenuOpened function address.
- ///
- public IntPtr SubContextMenuOpenedPtr { get; private set; }
-
- ///
- protected override void Setup64Bit(SigScanner scanner)
- {
- this.OpenSubContextMenuPtr = scanner.ScanText(SigOpenSubContextMenu);
- this.ContextMenuOpeningPtr = scanner.ScanText(SigContextMenuOpening);
- this.ContextMenuOpenedPtr = scanner.ScanText(SigContextMenuOpened);
- this.ContextMenuItemSelectedPtr = scanner.ScanText(SigContextMenuItemSelected);
- this.SubContextMenuOpeningPtr = scanner.ScanText(SigSubContextMenuOpening);
- this.SubContextMenuOpenedPtr = scanner.ScanText(SigSubContextMenuOpened);
- }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuItem.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuItem.cs
deleted file mode 100644
index c286ac4bb..000000000
--- a/Dalamud/Game/Gui/ContextMenus/ContextMenuItem.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System.Numerics;
-
-using Dalamud.Game.Text.SeStringHandling;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// An item in a context menu.
- ///
- public abstract class ContextMenuItem
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the item.
- internal ContextMenuItem(SeString name)
- {
- this.Name = name;
- }
-
- ///
- /// Gets the name of the item.
- ///
- public SeString Name { get; internal set; }
-
- ///
- /// Gets or sets a value indicating whether or not the item is enabled. When enabled, an item is selectable.
- ///
- public bool IsEnabled { get; set; } = true;
-
- ///
- /// Gets or sets the indicator of the item.
- ///
- public ContextMenuItemIndicator Indicator { get; set; } = ContextMenuItemIndicator.None;
-
- ///
- public override string ToString()
- {
- return this.Name.ToString();
- }
-
- ///
- public override int GetHashCode()
- {
- unchecked
- {
- var hash = 17;
- hash = (hash * 23) + new BigInteger(this.Name.Encode()).GetHashCode();
- hash = (hash * 23) + this.IsEnabled.GetHashCode();
- hash = (hash * 23) + ((int)this.Indicator).GetHashCode();
- return hash;
- }
- }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuItemIndicator.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuItemIndicator.cs
deleted file mode 100644
index cdd2aa694..000000000
--- a/Dalamud/Game/Gui/ContextMenus/ContextMenuItemIndicator.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// An indicator displayed on a context menu item.
- ///
- public enum ContextMenuItemIndicator
- {
- ///
- /// The item has no indicator.
- ///
- None,
-
- ///
- /// The item has a previous indicator.
- ///
- Previous,
-
- ///
- /// The item has a next indicator.
- ///
- Next,
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedArgs.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedArgs.cs
deleted file mode 100644
index 0924dcf54..000000000
--- a/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedArgs.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-using Dalamud.Game.Gui.ContextMenus.OldStructs;
-using Dalamud.Game.Text.SeStringHandling;
-using FFXIVClientStructs.FFXIV.Client.UI;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Provides data for methods.
- ///
- public sealed unsafe class ContextMenuOpenedArgs
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The addon associated with the context menu.
- /// 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, OldAgentContextInterface* agent, string? parentAddonName, IEnumerable items)
- {
- this.Addon = addon;
- this.Agent = agent;
- this.ParentAddonName = parentAddonName;
- this.Items = new List(items);
- }
-
- ///
- /// Gets the addon associated with the context menu.
- ///
- public AddonContextMenu* Addon { get; }
-
- ///
- /// Gets the agent associated with the context menu.
- ///
- public OldAgentContextInterface* Agent { get; }
-
- ///
- /// Gets the name of the parent addon associated with the context menu.
- ///
- public string? ParentAddonName { get; }
-
- ///
- /// Gets the title of the context menu.
- ///
- public string? Title { get; init; }
-
- ///
- /// Gets the game object context associated with the context menu.
- ///
- public GameObjectContext? GameObjectContext { get; init; }
-
- ///
- /// Gets the item context associated with the context menu.
- ///
- public InventoryItemContext? InventoryItemContext { get; init; }
-
- ///
- /// Gets the items in the context menu.
- ///
- internal List Items { get; }
-
- ///
- /// Append a custom context menu item to this context menu.
- ///
- /// The name of the item.
- /// The action to be executed once selected.
- public void AddCustomItem(SeString name, CustomContextMenuItemSelectedDelegate selected) =>
- this.Items.Add(new CustomContextMenuItem(name, selected));
-
- ///
- /// Append a custom submenu to this context menu.
- /// Note that these cannot be nested, and will be ignored if they are.
- ///
- /// The name of the submenu.
- /// The action to be executed once opened.
- public void AddCustomSubMenu(SeString name, ContextMenuOpenedDelegate opened)
- {
- if (this.GameObjectContext != null)
- throw new Exception("Submenus on GameObjects are not supported yet.");
-
- this.Items.Add(new OpenSubContextMenuItem(name, opened));
- }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedDelegate.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedDelegate.cs
deleted file mode 100644
index 4e3a162e2..000000000
--- a/Dalamud/Game/Gui/ContextMenus/ContextMenuOpenedDelegate.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Represents the method the event.
- ///
- /// The data associated with the event.
- public delegate void ContextMenuOpenedDelegate(ContextMenuOpenedArgs args);
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/ContextMenuReaderWriter.cs b/Dalamud/Game/Gui/ContextMenus/ContextMenuReaderWriter.cs
deleted file mode 100644
index 633c6560b..000000000
--- a/Dalamud/Game/Gui/ContextMenus/ContextMenuReaderWriter.cs
+++ /dev/null
@@ -1,553 +0,0 @@
-using System;
-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;
-using FFXIVClientStructs.FFXIV.Client.UI.Agent;
-using FFXIVClientStructs.FFXIV.Component.GUI;
-
-using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Class responsible for reading and writing to context menu data.
- ///
- internal unsafe class ContextMenuReaderWriter
- {
- private readonly OldAgentContextInterface* agentContextInterface;
-
- private int atkValueCount;
- private AtkValue* atkValues;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The AgentContextInterface to act upon.
- /// The number of ATK values to consider.
- /// Pointer to the array of ATK values.
- public ContextMenuReaderWriter(OldAgentContextInterface* agentContextInterface, int atkValueCount, AtkValue* atkValues)
- {
- PluginLog.Warning($"{(IntPtr)atkValues:X}");
-
- this.agentContextInterface = agentContextInterface;
- this.atkValueCount = atkValueCount;
- this.atkValues = atkValues;
- }
-
- private enum SubContextMenuStructLayout
- {
- Main,
- Alternate,
- }
-
- ///
- /// Gets the number of AtkValues for this context menu.
- ///
- public int AtkValueCount => this.atkValueCount;
-
- ///
- /// Gets the AtkValues for this context menu.
- ///
- public AtkValue* AtkValues => this.atkValues;
-
- ///
- /// Gets the amount of items in the context menu.
- ///
- public int ContextMenuItemCount => this.atkValues[0].Int;
-
- ///
- /// Gets a value indicating whether the context menu has a title.
- ///
- public bool HasTitle
- {
- get
- {
- bool isStringType =
- (int)this.atkValues[1].Type == 8
- || (int)this.atkValues[1].Type == 38
- || this.atkValues[1].Type == FFXIVClientStructs.FFXIV.Component.GUI.ValueType.String;
-
- return isStringType;
- }
- }
-
- ///
- /// Gets the title of the context menu.
- ///
- public SeString? Title
- {
- get
- {
- if (this.HasTitle && (&this.atkValues[1])->String != null)
- {
- MemoryHelper.ReadSeStringNullTerminated((IntPtr)(&this.atkValues[1])->String, out var str);
- return str;
- }
-
- return null;
- }
- }
-
- ///
- /// Gets the index of the first context menu item.
- ///
- public int FirstContextMenuItemIndex
- {
- get
- {
- if (this.HasTitle)
- {
- return 8;
- }
-
- return 7;
- }
- }
-
- ///
- /// Gets the position of the context menu.
- ///
- public Vector2? Position
- {
- get
- {
- if (this.HasTitle) return new Vector2(this.atkValues[2].Int, this.atkValues[3].Int);
-
- return null;
- }
- }
-
- private int HasPreviousIndicatorFlagsIndex
- {
- get
- {
- if (this.HasTitle)
- {
- return 6;
- }
-
- return 2;
- }
- }
-
- private int HasNextIndicatorFlagsIndex
- {
- get
- {
- if (this.HasTitle)
- {
- return 5;
- }
-
- return 3;
- }
- }
-
- private int NameIndexOffset
- {
- get
- {
- if (this.HasTitle && this.StructLayout == SubContextMenuStructLayout.Alternate)
- {
- return 1;
- }
-
- return 0;
- }
- }
-
- private int IsDisabledIndexOffset
- {
- get
- {
- if (this.HasTitle && this.StructLayout == SubContextMenuStructLayout.Alternate)
- {
- return 2;
- }
-
- return this.ContextMenuItemCount;
- }
- }
-
- /*
- ///
- /// 0x14000000 | action
- ///
- public int? MaskedActionIndexOffset
- {
- get
- {
- if (this.HasTitle && this.StructLayout == SubContextMenuStructLayout.Alternate) return 3;
-
- return null;
- }
- }
- */
-
- private int SequentialAtkValuesPerContextMenuItem
- {
- get
- {
- if (this.HasTitle && this.StructLayout == SubContextMenuStructLayout.Alternate) return 4;
-
- return 1;
- }
- }
-
- private int TotalDesiredAtkValuesPerContextMenuItem
- {
- get
- {
- if (this.HasTitle && this.StructLayout == SubContextMenuStructLayout.Alternate) return 4;
-
- return 2;
- }
- }
-
- private bool IsInventoryContext
- {
- get
- {
- if ((IntPtr)this.agentContextInterface == (IntPtr)AgentInventoryContext.Instance())
- {
- return true;
- }
-
- return false;
- }
- }
-
- private SubContextMenuStructLayout? StructLayout
- {
- get
- {
- if (this.HasTitle)
- {
- if (this.atkValues[7].Int == 8)
- return SubContextMenuStructLayout.Alternate;
-
- if (this.atkValues[7].Int == 1) return SubContextMenuStructLayout.Main;
- }
-
- return null;
- }
- }
-
- private byte NoopAction
- {
- get
- {
- if (this.IsInventoryContext)
- return 0xff;
- return 0x67;
- }
- }
-
- private byte OpenSubContextMenuAction
- {
- get
- {
- if (this.IsInventoryContext)
- {
- // This is actually the action to open the Second Tier context menu and we just hack around it
- return 0x31;
- }
-
- return 0x66;
- }
- }
-
- private byte? FirstUnhandledAction
- {
- get
- {
- if (this.StructLayout is SubContextMenuStructLayout.Alternate)
- return 0x68;
-
- return null;
- }
- }
-
- ///
- /// Read the context menu from the agent.
- ///
- /// Read menu items.
- public GameContextMenuItem[]? Read()
- {
- var gameContextMenuItems = new List();
- for (var contextMenuItemIndex = 0; contextMenuItemIndex < this.ContextMenuItemCount; contextMenuItemIndex++)
- {
- var contextMenuItemAtkValueBaseIndex = this.FirstContextMenuItemIndex + (contextMenuItemIndex * this.SequentialAtkValuesPerContextMenuItem);
-
- // Get the name
- var nameAtkValue = &this.atkValues[contextMenuItemAtkValueBaseIndex + this.NameIndexOffset];
- if (nameAtkValue->Type == 0)
- {
- continue;
- }
-
- var name = MemoryHelper.ReadSeStringNullTerminated((IntPtr)nameAtkValue->String);
-
- // Get the enabled state. Note that SE stores this as IsDisabled, NOT IsEnabled (those heathens)
- var isEnabled = true;
- var isDisabledDefined = this.FirstContextMenuItemIndex + this.ContextMenuItemCount < this.AtkValueCount;
- if (isDisabledDefined)
- {
- var isDisabledAtkValue = &this.atkValues[contextMenuItemAtkValueBaseIndex + this.IsDisabledIndexOffset];
- isEnabled = isDisabledAtkValue->Int == 0;
- }
-
- // Get the action
- byte action;
- if (this.IsInventoryContext)
- {
- var actions = &((OldAgentInventoryContext*)this.agentContextInterface)->Actions;
- action = *(actions + contextMenuItemAtkValueBaseIndex);
- }
- else if (this.StructLayout is SubContextMenuStructLayout.Alternate)
- {
- var redButtonActions = &((OldAgentContext*)this.agentContextInterface)->Items->RedButtonActions;
- action = (byte)*(redButtonActions + contextMenuItemIndex);
- }
- else if (((OldAgentContext*)this.agentContextInterface)->Items != null)
- {
- var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions;
- action = *(actions + contextMenuItemAtkValueBaseIndex);
- }
- else
- {
- PluginLog.Warning("Context Menu action failed, Items pointer was unexpectedly null.");
- return null;
- }
-
- // Get the has previous indicator flag
- var hasPreviousIndicatorFlagsAtkValue = &this.atkValues[this.HasPreviousIndicatorFlagsIndex];
- var hasPreviousIndicator = this.HasFlag(hasPreviousIndicatorFlagsAtkValue->UInt, contextMenuItemIndex);
-
- // Get the has next indicator flag
- var hasNextIndicatorFlagsAtkValue = &this.atkValues[this.HasNextIndicatorFlagsIndex];
- var hasNextIndicator = this.HasFlag(hasNextIndicatorFlagsAtkValue->UInt, contextMenuItemIndex);
-
- var indicator = ContextMenuItemIndicator.None;
- if (hasPreviousIndicator)
- {
- indicator = ContextMenuItemIndicator.Previous;
- }
- else if (hasNextIndicator)
- {
- indicator = ContextMenuItemIndicator.Next;
- }
-
- var gameContextMenuItem = new GameContextMenuItem(name, action)
- {
- IsEnabled = isEnabled,
- Indicator = indicator,
- };
-
- gameContextMenuItems.Add(gameContextMenuItem);
- }
-
- return gameContextMenuItems.ToArray();
- }
-
- ///
- /// Write items to the context menu.
- ///
- /// The items to write.
- /// Whether or not reallocation is allowed.
- public void Write(IEnumerable contextMenuItems, bool allowReallocate = true)
- {
- if (allowReallocate)
- {
- var newAtkValuesCount = this.FirstContextMenuItemIndex + (contextMenuItems.Count() * this.TotalDesiredAtkValuesPerContextMenuItem);
-
- // Allocate the new array. We have to do a little dance with the first 8 bytes which represents the array count
- const int arrayCountSize = 8;
- var newAtkValuesArraySize = arrayCountSize + (Marshal.SizeOf() * newAtkValuesCount);
- var newAtkValuesArray = MemoryHelper.GameAllocateUi((ulong)newAtkValuesArraySize);
- if (newAtkValuesArray == IntPtr.Zero)
- {
- return;
- }
-
- var newAtkValues = (AtkValue*)(newAtkValuesArray + arrayCountSize);
-
- // Zero the memory, then copy the atk values up to the first context menu item atk value
- Marshal.Copy(new byte[newAtkValuesArraySize], 0, newAtkValuesArray, newAtkValuesArraySize);
- Buffer.MemoryCopy(this.atkValues, newAtkValues, newAtkValuesArraySize - arrayCountSize, (long)sizeof(AtkValue) * this.FirstContextMenuItemIndex);
-
- // Free the old array
- var oldArray = (IntPtr)this.atkValues - arrayCountSize;
- var oldArrayCount = *(ulong*)oldArray;
- var oldArraySize = arrayCountSize + ((ulong)sizeof(AtkValue) * oldArrayCount);
- MemoryHelper.GameFree(ref oldArray, oldArraySize);
-
- // Set the array count
- *(ulong*)newAtkValuesArray = (ulong)newAtkValuesCount;
-
- this.atkValueCount = newAtkValuesCount;
- this.atkValues = newAtkValues;
- }
-
- // Set the context menu item count
- const int contextMenuItemCountAtkValueIndex = 0;
- var contextMenuItemCountAtkValue = &this.atkValues[contextMenuItemCountAtkValueIndex];
- contextMenuItemCountAtkValue->UInt = (uint)contextMenuItems.Count();
-
- // Clear the previous arrow flags
- var hasPreviousIndicatorAtkValue = &this.atkValues[this.HasPreviousIndicatorFlagsIndex];
- hasPreviousIndicatorAtkValue->UInt = 0;
-
- // Clear the next arrow flags
- var hasNextIndiactorFlagsAtkValue = &this.atkValues[this.HasNextIndicatorFlagsIndex];
- hasNextIndiactorFlagsAtkValue->UInt = 0;
-
- for (var contextMenuItemIndex = 0; contextMenuItemIndex < contextMenuItems.Count(); ++contextMenuItemIndex)
- {
- var contextMenuItem = contextMenuItems.ElementAt(contextMenuItemIndex);
-
- var contextMenuItemAtkValueBaseIndex = this.FirstContextMenuItemIndex + (contextMenuItemIndex * this.SequentialAtkValuesPerContextMenuItem);
-
- // Set the name
- var nameAtkValue = &this.atkValues[contextMenuItemAtkValueBaseIndex + this.NameIndexOffset];
- nameAtkValue->ChangeType(ValueType.String);
- fixed (byte* nameBytesPtr = contextMenuItem.Name.Encode().NullTerminate())
- {
- nameAtkValue->SetString(nameBytesPtr);
- }
-
- // Set the enabled state. Note that SE stores this as IsDisabled, NOT IsEnabled (those heathens)
- var disabledAtkValue = &this.atkValues[contextMenuItemAtkValueBaseIndex + this.IsDisabledIndexOffset];
- disabledAtkValue->ChangeType(ValueType.Int);
- disabledAtkValue->Int = contextMenuItem.IsEnabled ? 0 : 1;
-
- // Set the action
- byte action = 0;
- if (contextMenuItem is GameContextMenuItem gameContextMenuItem)
- {
- action = gameContextMenuItem.SelectedAction;
- }
- else if (contextMenuItem is CustomContextMenuItem customContextMenuItem)
- {
- action = this.NoopAction;
- }
- else if (contextMenuItem is OpenSubContextMenuItem openSubContextMenuItem)
- {
- action = this.OpenSubContextMenuAction;
- }
-
- if (this.IsInventoryContext)
- {
- var actions = &((OldAgentInventoryContext*)this.agentContextInterface)->Actions;
- *(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action;
- }
- else if (this.StructLayout is SubContextMenuStructLayout.Alternate && this.FirstUnhandledAction != null)
- {
- // Some weird placeholder goes here
- 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 = &((OldAgentContext*)this.agentContextInterface)->Items->UnkFunctionPointers;
- *(unkFunctionPointers + this.FirstContextMenuItemIndex + contextMenuItemIndex) = *(unkFunctionPointers + this.FirstContextMenuItemIndex);
-
- // The real action goes here
- var redButtonActions = &((OldAgentContext*)this.agentContextInterface)->Items->RedButtonActions;
- *(redButtonActions + contextMenuItemIndex) = action;
- }
- else if (((OldAgentContext*)this.agentContextInterface)->Items != null)
- {
- // TODO: figure out why this branch is reached on inventory contexts and why Items is sometimes null.
- var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions;
- *(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action;
- }
- else
- {
- PluginLog.Warning("Context Menu action failed, Items pointer was unexpectedly null.");
- }
-
- if (contextMenuItem.Indicator == ContextMenuItemIndicator.Previous)
- {
- this.SetFlag(ref hasPreviousIndicatorAtkValue->UInt, contextMenuItemIndex, true);
- }
- else if (contextMenuItem.Indicator == ContextMenuItemIndicator.Next)
- {
- this.SetFlag(ref hasNextIndiactorFlagsAtkValue->UInt, contextMenuItemIndex, true);
- }
- }
- }
-
- private bool HasFlag(uint mask, int itemIndex)
- {
- return (mask & (1 << itemIndex)) > 0;
- }
-
- private void SetFlag(ref uint mask, int itemIndex, bool value)
- {
- mask &= ~(1U << itemIndex);
-
- if (value)
- {
- mask |= (uint)(1 << itemIndex);
- }
- }
-
- /*
- private void Log()
- {
- Log(this.atkValueCount, this.atkValues);
- }
-
- private static void Log(int atkValueCount, AtkValue* atkValues)
- {
- PluginLog.Debug($"ContextMenuReader.Log");
-
- for (int atkValueIndex = 0; atkValueIndex < atkValueCount; ++atkValueIndex)
- {
- var atkValue = &atkValues[atkValueIndex];
-
- object? value;
- switch (atkValue->Type)
- {
- case ValueType.Int:
- value = atkValue->Int;
- break;
- case ValueType.Bool:
- value = atkValue->Byte;
- break;
- case ValueType.UInt:
- value = atkValue->UInt;
- break;
- case ValueType.Float:
- value = atkValue->Float;
- break;
- default:
- {
- if (atkValue->Type == ValueType.String
- || (int)atkValue->Type == 38
- || (int)atkValue->Type == 8)
- {
- value = MemoryHelper.ReadSeStringNullTerminated((IntPtr)atkValue->String);
- }
- else
- {
- value = $"{(IntPtr)atkValue->String:X}";
- }
-
- break;
- }
- }
-
- PluginLog.Debug($"atkValues[{atkValueIndex}]={(IntPtr)atkValue:X} {atkValue->Type}={value}");
- }
- }
- */
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItem.cs b/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItem.cs
deleted file mode 100644
index 029ca7ef0..000000000
--- a/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItem.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using Dalamud.Game.Text;
-using Dalamud.Game.Text.SeStringHandling;
-using Dalamud.Game.Text.SeStringHandling.Payloads;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// An item in a context menu with a user defined action.
- ///
- public sealed class CustomContextMenuItem : ContextMenuItem
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the item.
- /// The action that will be called when the item is selected.
- public CustomContextMenuItem(SeString name, CustomContextMenuItemSelectedDelegate itemSelected)
- : base(new SeString().Append(new UIForegroundPayload(539)).Append($"{SeIconChar.BoxedLetterD.ToIconString()} ").Append(new UIForegroundPayload(0)).Append(name))
- {
- this.ItemSelected = itemSelected;
- }
-
- ///
- /// Gets the action that will be called when the item is selected.
- ///
- public CustomContextMenuItemSelectedDelegate ItemSelected { get; }
-
- ///
- public override int GetHashCode()
- {
- unchecked
- {
- var hash = base.GetHashCode();
- hash = (hash * 23) + this.ItemSelected.GetHashCode();
- return hash;
- }
- }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItemSelectedArgs.cs b/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItemSelectedArgs.cs
deleted file mode 100644
index 1092a427d..000000000
--- a/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItemSelectedArgs.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Provides data for methods.
- ///
- public sealed class CustomContextMenuItemSelectedArgs
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The currently opened context menu.
- /// The selected item within the currently opened context menu.
- internal CustomContextMenuItemSelectedArgs(ContextMenuOpenedArgs contextMenuOpenedArgs, CustomContextMenuItem selectedItem)
- {
- this.ContextMenuOpenedArgs = contextMenuOpenedArgs;
- this.SelectedItem = selectedItem;
- }
-
- ///
- /// Gets the currently opened context menu.
- ///
- public ContextMenuOpenedArgs ContextMenuOpenedArgs { get; init; }
-
- ///
- /// Gets the selected item within the currently opened context menu.
- ///
- public CustomContextMenuItem SelectedItem { get; init; }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItemSelectedDelegate.cs b/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItemSelectedDelegate.cs
deleted file mode 100644
index 615c2e773..000000000
--- a/Dalamud/Game/Gui/ContextMenus/CustomContextMenuItemSelectedDelegate.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Represents the method that handles when a is selected.
- ///
- /// The data associated with the selected .
- public delegate void CustomContextMenuItemSelectedDelegate(CustomContextMenuItemSelectedArgs args);
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/GameContextMenuItem.cs b/Dalamud/Game/Gui/ContextMenus/GameContextMenuItem.cs
deleted file mode 100644
index cf4751f33..000000000
--- a/Dalamud/Game/Gui/ContextMenus/GameContextMenuItem.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Dalamud.Game.Text.SeStringHandling;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// An item in a context menu that with a specific game action.
- ///
- public sealed class GameContextMenuItem : ContextMenuItem
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the item.
- /// The game action that will be handled when the item is selected.
- internal GameContextMenuItem(SeString name, byte selectedAction)
- : base(name)
- {
- this.SelectedAction = selectedAction;
- }
-
- ///
- /// Gets the game action that will be handled when the item is selected.
- ///
- public byte SelectedAction { get; }
-
- ///
- public override int GetHashCode()
- {
- unchecked
- {
- var hash = base.GetHashCode();
- hash = (hash * 23) + this.SelectedAction;
- return hash;
- }
- }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/GameObjectContext.cs b/Dalamud/Game/Gui/ContextMenus/GameObjectContext.cs
deleted file mode 100644
index 076888f6a..000000000
--- a/Dalamud/Game/Gui/ContextMenus/GameObjectContext.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Provides game object context to a context menu.
- ///
- public sealed class GameObjectContext
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The id of the game object.
- /// The lower content id of the game object.
- /// The name of the game object.
- /// The world id of the game object.
- internal GameObjectContext(uint? id, ulong? contentId, string? name, ushort? worldId)
- {
- this.Id = id;
- this.ContentId = contentId;
- this.Name = name;
- this.WorldId = worldId;
- }
-
- ///
- /// Gets the id of the game object.
- ///
- public uint? Id { get; }
-
- ///
- /// Gets the content id of the game object.
- ///
- public ulong? ContentId { get; }
-
- ///
- /// Gets the name of the game object.
- ///
- public string? Name { get; }
-
- ///
- /// Gets the world id of the game object.
- ///
- public ushort? WorldId { get; }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/InventoryItemContext.cs b/Dalamud/Game/Gui/ContextMenus/InventoryItemContext.cs
deleted file mode 100644
index 7f9677ef9..000000000
--- a/Dalamud/Game/Gui/ContextMenus/InventoryItemContext.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// Provides inventory item context to a context menu.
- ///
- public sealed class InventoryItemContext
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The id of the item.
- /// The count of the item in the stack.
- /// Whether the item is high quality.
- internal InventoryItemContext(uint id, uint count, bool isHighQuality)
- {
- this.Id = id;
- this.Count = count;
- this.IsHighQuality = isHighQuality;
- }
-
- ///
- /// Gets the id of the item.
- ///
- public uint Id { get; }
-
- ///
- /// Gets the count of the item in the stack.
- ///
- public uint Count { get; }
-
- ///
- /// Gets a value indicating whether the item is high quality.
- ///
- public bool IsHighQuality { get; }
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs b/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs
deleted file mode 100644
index d0c59b616..000000000
--- a/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContext.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-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
deleted file mode 100644
index 2dde22dfb..000000000
--- a/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentContextInterface.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-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/ContextMenus/OldStructs/OldAgentInventoryContext.cs b/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentInventoryContext.cs
deleted file mode 100644
index 56fbbac97..000000000
--- a/Dalamud/Game/Gui/ContextMenus/OldStructs/OldAgentInventoryContext.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Runtime.InteropServices;
-
-using FFXIVClientStructs.FFXIV.Client.UI.Agent;
-using FFXIVClientStructs.FFXIV.Component.GUI;
-
-namespace Dalamud.Game.Gui.ContextMenus.OldStructs;
-
-[StructLayout(LayoutKind.Explicit)]
-public unsafe struct OldAgentInventoryContext
-{
- public static OldAgentInventoryContext* Instance() => (OldAgentInventoryContext*) FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.InventoryContext);
-
- [FieldOffset(0x0)] public AgentInterface AgentInterface;
- [FieldOffset(0x0)] public OldAgentContextInterface AgentContextInterface;
- [FieldOffset(0x2C)] public uint FirstContextMenuItemAtkValueIndex;
- [FieldOffset(0x30)] public uint ContextMenuItemCount;
- [FieldOffset(0x38)] public AtkValue AtkValues;
- [FieldOffset(0x558)] public unsafe byte Actions;
- [FieldOffset(0x5A8)] public uint UnkFlags;
- [FieldOffset(0x5B0)] public uint PositionX;
- [FieldOffset(0x5B4)] public uint PositionY;
- [FieldOffset(0x5F8)] public uint InventoryItemId;
- [FieldOffset(0x5FC)] public uint InventoryItemCount;
- [FieldOffset(0x604)] public bool InventoryItemIsHighQuality;
-}
diff --git a/Dalamud/Game/Gui/ContextMenus/OpenSubContextMenuItem.cs b/Dalamud/Game/Gui/ContextMenus/OpenSubContextMenuItem.cs
deleted file mode 100644
index 78be954f7..000000000
--- a/Dalamud/Game/Gui/ContextMenus/OpenSubContextMenuItem.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using Dalamud.Game.Text;
-using Dalamud.Game.Text.SeStringHandling;
-using Dalamud.Game.Text.SeStringHandling.Payloads;
-
-namespace Dalamud.Game.Gui.ContextMenus
-{
- ///
- /// An item in a context menu that can open a sub context menu.
- ///
- public sealed class OpenSubContextMenuItem : ContextMenuItem
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the item.
- /// The action that will be called when the item is selected.
- internal OpenSubContextMenuItem(SeString name, ContextMenuOpenedDelegate opened)
- : base(new SeString().Append(new UIForegroundPayload(539)).Append($"{SeIconChar.BoxedLetterD.ToIconString()} ").Append(new UIForegroundPayload(0)).Append(name))
- {
- this.Opened = opened;
- this.Indicator = ContextMenuItemIndicator.Next;
- }
-
- ///
- /// Gets the action that will be called when the item is selected.
- ///
- public ContextMenuOpenedDelegate Opened { get; }
-
- ///
- public override int GetHashCode()
- {
- unchecked
- {
- int hash = base.GetHashCode();
- hash = (hash * 23) + this.Opened.GetHashCode();
- return hash;
- }
- }
- }
-}
diff --git a/Dalamud/Game/Internal/DalamudAtkTweaks.cs b/Dalamud/Game/Internal/DalamudAtkTweaks.cs
index cd8ca156c..40bc1a26a 100644
--- a/Dalamud/Game/Internal/DalamudAtkTweaks.cs
+++ b/Dalamud/Game/Internal/DalamudAtkTweaks.cs
@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
using CheapLoc;
using Dalamud.Configuration.Internal;
using Dalamud.Data;
-using Dalamud.Game.Gui.ContextMenus;
+//using Dalamud.Game.Gui.ContextMenus;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
@@ -37,8 +37,8 @@ namespace Dalamud.Game.Internal
[ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service.Get();
- [ServiceManager.ServiceDependency]
- private readonly ContextMenu contextMenu = Service.Get();
+ // [ServiceManager.ServiceDependency]
+ // private readonly ContextMenu contextMenu = Service.Get();
private readonly string locDalamudPlugins;
private readonly string locDalamudSettings;
@@ -65,7 +65,7 @@ namespace Dalamud.Game.Internal
this.locDalamudPlugins = Loc.Localize("SystemMenuPlugins", "Dalamud Plugins");
this.locDalamudSettings = Loc.Localize("SystemMenuSettings", "Dalamud Settings");
- this.contextMenu.ContextMenuOpened += this.ContextMenuOnContextMenuOpened;
+ // this.contextMenu.ContextMenuOpened += this.ContextMenuOnContextMenuOpened;
}
private delegate void AgentHudOpenSystemMenuPrototype(void* thisPtr, AtkValue* atkValueArgs, uint menuSize);
@@ -86,6 +86,7 @@ namespace Dalamud.Game.Internal
this.hookAtkUnitBaseReceiveGlobalEvent.Enable();
}
+ /*
private void ContextMenuOnContextMenuOpened(ContextMenuOpenedArgs args)
{
var systemText = Service.GetNullable()?.GetExcelSheet()?.GetRow(1059)?.Text?.RawString; // "System"
@@ -109,6 +110,7 @@ namespace Dalamud.Game.Internal
}));
}
}
+ */
private IntPtr AtkUnitBaseReceiveGlobalEventDetour(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* arg)
{
@@ -270,7 +272,7 @@ namespace Dalamud.Game.Internal
this.hookUiModuleRequestMainCommand.Dispose();
this.hookAtkUnitBaseReceiveGlobalEvent.Dispose();
- this.contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened;
+ // this.contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened;
}
this.disposed = true;
diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ContextMenuAgingStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ContextMenuAgingStep.cs
index 2c6ea7a3c..76b6b59b2 100644
--- a/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ContextMenuAgingStep.cs
+++ b/Dalamud/Interface/Internal/Windows/SelfTest/AgingSteps/ContextMenuAgingStep.cs
@@ -1,7 +1,6 @@
using System;
using Dalamud.Data;
-using Dalamud.Game.Gui.ContextMenus;
using Dalamud.Utility;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
@@ -44,6 +43,7 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
///
public SelfTestStepResult RunStep()
{
+ /*
var contextMenu = Service.Get();
var dataMgr = Service.Get();
@@ -133,13 +133,16 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
}
return SelfTestStepResult.Waiting;
+ */
+
+ return SelfTestStepResult.Pass;
}
///
public void CleanUp()
{
- var contextMenu = Service.Get();
- contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened;
+ // var contextMenu = Service.Get();
+ // contextMenu.ContextMenuOpened -= this.ContextMenuOnContextMenuOpened;
this.currentSubStep = SubStep.Start;
this.clickedItemId = 0;
@@ -147,6 +150,7 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
this.multipleTriggerOne = this.multipleTriggerTwo = false;
}
+ /*
private void ContextMenuOnContextMenuOpened(ContextMenuOpenedArgs args)
{
Log.Information("Got context menu with parent addon: {ParentAddonName}, title:{Title}, itemcnt:{ItemCount}", args.ParentAddonName, args.Title, args.Items.Count);
@@ -239,5 +243,6 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
break;
}
}
+ */
}
}