Merge branch 'net5' into ContextNullCheck

This commit is contained in:
goaaats 2022-04-14 02:01:34 +02:00 committed by GitHub
commit 5741b23819
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 144 additions and 84 deletions

View file

@ -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<ContextMenuItem> initialContextMenuItems)
private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(AddonContextMenu* addonContextMenu, OldAgentContextInterface* agentContextInterface, string? title, ContextMenus.ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable<ContextMenuItem> 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)

View file

@ -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
/// <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="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.Agent = agent;
@ -34,7 +34,7 @@ namespace Dalamud.Game.Gui.ContextMenus
/// <summary>
/// Gets the agent associated with the context menu.
/// </summary>
public AgentContextInterface* Agent { get; }
public OldAgentContextInterface* Agent { get; }
/// <summary>
/// Gets the name of the parent addon associated with the context menu.

View file

@ -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
/// </summary>
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
/// <param name="agentContextInterface">The AgentContextInterface to act upon.</param>
/// <param name="atkValueCount">The number of ATK values to consider.</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}");
@ -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,28 +438,28 @@ 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 if (((AgentContext*)this.agentContextInterface)->Items != null)
{
// TODO: figure out why this branch is reached on inventory contexts and why Items is sometimes null.
var actions = &((AgentContext*)this.agentContextInterface)->Items->Actions;
var actions = &((OldAgentContext*)this.agentContextInterface)->Items->Actions;
*(actions + this.FirstContextMenuItemIndex + contextMenuItemIndex) = action;
}
else

View 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;
}

View file

@ -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;
}

View file

@ -15,6 +15,7 @@ using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.System.String;
using FFXIVClientStructs.FFXIV.Client.UI;
using ImGuiNET;
using Serilog;
@ -31,7 +32,6 @@ namespace Dalamud.Game.Gui
private readonly GetMatrixSingletonDelegate getMatrixSingleton;
private readonly ScreenToWorldNativeDelegate screenToWorldNative;
private readonly GetAgentModuleDelegate getAgentModule;
private readonly Hook<SetGlobalBgmDelegate> setGlobalBgmHook;
private readonly Hook<HandleItemHoverDelegate> handleItemHoverHook;
@ -60,7 +60,6 @@ namespace Dalamud.Game.Gui
Log.Verbose($"HandleItemHover address 0x{this.address.HandleItemHover.ToInt64():X}");
Log.Verbose($"HandleItemOut address 0x{this.address.HandleItemOut.ToInt64():X}");
Log.Verbose($"HandleImm address 0x{this.address.HandleImm.ToInt64():X}");
Log.Verbose($"GetAgentModule address 0x{this.address.GetAgentModule.ToInt64():X}");
Service<ChatGui>.Set(new ChatGui(this.address.ChatManager));
Service<PartyFinderGui>.Set();
@ -85,8 +84,6 @@ namespace Dalamud.Game.Gui
this.toggleUiHideHook = new Hook<ToggleUiHideDelegate>(this.address.ToggleUiHide, this.ToggleUiHideDetour);
this.getAgentModule = Marshal.GetDelegateForFunctionPointer<GetAgentModuleDelegate>(this.address.GetAgentModule);
this.utf8StringFromSequenceHook = new Hook<Utf8StringFromSequenceDelegate>(this.address.Utf8StringFromSequence, this.Utf8StringFromSequenceDetour);
}
@ -397,14 +394,14 @@ namespace Dalamud.Game.Gui
if (addon == IntPtr.Zero)
return IntPtr.Zero;
var uiModule = Service<GameGui>.Get().GetUIModule();
if (uiModule == IntPtr.Zero)
var uiModule = (UIModule*)Service<GameGui>.Get().GetUIModule();
if (uiModule == null)
{
return IntPtr.Zero;
}
var agentModule = this.getAgentModule(uiModule);
if (agentModule == IntPtr.Zero)
var agentModule = uiModule->GetAgentModule();
if (agentModule == null)
{
return IntPtr.Zero;
}
@ -412,18 +409,18 @@ 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;
for (var i = 0; i < 380; i++)
// Patch 6.1, 398 agents
for (var i = 0; i < 398; i++)
{
var agent = Marshal.ReadIntPtr(agentModule, 0x20 + (i * 8));
if (agent == IntPtr.Zero)
continue;
if (Marshal.ReadInt32(agent, 0x20) == id)
return agent;
var agent = &agentModule->AgentArray[i];
if (agent->GetAddonID() == id)
return new IntPtr(agent);
}
return IntPtr.Zero;

View file

@ -71,11 +71,6 @@ namespace Dalamud.Game.Gui
/// </summary>
public IntPtr ToggleUiHide { get; private set; }
/// <summary>
/// Gets the address of the native GetAgentModule method.
/// </summary>
public IntPtr GetAgentModule { get; private set; }
/// <summary>
/// Gets the address of the native Utf8StringFromSequence method.
/// </summary>
@ -94,9 +89,6 @@ namespace Dalamud.Game.Gui
this.ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??");
this.Utf8StringFromSequence = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8D 41 22 66 C7 41 ?? ?? ?? 48 89 01 49 8B D8");
var uiModuleVtableSig = sig.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 4C 89 61 28");
this.GetAgentModule = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size);
}
/// <inheritdoc/>