Code cleanup

This commit is contained in:
r00telement
2022-01-08 22:56:16 +00:00
parent 125f063aaa
commit c8abfcdb05
9 changed files with 106 additions and 187 deletions

View File

@@ -9,6 +9,9 @@ using System.Linq;
namespace PlayerTags.Features
{
/// <summary>
/// A feature that adds options for the management of custom tags to context menus.
/// </summary>
public class CustomTagsContextMenuFeature : IDisposable
{
private string?[] SupportedAddonNames = new string?[]
@@ -62,47 +65,6 @@ namespace PlayerTags.Features
private void ContextMenuHooks_ContextMenuOpened(ContextMenuOpenedArgs contextMenuOpenedArgs)
{
if (contextMenuOpenedArgs.GameObjectContext != null)
{
PluginLog.Debug($"ContextMenuHooks_ContextMenuOpened {contextMenuOpenedArgs.GameObjectContext?.Id} {contextMenuOpenedArgs.GameObjectContext?.ContentIdLower} '{contextMenuOpenedArgs.GameObjectContext?.Name}' {contextMenuOpenedArgs.GameObjectContext?.WorldId}");
}
if (contextMenuOpenedArgs.ItemContext != null)
{
PluginLog.Debug($"ContextMenuHooks_ContextMenuOpened {contextMenuOpenedArgs.ItemContext?.Id} {contextMenuOpenedArgs.ItemContext?.Count} {contextMenuOpenedArgs.ItemContext?.IsHighQuality}");
}
contextMenuOpenedArgs.ContextMenuItems.Add(new CustomContextMenuItem("Root1", (itemSelectedArgs =>
{
PluginLog.Debug("Executed Root1");
})));
contextMenuOpenedArgs.ContextMenuItems.Add(new OpenSubContextMenuItem("Root2", (subContextMenuOpenedArgs =>
{
PluginLog.Debug("Executed Root2");
List<ContextMenuItem> newContextMenuItems = new List<ContextMenuItem>();
newContextMenuItems.Add(new OpenSubContextMenuItem("Inner1", (subContextMenuOpenedArgs2 =>
{
PluginLog.Debug("Executed Inner1");
List<ContextMenuItem> newContextMenuItems = new List<ContextMenuItem>();
newContextMenuItems.Add(new CustomContextMenuItem("Inner3", (itemSelectedArgs =>
{
PluginLog.Debug("Executed Inner3");
})));
subContextMenuOpenedArgs2.ContextMenuItems.InsertRange(0, newContextMenuItems);
})));
newContextMenuItems.Add(new CustomContextMenuItem("Inner2", (itemSelectedArgs =>
{
PluginLog.Debug("Executed Inner2");
})));
subContextMenuOpenedArgs.ContextMenuItems.InsertRange(0, newContextMenuItems);
})));
if (!m_PluginConfiguration.IsCustomTagsContextMenuEnabled || !SupportedAddonNames.Contains(contextMenuOpenedArgs.ParentAddonName))
{
return;

View File

@@ -97,7 +97,7 @@ namespace PlayerTags.Features
private void Nameplate_PlayerNameplateUpdated(PlayerNameplateUpdatedArgs args)
{
var beforeTitleHashCode = args.Title.GetHashCode();
var beforeTitleBytes = args.Title.Encode();
AddTagsToNameplate(args.PlayerCharacter, args.Name, args.Title, args.FreeCompany/*, out isNameChanged, out isTitleChanged, out isFreeCompanyChanged*/);
if (m_PluginConfiguration.NameplateTitlePosition == NameplateTitlePosition.AlwaysAboveName)
@@ -122,7 +122,7 @@ namespace PlayerTags.Features
}
else if (m_PluginConfiguration.NameplateTitleVisibility == NameplateTitleVisibility.WhenHasTags)
{
bool hasTitleChanged = beforeTitleHashCode != args.Title.GetHashCode();
bool hasTitleChanged = !beforeTitleBytes.SequenceEqual(args.Title.Encode());
args.IsTitleVisible = hasTitleChanged;
}
@@ -132,7 +132,6 @@ namespace PlayerTags.Features
else if (m_PluginConfiguration.NameplateFreeCompanyVisibility == NameplateFreeCompanyVisibility.Never)
{
args.FreeCompany.Payloads.Clear();
//isFreeCompanyChanged = true;
}
}

View File

@@ -121,20 +121,20 @@ namespace PlayerTags.GameInterface.ContextMenus
private delegate IntPtr GetAddonByIdDelegate_Unmanaged(IntPtr raptureAtkUnitManager, ushort id);
private readonly GetAddonByIdDelegate_Unmanaged? m_GetAddonById;
private delegate byte OpenSubContextMenuDelegate_Unmanaged(IntPtr agent);
private delegate bool OpenSubContextMenuDelegate_Unmanaged(IntPtr agent);
private readonly OpenSubContextMenuDelegate_Unmanaged? m_OpenSubContextMenu;
private delegate IntPtr ContextMenuOpeningDelegate_Unmanaged(IntPtr a1, IntPtr a2, IntPtr a3, uint a4, IntPtr a5, IntPtr agent, IntPtr a7, ushort a8);
private Hook<ContextMenuOpeningDelegate_Unmanaged>? m_ContextMenuOpeningHook;
private unsafe delegate byte ContextMenuOpenedDelegate_Unmanaged(IntPtr addon, int menuSize, AtkValue* atkValueArgs);
private unsafe delegate bool ContextMenuOpenedDelegate_Unmanaged(IntPtr addon, int menuSize, AtkValue* atkValueArgs);
private Hook<ContextMenuOpenedDelegate_Unmanaged>? m_ContextMenuOpenedHook;
private Hook<ContextMenuOpenedDelegate_Unmanaged>? m_SubContextMenuOpenedHook;
private delegate byte ContextMenuItemSelectedDelegate_Unmanaged(IntPtr addon, int index, byte a3);
private delegate bool ContextMenuItemSelectedDelegate_Unmanaged(IntPtr addon, int index, byte a3);
private Hook<ContextMenuItemSelectedDelegate_Unmanaged>? m_ContextMenuItemSelectedHook;
private delegate byte SubContextMenuOpeningDelegate_Unmanaged(IntPtr agent);
private delegate bool SubContextMenuOpeningDelegate_Unmanaged(IntPtr agent);
private Hook<SubContextMenuOpeningDelegate_Unmanaged>? m_SubContextMenuOpeningHook;
private delegate IntPtr OpenInventoryContextMenuDelegate_Unmanaged(IntPtr agent, byte hasTitle, byte zero);
@@ -150,8 +150,8 @@ namespace PlayerTags.GameInterface.ContextMenus
private IntPtr m_CurrentContextMenuAgent;
private IntPtr m_CurrentSubContextMenuTitle;
private ContextMenuOpenedArgs? m_ContextMenuOpenedArgs;
private OpenSubContextMenuItem? m_OpenSubContextMenuItem;
private ContextMenuItem? m_CurrentSelectedItem;
private ContextMenuOpenedArgs? m_CurrentContextMenuOpenedArgs;
/// <summary>
/// Occurs when a context menu is opened by the game.
@@ -279,12 +279,12 @@ namespace PlayerTags.GameInterface.ContextMenus
return m_ContextMenuOpeningHook!.Original(a1, a2, a3, a4, a5, agent, a7, a8);
}
private unsafe byte ContextMenuOpenedDetour(IntPtr addon, int atkValueCount, AtkValue* atkValues)
private unsafe bool ContextMenuOpenedDetour(IntPtr addon, int atkValueCount, AtkValue* atkValues)
{
PluginLog.Debug($"ContextMenuOpenedDetour");
if (m_ContextMenuOpenedHook == null)
{
return 0;
return false;
}
var addonContext = (AddonContext*)addon;
@@ -306,7 +306,7 @@ namespace PlayerTags.GameInterface.ContextMenus
private unsafe void ContextMenuOpenedImplementation(IntPtr addon, ref int atkValueCount, ref AtkValue* atkValues)
{
PluginLog.Debug($"ContextMenuOpenedImplementation");
PluginLog.Debug($"ContextMenuOpenedImplementation {m_CurrentSelectedItem}");
if (m_AtkValueChangeType == null
|| m_AtkValueSetString == null
@@ -316,19 +316,21 @@ namespace PlayerTags.GameInterface.ContextMenus
return;
}
ContextMenuReaderWriter contextMenuReaderWriter = new ContextMenuReaderWriter(m_CurrentContextMenuAgent, atkValueCount, atkValues);
// Read the context menu items from the game, then allow subscribers to modify them
if (m_ContextMenuOpenedArgs == null)
ContextMenuOpenedDelegate contextMenuOpenedDelegate = ContextMenuOpened;
if (m_CurrentSelectedItem is OpenSubContextMenuItem openSubContextMenuItem)
{
m_ContextMenuOpenedArgs = NotifyContextMenuOpened(addon, m_CurrentContextMenuAgent, ContextMenuOpened, contextMenuReaderWriter.Read());
if (m_ContextMenuOpenedArgs == null)
{
return;
}
contextMenuOpenedDelegate = openSubContextMenuItem.OpenedAction;
}
contextMenuReaderWriter.Write(null, m_ContextMenuOpenedArgs.ContextMenuItems, m_AtkValueChangeType, m_AtkValueSetString);
// Read the context menu items from the game, then allow subscribers to modify them
ContextMenuReaderWriter contextMenuReaderWriter = new ContextMenuReaderWriter(m_CurrentContextMenuAgent, atkValueCount, atkValues);
m_CurrentContextMenuOpenedArgs = NotifyContextMenuOpened(addon, m_CurrentContextMenuAgent, m_CurrentSelectedItem, contextMenuOpenedDelegate, contextMenuReaderWriter.Read());
if (m_CurrentContextMenuOpenedArgs == null)
{
return;
}
contextMenuReaderWriter.Write(m_CurrentContextMenuOpenedArgs, m_AtkValueChangeType, m_AtkValueSetString);
// Update the addon
var addonContext = (AddonContext*)addon;
@@ -336,17 +338,17 @@ namespace PlayerTags.GameInterface.ContextMenus
atkValues = *(&addonContext->AtkValues) = contextMenuReaderWriter.AtkValues;
}
private byte SubContextMenuOpeningDetour(IntPtr agent)
private bool SubContextMenuOpeningDetour(IntPtr agent)
{
PluginLog.Debug($"SubContextMenuOpeningDetour");
if (m_SubContextMenuOpeningHook == null)
{
return 0;
return false;
}
if (SubContextMenuOpeningImplementation(agent))
{
return 0x0;
return true;
}
return m_SubContextMenuOpeningHook.Original(agent);
@@ -354,27 +356,16 @@ namespace PlayerTags.GameInterface.ContextMenus
private unsafe bool SubContextMenuOpeningImplementation(IntPtr agent)
{
PluginLog.Debug($"SubContextMenuOpeningImplementation {m_OpenSubContextMenuItem}");
PluginLog.Debug($"SubContextMenuOpeningImplementation {m_CurrentSelectedItem}");
if (m_OpenSubContextMenu == null
|| m_OpenInventoryContextMenu == null
|| m_AtkValueChangeType == null
|| m_OpenSubContextMenuItem == null)
|| !(m_CurrentSelectedItem is OpenSubContextMenuItem))
{
return false;
}
// This isn't our own sub context menu -- don't go any further
//if (m_OpenSubContextMenuItem == null)
//{
// return false;
//}
//var a = (AgentContext*)agent;
//var s = a->SelectedIndex;
//*(&a->SelectedIndex) = 0xff;
// The important things to make this work are:
// 1. Temporary allocate a sub context menu title
// 1. Temporarily increase the atk value count by 1 so the game knows to expect at least 1 context menu item
@@ -398,8 +389,6 @@ namespace PlayerTags.GameInterface.ContextMenus
*(&agentContext->SubContextMenuTitle) = (byte*)m_CurrentSubContextMenuTitle;
}
//*(&a->SelectedIndex) = s;
var atkValues = &agentContext->ItemData->AtkValues;
// Let the game know the context menu will have at least 1 item in it
@@ -412,22 +401,17 @@ namespace PlayerTags.GameInterface.ContextMenus
return true;
}
private unsafe byte SubContextMenuOpenedDetour(IntPtr addon, int atkValueCount, AtkValue* atkValues)
private unsafe bool SubContextMenuOpenedDetour(IntPtr addon, int atkValueCount, AtkValue* atkValues)
{
PluginLog.Debug($"SubContextMenuOpenedDetour");
if (m_SubContextMenuOpenedHook == null)
{
return 0;
return false;
}
var addonContext = (AddonContext*)addon;
PluginLog.Debug($"SubContextMenuOpenedDetour addonContext->IsInitialMenu={addonContext->IsInitialMenu}");
ContextMenuReaderWriter.Print(atkValueCount, atkValues);
try
{
SubContextMenuOpenedImplementation(addon, ref atkValueCount, ref atkValues);
ContextMenuOpenedImplementation(addon, ref atkValueCount, ref atkValues);
}
catch (Exception ex)
{
@@ -437,57 +421,16 @@ namespace PlayerTags.GameInterface.ContextMenus
return m_SubContextMenuOpenedHook.Original(addon, atkValueCount, atkValues);
}
private unsafe void SubContextMenuOpenedImplementation(IntPtr addon, ref int atkValueCount, ref AtkValue* atkValues)
{
PluginLog.Debug($"SubContextMenuOpenedImplementation");
if (m_AtkValueSetString == null
|| m_AtkValueChangeType == null
|| ContextMenuOpened == null)
{
return;
}
ContextMenuReaderWriter contextMenuReader = new ContextMenuReaderWriter(m_CurrentContextMenuAgent, atkValueCount, atkValues);
if (m_OpenSubContextMenuItem != null)
{
m_ContextMenuOpenedArgs = NotifyContextMenuOpened(addon, m_CurrentContextMenuAgent, m_OpenSubContextMenuItem.OpenedAction, contextMenuReader.Read());
if (m_ContextMenuOpenedArgs == null)
{
return;
}
}
else
{
m_ContextMenuOpenedArgs = NotifyContextMenuOpened(addon, m_CurrentContextMenuAgent, ContextMenuOpened, contextMenuReader.Read());
if (m_ContextMenuOpenedArgs == null)
{
return;
}
}
contextMenuReader.Write(m_OpenSubContextMenuItem, m_ContextMenuOpenedArgs.ContextMenuItems, m_AtkValueChangeType, m_AtkValueSetString);
// Update the addon
var addonContext = (AddonContext*)addon;
atkValueCount = *(&addonContext->AtkValuesCount) = (ushort)contextMenuReader.AtkValueCount;
atkValues = *(&addonContext->AtkValues) = contextMenuReader.AtkValues;
}
private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(IntPtr addon, IntPtr agent, ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable<ContextMenuItem> initialContextMenuItems)
private unsafe ContextMenuOpenedArgs? NotifyContextMenuOpened(IntPtr addon, IntPtr agent, ContextMenuItem? selectedContextMenuItem, ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable<ContextMenuItem> initialContextMenuItems)
{
var parentAddonName = GetParentAddonName(addon);
ContextMenuOpenedArgs contextMenuOpenedArgs;
ItemContext? itemContext = null;
GameObjectContext? gameObjectContext = null;
if (IsInventoryContext(agent))
{
var agentInventoryContext = (AgentInventoryContext*)agent;
contextMenuOpenedArgs = new ContextMenuOpenedArgs(addon, agent, parentAddonName, initialContextMenuItems)
{
ItemContext = new ItemContext(agentInventoryContext->ItemId, agentInventoryContext->ItemCount, agentInventoryContext->IsHighQuality)
};
itemContext = new ItemContext(agentInventoryContext->ItemId, agentInventoryContext->ItemCount, agentInventoryContext->IsHighQuality);
}
else
{
@@ -499,12 +442,16 @@ namespace PlayerTags.GameInterface.ContextMenus
objectName = GameInterfaceHelper.ReadSeString((IntPtr)agentContext->ObjectName.StringPtr);
}
contextMenuOpenedArgs = new ContextMenuOpenedArgs(addon, agent, parentAddonName, initialContextMenuItems)
{
GameObjectContext = new GameObjectContext(agentContext->ObjectId, agentContext->ObjectContentIdLower, objectName, agentContext->ObjectWorldId)
};
gameObjectContext = new GameObjectContext(agentContext->ObjectId, agentContext->ObjectContentIdLower, objectName, agentContext->ObjectWorldId);
}
var contextMenuOpenedArgs = new ContextMenuOpenedArgs(addon, agent, parentAddonName, initialContextMenuItems)
{
SelectedItem = selectedContextMenuItem,
ItemContext = itemContext,
GameObjectContext = gameObjectContext
};
try
{
contextMenuOpenedDelegate.Invoke(contextMenuOpenedArgs);
@@ -529,12 +476,12 @@ namespace PlayerTags.GameInterface.ContextMenus
return contextMenuOpenedArgs;
}
private unsafe byte ContextMenuItemSelectedDetour(IntPtr addon, int index, byte a3)
private unsafe bool ContextMenuItemSelectedDetour(IntPtr addon, int index, byte a3)
{
PluginLog.Debug($"ContextMenuItemSelectedDetour");
PluginLog.Debug($"ContextMenuItemSelectedDetour index={index}");
if (m_ContextMenuItemSelectedHook == null)
{
return 0;
return false;
}
try
@@ -553,10 +500,10 @@ namespace PlayerTags.GameInterface.ContextMenus
{
PluginLog.Debug($"ContextMenuItemSelectedImplementation index={index}");
if (m_ContextMenuOpenedArgs == null)
if (m_CurrentContextMenuOpenedArgs == null)
{
m_ContextMenuOpenedArgs = null;
m_OpenSubContextMenuItem = null;
m_CurrentContextMenuOpenedArgs = null;
m_CurrentSelectedItem = null;
return;
}
@@ -564,39 +511,31 @@ namespace PlayerTags.GameInterface.ContextMenus
var addonContext = (AddonContext*)addon;
ContextMenuReaderWriter.Print(addonContext->AtkValuesCount, addonContext->AtkValues);
var contextMenuItem = m_ContextMenuOpenedArgs.ContextMenuItems.ElementAtOrDefault(index);
var contextMenuItem = m_CurrentContextMenuOpenedArgs.ContextMenuItems.ElementAtOrDefault(index);
if (contextMenuItem == null)
{
m_ContextMenuOpenedArgs = null;
m_OpenSubContextMenuItem = null;
m_CurrentContextMenuOpenedArgs = null;
m_CurrentSelectedItem = null;
return;
}
if (contextMenuItem is OpenSubContextMenuItem openSubContextMenuItem)
if (contextMenuItem is CustomContextMenuItem customContextMenuItem)
{
m_OpenSubContextMenuItem = openSubContextMenuItem;
}
else if (contextMenuItem is CustomContextMenuItem customContextMenuItem)
{
var args = new CustomContextMenuItemSelectedArgs(m_ContextMenuOpenedArgs, customContextMenuItem);
try
{
customContextMenuItem.CustomAction(args);
var customContextMenuItemSelectedArgs = new CustomContextMenuItemSelectedArgs(m_CurrentContextMenuOpenedArgs, customContextMenuItem);
customContextMenuItem.ItemSelected(customContextMenuItemSelectedArgs);
}
catch (Exception ex)
{
PluginLog.LogError(ex, "ContextMenuItemSelectedImplementation");
}
}
m_ContextMenuOpenedArgs = null;
m_OpenSubContextMenuItem = null;
}
else
{
m_ContextMenuOpenedArgs = null;
m_OpenSubContextMenuItem = null;
}
m_CurrentSelectedItem = contextMenuItem;// is OpenSubContextMenuItem ? contextMenuItem : null;
m_CurrentContextMenuOpenedArgs = null;
PluginLog.Debug($"ContextMenuItemSelectedImplementation index={index} dddddddddddddd");
}
private void InventoryContextMenuEvent30Detour(IntPtr agent, IntPtr a2, int a3, int a4, short a5)

View File

@@ -14,6 +14,8 @@ namespace PlayerTags.GameInterface.ContextMenus
public List<ContextMenuItem> ContextMenuItems { get; }
public ContextMenuItem? SelectedItem { get; init; }
public GameObjectContext? GameObjectContext { get; init; }
public ItemContext? ItemContext { get; init; }

View File

@@ -278,11 +278,11 @@ namespace PlayerTags.GameInterface.ContextMenus
return gameContextMenuItems.ToArray();
}
public unsafe void Write(OpenSubContextMenuItem? selectedOpenSubContextMenuItem, IEnumerable<ContextMenuItem> contextMenuItems, AtkValueChangeTypeDelegate_Unmanaged atkValueChangeType, AtkValueSetStringDelegate_Unmanaged atkValueSetString)
public unsafe void Write(ContextMenuOpenedArgs contextMenuOpenedArgs, AtkValueChangeTypeDelegate_Unmanaged atkValueChangeType, AtkValueSetStringDelegate_Unmanaged atkValueSetString)
{
Print();
var newAtkValuesCount = FirstContextMenuItemIndex + (contextMenuItems.Count() * TotalDesiredAtkValuesPerContextMenuItem);
var newAtkValuesCount = FirstContextMenuItemIndex + (contextMenuOpenedArgs.ContextMenuItems.Count() * 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;
@@ -311,11 +311,11 @@ namespace PlayerTags.GameInterface.ContextMenus
m_AtkValueCount = newAtkValuesCount;
m_AtkValues = newAtkValues;
// Set the title
if (selectedOpenSubContextMenuItem != null)
// Set the custom title if appropriate
if (contextMenuOpenedArgs.SelectedItem is OpenSubContextMenuItem)
{
var titleAtkValue = &m_AtkValues[1];
fixed (byte* TtlePtr = selectedOpenSubContextMenuItem.Name.Encode().NullTerminate())
fixed (byte* TtlePtr = contextMenuOpenedArgs.SelectedItem.Name.Encode().NullTerminate())
{
atkValueSetString(titleAtkValue, TtlePtr);
}
@@ -324,7 +324,7 @@ namespace PlayerTags.GameInterface.ContextMenus
// Set the context menu item count
const int contextMenuItemCountAtkValueIndex = 0;
var contextMenuItemCountAtkValue = &m_AtkValues[contextMenuItemCountAtkValueIndex];
contextMenuItemCountAtkValue->UInt = (uint)contextMenuItems.Count();
contextMenuItemCountAtkValue->UInt = (uint)contextMenuOpenedArgs.ContextMenuItems.Count();
// Clear the previous arrow flags
var hasPreviousArrowAtkValue = &m_AtkValues[HasPreviousArrowFlagsIndex];
@@ -334,9 +334,9 @@ namespace PlayerTags.GameInterface.ContextMenus
var subContextMenusFlagsAtkValue = &m_AtkValues[HasNextArrowFlagsIndex];
subContextMenusFlagsAtkValue->UInt = 0;
for (int contextMenuItemIndex = 0; contextMenuItemIndex < contextMenuItems.Count(); ++contextMenuItemIndex)
for (int contextMenuItemIndex = 0; contextMenuItemIndex < contextMenuOpenedArgs.ContextMenuItems.Count(); ++contextMenuItemIndex)
{
var contextMenuItem = contextMenuItems.ElementAt(contextMenuItemIndex);
var contextMenuItem = contextMenuOpenedArgs.ContextMenuItems.ElementAt(contextMenuItemIndex);
var contextMenuItemAtkValueBaseIndex = FirstContextMenuItemIndex + (contextMenuItemIndex * SequentialAtkValuesPerContextMenuItem);

View File

@@ -4,12 +4,12 @@ namespace PlayerTags.GameInterface.ContextMenus
{
public class CustomContextMenuItem : ContextMenuItem
{
public CustomContextMenuItemSelectedDelegate CustomAction { get; }
public CustomContextMenuItemSelectedDelegate ItemSelected { get; }
internal CustomContextMenuItem(SeString name, CustomContextMenuItemSelectedDelegate customAction)
internal CustomContextMenuItem(SeString name, CustomContextMenuItemSelectedDelegate itemSelected)
: base(name)
{
CustomAction = customAction;
ItemSelected = itemSelected;
}
}
}

View File

@@ -1,9 +1,18 @@
namespace PlayerTags.GameInterface.ContextMenus
{
/// <summary>
/// Provides data for <see cref="CustomContextMenuItemSelectedDelegate"/> events.
/// </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; }
public CustomContextMenuItemSelectedArgs(ContextMenuOpenedArgs contextMenuOpenedArgs, CustomContextMenuItem selectedItem)

View File

@@ -74,10 +74,8 @@ namespace PlayerTags.GameInterface
return true;
}
public static IntPtr PluginAllocate(SeString seString)
public static IntPtr PluginAllocate(byte[] bytes)
{
var bytes = seString.Encode();
IntPtr pointer = Marshal.AllocHGlobal(bytes.Length + 1);
Marshal.Copy(bytes, 0, pointer, bytes.Length);
Marshal.WriteByte(pointer, bytes.Length, 0);
@@ -85,6 +83,11 @@ namespace PlayerTags.GameInterface
return pointer;
}
public static IntPtr PluginAllocate(SeString seString)
{
return PluginAllocate(seString.Encode());
}
public static void PluginFree(ref IntPtr ptr)
{
Marshal.FreeHGlobal(ptr);

View File

@@ -7,6 +7,7 @@ using Dalamud.Logging;
using FFXIVClientStructs.FFXIV.Client.UI;
using System;
using System.Runtime.InteropServices;
using System.Linq;
namespace PlayerTags.GameInterface.Nameplates
{
@@ -97,34 +98,38 @@ namespace PlayerTags.GameInterface.Nameplates
isTitleAboveName,
iconId);
var beforeNameHashCode = playerNameplateUpdatedArgs.Name.GetHashCode();
var beforeTitleHashCode = playerNameplateUpdatedArgs.Title.GetHashCode();
var beforeFreeCompanyHashCode = playerNameplateUpdatedArgs.FreeCompany.GetHashCode();
byte[] beforeNameBytes = playerNameplateUpdatedArgs.Name.Encode();
byte[] beforeTitleBytes = playerNameplateUpdatedArgs.Title.Encode();
byte[] beforeFreeCompanyBytes = playerNameplateUpdatedArgs.FreeCompany.Encode();
PlayerNameplateUpdated?.Invoke(playerNameplateUpdatedArgs);
byte[] afterNameBytes = playerNameplateUpdatedArgs.Name.Encode();
byte[] afterTitleBytes = playerNameplateUpdatedArgs.Title.Encode();
byte[] afterFreeCompanyBytes = playerNameplateUpdatedArgs.FreeCompany.Encode();
IntPtr newNamePtr = namePtr;
bool hasNameChanged = beforeNameHashCode != playerNameplateUpdatedArgs.Name.GetHashCode();
bool hasNameChanged = !beforeNameBytes.SequenceEqual(afterNameBytes);
if (hasNameChanged)
{
newNamePtr = GameInterfaceHelper.PluginAllocate(playerNameplateUpdatedArgs.Name);
newNamePtr = GameInterfaceHelper.PluginAllocate(afterNameBytes);
}
IntPtr newTitlePtr = titlePtr;
bool hasTitleChanged = beforeTitleHashCode != playerNameplateUpdatedArgs.Title.GetHashCode();
bool hasTitleChanged = !beforeTitleBytes.SequenceEqual(afterTitleBytes);
if (hasTitleChanged)
{
newTitlePtr = GameInterfaceHelper.PluginAllocate(playerNameplateUpdatedArgs.Title);
newTitlePtr = GameInterfaceHelper.PluginAllocate(afterTitleBytes);
}
IntPtr newFreeCompanyPtr = freeCompanyPtr;
bool hasFreeCompanyChanged = beforeFreeCompanyHashCode != playerNameplateUpdatedArgs.FreeCompany.GetHashCode();
bool hasFreeCompanyChanged = !beforeFreeCompanyBytes.SequenceEqual(afterFreeCompanyBytes);
if (hasFreeCompanyChanged)
{
newFreeCompanyPtr = GameInterfaceHelper.PluginAllocate(playerNameplateUpdatedArgs.FreeCompany);
newFreeCompanyPtr = GameInterfaceHelper.PluginAllocate(afterFreeCompanyBytes);
}
var result = m_SetPlayerNameplateHook.Original(playerNameplateObjectPtr, playerNameplateUpdatedArgs.IsTitleAboveName, playerNameplateUpdatedArgs.IsTitleVisible, newNamePtr, newTitlePtr, newFreeCompanyPtr, playerNameplateUpdatedArgs.IconId);
var result = m_SetPlayerNameplateHook.Original(playerNameplateObjectPtr, playerNameplateUpdatedArgs.IsTitleAboveName, playerNameplateUpdatedArgs.IsTitleVisible, newTitlePtr, newNamePtr, newFreeCompanyPtr, playerNameplateUpdatedArgs.IconId);
if (hasNameChanged)
{