diff --git a/Pilz.Dalamud/Nameplates/Model/StatusIcons.cs b/Pilz.Dalamud/Icons/StatusIcons.cs similarity index 92% rename from Pilz.Dalamud/Nameplates/Model/StatusIcons.cs rename to Pilz.Dalamud/Icons/StatusIcons.cs index f32493b..5a78152 100644 --- a/Pilz.Dalamud/Nameplates/Model/StatusIcons.cs +++ b/Pilz.Dalamud/Icons/StatusIcons.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; -namespace Pilz.Dalamud.Nameplates.Model; +namespace Pilz.Dalamud.Icons; [JsonConverter(typeof(StringEnumConverter))] public enum StatusIcons diff --git a/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameEventArgs.cs deleted file mode 100644 index 8134fad..0000000 --- a/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameEventArgs.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Pilz.Dalamud.Nameplates.EventArgs; - -public class AddonNamePlate_SetPlayerNameEventArgs : HookWithResultBaseEventArgs -{ - public IntPtr PlayerNameplateObjectPtr { get; set; } - public IntPtr TitlePtr { get; set; } - public IntPtr NamePtr { get; set; } - public IntPtr FreeCompanyPtr { get; set; } - public IntPtr PrefixPtr { get; set; } - public bool IsTitleAboveName { get; set; } - public bool IsTitleVisible { get; set; } - public int IconID { get; set; } -} diff --git a/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameManagedEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameManagedEventArgs.cs deleted file mode 100644 index 2683bb3..0000000 --- a/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameManagedEventArgs.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Dalamud.Game.Text.SeStringHandling; -using Pilz.Dalamud.Nameplates.Model; - -namespace Pilz.Dalamud.Nameplates.EventArgs; - -public class AddonNamePlate_SetPlayerNameManagedEventArgs : HookWithResultManagedBaseEventArgs -{ - public new AddonNamePlate_SetPlayerNameEventArgs OriginalEventArgs - { - get => base.OriginalEventArgs as AddonNamePlate_SetPlayerNameEventArgs; - set => base.OriginalEventArgs = value; - } - - public SafeNameplateObject SafeNameplateObject { get; set; } - public SeString Title { get; internal set; } - public SeString Name { get; internal set; } - public SeString FreeCompany { get; internal set; } - public SeString Prefix { get; internal set; } - - public bool IsTitleAboveName - { - get => OriginalEventArgs.IsTitleAboveName; - set => OriginalEventArgs.IsTitleAboveName = value; - } - - public bool IsTitleVisible - { - get => OriginalEventArgs.IsTitleVisible; - set => OriginalEventArgs.IsTitleVisible = value; - } - - public int IconID - { - get => OriginalEventArgs.IconID; - set => OriginalEventArgs.IconID = value; - } -} diff --git a/Pilz.Dalamud/Nameplates/EventArgs/HookBaseEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/HookBaseEventArgs.cs deleted file mode 100644 index c2c268e..0000000 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookBaseEventArgs.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Pilz.Dalamud.Nameplates.EventArgs; - -public abstract class HookBaseEventArgs -{ - internal event Action CallOriginal; - - public void Original() - { - CallOriginal?.Invoke(); - } -} diff --git a/Pilz.Dalamud/Nameplates/EventArgs/HookManagedBaseEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/HookManagedBaseEventArgs.cs deleted file mode 100644 index 96ff8bc..0000000 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookManagedBaseEventArgs.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Pilz.Dalamud.Nameplates.EventArgs; - -public abstract class HookManagedBaseEventArgs -{ - public HookBaseEventArgs OriginalEventArgs { get; internal set; } -} diff --git a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultBaseEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultBaseEventArgs.cs deleted file mode 100644 index a086b3d..0000000 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultBaseEventArgs.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Pilz.Dalamud.Nameplates.EventArgs; - -public abstract class HookWithResultBaseEventArgs -{ - internal event Func CallOriginal; - - public TResult Result { get; set; } - - // Call Original based on the given properties - public TResult Original() - { - return CallOriginal.Invoke(); - } -} diff --git a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultManagedBaseEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultManagedBaseEventArgs.cs deleted file mode 100644 index dd509d9..0000000 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultManagedBaseEventArgs.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Pilz.Dalamud.Nameplates.EventArgs; - -public abstract class HookWithResultManagedBaseEventArgs -{ - public HookWithResultBaseEventArgs OriginalEventArgs { get; internal set; } -} diff --git a/Pilz.Dalamud/Nameplates/Model/SafeAddonNameplate.cs b/Pilz.Dalamud/Nameplates/Model/SafeAddonNameplate.cs deleted file mode 100644 index ce8c126..0000000 --- a/Pilz.Dalamud/Nameplates/Model/SafeAddonNameplate.cs +++ /dev/null @@ -1,35 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.UI; -using System.Runtime.InteropServices; - -namespace Pilz.Dalamud.Nameplates.Model; - -public class SafeAddonNameplate -{ - private readonly DalamudPluginInterface Interface; - - public IntPtr Pointer => PluginServices.GameGui.GetAddonByName("NamePlate", 1); - - public SafeAddonNameplate(DalamudPluginInterface pluginInterface) - { - Interface = pluginInterface; - } - - public unsafe SafeNameplateObject GetNamePlateObject(int index) - { - SafeNameplateObject result = null; - - if (Pointer != IntPtr.Zero) - { - var npObjectArrayPtrPtr = Pointer + Marshal.OffsetOf(typeof(AddonNamePlate), nameof(AddonNamePlate.NamePlateObjectArray)).ToInt32(); - var npObjectArrayPtr = Marshal.ReadIntPtr(npObjectArrayPtrPtr); - - if (npObjectArrayPtr != IntPtr.Zero) - { - var npObjectPtr = npObjectArrayPtr + Marshal.SizeOf(typeof(AddonNamePlate.NamePlateObject)) * index; - result = new(npObjectPtr, index); - } - } - - return result; - } -} diff --git a/Pilz.Dalamud/Nameplates/Model/SafeNameplateInfo.cs b/Pilz.Dalamud/Nameplates/Model/SafeNameplateInfo.cs deleted file mode 100644 index 3cac3df..0000000 --- a/Pilz.Dalamud/Nameplates/Model/SafeNameplateInfo.cs +++ /dev/null @@ -1,50 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.System.String; -using FFXIVClientStructs.FFXIV.Client.UI; -using System.Runtime.InteropServices; - -namespace Pilz.Dalamud.Nameplates.Model; - -public class SafeNameplateInfo -{ - public readonly IntPtr Pointer; - public readonly RaptureAtkModule.NamePlateInfo Data; - - public SafeNameplateInfo(IntPtr pointer) - { - Pointer = pointer; - Data = Marshal.PtrToStructure(Pointer); - } - - internal IntPtr NameAddress => GetStringPtr(nameof(RaptureAtkModule.NamePlateInfo.Name)); - internal IntPtr FcNameAddress => GetStringPtr(nameof(RaptureAtkModule.NamePlateInfo.FcName)); - internal IntPtr TitleAddress => GetStringPtr(nameof(RaptureAtkModule.NamePlateInfo.Title)); - internal IntPtr DisplayTitleAddress => GetStringPtr(nameof(RaptureAtkModule.NamePlateInfo.DisplayTitle)); - internal IntPtr LevelTextAddress => GetStringPtr(nameof(RaptureAtkModule.NamePlateInfo.LevelText)); - - public string Name => GetString(NameAddress); - public string FcName => GetString(FcNameAddress); - public string Title => GetString(TitleAddress); - public string DisplayTitle => GetString(DisplayTitleAddress); - public string LevelText => GetString(LevelTextAddress); - - //public bool IsPlayerCharacter() => XivApi.IsPlayerCharacter(Data.ObjectID.ObjectID); - - //public bool IsPartyMember() => XivApi.IsPartyMember(Data.ObjectID.ObjectID); - - //public bool IsAllianceMember() => XivApi.IsAllianceMember(Data.ObjectID.ObjectID); - - //public uint GetJobID() => GetJobId(Data.ObjectID.ObjectID); - - private unsafe IntPtr GetStringPtr(string name) - { - var namePtr = Pointer + Marshal.OffsetOf(typeof(RaptureAtkModule.NamePlateInfo), name).ToInt32(); - var stringPtrPtr = namePtr + Marshal.OffsetOf(typeof(Utf8String), nameof(Utf8String.StringPtr)).ToInt32(); - var stringPtr = Marshal.ReadIntPtr(stringPtrPtr); - return stringPtr; - } - - private string GetString(IntPtr stringPtr) - { - return Marshal.PtrToStringUTF8(stringPtr); - } -} diff --git a/Pilz.Dalamud/Nameplates/Model/SafeNameplateObject.cs b/Pilz.Dalamud/Nameplates/Model/SafeNameplateObject.cs deleted file mode 100644 index efaf821..0000000 --- a/Pilz.Dalamud/Nameplates/Model/SafeNameplateObject.cs +++ /dev/null @@ -1,121 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.UI; -using FFXIVClientStructs.FFXIV.Component.GUI; -using System.Runtime.InteropServices; - -namespace Pilz.Dalamud.Nameplates.Model; - -public class SafeNameplateObject -{ - public IntPtr Pointer { get; } - public AddonNamePlate.NamePlateObject Data { get; } - - private int _Index; - private SafeNameplateInfo _NamePlateInfo; - - public SafeNameplateObject(IntPtr pointer, int index = -1) - { - Pointer = pointer; - Data = Marshal.PtrToStructure(pointer); - _Index = index; - } - - public int Index - { - get - { - int result = _Index; - - if (_Index == -1) - { - var addon = XivApi.GetSafeAddonNamePlate(); - var npObject0 = addon.GetNamePlateObject(0); - - if (npObject0 == null) - result = -1; // NamePlateObject0 was null - else - { - var npObjectBase = npObject0.Pointer; - var npObjectSize = Marshal.SizeOf(typeof(AddonNamePlate.NamePlateObject)); - var index = (Pointer.ToInt64() - npObjectBase.ToInt64()) / npObjectSize; - - if (index < 0 || index >= 50) - result = -2; // NamePlateObject index was out of bounds - else - result = _Index = (int)index; - } - } - - return result; - } - } - - public SafeNameplateInfo NamePlateInfo - { - get - { - SafeNameplateInfo result = null; - - if (_NamePlateInfo != null) - { - var rapturePtr = XivApi.RaptureAtkModulePtr; - - if (rapturePtr != IntPtr.Zero) - { - var npInfoArrayPtr = rapturePtr + Marshal.OffsetOf(typeof(RaptureAtkModule), nameof(RaptureAtkModule.NamePlateInfoArray)).ToInt32(); - var npInfoPtr = npInfoArrayPtr + Marshal.SizeOf(typeof(RaptureAtkModule.NamePlateInfo)) * Index; - result = _NamePlateInfo = new SafeNameplateInfo(npInfoPtr); - } - } - - return result; - } - } - - #region Getters - - public unsafe IntPtr IconImageNodeAddress => Marshal.ReadIntPtr(Pointer + Marshal.OffsetOf(typeof(AddonNamePlate.NamePlateObject), nameof(AddonNamePlate.NamePlateObject.IconImageNode)).ToInt32()); - public unsafe IntPtr NameNodeAddress => Marshal.ReadIntPtr(Pointer + Marshal.OffsetOf(typeof(AddonNamePlate.NamePlateObject), nameof(AddonNamePlate.NamePlateObject.NameText)).ToInt32()); - - public AtkImageNode IconImageNode => Marshal.PtrToStructure(IconImageNodeAddress); - public AtkTextNode NameTextNode => Marshal.PtrToStructure(NameNodeAddress); - - #endregion - - public unsafe bool IsVisible => Data.IsVisible; - public unsafe bool IsLocalPlayer => Data.IsLocalPlayer; - public bool IsPlayer => Data.NameplateKind == 0; - - //public void SetIconScale(float scale, bool force = false) - //{ - // if (force || IconImageNode.AtkResNode.ScaleX != scale || IconImageNode.AtkResNode.ScaleY != scale) - // { - // Instance.SetNodeScale(IconImageNodeAddress, scale, scale); - // } - //} - - //public void SetNameScale(float scale, bool force = false) - //{ - // if (force || NameTextNode.AtkResNode.ScaleX != scale || NameTextNode.AtkResNode.ScaleY != scale) - // { - // Instance.SetNodeScale(NameNodeAddress, scale, scale); - // } - //} - - //public unsafe void SetName(IntPtr ptr) - //{ - // NameTextNode.SetText("aaa"); - //} - - //public void SetIcon(int icon) - //{ - // IconImageNode.LoadIconTexture(icon, 1); - //} - - public void SetIconPosition(short x, short y) - { - var iconXAdjustPtr = Pointer + Marshal.OffsetOf(typeof(AddonNamePlate.NamePlateObject), nameof(AddonNamePlate.NamePlateObject.IconXAdjust)).ToInt32(); - var iconYAdjustPtr = Pointer + Marshal.OffsetOf(typeof(AddonNamePlate.NamePlateObject), nameof(AddonNamePlate.NamePlateObject.IconYAdjust)).ToInt32(); - Marshal.WriteInt16(iconXAdjustPtr, x); - Marshal.WriteInt16(iconYAdjustPtr, y); - } -} diff --git a/Pilz.Dalamud/Nameplates/NameplateHooks.cs b/Pilz.Dalamud/Nameplates/NameplateHooks.cs deleted file mode 100644 index 5865b83..0000000 --- a/Pilz.Dalamud/Nameplates/NameplateHooks.cs +++ /dev/null @@ -1,230 +0,0 @@ -using Dalamud.Hooking; -using Dalamud.Utility.Signatures; -using Pilz.Dalamud.Nameplates.EventArgs; -using Pilz.Dalamud.Nameplates.Model; - -namespace Pilz.Dalamud.Nameplates; - -public class NameplateHooks : IDisposable -{ - /// - /// Will be executed when the the Game wants to update the content of a nameplate with the details of the Player. - /// - public event AddonNamePlate_SetPlayerNameEventHandler AddonNamePlate_SetPlayerName; - public delegate void AddonNamePlate_SetPlayerNameEventHandler(AddonNamePlate_SetPlayerNameEventArgs eventArgs); - - /// - /// Will be executed when the the Game wants to update the content of a nameplate with the details of the Player. - /// This will event acts on a higher level with SeString instead of IntPtr e.g. - /// - public event AddonNamePlate_SetPlayerNameManagedEventHandler AddonNamePlate_SetPlayerNameManaged; - public delegate void AddonNamePlate_SetPlayerNameManagedEventHandler(AddonNamePlate_SetPlayerNameManagedEventArgs eventArgs); - - [Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B 5C 24 ?? 45 38 BE", DetourName = nameof(SetPlayerNameplateDetour))] - private Hook? hook_AddonNamePlate_SetPlayerNameplateDetour = null; - private unsafe delegate IntPtr AddonNamePlate_SetPlayerNameplateDetour(IntPtr playerNameplateObjectPtr, bool isTitleAboveName, bool isTitleVisible, IntPtr titlePtr, IntPtr namePtr, IntPtr freeCompanyPtr, IntPtr prefix, int iconId); - - /// - /// Defines if all hooks are enabled. If this is false, then there might be something wrong or the class already has been disposed. - /// - public bool IsValid - { - get - { - var isValid = true; - - isValid &= IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour); - - return isValid; - } - } - - /// - /// Create a new instance of NAmeplateHooks and automatically initialize and enable all Hooks. - /// - public NameplateHooks() - { - PluginServices.GameInteropProvider.InitializeFromAttributes(this); - } - - ~NameplateHooks() - { - Dispose(); - } - - public void Dispose() - { - Unhook(true); - GC.SuppressFinalize(this); - } - - /// - /// Initialize and enable all Hooks. - /// - internal void Initialize() - { - if (!IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour)) - hook_AddonNamePlate_SetPlayerNameplateDetour?.Enable(); - } - - /// - /// Disable all Hooks. - /// - internal void Unhook() - { - Unhook(false); - } - - private void Unhook(bool isDisposing) - { - if (isDisposing) - { - if (!IsHookDisposed(hook_AddonNamePlate_SetPlayerNameplateDetour)) - hook_AddonNamePlate_SetPlayerNameplateDetour?.Dispose(); - } - else - { - if (IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour)) - hook_AddonNamePlate_SetPlayerNameplateDetour?.Disable(); - } - } - - private static bool IsHookDisposed(Hook hook) where T : Delegate - { - return hook == null || hook.IsDisposed; - } - - private static bool IsHookEnabled(Hook hook) where T : Delegate - { - return !IsHookDisposed(hook) && hook.IsEnabled; - } - - private IntPtr SetPlayerNameplateDetour(IntPtr playerNameplateObjectPtr, bool isTitleAboveName, bool isTitleVisible, IntPtr titlePtr, IntPtr namePtr, IntPtr freeCompanyPtr, IntPtr prefix, int iconId) - { - var result = IntPtr.Zero; - - if (IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour)) - { - var eventArgs = new AddonNamePlate_SetPlayerNameEventArgs - { - PlayerNameplateObjectPtr = playerNameplateObjectPtr, - TitlePtr = titlePtr, - NamePtr = namePtr, - FreeCompanyPtr = freeCompanyPtr, - PrefixPtr = prefix, - IsTitleAboveName = isTitleAboveName, - IsTitleVisible = isTitleVisible, - IconID = iconId - }; - - void callOriginal() - { - eventArgs.Result = eventArgs.Original(); - } - - // Add handler for the Original call - eventArgs.CallOriginal += () => - { - return hook_AddonNamePlate_SetPlayerNameplateDetour.Original( - eventArgs.PlayerNameplateObjectPtr, - eventArgs.IsTitleAboveName, - eventArgs.IsTitleVisible, - eventArgs.TitlePtr, - eventArgs.NamePtr, - eventArgs.FreeCompanyPtr, - prefix, - eventArgs.IconID); - }; - - // Invoke Event - var hasDefaultHookEvent = AddonNamePlate_SetPlayerName != null; - AddonNamePlate_SetPlayerName?.Invoke(eventArgs); - - if (AddonNamePlate_SetPlayerNameManaged != null) - { - var freeTitle = false; - var freeName = false; - var freeFreeCompany = false; - var freePrefix = false; - - // Create NamePlateObject if possible - var namePlateObj = new SafeNameplateObject(playerNameplateObjectPtr); - - // Create new event - var managedEventArgs = new AddonNamePlate_SetPlayerNameManagedEventArgs - { - OriginalEventArgs = eventArgs, - SafeNameplateObject = namePlateObj, - Title = GameInterfaceHelper.ReadSeString(eventArgs.TitlePtr), - Name = GameInterfaceHelper.ReadSeString(eventArgs.NamePtr), - FreeCompany = GameInterfaceHelper.ReadSeString(eventArgs.FreeCompanyPtr), - Prefix = GameInterfaceHelper.ReadSeString(eventArgs.PrefixPtr) - }; - - // Get raw string content - var titleRaw = managedEventArgs.Title.Encode(); - var nameRaw = managedEventArgs.Name.Encode(); - var freeCompanyRaw = managedEventArgs.FreeCompany.Encode(); - var prefixRaw = managedEventArgs.Prefix.Encode(); - - // Invoke Managed Event - AddonNamePlate_SetPlayerNameManaged.Invoke(managedEventArgs); - - // Get new Title string content - var titleNewRaw = managedEventArgs.Title.Encode(); - if (!titleRaw.SequenceEqual(titleNewRaw)) - { - eventArgs.TitlePtr = GameInterfaceHelper.PluginAllocate(titleNewRaw); - freeTitle = true; - } - - // Get new Name string content - var nameNewRaw = managedEventArgs.Name.Encode(); - if (!nameRaw.SequenceEqual(nameNewRaw)) - { - eventArgs.NamePtr = GameInterfaceHelper.PluginAllocate(nameNewRaw); - freeName = true; - } - - // Get new Free Company string content - var freeCompanyNewRaw = managedEventArgs.FreeCompany.Encode(); - if (!freeCompanyRaw.SequenceEqual(freeCompanyNewRaw)) - { - eventArgs.FreeCompanyPtr = GameInterfaceHelper.PluginAllocate(freeCompanyNewRaw); - freeFreeCompany = true; - } - - // Get new Prefix string content - var prefixNewRaw = managedEventArgs.Prefix.Encode(); - if (!prefixRaw.SequenceEqual(prefixNewRaw)) - { - eventArgs.PrefixPtr = GameInterfaceHelper.PluginAllocate(prefixNewRaw); - freePrefix = true; - } - - // Call Original as we changed something - callOriginal(); - - // Free memory - if (freeTitle) - GameInterfaceHelper.PluginFree(eventArgs.TitlePtr); - if (freeName) - GameInterfaceHelper.PluginFree(eventArgs.NamePtr); - if (freeFreeCompany) - GameInterfaceHelper.PluginFree(eventArgs.FreeCompanyPtr); - if (freePrefix) - GameInterfaceHelper.PluginFree(eventArgs.PrefixPtr); - } - else if (!hasDefaultHookEvent) - { - // Call original in case of nothing get called, just to get secure it will not break the game when not calling it. - callOriginal(); - } - - // Set result - result = eventArgs.Result; - } - - return result; - } -} diff --git a/Pilz.Dalamud/Nameplates/NameplateManager.cs b/Pilz.Dalamud/Nameplates/NameplateManager.cs deleted file mode 100644 index 84cf339..0000000 --- a/Pilz.Dalamud/Nameplates/NameplateManager.cs +++ /dev/null @@ -1,77 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.UI; -using Pilz.Dalamud.Nameplates.Model; -using System.Runtime.InteropServices; - -namespace Pilz.Dalamud.Nameplates; - -public class NameplateManager : IDisposable -{ - /// - /// Provides events that you can hook to. - /// - public NameplateHooks Hooks { get; init; } = new(); - - /// - /// Defines if all hooks are enabled and the NameplateManager is ready to go. If this is false, then there might be something wrong or something already has been disposed. - /// - public bool IsValid => Hooks.IsValid; - - /// - /// Creates a new instance of the NameplateManager. - /// - public NameplateManager() - { - Hooks.Initialize(); - } - - ~NameplateManager() - { - Dispose(); - } - - public void Dispose() - { - Hooks?.Dispose(); - GC.SuppressFinalize(this); - } - - public static T? GetNameplateGameObject(SafeNameplateObject namePlateObject) where T : GameObject - { - return GetNameplateGameObject(namePlateObject.Pointer); - } - - public static T? GetNameplateGameObject(IntPtr nameplateObjectPtr) where T : GameObject - { - // Get the nameplate object array - var nameplateAddonPtr = PluginServices.GameGui.GetAddonByName("NamePlate", 1); - var nameplateObjectArrayPtrPtr = nameplateAddonPtr + Marshal.OffsetOf(typeof(AddonNamePlate), nameof(AddonNamePlate.NamePlateObjectArray)).ToInt32(); - var nameplateObjectArrayPtr = Marshal.ReadIntPtr(nameplateObjectArrayPtrPtr); - - if (nameplateObjectArrayPtr == IntPtr.Zero) - return null; - - // Determine the index of the nameplate object within the nameplate object array - var namePlateObjectSize = Marshal.SizeOf(typeof(AddonNamePlate.NamePlateObject)); - var namePlateObjectPtr0 = nameplateObjectArrayPtr + namePlateObjectSize * 0; - var namePlateIndex = (nameplateObjectPtr.ToInt64() - namePlateObjectPtr0.ToInt64()) / namePlateObjectSize; - - if (namePlateIndex < 0 || namePlateIndex >= AddonNamePlate.NumNamePlateObjects) - return null; - - // Get the nameplate info array - IntPtr nameplateInfoArrayPtr = IntPtr.Zero; - unsafe - { - var framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance(); - nameplateInfoArrayPtr = new IntPtr(&framework->GetUiModule()->GetRaptureAtkModule()->NamePlateInfoArray); - } - - // Get the nameplate info for the nameplate object - var namePlateInfoPtr = new IntPtr(nameplateInfoArrayPtr.ToInt64() + Marshal.SizeOf(typeof(RaptureAtkModule.NamePlateInfo)) * namePlateIndex); - RaptureAtkModule.NamePlateInfo namePlateInfo = Marshal.PtrToStructure(namePlateInfoPtr); - - // Return the object for its object id - var objectId = namePlateInfo.ObjectID.ObjectID; - return PluginServices.ObjectTable.SearchById(objectId) as T; - } -} diff --git a/Pilz.Dalamud/Nameplates/Tools/NameplateChanges.cs b/Pilz.Dalamud/Nameplates/Tools/NameplateChanges.cs deleted file mode 100644 index 40064d8..0000000 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateChanges.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Pilz.Dalamud.Nameplates.EventArgs; -using Pilz.Dalamud.Tools.Strings; - -namespace Pilz.Dalamud.Nameplates.Tools; - -public class NameplateChanges -{ - private readonly Dictionary changes = []; - - public NameplateChanges() - { - changes.Add(NameplateElements.Title, new()); - changes.Add(NameplateElements.Name, new()); - changes.Add(NameplateElements.FreeCompany, new()); - } - - public NameplateChanges(AddonNamePlate_SetPlayerNameManagedEventArgs eventArgs) : this() - { - GetProps(NameplateElements.Title).Destination = eventArgs.Title; - GetProps(NameplateElements.Name).Destination = eventArgs.Name; - GetProps(NameplateElements.FreeCompany).Destination = eventArgs.FreeCompany; - } - - /// - /// Gets the properties with the changes of an element of your choice where you can add your payloads to a change and setup some options. - /// - /// The position of your choice. - /// - public StringChangesProps GetProps(NameplateElements element) - { - return changes[element]; - } - - /// - /// Gets the changes of an element of your choice where you can add your payloads to a change. - /// - /// The position of your choice. - /// - public StringChanges GetChanges(NameplateElements element) - { - return GetProps(element).StringChanges; - } - - /// - /// Gets a change of the position of the element of your choice where you can add your payloads. - /// - /// The position of your choice. - /// The position of your choice. - /// - public StringChange GetChange(NameplateElements element, StringPosition position) - { - return GetChanges(element).GetChange(position); - } -} diff --git a/Pilz.Dalamud/Nameplates/Tools/NameplateElements.cs b/Pilz.Dalamud/Nameplates/Tools/NameplateElements.cs deleted file mode 100644 index a327334..0000000 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateElements.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Pilz.Dalamud.Nameplates.Tools; - -public enum NameplateElements -{ - Name, - Title, - FreeCompany -} diff --git a/Pilz.Dalamud/Nameplates/Tools/NameplateUpdateFactory.cs b/Pilz.Dalamud/Nameplates/Tools/NameplateUpdateFactory.cs deleted file mode 100644 index 0a00ed0..0000000 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateUpdateFactory.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Dalamud.Game.Text.SeStringHandling.Payloads; -using Pilz.Dalamud.ActivityContexts; -using Pilz.Dalamud.Nameplates.Model; -using Pilz.Dalamud.Tools; -using Pilz.Dalamud.Tools.Strings; - -namespace Pilz.Dalamud.Nameplates.Tools; - -public static class NameplateUpdateFactory -{ - public static void ApplyNameplateChanges(NameplateChangesProps props) - { - foreach (NameplateElements element in Enum.GetValues(typeof(NameplateElements))) - { - var change = props.Changes.GetProps(element); - StringUpdateFactory.ApplyStringChanges(change); - } - } - - public static bool ApplyStatusIconWithPrio(ref int statusIcon, int newStatusIcon, StringChange stringChange, ActivityContext activityContext, StatusIconPriorizer priorizer, bool moveIconToNameplateIfPossible) - { - bool? isPrio = null; - var fontIcon = StatusIconFontConverter.GetBitmapFontIconFromStatusIcon((StatusIcons)statusIcon); - - if (moveIconToNameplateIfPossible) - { - if (fontIcon != null) - { - // Set new font icon as string change - var iconPayload = new IconPayload(fontIcon.Value); - stringChange.Payloads.Insert(0, iconPayload); - - // If we moved it, we don't need it as icon anymore, yay :D - isPrio = false; - } - } - - isPrio ??= priorizer.IsPriorityIcon(statusIcon, activityContext); - - if (!isPrio.Value) - statusIcon = newStatusIcon; - - return isPrio.Value; - } -} diff --git a/Pilz.Dalamud/PluginServices.cs b/Pilz.Dalamud/PluginServices.cs index 9d28242..5a1cdf4 100644 --- a/Pilz.Dalamud/PluginServices.cs +++ b/Pilz.Dalamud/PluginServices.cs @@ -6,12 +6,12 @@ namespace Pilz.Dalamud; public class PluginServices { - [PluginService] public static IDalamudPluginInterface PluginInterface { get; set; } = null; - [PluginService] public static IGameGui GameGui { get; set; } = null; - [PluginService] public static IClientState ClientState { get; set; } = null; - [PluginService] public static IDataManager DataManager { get; set; } = null; - [PluginService] public static IObjectTable ObjectTable { get; set; } = null; - [PluginService] public static IGameInteropProvider GameInteropProvider { get; set; } = null; + [PluginService] public static IDalamudPluginInterface PluginInterface { get; set; } + [PluginService] public static IGameGui GameGui { get; set; } + [PluginService] public static IClientState ClientState { get; set; } + [PluginService] public static IDataManager DataManager { get; set; } + [PluginService] public static IObjectTable ObjectTable { get; set; } + [PluginService] public static IGameInteropProvider GameInteropProvider { get; set; } public static void Initialize(IDalamudPluginInterface dalamudPluginInterface) { diff --git a/Pilz.Dalamud/Tools/NamePlates/NameplateChanges.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateChanges.cs new file mode 100644 index 0000000..2a56815 --- /dev/null +++ b/Pilz.Dalamud/Tools/NamePlates/NameplateChanges.cs @@ -0,0 +1,25 @@ +using Dalamud.Game.Gui.NamePlate; + +namespace Pilz.Dalamud.Tools.NamePlates; + +public class NameplateChanges +{ + private readonly List changes = []; + + public NameplateChanges(INamePlateUpdateHandler handler) + { + changes.Add(new(NameplateElements.Title, handler)); + changes.Add(new(NameplateElements.Name, handler)); + changes.Add(new(NameplateElements.FreeCompany, handler)); + } + + /// + /// Gets the properties with the changes of an element of your choice where you can add your payloads to a change and setup some options. + /// + /// The position of your choice. + /// + public NameplateElementChange GetChange(NameplateElements element) + { + return changes.FirstOrDefault(n => n.Element == element); + } +} diff --git a/Pilz.Dalamud/Nameplates/Tools/NameplateChangesProps.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateChangesProps.cs similarity index 88% rename from Pilz.Dalamud/Nameplates/Tools/NameplateChangesProps.cs rename to Pilz.Dalamud/Tools/NamePlates/NameplateChangesProps.cs index b8427f3..cf11fd7 100644 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateChangesProps.cs +++ b/Pilz.Dalamud/Tools/NamePlates/NameplateChangesProps.cs @@ -1,4 +1,4 @@ -namespace Pilz.Dalamud.Nameplates.Tools; +namespace Pilz.Dalamud.Tools.NamePlates; public class NameplateChangesProps { diff --git a/Pilz.Dalamud/Tools/NamePlates/NameplateElementChange.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateElementChange.cs new file mode 100644 index 0000000..d5b1b13 --- /dev/null +++ b/Pilz.Dalamud/Tools/NamePlates/NameplateElementChange.cs @@ -0,0 +1,44 @@ +using Dalamud.Game.Gui.NamePlate; +using Dalamud.Game.Text.SeStringHandling; +using Pilz.Dalamud.Tools.Strings; + +namespace Pilz.Dalamud.Tools.NamePlates; + +public class NameplateElementChange(NameplateElements element, INamePlateUpdateHandler handler) +{ + public NameplateElements Element => element; + public StringChanges Changes { get; set; } = new(); + + public void ApplyFormatting(SeString prefix, SeString postfix) + { + var parts = (prefix, postfix); + + switch (element) + { + case NameplateElements.Name: + handler.NameParts.TextWrap = parts; + break; + case NameplateElements.Title: + handler.TitleParts.TextWrap = parts; + break; + case NameplateElements.FreeCompany: + handler.FreeCompanyTagParts.TextWrap = parts; + break; + } + } + + public void ApplyChanges() + { + StringUpdateFactory.ApplyStringChanges(new() + { + StringChanges = Changes, + Destination = element switch + { + NameplateElements.Name => handler.NameParts.Text ??= handler.InfoView.Name, + NameplateElements.Title => handler.TitleParts.Text ??= handler.InfoView.Title, + NameplateElements.FreeCompany => handler.FreeCompanyTagParts.Text ??= handler.InfoView.FreeCompanyTag, + _ => null, + }, + }); + } +} diff --git a/Pilz.Dalamud/Tools/NamePlates/NameplateElements.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateElements.cs new file mode 100644 index 0000000..a76b4fc --- /dev/null +++ b/Pilz.Dalamud/Tools/NamePlates/NameplateElements.cs @@ -0,0 +1,8 @@ +namespace Pilz.Dalamud.Tools.NamePlates; + +public enum NameplateElements +{ + Name, + Title, + FreeCompany, +} diff --git a/Pilz.Dalamud/Tools/NamePlates/NameplateUpdateFactory.cs b/Pilz.Dalamud/Tools/NamePlates/NameplateUpdateFactory.cs new file mode 100644 index 0000000..786c4ea --- /dev/null +++ b/Pilz.Dalamud/Tools/NamePlates/NameplateUpdateFactory.cs @@ -0,0 +1,48 @@ +using Dalamud.Game.Gui.NamePlate; +using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Game.Text.SeStringHandling.Payloads; +using Pilz.Dalamud.ActivityContexts; +using Pilz.Dalamud.Icons; + +namespace Pilz.Dalamud.Tools.NamePlates; + +public static class NameplateUpdateFactory +{ + public static void ApplyNameplateChanges(NameplateChangesProps props) + { + foreach (NameplateElements element in Enum.GetValues(typeof(NameplateElements))) + { + var change = props.Changes.GetChange(element); + change.ApplyChanges(); + } + } + + public static bool ApplyStatusIconWithPrio(INamePlateUpdateHandler handler, int newStatusIcon, ActivityContext activityContext, StatusIconPriorizer priorizer, bool moveIconToNameplateIfPossible) + { + bool? isPrio = null; + var fontIcon = StatusIconFontConverter.GetBitmapFontIconFromStatusIcon((StatusIcons)handler.NameIconId); + + if (moveIconToNameplateIfPossible) + { + if (fontIcon != null) + { + // Set new font icon as string change + var icon = new IconPayload(fontIcon.Value); ; + if (handler.StatusPrefix is SeString str) + str.Payloads.Insert(0, icon); + else + handler.StatusPrefix = SeString.Empty.Append(icon); + + // If we moved it, we don't need it as icon anymore, yay :D + isPrio = false; + } + } + + isPrio ??= priorizer.IsPriorityIcon(handler.NameIconId, activityContext); + + if (!isPrio.Value) + handler.NameIconId = newStatusIcon; + + return isPrio.Value; + } +} diff --git a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizer.cs b/Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizer.cs similarity index 96% rename from Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizer.cs rename to Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizer.cs index 26dffce..1c2fd0b 100644 --- a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizer.cs +++ b/Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizer.cs @@ -1,7 +1,7 @@ using Pilz.Dalamud.ActivityContexts; -using Pilz.Dalamud.Nameplates.Model; +using Pilz.Dalamud.Icons; -namespace Pilz.Dalamud.Nameplates.Tools; +namespace Pilz.Dalamud.Tools.NamePlates; public class StatusIconPriorizer { diff --git a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerConditionSets.cs b/Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizerConditionSets.cs similarity index 66% rename from Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerConditionSets.cs rename to Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizerConditionSets.cs index fd47ac7..32a6988 100644 --- a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerConditionSets.cs +++ b/Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizerConditionSets.cs @@ -1,4 +1,4 @@ -namespace Pilz.Dalamud.Nameplates.Tools; +namespace Pilz.Dalamud.Tools.NamePlates; public enum StatusIconPriorizerConditionSets { diff --git a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerSettings.cs b/Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizerSettings.cs similarity index 97% rename from Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerSettings.cs rename to Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizerSettings.cs index 7fef580..3316d89 100644 --- a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerSettings.cs +++ b/Pilz.Dalamud/Tools/NamePlates/StatusIconPriorizerSettings.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; -using Pilz.Dalamud.Nameplates.Model; +using Pilz.Dalamud.Icons; -namespace Pilz.Dalamud.Nameplates.Tools; +namespace Pilz.Dalamud.Tools.NamePlates; public class StatusIconPriorizerSettings { diff --git a/Pilz.Dalamud/Tools/StatusIconFontConverter.cs b/Pilz.Dalamud/Tools/StatusIconFontConverter.cs index 3cca543..422fc27 100644 --- a/Pilz.Dalamud/Tools/StatusIconFontConverter.cs +++ b/Pilz.Dalamud/Tools/StatusIconFontConverter.cs @@ -1,5 +1,5 @@ using Dalamud.Game.Text.SeStringHandling; -using Pilz.Dalamud.Nameplates.Model; +using Pilz.Dalamud.Icons; namespace Pilz.Dalamud.Tools; diff --git a/Pilz.Dalamud/XivApi.cs b/Pilz.Dalamud/XivApi.cs deleted file mode 100644 index 45d8c3e..0000000 --- a/Pilz.Dalamud/XivApi.cs +++ /dev/null @@ -1,33 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.System.Framework; -using Pilz.Dalamud.Nameplates.Model; - -namespace Pilz.Dalamud; - -public class XivApi -{ - private static IntPtr _RaptureAtkModulePtr = IntPtr.Zero; - - public static IntPtr RaptureAtkModulePtr - { - get - { - if (_RaptureAtkModulePtr == IntPtr.Zero) - { - unsafe - { - var framework = Framework.Instance(); - var uiModule = framework->GetUiModule(); - - _RaptureAtkModulePtr = new IntPtr(uiModule->GetRaptureAtkModule()); - } - } - - return _RaptureAtkModulePtr; - } - } - - public static SafeAddonNameplate GetSafeAddonNamePlate() - { - return new(PluginServices.PluginInterface); - } -}