refactor: ContextMenus cleanup, docs

This commit is contained in:
goaaats 2022-01-28 23:50:06 +01:00
parent 4aebbfa2cb
commit 7a242c962a
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
14 changed files with 179 additions and 135 deletions

View file

@ -12,7 +12,7 @@ using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using Serilog;
using SignatureHelper = Dalamud.Utility.Signatures.SignatureHelper;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
namespace Dalamud.Game.Gui.ContextMenus
@ -48,7 +48,6 @@ namespace Dalamud.Game.Gui.ContextMenus
/// <summary>
/// Initializes a new instance of the <see cref="ContextMenu"/> class.
/// </summary>
/// <param name="address">Address resolver for context menu hooks.</param>
public ContextMenu()
{
this.Address = new ContextMenuAddressResolver();
@ -66,7 +65,6 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
#region Delegates
private unsafe delegate bool OpenSubContextMenuDelegate(AgentContext* agentContext);

View file

@ -2,9 +2,11 @@
namespace Dalamud.Game.Gui.ContextMenus
{
/// <summary>
/// Address resolver for context menu functions.
/// </summary>
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";
@ -12,18 +14,37 @@ namespace Dalamud.Game.Gui.ContextMenus
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";
/// <summary>
/// Gets the OpenSubContextMenu function address.
/// </summary>
public IntPtr OpenSubContextMenuPtr { get; private set; }
/// <summary>
/// Gets the ContextMenuOpening function address.
/// </summary>
public IntPtr ContextMenuOpeningPtr { get; private set; }
/// <summary>
/// Gets the ContextMenuOpened function address.
/// </summary>
public IntPtr ContextMenuOpenedPtr { get; private set; }
/// <summary>
/// Gets the ContextMenuItemSelected function address.
/// </summary>
public IntPtr ContextMenuItemSelectedPtr { get; private set; }
/// <summary>
/// Gets the SubContextMenuOpening function address.
/// </summary>
public IntPtr SubContextMenuOpeningPtr { get; private set; }
/// <summary>
/// Gets the SubContextMenuOpened function address.
/// </summary>
public IntPtr SubContextMenuOpenedPtr { get; private set; }
/// <inheritdoc/>
protected override void Setup64Bit(SigScanner scanner)
{
this.OpenSubContextMenuPtr = scanner.ScanText(SigOpenSubContextMenu);

View file

@ -1,7 +1,6 @@
using System.Numerics;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
namespace Dalamud.Game.Gui.ContextMenus
{

View file

@ -9,13 +9,15 @@
/// The item has no indicator.
/// </summary>
None,
/// <summary>
/// The item has a previous indicator.
/// </summary>
Previous,
/// <summary>
/// The item has a next indicator.
/// </summary>
Next
Next,
}
}

View file

@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Gui.ContextMenus
{

View file

@ -14,6 +14,9 @@ using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
namespace Dalamud.Game.Gui.ContextMenus
{
/// <summary>
/// Class responsible for reading and writing to context menu data.
/// </summary>
internal unsafe class ContextMenuReaderWriter
{
private readonly AgentContextInterface* agentContextInterface;
@ -42,12 +45,24 @@ namespace Dalamud.Game.Gui.ContextMenus
Alternate,
}
/// <summary>
/// Gets the number of AtkValues for this context menu.
/// </summary>
public int AtkValueCount => this.atkValueCount;
/// <summary>
/// Gets the AtkValues for this context menu.
/// </summary>
public AtkValue* AtkValues => this.atkValues;
/// <summary>
/// Gets the amount of items in the context menu.
/// </summary>
public int ContextMenuItemCount => this.atkValues[0].Int;
/// <summary>
/// Gets a value indicating whether the context menu has a title.
/// </summary>
public bool HasTitle
{
get
@ -61,6 +76,9 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
/// <summary>
/// Gets the title of the context menu.
/// </summary>
public SeString? Title
{
get
@ -75,32 +93,9 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
public int HasPreviousIndicatorFlagsIndex
{
get
{
if (this.HasTitle)
{
return 6;
}
return 2;
}
}
public int HasNextIndicatorFlagsIndex
{
get
{
if (this.HasTitle)
{
return 5;
}
return 3;
}
}
/// <summary>
/// Gets the index of the first context menu item.
/// </summary>
public int FirstContextMenuItemIndex
{
get
@ -114,7 +109,46 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
public int NameIndexOffset
/// <summary>
/// Gets the position of the context menu.
/// </summary>
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
{
@ -127,7 +161,7 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
public int IsDisabledIndexOffset
private int IsDisabledIndexOffset
{
get
{
@ -140,6 +174,7 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
/*
/// <summary>
/// 0x14000000 | action
/// </summary>
@ -152,8 +187,9 @@ namespace Dalamud.Game.Gui.ContextMenus
return null;
}
}
*/
public int SequentialAtkValuesPerContextMenuItem
private int SequentialAtkValuesPerContextMenuItem
{
get
{
@ -163,7 +199,7 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
public int TotalDesiredAtkValuesPerContextMenuItem
private int TotalDesiredAtkValuesPerContextMenuItem
{
get
{
@ -173,17 +209,7 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
public Vector2? Position
{
get
{
if (this.HasTitle) return new Vector2(this.atkValues[2].Int, this.atkValues[3].Int);
return null;
}
}
public unsafe bool IsInventoryContext
private bool IsInventoryContext
{
get
{
@ -200,58 +226,48 @@ namespace Dalamud.Game.Gui.ContextMenus
{
get
{
if (HasTitle)
if (this.HasTitle)
{
if (this.atkValues[7].Int == 8)
{
return SubContextMenuStructLayout.Alternate;
}
else if (this.atkValues[7].Int == 1)
{
return SubContextMenuStructLayout.Main;
}
if (this.atkValues[7].Int == 1) return SubContextMenuStructLayout.Main;
}
return null;
}
}
public byte NoopAction
private byte NoopAction
{
get
{
if (IsInventoryContext)
{
if (this.IsInventoryContext)
return 0xff;
}
else
{
return 0x67;
}
return 0x67;
}
}
public byte OpenSubContextMenuAction
private byte OpenSubContextMenuAction
{
get
{
if (IsInventoryContext)
if (this.IsInventoryContext)
{
// This is actually the action to open the Second Tier context menu and we just hack around it
return 0x31;
}
else
{
return 0x66;
}
return 0x66;
}
}
public byte? FirstUnhandledAction
private byte? FirstUnhandledAction
{
get
{
if (this.StructLayout is SubContextMenuStructLayout.Alternate) return 0x68;
if (this.StructLayout is SubContextMenuStructLayout.Alternate)
return 0x68;
return null;
}
@ -334,6 +350,11 @@ namespace Dalamud.Game.Gui.ContextMenus
return gameContextMenuItems.ToArray();
}
/// <summary>
/// Write items to the context menu.
/// </summary>
/// <param name="contextMenuItems">The items to write.</param>
/// <param name="allowReallocate">Whether or not reallocation is allowed.</param>
public void Write(IEnumerable<ContextMenuItem> contextMenuItems, bool allowReallocate = true)
{
if (allowReallocate)
@ -353,7 +374,7 @@ namespace Dalamud.Game.Gui.ContextMenus
// 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) * FirstContextMenuItemIndex);
Buffer.MemoryCopy(this.atkValues, newAtkValues, newAtkValuesArraySize - arrayCountSize, (long)sizeof(AtkValue) * this.FirstContextMenuItemIndex);
// Free the old array
var oldArray = (IntPtr)this.atkValues - arrayCountSize;
@ -467,12 +488,13 @@ namespace Dalamud.Game.Gui.ContextMenus
}
}
public void Log()
/*
private void Log()
{
Log(this.atkValueCount, this.atkValues);
}
public static void Log(int atkValueCount, AtkValue* atkValues)
private static void Log(int atkValueCount, AtkValue* atkValues)
{
PluginLog.Debug($"ContextMenuReader.Log");
@ -515,5 +537,6 @@ namespace Dalamud.Game.Gui.ContextMenus
PluginLog.Debug($"atkValues[{atkValueIndex}]={(IntPtr)atkValue:X} {atkValue->Type}={value}");
}
}
*/
}
}

View file

@ -9,11 +9,6 @@ namespace Dalamud.Game.Gui.ContextMenus
/// </summary>
public class CustomContextMenuItem : ContextMenuItem
{
/// <summary>
/// The action that will be called when the item is selected.
/// </summary>
public CustomContextMenuItemSelectedDelegate ItemSelected { get; }
/// <summary>
/// Initializes a new instance of the <see cref="CustomContextMenuItem"/> class.
/// </summary>
@ -22,15 +17,21 @@ namespace Dalamud.Game.Gui.ContextMenus
internal CustomContextMenuItem(SeString name, CustomContextMenuItemSelectedDelegate itemSelected)
: base(new SeString().Append(new UIForegroundPayload(539)).Append($"{SeIconChar.BoxedLetterD.ToIconString()} ").Append(new UIForegroundPayload(0)).Append(name))
{
ItemSelected = itemSelected;
this.ItemSelected = itemSelected;
}
/// <summary>
/// Gets the action that will be called when the item is selected.
/// </summary>
public CustomContextMenuItemSelectedDelegate ItemSelected { get; }
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
int hash = base.GetHashCode();
hash = hash * 23 + ItemSelected.GetHashCode();
var hash = base.GetHashCode();
hash = (hash * 23) + this.ItemSelected.GetHashCode();
return hash;
}
}

View file

@ -5,16 +5,6 @@
/// </summary>
public class CustomContextMenuItemSelectedArgs
{
/// <summary>
/// The currently opened context menu.
/// </summary>
public ContextMenuOpenedArgs ContextMenuOpenedArgs { get; init; }
/// <summary>
/// The selected item within the currently opened context menu.
/// </summary>
public CustomContextMenuItem SelectedItem { get; init; }
/// <summary>
/// Initializes a new instance of the <see cref="CustomContextMenuItemSelectedArgs"/> class.
/// </summary>
@ -22,8 +12,18 @@
/// <param name="selectedItem">The selected item within the currently opened context menu.</param>
public CustomContextMenuItemSelectedArgs(ContextMenuOpenedArgs contextMenuOpenedArgs, CustomContextMenuItem selectedItem)
{
ContextMenuOpenedArgs = contextMenuOpenedArgs;
SelectedItem = selectedItem;
this.ContextMenuOpenedArgs = contextMenuOpenedArgs;
this.SelectedItem = selectedItem;
}
/// <summary>
/// Gets the currently opened context menu.
/// </summary>
public ContextMenuOpenedArgs ContextMenuOpenedArgs { get; init; }
/// <summary>
/// Gets the selected item within the currently opened context menu.
/// </summary>
public CustomContextMenuItem SelectedItem { get; init; }
}
}

View file

@ -7,11 +7,6 @@ namespace Dalamud.Game.Gui.ContextMenus
/// </summary>
public class GameContextMenuItem : ContextMenuItem
{
/// <summary>
/// The game action that will be handled when the item is selected.
/// </summary>
public byte SelectedAction { get; }
/// <summary>
/// Initializes a new instance of the <see cref="GameContextMenuItem"/> class.
/// </summary>
@ -20,15 +15,21 @@ namespace Dalamud.Game.Gui.ContextMenus
public GameContextMenuItem(SeString name, byte selectedAction)
: base(name)
{
SelectedAction = selectedAction;
this.SelectedAction = selectedAction;
}
/// <summary>
/// Gets the game action that will be handled when the item is selected.
/// </summary>
public byte SelectedAction { get; }
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
int hash = base.GetHashCode();
hash = hash * 23 + SelectedAction;
var hash = base.GetHashCode();
hash = (hash * 23) + this.SelectedAction;
return hash;
}
}

View file

@ -5,21 +5,6 @@
/// </summary>
public class InventoryItemContext
{
/// <summary>
/// The id of the item.
/// </summary>
public uint Id { get; }
/// <summary>
/// The count of the item in the stack.
/// </summary>
public uint Count { get; }
/// <summary>
/// Whether the item is high quality.
/// </summary>
public bool IsHighQuality { get; }
/// <summary>
/// Initializes a new instance of the <see cref="InventoryItemContext"/> class.
/// </summary>
@ -28,9 +13,24 @@
/// <param name="isHighQuality">Whether the item is high quality.</param>
public InventoryItemContext(uint id, uint count, bool isHighQuality)
{
Id = id;
Count = count;
IsHighQuality = isHighQuality;
this.Id = id;
this.Count = count;
this.IsHighQuality = isHighQuality;
}
/// <summary>
/// Gets the id of the item.
/// </summary>
public uint Id { get; }
/// <summary>
/// Gets the count of the item in the stack.
/// </summary>
public uint Count { get; }
/// <summary>
/// Gets a value indicating whether the item is high quality.
/// </summary>
public bool IsHighQuality { get; }
}
}

View file

@ -7,11 +7,6 @@ namespace Dalamud.Game.Gui.ContextMenus
/// </summary>
public class OpenSubContextMenuItem : ContextMenuItem
{
/// <summary>
/// The action that will be called when the item is selected.
/// </summary>
public ContextMenuOpenedDelegate Opened { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="OpenSubContextMenuItem"/> class.
/// </summary>
@ -20,16 +15,22 @@ namespace Dalamud.Game.Gui.ContextMenus
internal OpenSubContextMenuItem(SeString name, ContextMenuOpenedDelegate opened)
: base(name)
{
Opened = opened;
Indicator = ContextMenuItemIndicator.Next;
this.Opened = opened;
this.Indicator = ContextMenuItemIndicator.Next;
}
/// <summary>
/// Gets the action that will be called when the item is selected.
/// </summary>
public ContextMenuOpenedDelegate Opened { get; }
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
int hash = base.GetHashCode();
hash = hash * 23 + Opened.GetHashCode();
hash = (hash * 23) + this.Opened.GetHashCode();
return hash;
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Numerics;
using System.Runtime.InteropServices;
using Dalamud.Game.Gui.ContextMenus;
using Dalamud.Game.Gui.FlyText;
using Dalamud.Game.Gui.PartyFinder;

View file

@ -1,7 +1,7 @@
namespace Dalamud.Game.Text
{
/// <summary>
/// Extension methods for <see cref="SeIconChar"/>
/// Extension methods for <see cref="SeIconChar"/>.
/// </summary>
public static class SeIconCharExtensions
{

View file

@ -1,13 +1,11 @@
using System;
using System.Runtime.CompilerServices;
using Dalamud.Data;
using Dalamud.Game.Gui.ContextMenus;
using Dalamud.Utility;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Lumina.Text;
using Serilog;
using SeString = Dalamud.Game.Text.SeStringHandling.SeString;
namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps
{