diff --git a/Pilz.Dalamud/ActivityContexts/ActivityContext.cs b/Pilz.Dalamud/ActivityContexts/ActivityContext.cs index ae9fd79..e760d0a 100644 --- a/Pilz.Dalamud/ActivityContexts/ActivityContext.cs +++ b/Pilz.Dalamud/ActivityContexts/ActivityContext.cs @@ -1,25 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.ActivityContexts; -namespace Pilz.Dalamud.ActivityContexts +public class ActivityContext { - public class ActivityContext + public ActivityType ActivityType { get; init; } + public ZoneType ZoneType { get; init; } + + public ActivityContext(ActivityType activityType, ZoneType zoneType) { - public ActivityType ActivityType { get; init; } - public ZoneType ZoneType { get; init; } + ActivityType = activityType; + ZoneType = zoneType; + } - public ActivityContext(ActivityType activityType, ZoneType zoneType) - { - ActivityType = activityType; - ZoneType = zoneType; - } - - public bool IsInDuty - { - get => ZoneType != ZoneType.Overworld; - } + public bool IsInDuty + { + get => ZoneType != ZoneType.Overworld; } } diff --git a/Pilz.Dalamud/ActivityContexts/ActivityContextManager.cs b/Pilz.Dalamud/ActivityContexts/ActivityContextManager.cs index af0b902..35f5878 100644 --- a/Pilz.Dalamud/ActivityContexts/ActivityContextManager.cs +++ b/Pilz.Dalamud/ActivityContexts/ActivityContextManager.cs @@ -1,89 +1,82 @@ -using Dalamud.Logging; -using Lumina.Excel; +using Lumina.Excel; using Lumina.Excel.GeneratedSheets; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.ActivityContexts +namespace Pilz.Dalamud.ActivityContexts; + +public class ActivityContextManager : IDisposable { - public class ActivityContextManager : IDisposable + public delegate void ActivityContextChangedEventHandler(ActivityContextManager sender, ActivityContext activityContext); + public event ActivityContextChangedEventHandler ActivityContextChanged; + + private readonly ExcelSheet contentFinderConditionsSheet; + + public ActivityContext CurrentActivityContext { get; protected set; } + + public ActivityContextManager() { - public delegate void ActivityContextChangedEventHandler(ActivityContextManager sender, ActivityContext activityContext); - public event ActivityContextChangedEventHandler ActivityContextChanged; + // Get condition sheet + contentFinderConditionsSheet = PluginServices.DataManager.GameData.GetExcelSheet(); - private readonly ExcelSheet contentFinderConditionsSheet; + // Checks current territory type (if enabled/installed during a dutiy e.g.) + CheckCurrentTerritory(); - public ActivityContext CurrentActivityContext { get; protected set; } + // Enable event for automatic checks + PluginServices.ClientState.TerritoryChanged += ClientState_TerritoryChanged; + } - public ActivityContextManager() + public void Dispose() + { + PluginServices.ClientState.TerritoryChanged -= ClientState_TerritoryChanged; + } + + private void ClientState_TerritoryChanged(ushort obj) + { + CheckCurrentTerritory(); + } + + private void CheckCurrentTerritory() + { + var content = contentFinderConditionsSheet.FirstOrDefault(c => c.TerritoryType.Row == PluginServices.ClientState.TerritoryType); + ActivityType newActivityContext; + ZoneType newZoneType; + + if (content == null) { - // Get condition sheet - contentFinderConditionsSheet = PluginServices.DataManager.GameData.GetExcelSheet(); - - // Checks current territory type (if enabled/installed during a dutiy e.g.) - CheckCurrentTerritory(); - - // Enable event for automatic checks - PluginServices.ClientState.TerritoryChanged += ClientState_TerritoryChanged; + // No content found, so we must be on the overworld + newActivityContext = ActivityType.None; + newZoneType = ZoneType.Overworld; } - - public void Dispose() + else { - PluginServices.ClientState.TerritoryChanged -= ClientState_TerritoryChanged; - } - - private void ClientState_TerritoryChanged(ushort obj) - { - CheckCurrentTerritory(); - } - - private void CheckCurrentTerritory() - { - var content = contentFinderConditionsSheet.FirstOrDefault(c => c.TerritoryType.Row == PluginServices.ClientState.TerritoryType); - ActivityType newActivityContext; - ZoneType newZoneType; - - if (content == null) + if (content.PvP) { - // No content found, so we must be on the overworld - newActivityContext = ActivityType.None; - newZoneType = ZoneType.Overworld; + newActivityContext = ActivityType.PvpDuty; + newZoneType = ZoneType.Pvp; } else { - if (content.PvP) - { - newActivityContext = ActivityType.PvpDuty; - newZoneType = ZoneType.Pvp; - } - else - { - newActivityContext = ActivityType.PveDuty; + newActivityContext = ActivityType.PveDuty; - // Find correct member type - var memberType = content.ContentMemberType.Row; - if (content.RowId == 16 || content.RowId == 15) - memberType = 2; // Praetorium and Castrum Meridianum - else if (content.RowId == 735 || content.RowId == 778) - memberType = 127; // Bozja + // Find correct member type + var memberType = content.ContentMemberType.Row; + if (content.RowId == 16 || content.RowId == 15) + memberType = 2; // Praetorium and Castrum Meridianum + else if (content.RowId == 735 || content.RowId == 778) + memberType = 127; // Bozja - // Check for ZoneType - newZoneType = memberType switch - { - 2 => ZoneType.Doungen, - 3 => ZoneType.Raid, - 4 => ZoneType.AllianceRaid, - 127 => ZoneType.Foray, - _ => ZoneType.Doungen, - }; - } + // Check for ZoneType + newZoneType = memberType switch + { + 2 => ZoneType.Doungen, + 3 => ZoneType.Raid, + 4 => ZoneType.AllianceRaid, + 127 => ZoneType.Foray, + _ => ZoneType.Doungen, + }; } - - CurrentActivityContext = new(newActivityContext, newZoneType); - ActivityContextChanged?.Invoke(this, CurrentActivityContext); } + + CurrentActivityContext = new(newActivityContext, newZoneType); + ActivityContextChanged?.Invoke(this, CurrentActivityContext); } } diff --git a/Pilz.Dalamud/ActivityContexts/ActivityType.cs b/Pilz.Dalamud/ActivityContexts/ActivityType.cs index d82d5ab..ad42186 100644 --- a/Pilz.Dalamud/ActivityContexts/ActivityType.cs +++ b/Pilz.Dalamud/ActivityContexts/ActivityType.cs @@ -1,18 +1,12 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.ActivityContexts +namespace Pilz.Dalamud.ActivityContexts; + +[JsonConverter(typeof(StringEnumConverter))] +public enum ActivityType { - [JsonConverter(typeof(StringEnumConverter))] - public enum ActivityType - { - None = 0x0, - PveDuty = 0x1, - PvpDuty = 0x2 - } + None = 0x0, + PveDuty = 0x1, + PvpDuty = 0x2 } diff --git a/Pilz.Dalamud/ActivityContexts/ZoneType.cs b/Pilz.Dalamud/ActivityContexts/ZoneType.cs index aa40d28..df03acd 100644 --- a/Pilz.Dalamud/ActivityContexts/ZoneType.cs +++ b/Pilz.Dalamud/ActivityContexts/ZoneType.cs @@ -1,22 +1,16 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.ActivityContexts +namespace Pilz.Dalamud.ActivityContexts; + +[Flags, JsonConverter(typeof(StringEnumConverter))] +public enum ZoneType { - [Flags, JsonConverter(typeof(StringEnumConverter))] - public enum ZoneType - { - Overworld = 1, - Doungen = 2, - Raid = 4, - AllianceRaid = 8, - Foray = 16, - Pvp = 32, - Everywhere = int.MaxValue - } + Overworld = 1, + Doungen = 2, + Raid = 4, + AllianceRaid = 8, + Foray = 16, + Pvp = 32, + Everywhere = int.MaxValue } diff --git a/Pilz.Dalamud/Extensions.cs b/Pilz.Dalamud/Extensions.cs index 94e5113..5f195b0 100644 --- a/Pilz.Dalamud/Extensions.cs +++ b/Pilz.Dalamud/Extensions.cs @@ -1,40 +1,34 @@ using Dalamud.Game.Text.SeStringHandling; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud +namespace Pilz.Dalamud; + +public static class Extensions { - public static class Extensions + /// + /// Removes a Payload from a given SeString. + /// Using SeString.Payloads.Remove() does not use the reference to compare for some reason. Tis is a workaround. + /// + /// + /// + public static void Remove(this SeString seString, Payload payload) { - /// - /// Removes a Payload from a given SeString. - /// Using SeString.Payloads.Remove() does not use the reference to compare for some reason. Tis is a workaround. - /// - /// - /// - public static void Remove(this SeString seString, Payload payload) - { - Remove(seString.Payloads, payload); - } + Remove(seString.Payloads, payload); + } - /// - /// Removes a Payload from a given list. - /// Using List.Remove() does not use the reference to compare for some reason. Tis is a workaround. - /// - /// - /// - public static void Remove(this List payloads, Payload payload) + /// + /// Removes a Payload from a given list. + /// Using List.Remove() does not use the reference to compare for some reason. Tis is a workaround. + /// + /// + /// + public static void Remove(this List payloads, Payload payload) + { + for (int i = 0; i < payloads.Count; i++) { - for (int i = 0; i < payloads.Count; i++) + if (ReferenceEquals(payloads[i], payload)) { - if (ReferenceEquals(payloads[i], payload)) - { - payloads.RemoveAt(i); - break; - } + payloads.RemoveAt(i); + break; } } } diff --git a/Pilz.Dalamud/GameInterfaceHelper.cs b/Pilz.Dalamud/GameInterfaceHelper.cs index f786f13..5c16ba7 100644 --- a/Pilz.Dalamud/GameInterfaceHelper.cs +++ b/Pilz.Dalamud/GameInterfaceHelper.cs @@ -1,153 +1,148 @@ using Dalamud.Game.Text.SeStringHandling; using FFXIVClientStructs.FFXIV.Client.System.Memory; -using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud +namespace Pilz.Dalamud; + +public static class GameInterfaceHelper { - public static class GameInterfaceHelper + public static SeString ReadSeString(IntPtr ptr) { - public static SeString ReadSeString(IntPtr ptr) + if (ptr == IntPtr.Zero) { - if (ptr == IntPtr.Zero) - { - return new SeString(); - } - - if (TryReadStringBytes(ptr, out var bytes) && bytes != null) - { - return SeString.Parse(bytes); - } - return new SeString(); } - public static bool TryReadSeString(IntPtr ptr, out SeString? seString) + if (TryReadStringBytes(ptr, out var bytes) && bytes != null) { - seString = null; - if (ptr == IntPtr.Zero) - { - return false; - } + return SeString.Parse(bytes); + } - if (TryReadStringBytes(ptr, out var bytes) && bytes != null) - { - seString = SeString.Parse(bytes); - return true; - } + return new SeString(); + } + public static bool TryReadSeString(IntPtr ptr, out SeString? seString) + { + seString = null; + if (ptr == IntPtr.Zero) + { return false; } - public static string? ReadString(IntPtr ptr) + if (TryReadStringBytes(ptr, out var bytes) && bytes != null) { - if (ptr == IntPtr.Zero) - { - return null; - } - - if (TryReadStringBytes(ptr, out var bytes) && bytes != null) - { - return Encoding.UTF8.GetString(bytes); - } - - return null; - } - - public static bool TryReadString(IntPtr ptr, out string? str) - { - str = null; - if (ptr == IntPtr.Zero) - { - return false; - } - - if (TryReadStringBytes(ptr, out var bytes) && bytes != null) - { - str = Encoding.UTF8.GetString(bytes); - return true; - } - - return false; - } - - public static bool TryReadStringBytes(IntPtr ptr, out byte[]? bytes) - { - bytes = null; - if (ptr == IntPtr.Zero) - { - return false; - } - - var size = 0; - while (Marshal.ReadByte(ptr, size) != 0) - { - size++; - } - - bytes = new byte[size]; - Marshal.Copy(ptr, bytes, 0, size); - + seString = SeString.Parse(bytes); return true; } - public static IntPtr PluginAllocate(byte[] bytes) - { - IntPtr pointer = Marshal.AllocHGlobal(bytes.Length + 1); - Marshal.Copy(bytes, 0, pointer, bytes.Length); - Marshal.WriteByte(pointer, bytes.Length, 0); + return false; + } - return pointer; + public static string? ReadString(IntPtr ptr) + { + if (ptr == IntPtr.Zero) + { + return null; } - public static IntPtr PluginAllocate(SeString seString) + if (TryReadStringBytes(ptr, out var bytes) && bytes != null) { - return PluginAllocate(seString.Encode()); + return Encoding.UTF8.GetString(bytes); } - public static void PluginFree(IntPtr ptr) + return null; + } + + public static bool TryReadString(IntPtr ptr, out string? str) + { + str = null; + if (ptr == IntPtr.Zero) { - Marshal.FreeHGlobal(ptr); + return false; } - public static void PluginFree(ref IntPtr ptr) + if (TryReadStringBytes(ptr, out var bytes) && bytes != null) { - PluginFree(ptr); - ptr = IntPtr.Zero; + str = Encoding.UTF8.GetString(bytes); + return true; } - public static byte[] NullTerminate(this byte[] bytes) + return false; + } + + public static bool TryReadStringBytes(IntPtr ptr, out byte[]? bytes) + { + bytes = null; + if (ptr == IntPtr.Zero) { - if (bytes.Length == 0 || bytes[bytes.Length - 1] != 0) - { - var newBytes = new byte[bytes.Length + 1]; - Array.Copy(bytes, newBytes, bytes.Length); - newBytes[^1] = 0; - - return newBytes; - } - - return bytes; + return false; } - public static unsafe IntPtr GameUIAllocate(ulong size) + var size = 0; + while (Marshal.ReadByte(ptr, size) != 0) { - return (IntPtr)IMemorySpace.GetUISpace()->Malloc(size, 0); + size++; } - public static unsafe void GameFree(ref IntPtr ptr, ulong size) - { - if (ptr == IntPtr.Zero) - { - return; - } + bytes = new byte[size]; + Marshal.Copy(ptr, bytes, 0, size); - IMemorySpace.Free((void*)ptr, size); - ptr = IntPtr.Zero; + return true; + } + + public static IntPtr PluginAllocate(byte[] bytes) + { + IntPtr pointer = Marshal.AllocHGlobal(bytes.Length + 1); + Marshal.Copy(bytes, 0, pointer, bytes.Length); + Marshal.WriteByte(pointer, bytes.Length, 0); + + return pointer; + } + + public static IntPtr PluginAllocate(SeString seString) + { + return PluginAllocate(seString.Encode()); + } + + public static void PluginFree(IntPtr ptr) + { + Marshal.FreeHGlobal(ptr); + } + + public static void PluginFree(ref IntPtr ptr) + { + PluginFree(ptr); + ptr = IntPtr.Zero; + } + + public static byte[] NullTerminate(this byte[] bytes) + { + if (bytes.Length == 0 || bytes[bytes.Length - 1] != 0) + { + var newBytes = new byte[bytes.Length + 1]; + Array.Copy(bytes, newBytes, bytes.Length); + newBytes[^1] = 0; + + return newBytes; } + + return bytes; + } + + public static unsafe IntPtr GameUIAllocate(ulong size) + { + return (IntPtr)IMemorySpace.GetUISpace()->Malloc(size, 0); + } + + public static unsafe void GameFree(ref IntPtr ptr, ulong size) + { + if (ptr == IntPtr.Zero) + { + return; + } + + IMemorySpace.Free((void*)ptr, size); + ptr = IntPtr.Zero; } } diff --git a/Pilz.Dalamud/Icons/JobIconSet.cs b/Pilz.Dalamud/Icons/JobIconSet.cs index db7acc0..fed9456 100644 --- a/Pilz.Dalamud/Icons/JobIconSet.cs +++ b/Pilz.Dalamud/Icons/JobIconSet.cs @@ -1,27 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Icons; -namespace Pilz.Dalamud.Icons +public class JobIconSet { - public class JobIconSet + private readonly int[] icons; + + public float IconScale { get; init; } + + public JobIconSet(int[] icons, float iconScale) { - private readonly int[] icons; + this.icons = icons; + IconScale = iconScale; + } - public float IconScale { get; init; } - - public JobIconSet(int[] icons, float iconScale) - { - this.icons = icons; - IconScale = iconScale; - } - - public int GetIcon(uint jobID) - { - return icons[jobID - 1]; - } + public int GetIcon(uint jobID) + { + return icons[jobID - 1]; } } diff --git a/Pilz.Dalamud/Icons/JobIconSetName.cs b/Pilz.Dalamud/Icons/JobIconSetName.cs index 7d19a2c..3d1f21a 100644 --- a/Pilz.Dalamud/Icons/JobIconSetName.cs +++ b/Pilz.Dalamud/Icons/JobIconSetName.cs @@ -1,24 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Icons; -namespace Pilz.Dalamud.Icons +public enum JobIconSetName { - public enum JobIconSetName - { - Gold, - Framed, - Glowing, - Blue, - Red, - Purple, - Black, - Yellow, - Orange, - Green, - Grey, - Role - } + Gold, + Framed, + Glowing, + Blue, + Red, + Purple, + Black, + Yellow, + Orange, + Green, + Grey, + Role } diff --git a/Pilz.Dalamud/Icons/JobIconSets.cs b/Pilz.Dalamud/Icons/JobIconSets.cs index 376b7f5..4fe3e85 100644 --- a/Pilz.Dalamud/Icons/JobIconSets.cs +++ b/Pilz.Dalamud/Icons/JobIconSets.cs @@ -1,128 +1,120 @@ -using Lumina.Excel.GeneratedSheets; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Icons; -namespace Pilz.Dalamud.Icons +public class JobIconSets { - public class JobIconSets + private readonly Dictionary iconSets = []; + + public JobIconSets() { - private readonly Dictionary iconSets = new(); - - public JobIconSets() + Add(JobIconSetName.Gold, new[] { - Add(JobIconSetName.Gold, new[] - { - 62001, 62002, 62003, 62004, 62005, 62006, 62007, 62008, 62009, 62010, - 62011, 62012, 62013, 62014, 62015, 62016, 62017, 62018, 62019, 62020, - 62021, 62022, 62023, 62024, 62025, 62026, 62027, 62028, 62029, 62030, - 62031, 62032, 62033, 62034, 62035, 62036, 62037, 62038, 62039, 62040 - }, 1); + 62001, 62002, 62003, 62004, 62005, 62006, 62007, 62008, 62009, 62010, + 62011, 62012, 62013, 62014, 62015, 62016, 62017, 62018, 62019, 62020, + 62021, 62022, 62023, 62024, 62025, 62026, 62027, 62028, 62029, 62030, + 62031, 62032, 62033, 62034, 62035, 62036, 62037, 62038, 62039, 62040 + }, 1); - Add(JobIconSetName.Framed, new[] - { - 62101, 62102, 62103, 62104, 62105, 62106, 62107, 62108, 62109, 62110, - 62111, 62112, 62113, 62114, 62115, 62116, 62117, 62118, 62119, 62120, - 62121, 62122, 62123, 62124, 62125, 62126, 62127, 62128, 62129, 62130, - 62131, 62132, 62133, 62134, 62135, 62136, 62137, 62138, 62139, 62140 - }); - - Add(JobIconSetName.Glowing, new[] - { - 62301, 62302, 62303, 62304, 62305, 62306, 62307, 62310, 62311, 62312, - 62313, 62314, 62315, 62316, 62317, 62318, 62319, 62320, 62401, 62402, - 62403, 62404, 62405, 62406, 62407, 62308, 62408, 62409, 62309, 62410, - 62411, 62412, 62413, 62414, 62415, 62416, 62417, 62418, 62419, 62420 - }); - - Add(JobIconSetName.Grey, new[] - { - 91022, 91023, 91024, 91025, 91026, 91028, 91029, 91031, 91032, 91033, - 91034, 91035, 91036, 91037, 91038, 91039, 91040, 91041, 91079, 91080, - 91081, 91082, 91083, 91084, 91085, 91030, 91086, 91087, 91121, 91122, - 91125, 91123, 91124, 91127, 91128, 91129, 91130, 91131, 91132, 91133 - }, 2); - - Add(JobIconSetName.Black, new[] - { - 91522, 91523, 91524, 91525, 91526, 91528, 91529, 91531, 91532, 91533, - 91534, 91535, 91536, 91537, 91538, 91539, 91540, 91541, 91579, 91580, - 91581, 91582, 91583, 91584, 91585, 91530, 91586, 91587, 91621, 91622, - 91625, 91623, 91624, 91627, 91628, 91629, 91630, 91631, 91632, 91633 - }, 2); - - Add(JobIconSetName.Yellow, new[] - { - 92022, 92023, 92024, 92025, 92026, 92028, 92029, 92031, 92032, 92033, - 92034, 92035, 92036, 92037, 92038, 92039, 92040, 92041, 92079, 92080, - 92081, 92082, 92083, 92084, 92085, 92030, 92086, 92087, 92121, 92122, - 92125, 92123, 92124, 92127, 92128, 92129, 92130, 92131, 92132, 92133 - }, 2); - - Add(JobIconSetName.Orange, new[] - { - 92522, 92523, 92524, 92525, 92526, 92528, 92529, 92531, 92532, 92533, - 92534, 92535, 92536, 92537, 92538, 92539, 92540, 92541, 92579, 92580, - 92581, 92582, 92583, 92584, 92585, 92530, 92586, 92587, 92621, 92622, - 92625, 92623, 92624, 92627, 92628, 92629, 92630, 92631, 92632, 92633 - }, 2); - - Add(JobIconSetName.Red, new[] - { - 93022, 93023, 93024, 93025, 93026, 93028, 93029, 93031, 93032, 93033, - 93034, 93035, 93036, 93037, 93038, 93039, 93040, 93041, 93079, 93080, - 93081, 93082, 93083, 93084, 93085, 93030, 93086, 93087, 93121, 93122, - 93125, 93123, 93124, 93127, 93128, 93129, 93130, 93131, 93132, 93133 - }, 2); - - Add(JobIconSetName.Purple, new[] - { - 93522, 93523, 93524, 93525, 93526, 93528, 93529, 93531, 93532, 93533, - 93534, 93535, 93536, 93537, 93538, 93539, 93540, 93541, 93579, 93580, - 93581, 93582, 93583, 93584, 93585, 93530, 93586, 93587, 93621, 93622, - 93625, 93623, 93624, 93627, 93628, 93629, 93630, 93631, 93632, 93633 - }, 2); - - Add(JobIconSetName.Blue, new[] - { - 94022, 94023, 94024, 94025, 94026, 94028, 94029, 94031, 94032, 94033, - 94034, 94035, 94036, 94037, 94038, 94039, 94040, 94041, 94079, 94080, - 94081, 94082, 94083, 94084, 94085, 94030, 94086, 94087, 94121, 94122, - 94125, 94123, 94124, 94127, 94128, 94129, 94130, 94131, 94132, 94133 - }, 2); - - Add(JobIconSetName.Green, new[] - { - 94522, 94523, 94524, 94525, 94526, 94528, 94529, 94531, 94532, 94533, - 94534, 94535, 94536, 94537, 94538, 94539, 94540, 94541, 94579, 94580, - 94581, 94582, 94583, 94584, 94585, 94530, 94586, 94587, 94621, 94622, - 94625, 94623, 94624, 94627, 94628, 94629, 94630, 94631, 94632, 94633 - }, 2); - - Add(JobIconSetName.Role, new[] - { - 62581, 62584, 62581, 62584, 62586, 62582, 62502, 62502, 62503, 62504, - 62505, 62506, 62507, 62508, 62509, 62510, 62511, 62512, 62581, 62584, - 62581, 62584, 62586, 62582, 62587, 62587, 62587, 62582, 62584, 62584, - 62586, 62581, 62582, 62584, 62587, 62587, 62581, 62586, 62584, 62582 - }); - } - - private void Add(JobIconSetName id, int[] icons, float scale = 1f) + Add(JobIconSetName.Framed, new[] { - iconSets[id] = new JobIconSet(icons, scale); - } + 62101, 62102, 62103, 62104, 62105, 62106, 62107, 62108, 62109, 62110, + 62111, 62112, 62113, 62114, 62115, 62116, 62117, 62118, 62119, 62120, + 62121, 62122, 62123, 62124, 62125, 62126, 62127, 62128, 62129, 62130, + 62131, 62132, 62133, 62134, 62135, 62136, 62137, 62138, 62139, 62140 + }); - public int GetJobIcon(JobIconSetName set, uint jobId) + Add(JobIconSetName.Glowing, new[] { - return iconSets[set].GetIcon(jobId); - } + 62301, 62302, 62303, 62304, 62305, 62306, 62307, 62310, 62311, 62312, + 62313, 62314, 62315, 62316, 62317, 62318, 62319, 62320, 62401, 62402, + 62403, 62404, 62405, 62406, 62407, 62308, 62408, 62409, 62309, 62410, + 62411, 62412, 62413, 62414, 62415, 62416, 62417, 62418, 62419, 62420 + }); - public float GetJobIconSale(JobIconSetName set) + Add(JobIconSetName.Grey, new[] { - return iconSets[set].IconScale; - } + 91022, 91023, 91024, 91025, 91026, 91028, 91029, 91031, 91032, 91033, + 91034, 91035, 91036, 91037, 91038, 91039, 91040, 91041, 91079, 91080, + 91081, 91082, 91083, 91084, 91085, 91030, 91086, 91087, 91121, 91122, + 91125, 91123, 91124, 91127, 91128, 91129, 91130, 91131, 91132, 91133 + }, 2); + + Add(JobIconSetName.Black, new[] + { + 91522, 91523, 91524, 91525, 91526, 91528, 91529, 91531, 91532, 91533, + 91534, 91535, 91536, 91537, 91538, 91539, 91540, 91541, 91579, 91580, + 91581, 91582, 91583, 91584, 91585, 91530, 91586, 91587, 91621, 91622, + 91625, 91623, 91624, 91627, 91628, 91629, 91630, 91631, 91632, 91633 + }, 2); + + Add(JobIconSetName.Yellow, new[] + { + 92022, 92023, 92024, 92025, 92026, 92028, 92029, 92031, 92032, 92033, + 92034, 92035, 92036, 92037, 92038, 92039, 92040, 92041, 92079, 92080, + 92081, 92082, 92083, 92084, 92085, 92030, 92086, 92087, 92121, 92122, + 92125, 92123, 92124, 92127, 92128, 92129, 92130, 92131, 92132, 92133 + }, 2); + + Add(JobIconSetName.Orange, new[] + { + 92522, 92523, 92524, 92525, 92526, 92528, 92529, 92531, 92532, 92533, + 92534, 92535, 92536, 92537, 92538, 92539, 92540, 92541, 92579, 92580, + 92581, 92582, 92583, 92584, 92585, 92530, 92586, 92587, 92621, 92622, + 92625, 92623, 92624, 92627, 92628, 92629, 92630, 92631, 92632, 92633 + }, 2); + + Add(JobIconSetName.Red, new[] + { + 93022, 93023, 93024, 93025, 93026, 93028, 93029, 93031, 93032, 93033, + 93034, 93035, 93036, 93037, 93038, 93039, 93040, 93041, 93079, 93080, + 93081, 93082, 93083, 93084, 93085, 93030, 93086, 93087, 93121, 93122, + 93125, 93123, 93124, 93127, 93128, 93129, 93130, 93131, 93132, 93133 + }, 2); + + Add(JobIconSetName.Purple, new[] + { + 93522, 93523, 93524, 93525, 93526, 93528, 93529, 93531, 93532, 93533, + 93534, 93535, 93536, 93537, 93538, 93539, 93540, 93541, 93579, 93580, + 93581, 93582, 93583, 93584, 93585, 93530, 93586, 93587, 93621, 93622, + 93625, 93623, 93624, 93627, 93628, 93629, 93630, 93631, 93632, 93633 + }, 2); + + Add(JobIconSetName.Blue, new[] + { + 94022, 94023, 94024, 94025, 94026, 94028, 94029, 94031, 94032, 94033, + 94034, 94035, 94036, 94037, 94038, 94039, 94040, 94041, 94079, 94080, + 94081, 94082, 94083, 94084, 94085, 94030, 94086, 94087, 94121, 94122, + 94125, 94123, 94124, 94127, 94128, 94129, 94130, 94131, 94132, 94133 + }, 2); + + Add(JobIconSetName.Green, new[] + { + 94522, 94523, 94524, 94525, 94526, 94528, 94529, 94531, 94532, 94533, + 94534, 94535, 94536, 94537, 94538, 94539, 94540, 94541, 94579, 94580, + 94581, 94582, 94583, 94584, 94585, 94530, 94586, 94587, 94621, 94622, + 94625, 94623, 94624, 94627, 94628, 94629, 94630, 94631, 94632, 94633 + }, 2); + + Add(JobIconSetName.Role, new[] + { + 62581, 62584, 62581, 62584, 62586, 62582, 62502, 62502, 62503, 62504, + 62505, 62506, 62507, 62508, 62509, 62510, 62511, 62512, 62581, 62584, + 62581, 62584, 62586, 62582, 62587, 62587, 62587, 62582, 62584, 62584, + 62586, 62581, 62582, 62584, 62587, 62587, 62581, 62586, 62584, 62582 + }); + } + + private void Add(JobIconSetName id, int[] icons, float scale = 1f) + { + iconSets[id] = new JobIconSet(icons, scale); + } + + public int GetJobIcon(JobIconSetName set, uint jobId) + { + return iconSets[set].GetIcon(jobId); + } + + public float GetJobIconSale(JobIconSetName set) + { + return iconSets[set].IconScale; } } diff --git a/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameEventArgs.cs index ee54336..8134fad 100644 --- a/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameEventArgs.cs +++ b/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameEventArgs.cs @@ -1,20 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.EventArgs; -namespace Pilz.Dalamud.Nameplates.EventArgs +public class AddonNamePlate_SetPlayerNameEventArgs : HookWithResultBaseEventArgs { - 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; } - } + 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 index defcdf6..2683bb3 100644 --- a/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameManagedEventArgs.cs +++ b/Pilz.Dalamud/Nameplates/EventArgs/AddonNamePlate_SetPlayerNameManagedEventArgs.cs @@ -1,43 +1,37 @@ using Dalamud.Game.Text.SeStringHandling; using Pilz.Dalamud.Nameplates.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.EventArgs +namespace Pilz.Dalamud.Nameplates.EventArgs; + +public class AddonNamePlate_SetPlayerNameManagedEventArgs : HookWithResultManagedBaseEventArgs { - public class AddonNamePlate_SetPlayerNameManagedEventArgs : HookWithResultManagedBaseEventArgs + public new AddonNamePlate_SetPlayerNameEventArgs OriginalEventArgs { - public new AddonNamePlate_SetPlayerNameEventArgs OriginalEventArgs - { - get => base.OriginalEventArgs as AddonNamePlate_SetPlayerNameEventArgs; - set => base.OriginalEventArgs = value; - } + 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 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 IsTitleAboveName + { + get => OriginalEventArgs.IsTitleAboveName; + set => OriginalEventArgs.IsTitleAboveName = value; + } - public bool IsTitleVisible - { - get => OriginalEventArgs.IsTitleVisible; - set => OriginalEventArgs.IsTitleVisible = value; - } + public bool IsTitleVisible + { + get => OriginalEventArgs.IsTitleVisible; + set => OriginalEventArgs.IsTitleVisible = value; + } - public int IconID - { - get => OriginalEventArgs.IconID; - set => OriginalEventArgs.IconID = 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 index 2df854d..c2c268e 100644 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookBaseEventArgs.cs +++ b/Pilz.Dalamud/Nameplates/EventArgs/HookBaseEventArgs.cs @@ -1,18 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.EventArgs; -namespace Pilz.Dalamud.Nameplates.EventArgs +public abstract class HookBaseEventArgs { - public abstract class HookBaseEventArgs - { - internal event Action CallOriginal; + internal event Action CallOriginal; - public void Original() - { - CallOriginal?.Invoke(); - } + public void Original() + { + CallOriginal?.Invoke(); } } diff --git a/Pilz.Dalamud/Nameplates/EventArgs/HookManagedBaseEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/HookManagedBaseEventArgs.cs index 71df630..96ff8bc 100644 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookManagedBaseEventArgs.cs +++ b/Pilz.Dalamud/Nameplates/EventArgs/HookManagedBaseEventArgs.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.EventArgs; -namespace Pilz.Dalamud.Nameplates.EventArgs +public abstract class HookManagedBaseEventArgs { - public abstract class HookManagedBaseEventArgs - { - public HookBaseEventArgs OriginalEventArgs { get; internal set; } - } + public HookBaseEventArgs OriginalEventArgs { get; internal set; } } diff --git a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultBaseEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultBaseEventArgs.cs index ad3c130..a086b3d 100644 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultBaseEventArgs.cs +++ b/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultBaseEventArgs.cs @@ -1,21 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.EventArgs; -namespace Pilz.Dalamud.Nameplates.EventArgs +public abstract class HookWithResultBaseEventArgs { - public abstract class HookWithResultBaseEventArgs + internal event Func CallOriginal; + + public TResult Result { get; set; } + + // Call Original based on the given properties + public TResult Original() { - internal event Func CallOriginal; - - public TResult Result { get; set; } - - // Call Original based on the given properties - public TResult Original() - { - return CallOriginal.Invoke(); - } + return CallOriginal.Invoke(); } } diff --git a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultManagedBaseEventArgs.cs b/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultManagedBaseEventArgs.cs index 59993fd..dd509d9 100644 --- a/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultManagedBaseEventArgs.cs +++ b/Pilz.Dalamud/Nameplates/EventArgs/HookWithResultManagedBaseEventArgs.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.EventArgs; -namespace Pilz.Dalamud.Nameplates.EventArgs +public abstract class HookWithResultManagedBaseEventArgs { - public abstract class HookWithResultManagedBaseEventArgs - { - public HookWithResultBaseEventArgs OriginalEventArgs { get; internal set; } - } + public HookWithResultBaseEventArgs OriginalEventArgs { get; internal set; } } diff --git a/Pilz.Dalamud/Nameplates/Model/SafeAddonNameplate.cs b/Pilz.Dalamud/Nameplates/Model/SafeAddonNameplate.cs index 2b8736b..ce8c126 100644 --- a/Pilz.Dalamud/Nameplates/Model/SafeAddonNameplate.cs +++ b/Pilz.Dalamud/Nameplates/Model/SafeAddonNameplate.cs @@ -1,43 +1,35 @@ -using Dalamud.Logging; -using Dalamud.Plugin; -using FFXIVClientStructs.FFXIV.Client.UI; -using System; -using System.Collections.Generic; -using System.Linq; +using FFXIVClientStructs.FFXIV.Client.UI; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.Model +namespace Pilz.Dalamud.Nameplates.Model; + +public class SafeAddonNameplate { - public class SafeAddonNameplate + private readonly DalamudPluginInterface Interface; + + public IntPtr Pointer => PluginServices.GameGui.GetAddonByName("NamePlate", 1); + + public SafeAddonNameplate(DalamudPluginInterface pluginInterface) { - private readonly DalamudPluginInterface Interface; + Interface = pluginInterface; + } - public IntPtr Pointer => PluginServices.GameGui.GetAddonByName("NamePlate", 1); + public unsafe SafeNameplateObject GetNamePlateObject(int index) + { + SafeNameplateObject result = null; - public SafeAddonNameplate(DalamudPluginInterface pluginInterface) + if (Pointer != IntPtr.Zero) { - Interface = pluginInterface; - } + var npObjectArrayPtrPtr = Pointer + Marshal.OffsetOf(typeof(AddonNamePlate), nameof(AddonNamePlate.NamePlateObjectArray)).ToInt32(); + var npObjectArrayPtr = Marshal.ReadIntPtr(npObjectArrayPtrPtr); - public unsafe SafeNameplateObject GetNamePlateObject(int index) - { - SafeNameplateObject result = null; - - if (Pointer != IntPtr.Zero) + if (npObjectArrayPtr != 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); - } + var npObjectPtr = npObjectArrayPtr + Marshal.SizeOf(typeof(AddonNamePlate.NamePlateObject)) * index; + result = new(npObjectPtr, index); } - - return result; } + + return result; } } diff --git a/Pilz.Dalamud/Nameplates/Model/SafeNameplateInfo.cs b/Pilz.Dalamud/Nameplates/Model/SafeNameplateInfo.cs index 5076d63..3cac3df 100644 --- a/Pilz.Dalamud/Nameplates/Model/SafeNameplateInfo.cs +++ b/Pilz.Dalamud/Nameplates/Model/SafeNameplateInfo.cs @@ -1,57 +1,50 @@ using FFXIVClientStructs.FFXIV.Client.System.String; using FFXIVClientStructs.FFXIV.Client.UI; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.Model +namespace Pilz.Dalamud.Nameplates.Model; + +public class SafeNameplateInfo { - public class SafeNameplateInfo + public readonly IntPtr Pointer; + public readonly RaptureAtkModule.NamePlateInfo Data; + + public SafeNameplateInfo(IntPtr pointer) { - public readonly IntPtr Pointer; - public readonly RaptureAtkModule.NamePlateInfo Data; + Pointer = pointer; + Data = Marshal.PtrToStructure(Pointer); + } - 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)); - 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 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 IsPlayerCharacter() => XivApi.IsPlayerCharacter(Data.ObjectID.ObjectID); + //public bool IsPartyMember() => XivApi.IsPartyMember(Data.ObjectID.ObjectID); - //public bool IsPartyMember() => XivApi.IsPartyMember(Data.ObjectID.ObjectID); + //public bool IsAllianceMember() => XivApi.IsAllianceMember(Data.ObjectID.ObjectID); - //public bool IsAllianceMember() => XivApi.IsAllianceMember(Data.ObjectID.ObjectID); + //public uint GetJobID() => GetJobId(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 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); - } + 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 index 6a39ba0..efaf821 100644 --- a/Pilz.Dalamud/Nameplates/Model/SafeNameplateObject.cs +++ b/Pilz.Dalamud/Nameplates/Model/SafeNameplateObject.cs @@ -1,128 +1,121 @@ -using Dalamud.Logging; -using FFXIVClientStructs.FFXIV.Client.UI; +using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Component.GUI; -using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.Model +namespace Pilz.Dalamud.Nameplates.Model; + +public class SafeNameplateObject { - 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) { - public IntPtr Pointer { get; } - public AddonNamePlate.NamePlateObject Data { get; } + Pointer = pointer; + Data = Marshal.PtrToStructure(pointer); + _Index = index; + } - private int _Index; - private SafeNameplateInfo _NamePlateInfo; - - public SafeNameplateObject(IntPtr pointer, int index = -1) + public int Index + { + get { - Pointer = pointer; - Data = Marshal.PtrToStructure(pointer); - _Index = index; - } + int result = _Index; - public int Index - { - get + if (_Index == -1) { - int result = _Index; + var addon = XivApi.GetSafeAddonNamePlate(); + var npObject0 = addon.GetNamePlateObject(0); - if (_Index == -1) + if (npObject0 == null) + result = -1; // NamePlateObject0 was null + else { - var addon = XivApi.GetSafeAddonNamePlate(); - var npObject0 = addon.GetNamePlateObject(0); + var npObjectBase = npObject0.Pointer; + var npObjectSize = Marshal.SizeOf(typeof(AddonNamePlate.NamePlateObject)); + var index = (Pointer.ToInt64() - npObjectBase.ToInt64()) / npObjectSize; - if (npObject0 == null) - result = -1; // NamePlateObject0 was null + if (index < 0 || index >= 50) + result = -2; // NamePlateObject index was out of bounds 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; - } + 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); + 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/Model/StatusIcons.cs b/Pilz.Dalamud/Nameplates/Model/StatusIcons.cs index 89d7448..f32493b 100644 --- a/Pilz.Dalamud/Nameplates/Model/StatusIcons.cs +++ b/Pilz.Dalamud/Nameplates/Model/StatusIcons.cs @@ -1,31 +1,25 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.Model +namespace Pilz.Dalamud.Nameplates.Model; + +[JsonConverter(typeof(StringEnumConverter))] +public enum StatusIcons { - [JsonConverter(typeof(StringEnumConverter))] - public enum StatusIcons - { - Disconnecting = 061503, - InDuty = 061506, - ViewingCutscene = 061508, - Busy = 061509, - Idle = 061511, - DutyFinder = 061517, - PartyLeader = 061521, - PartyMember = 061522, - RolePlaying = 061545, - GroupPose = 061546, - NewAdventurer = 061523, - Mentor = 061540, - MentorPvE = 061542, - MentorCrafting = 061543, - MentorPvP = 061544, - Returner = 061547, - } + Disconnecting = 061503, + InDuty = 061506, + ViewingCutscene = 061508, + Busy = 061509, + Idle = 061511, + DutyFinder = 061517, + PartyLeader = 061521, + PartyMember = 061522, + RolePlaying = 061545, + GroupPose = 061546, + NewAdventurer = 061523, + Mentor = 061540, + MentorPvE = 061542, + MentorCrafting = 061543, + MentorPvP = 061544, + Returner = 061547, } diff --git a/Pilz.Dalamud/Nameplates/NameplateHooks.cs b/Pilz.Dalamud/Nameplates/NameplateHooks.cs index cf28548..5865b83 100644 --- a/Pilz.Dalamud/Nameplates/NameplateHooks.cs +++ b/Pilz.Dalamud/Nameplates/NameplateHooks.cs @@ -1,240 +1,230 @@ using Dalamud.Hooking; -using Pilz.Dalamud.Nameplates.EventArgs; using Dalamud.Utility.Signatures; -using ImGuiNET; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Pilz.Dalamud.Nameplates.EventArgs; using Pilz.Dalamud.Nameplates.Model; -using Lumina.Excel.GeneratedSheets; -using System.Xml.Linq; -using Dalamud.Plugin.Services; -namespace Pilz.Dalamud.Nameplates +namespace Pilz.Dalamud.Nameplates; + +public class NameplateHooks : IDisposable { - 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 { - /// - /// 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 { - get - { - var isValid = true; + var isValid = true; - isValid &= IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour); + 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; + 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 index acf4cfb..84cf339 100644 --- a/Pilz.Dalamud/Nameplates/NameplateManager.cs +++ b/Pilz.Dalamud/Nameplates/NameplateManager.cs @@ -1,82 +1,77 @@ -using Dalamud.Hooking; -using Pilz.Dalamud.Nameplates.EventArgs; -using Dalamud.Utility.Signatures; -using FFXIVClientStructs.FFXIV.Client.UI; -using System.Runtime.InteropServices; -using Dalamud.Game.ClientState.Objects.Types; +using FFXIVClientStructs.FFXIV.Client.UI; using Pilz.Dalamud.Nameplates.Model; +using System.Runtime.InteropServices; -namespace Pilz.Dalamud.Nameplates +namespace Pilz.Dalamud.Nameplates; + +public class NameplateManager : IDisposable { - 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() { - /// - /// Provides events that you can hook to. - /// - public NameplateHooks Hooks { get; init; } = new(); + Hooks.Initialize(); + } - /// - /// 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; + ~NameplateManager() + { + Dispose(); + } - /// - /// Creates a new instance of the NameplateManager. - /// - public NameplateManager() + 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 { - Hooks.Initialize(); + var framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance(); + nameplateInfoArrayPtr = new IntPtr(&framework->GetUiModule()->GetRaptureAtkModule()->NamePlateInfoArray); } - ~NameplateManager() - { - Dispose(); - } + // 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); - 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; - } + // 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 index bd935b2..40064d8 100644 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateChanges.cs +++ b/Pilz.Dalamud/Nameplates/Tools/NameplateChanges.cs @@ -1,60 +1,54 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Pilz.Dalamud.Nameplates.EventArgs; +using Pilz.Dalamud.Nameplates.EventArgs; using Pilz.Dalamud.Tools.Strings; -namespace Pilz.Dalamud.Nameplates.Tools +namespace Pilz.Dalamud.Nameplates.Tools; + +public class NameplateChanges { - public class NameplateChanges + private readonly Dictionary changes = []; + + public NameplateChanges() { - private readonly Dictionary changes = new(); + changes.Add(NameplateElements.Title, new()); + changes.Add(NameplateElements.Name, new()); + changes.Add(NameplateElements.FreeCompany, new()); + } - 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; + } - 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 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 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); - } + /// + /// 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/NameplateChangesProps.cs b/Pilz.Dalamud/Nameplates/Tools/NameplateChangesProps.cs index 201bcf5..b8427f3 100644 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateChangesProps.cs +++ b/Pilz.Dalamud/Nameplates/Tools/NameplateChangesProps.cs @@ -1,25 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.Tools; -namespace Pilz.Dalamud.Nameplates.Tools +public class NameplateChangesProps { - public class NameplateChangesProps + /// + /// All the changes to the nameplate that should be made. + /// + public NameplateChanges Changes { get; set; } + + public NameplateChangesProps() { - /// - /// All the changes to the nameplate that should be made. - /// - public NameplateChanges Changes { get; set; } + } - public NameplateChangesProps() - { - } - - public NameplateChangesProps(NameplateChanges changes) : this() - { - Changes = changes; - } + public NameplateChangesProps(NameplateChanges changes) : this() + { + Changes = changes; } } diff --git a/Pilz.Dalamud/Nameplates/Tools/NameplateElements.cs b/Pilz.Dalamud/Nameplates/Tools/NameplateElements.cs index 0a15cf9..a327334 100644 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateElements.cs +++ b/Pilz.Dalamud/Nameplates/Tools/NameplateElements.cs @@ -1,15 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.Tools; -namespace Pilz.Dalamud.Nameplates.Tools +public enum NameplateElements { - public enum NameplateElements - { - Name, - Title, - FreeCompany - } + Name, + Title, + FreeCompany } diff --git a/Pilz.Dalamud/Nameplates/Tools/NameplateUpdateFactory.cs b/Pilz.Dalamud/Nameplates/Tools/NameplateUpdateFactory.cs index ebc9518..0a00ed0 100644 --- a/Pilz.Dalamud/Nameplates/Tools/NameplateUpdateFactory.cs +++ b/Pilz.Dalamud/Nameplates/Tools/NameplateUpdateFactory.cs @@ -1,52 +1,45 @@ -using Dalamud.Game.Text.SeStringHandling; -using Dalamud.Game.Text.SeStringHandling.Payloads; +using Dalamud.Game.Text.SeStringHandling.Payloads; using Pilz.Dalamud.ActivityContexts; using Pilz.Dalamud.Nameplates.Model; using Pilz.Dalamud.Tools; using Pilz.Dalamud.Tools.Strings; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.Tools +namespace Pilz.Dalamud.Nameplates.Tools; + +public static class NameplateUpdateFactory { - public static class NameplateUpdateFactory + public static void ApplyNameplateChanges(NameplateChangesProps props) { - public static void ApplyNameplateChanges(NameplateChangesProps props) + foreach (NameplateElements element in Enum.GetValues(typeof(NameplateElements))) { - 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; + 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/Nameplates/Tools/StatusIconPriorizer.cs b/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizer.cs index 2ae64c3..26dffce 100644 --- a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizer.cs +++ b/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizer.cs @@ -1,67 +1,60 @@ -using Lumina.Excel.GeneratedSheets; -using Pilz.Dalamud.ActivityContexts; +using Pilz.Dalamud.ActivityContexts; using Pilz.Dalamud.Nameplates.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.Tools +namespace Pilz.Dalamud.Nameplates.Tools; + +public class StatusIconPriorizer { - public class StatusIconPriorizer + private static StatusIconPriorizerSettings DefaultSettings { get; } = new(); + public StatusIconPriorizerSettings Settings { get; init; } + + public StatusIconPriorizer() : this(DefaultSettings) { - private static StatusIconPriorizerSettings DefaultSettings { get; } = new(); - public StatusIconPriorizerSettings Settings { get; init; } + } - public StatusIconPriorizer() : this(DefaultSettings) + public StatusIconPriorizer(StatusIconPriorizerSettings settings) + { + Settings = settings; + } + + /// + /// Check for an icon that should take priority over the job icon, + /// taking into account whether or not the player is in a duty. + /// + /// The incoming icon id that is being overwritten by the plugin. + /// + /// Whether a priority icon was found. + public bool IsPriorityIcon(int iconId, ActivityContext activityContext) + { + bool isPrioIcon; + + if (!Settings.UsePriorizedIcons && iconId != (int)StatusIcons.Disconnecting && iconId != (int)StatusIcons.Disconnecting + 50) + isPrioIcon = false; + else { + // Select which set of priority icons to use based on whether we're in a duty + // In the future, there can be a third list used when in combat + var priorityIcons = GetPriorityIcons(activityContext); + + // Determine whether the incoming icon should take priority over the job icon + // Check the id plus 50 as that's an alternately sized version + isPrioIcon = priorityIcons.Contains(iconId) || priorityIcons.Contains(iconId + 50); } - public StatusIconPriorizer(StatusIconPriorizerSettings settings) - { - Settings = settings; - } + return isPrioIcon; + } - /// - /// Check for an icon that should take priority over the job icon, - /// taking into account whether or not the player is in a duty. - /// - /// The incoming icon id that is being overwritten by the plugin. - /// - /// Whether a priority icon was found. - public bool IsPriorityIcon(int iconId, ActivityContext activityContext) - { - bool isPrioIcon; + private IEnumerable GetPriorityIcons(ActivityContext activityContext) + { + StatusIconPriorizerConditionSets set; - if (!Settings.UsePriorizedIcons && iconId != (int)StatusIcons.Disconnecting && iconId != (int)StatusIcons.Disconnecting + 50) - isPrioIcon = false; - else - { - // Select which set of priority icons to use based on whether we're in a duty - // In the future, there can be a third list used when in combat - var priorityIcons = GetPriorityIcons(activityContext); + if (activityContext.ZoneType == ZoneType.Foray) + set = StatusIconPriorizerConditionSets.InForay; + else if (activityContext.IsInDuty) + set = StatusIconPriorizerConditionSets.InDuty; + else + set = StatusIconPriorizerConditionSets.Overworld; - // Determine whether the incoming icon should take priority over the job icon - // Check the id plus 50 as that's an alternately sized version - isPrioIcon = priorityIcons.Contains(iconId) || priorityIcons.Contains(iconId + 50); - } - - return isPrioIcon; - } - - private IEnumerable GetPriorityIcons(ActivityContext activityContext) - { - StatusIconPriorizerConditionSets set; - - if (activityContext.ZoneType == ZoneType.Foray) - set = StatusIconPriorizerConditionSets.InForay; - else if (activityContext.IsInDuty) - set = StatusIconPriorizerConditionSets.InDuty; - else - set = StatusIconPriorizerConditionSets.Overworld; - - return Settings.GetConditionSet(set).Select(n => (int)n); - } + return Settings.GetConditionSet(set).Select(n => (int)n); } } diff --git a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerConditionSets.cs b/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerConditionSets.cs index 6c78cc7..fd47ac7 100644 --- a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerConditionSets.cs +++ b/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerConditionSets.cs @@ -1,15 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Nameplates.Tools; -namespace Pilz.Dalamud.Nameplates.Tools +public enum StatusIconPriorizerConditionSets { - public enum StatusIconPriorizerConditionSets - { - Overworld, - InDuty, - InForay - } + Overworld, + InDuty, + InForay } diff --git a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerSettings.cs b/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerSettings.cs index a5bfe34..7fef580 100644 --- a/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerSettings.cs +++ b/Pilz.Dalamud/Nameplates/Tools/StatusIconPriorizerSettings.cs @@ -1,110 +1,103 @@ using Newtonsoft.Json; -using Pilz.Dalamud.ActivityContexts; using Pilz.Dalamud.Nameplates.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Nameplates.Tools +namespace Pilz.Dalamud.Nameplates.Tools; + +public class StatusIconPriorizerSettings { - public class StatusIconPriorizerSettings + [JsonProperty("IconConditionSets")] + private Dictionary> iconConditionSets = []; + public bool UsePriorizedIcons { get; set; } = true; + + [JsonConstructor] + private StatusIconPriorizerSettings(JsonConstructorAttribute dummy) { - [JsonProperty("IconConditionSets")] - private Dictionary> iconConditionSets = new(); - public bool UsePriorizedIcons { get; set; } = true; + } - [JsonConstructor] - private StatusIconPriorizerSettings(JsonConstructorAttribute dummy) - { - } + public StatusIconPriorizerSettings() : this(false) + { + } - public StatusIconPriorizerSettings() : this(false) - { - } + public StatusIconPriorizerSettings(bool fillWithDefaultSettings) + { + foreach (StatusIconPriorizerConditionSets set in Enum.GetValues(typeof(StatusIconPriorizerConditionSets))) + iconConditionSets.Add(set, []); - public StatusIconPriorizerSettings(bool fillWithDefaultSettings) - { - foreach (StatusIconPriorizerConditionSets set in Enum.GetValues(typeof(StatusIconPriorizerConditionSets))) - iconConditionSets.Add(set, new List()); - - if (fillWithDefaultSettings) - FillWithDefaultSettings(); - } - - public List GetConditionSet(StatusIconPriorizerConditionSets set) - { - return iconConditionSets[set]; - } - - public void ResetToEmpty() - { - foreach (var kvp in iconConditionSets) - kvp.Value.Clear(); - } - - public void ResetToDefault() - { - ResetToEmpty(); + if (fillWithDefaultSettings) FillWithDefaultSettings(); - } + } - private void FillWithDefaultSettings() + public List GetConditionSet(StatusIconPriorizerConditionSets set) + { + return iconConditionSets[set]; + } + + public void ResetToEmpty() + { + foreach (var kvp in iconConditionSets) + kvp.Value.Clear(); + } + + public void ResetToDefault() + { + ResetToEmpty(); + FillWithDefaultSettings(); + } + + private void FillWithDefaultSettings() + { + var setOverworld = GetConditionSet(StatusIconPriorizerConditionSets.Overworld); + setOverworld.AddRange(new[] { - var setOverworld = GetConditionSet(StatusIconPriorizerConditionSets.Overworld); - setOverworld.AddRange(new[] - { - StatusIcons.Disconnecting, // Disconnecting - StatusIcons.InDuty, // In Duty - StatusIcons.ViewingCutscene, // Viewing Cutscene - StatusIcons.Busy, // Busy - StatusIcons.Idle, // Idle - StatusIcons.DutyFinder, // Duty Finder - StatusIcons.PartyLeader, // Party Leader - StatusIcons.PartyMember, // Party Member - StatusIcons.RolePlaying, // Role Playing - StatusIcons.GroupPose, // Group Pose - StatusIcons.Mentor, - StatusIcons.MentorCrafting, - StatusIcons.MentorPvE, - StatusIcons.MentorPvP, - StatusIcons.Returner, - StatusIcons.NewAdventurer, - }); + StatusIcons.Disconnecting, // Disconnecting + StatusIcons.InDuty, // In Duty + StatusIcons.ViewingCutscene, // Viewing Cutscene + StatusIcons.Busy, // Busy + StatusIcons.Idle, // Idle + StatusIcons.DutyFinder, // Duty Finder + StatusIcons.PartyLeader, // Party Leader + StatusIcons.PartyMember, // Party Member + StatusIcons.RolePlaying, // Role Playing + StatusIcons.GroupPose, // Group Pose + StatusIcons.Mentor, + StatusIcons.MentorCrafting, + StatusIcons.MentorPvE, + StatusIcons.MentorPvP, + StatusIcons.Returner, + StatusIcons.NewAdventurer, + }); - var setInDuty = GetConditionSet(StatusIconPriorizerConditionSets.InDuty); - setInDuty.AddRange(new[] - { - StatusIcons.Disconnecting, // Disconnecting - StatusIcons.ViewingCutscene, // Viewing Cutscene - StatusIcons.Idle, // Idle - StatusIcons.GroupPose, // Group Pose - StatusIcons.Mentor, - StatusIcons.MentorCrafting, - StatusIcons.MentorPvE, - StatusIcons.MentorPvP, - StatusIcons.Returner, - StatusIcons.NewAdventurer, - }); + var setInDuty = GetConditionSet(StatusIconPriorizerConditionSets.InDuty); + setInDuty.AddRange(new[] + { + StatusIcons.Disconnecting, // Disconnecting + StatusIcons.ViewingCutscene, // Viewing Cutscene + StatusIcons.Idle, // Idle + StatusIcons.GroupPose, // Group Pose + StatusIcons.Mentor, + StatusIcons.MentorCrafting, + StatusIcons.MentorPvE, + StatusIcons.MentorPvP, + StatusIcons.Returner, + StatusIcons.NewAdventurer, + }); - var setInForay = GetConditionSet(StatusIconPriorizerConditionSets.InForay); - setInForay.AddRange(new[] - { - // This allows you to see which players don't have a party - StatusIcons.InDuty, // In Duty + var setInForay = GetConditionSet(StatusIconPriorizerConditionSets.InForay); + setInForay.AddRange(new[] + { + // This allows you to see which players don't have a party + StatusIcons.InDuty, // In Duty - StatusIcons.Disconnecting, // Disconnecting - StatusIcons.ViewingCutscene, // Viewing Cutscene - StatusIcons.Idle, // Idle - StatusIcons.GroupPose, // Group Pose - StatusIcons.Mentor, - StatusIcons.MentorCrafting, - StatusIcons.MentorPvE, - StatusIcons.MentorPvP, - StatusIcons.Returner, - StatusIcons.NewAdventurer, - }); - } + StatusIcons.Disconnecting, // Disconnecting + StatusIcons.ViewingCutscene, // Viewing Cutscene + StatusIcons.Idle, // Idle + StatusIcons.GroupPose, // Group Pose + StatusIcons.Mentor, + StatusIcons.MentorCrafting, + StatusIcons.MentorPvE, + StatusIcons.MentorPvP, + StatusIcons.Returner, + StatusIcons.NewAdventurer, + }); } } diff --git a/Pilz.Dalamud/PluginServices.cs b/Pilz.Dalamud/PluginServices.cs index 21b0e80..9d28242 100644 --- a/Pilz.Dalamud/PluginServices.cs +++ b/Pilz.Dalamud/PluginServices.cs @@ -1,30 +1,20 @@ -using Dalamud.Data; -using Dalamud.Game.ClientState; -using Dalamud.Game.ClientState.Objects; -using Dalamud.Game.Gui; -using Dalamud.IoC; +using Dalamud.IoC; using Dalamud.Plugin; using Dalamud.Plugin.Services; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud +namespace Pilz.Dalamud; + +public class PluginServices { - 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; } = 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; - public static void Initialize(IDalamudPluginInterface dalamudPluginInterface) - { - dalamudPluginInterface.Create(); - } + public static void Initialize(IDalamudPluginInterface dalamudPluginInterface) + { + dalamudPluginInterface.Create(); } } diff --git a/Pilz.Dalamud/Tools/StatusIconFontConverter.cs b/Pilz.Dalamud/Tools/StatusIconFontConverter.cs index d5ecff2..3cca543 100644 --- a/Pilz.Dalamud/Tools/StatusIconFontConverter.cs +++ b/Pilz.Dalamud/Tools/StatusIconFontConverter.cs @@ -1,41 +1,35 @@ using Dalamud.Game.Text.SeStringHandling; using Pilz.Dalamud.Nameplates.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Tools +namespace Pilz.Dalamud.Tools; + +public static class StatusIconFontConverter { - public static class StatusIconFontConverter + public static StatusIcons? GetStatusIconFromBitmapFontIcon(BitmapFontIcon fontIcon) { - public static StatusIcons? GetStatusIconFromBitmapFontIcon(BitmapFontIcon fontIcon) + return fontIcon switch { - return fontIcon switch - { - BitmapFontIcon.NewAdventurer => StatusIcons.NewAdventurer, - BitmapFontIcon.Mentor => StatusIcons.Mentor, - BitmapFontIcon.MentorPvE => StatusIcons.MentorPvE, - BitmapFontIcon.MentorCrafting => StatusIcons.MentorCrafting, - BitmapFontIcon.MentorPvP => StatusIcons.MentorPvP, - BitmapFontIcon.Returner => StatusIcons.Returner, - _ => null - }; - } + BitmapFontIcon.NewAdventurer => StatusIcons.NewAdventurer, + BitmapFontIcon.Mentor => StatusIcons.Mentor, + BitmapFontIcon.MentorPvE => StatusIcons.MentorPvE, + BitmapFontIcon.MentorCrafting => StatusIcons.MentorCrafting, + BitmapFontIcon.MentorPvP => StatusIcons.MentorPvP, + BitmapFontIcon.Returner => StatusIcons.Returner, + _ => null + }; + } - public static BitmapFontIcon? GetBitmapFontIconFromStatusIcon(StatusIcons icon) + public static BitmapFontIcon? GetBitmapFontIconFromStatusIcon(StatusIcons icon) + { + return icon switch { - return icon switch - { - StatusIcons.NewAdventurer => BitmapFontIcon.NewAdventurer, - StatusIcons.Mentor => BitmapFontIcon.Mentor, - StatusIcons.MentorPvE => BitmapFontIcon.MentorPvE, - StatusIcons.MentorCrafting => BitmapFontIcon.MentorCrafting, - StatusIcons.MentorPvP => BitmapFontIcon.MentorPvP, - StatusIcons.Returner => BitmapFontIcon.Returner, - _ => null - }; - } + StatusIcons.NewAdventurer => BitmapFontIcon.NewAdventurer, + StatusIcons.Mentor => BitmapFontIcon.Mentor, + StatusIcons.MentorPvE => BitmapFontIcon.MentorPvE, + StatusIcons.MentorCrafting => BitmapFontIcon.MentorCrafting, + StatusIcons.MentorPvP => BitmapFontIcon.MentorPvP, + StatusIcons.Returner => BitmapFontIcon.Returner, + _ => null + }; } } diff --git a/Pilz.Dalamud/Tools/Strings/StringChange.cs b/Pilz.Dalamud/Tools/Strings/StringChange.cs index f6a019e..072c350 100644 --- a/Pilz.Dalamud/Tools/Strings/StringChange.cs +++ b/Pilz.Dalamud/Tools/Strings/StringChange.cs @@ -1,24 +1,18 @@ using Dalamud.Game.Text.SeStringHandling; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Tools.Strings +namespace Pilz.Dalamud.Tools.Strings; + +public class StringChange { - public class StringChange - { - /// - /// The payloads to use for inserting/replacing. - /// - public List Payloads { get; init; } = new(); + /// + /// The payloads to use for inserting/replacing. + /// + public List Payloads { get; init; } = []; - /// - /// Defines if only one anchor payload should be used, if using anchor payloads. - /// With this true the single anchor payload will be used in StringUpdateFactory instead of the anchor payload list. - /// Not needed to be true for the most cases. - /// - public bool ForceUsingSingleAnchorPayload { get; set; } = false; - } + /// + /// Defines if only one anchor payload should be used, if using anchor payloads. + /// With this true the single anchor payload will be used in StringUpdateFactory instead of the anchor payload list. + /// Not needed to be true for the most cases. + /// + public bool ForceUsingSingleAnchorPayload { get; set; } = false; } diff --git a/Pilz.Dalamud/Tools/Strings/StringChanges.cs b/Pilz.Dalamud/Tools/Strings/StringChanges.cs index 1ae85c0..b34e9f8 100644 --- a/Pilz.Dalamud/Tools/Strings/StringChanges.cs +++ b/Pilz.Dalamud/Tools/Strings/StringChanges.cs @@ -1,40 +1,32 @@ -using Dalamud.Game.Text.SeStringHandling; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Tools.Strings; -namespace Pilz.Dalamud.Tools.Strings +public class StringChanges { - public class StringChanges + private readonly Dictionary changes = []; + + public StringChanges() { - private readonly Dictionary changes = new(); + changes.Add(StringPosition.Before, new StringChange()); + changes.Add(StringPosition.After, new StringChange()); + changes.Add(StringPosition.Replace, new StringChange()); + } - public StringChanges() - { - changes.Add(StringPosition.Before, new StringChange()); - changes.Add(StringPosition.After, new StringChange()); - changes.Add(StringPosition.Replace, new StringChange()); - } + /// + /// Gets a change of the position of your choice where you can add your payloads. + /// + /// The position of your choice. + /// + public StringChange GetChange(StringPosition position) + { + return changes[position]; + } - /// - /// Gets a change of the position of your choice where you can add your payloads. - /// - /// The position of your choice. - /// - public StringChange GetChange(StringPosition position) - { - return changes[position]; - } - - /// - /// Checks if there is any string change listed. - /// - /// - public bool Any() - { - return changes.Sum(n => n.Value.Payloads.Count) != 0; - } + /// + /// Checks if there is any string change listed. + /// + /// + public bool Any() + { + return changes.Sum(n => n.Value.Payloads.Count) != 0; } } diff --git a/Pilz.Dalamud/Tools/Strings/StringChangesProps.cs b/Pilz.Dalamud/Tools/Strings/StringChangesProps.cs index d0cd253..6b59a8e 100644 --- a/Pilz.Dalamud/Tools/Strings/StringChangesProps.cs +++ b/Pilz.Dalamud/Tools/Strings/StringChangesProps.cs @@ -1,31 +1,24 @@ -using Dalamud.Game.ClientState.Objects.Types; -using Dalamud.Game.Text.SeStringHandling; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Dalamud.Game.Text.SeStringHandling; -namespace Pilz.Dalamud.Tools.Strings +namespace Pilz.Dalamud.Tools.Strings; + +public class StringChangesProps { - public class StringChangesProps - { - /// - /// The string where the changes should be applied. - /// - public SeString Destination { get; set; } - /// - /// The changes that should be applied to the destination. - /// - public StringChanges StringChanges { get; set; } = new(); - /// - /// Payloads to use as anchor where the changes should be applied to. - /// - public List AnchorPayloads { get; set; } = new(); - /// - /// A single payload to use as anchor where the changes should be applied to. - /// This property will only be used if StringChange.ForceSingleAnchorPayload is true. - /// - public Payload AnchorPayload { get; set; } - } + /// + /// The string where the changes should be applied. + /// + public SeString Destination { get; set; } + /// + /// The changes that should be applied to the destination. + /// + public StringChanges StringChanges { get; set; } = new(); + /// + /// Payloads to use as anchor where the changes should be applied to. + /// + public List AnchorPayloads { get; set; } = []; + /// + /// A single payload to use as anchor where the changes should be applied to. + /// This property will only be used if StringChange.ForceSingleAnchorPayload is true. + /// + public Payload AnchorPayload { get; set; } } diff --git a/Pilz.Dalamud/Tools/Strings/StringPosition.cs b/Pilz.Dalamud/Tools/Strings/StringPosition.cs index 46a05db..8bc4391 100644 --- a/Pilz.Dalamud/Tools/Strings/StringPosition.cs +++ b/Pilz.Dalamud/Tools/Strings/StringPosition.cs @@ -1,15 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Pilz.Dalamud.Tools.Strings; -namespace Pilz.Dalamud.Tools.Strings +public enum StringPosition { - public enum StringPosition - { - Before, - After, - Replace - } + Before, + After, + Replace } diff --git a/Pilz.Dalamud/Tools/Strings/StringUpdateFactory.cs b/Pilz.Dalamud/Tools/Strings/StringUpdateFactory.cs index 3c240f5..7fb74fc 100644 --- a/Pilz.Dalamud/Tools/Strings/StringUpdateFactory.cs +++ b/Pilz.Dalamud/Tools/Strings/StringUpdateFactory.cs @@ -1,132 +1,125 @@ using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling.Payloads; -using Lumina.Text; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Pilz.Dalamud.Tools.Strings +namespace Pilz.Dalamud.Tools.Strings; + +public static class StringUpdateFactory { - public static class StringUpdateFactory + public static void ApplyStringChanges(StringChangesProps props) { - public static void ApplyStringChanges(StringChangesProps props) + if (props.StringChanges != null && props.StringChanges.Any()) { - if (props.StringChanges != null && props.StringChanges.Any()) + var seString = props.Destination; + List stringPositionsOrdered = GetOrderedStringPositions(props); + + foreach (var stringPosition in stringPositionsOrdered) { - var seString = props.Destination; - List stringPositionsOrdered = GetOrderedStringPositions(props); - - foreach (var stringPosition in stringPositionsOrdered) + var stringChange = props.StringChanges.GetChange(stringPosition); + if (stringChange != null && stringChange.Payloads.Any()) { - var stringChange = props.StringChanges.GetChange(stringPosition); - if (stringChange != null && stringChange.Payloads.Any()) + AddSpacesBetweenTextPayloads(stringChange.Payloads, stringPosition); + + if (stringPosition == StringPosition.Before) { - AddSpacesBetweenTextPayloads(stringChange.Payloads, stringPosition); + Payload anchorFirst = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.FirstOrDefault(); - if (stringPosition == StringPosition.Before) + if (anchorFirst != null) { - Payload anchorFirst = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.FirstOrDefault(); - - if (anchorFirst != null) - { - var anchorPayloadIndex = seString.Payloads.IndexOf(anchorFirst); - seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads); - } - else - seString.Payloads.InsertRange(0, stringChange.Payloads); + var anchorPayloadIndex = seString.Payloads.IndexOf(anchorFirst); + seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads); } - else if (stringPosition == StringPosition.After) - { - Payload anchorLast = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.LastOrDefault(); + else + seString.Payloads.InsertRange(0, stringChange.Payloads); + } + else if (stringPosition == StringPosition.After) + { + Payload anchorLast = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.LastOrDefault(); - if (anchorLast != null) - { - var anchorPayloadIndex = seString.Payloads.IndexOf(anchorLast); - seString.Payloads.InsertRange(anchorPayloadIndex + 1, stringChange.Payloads); - } - else - seString.Payloads.AddRange(stringChange.Payloads); + if (anchorLast != null) + { + var anchorPayloadIndex = seString.Payloads.IndexOf(anchorLast); + seString.Payloads.InsertRange(anchorPayloadIndex + 1, stringChange.Payloads); } - else if (stringPosition == StringPosition.Replace) - { - Payload anchorReplace = props.AnchorPayload; + else + seString.Payloads.AddRange(stringChange.Payloads); + } + else if (stringPosition == StringPosition.Replace) + { + Payload anchorReplace = props.AnchorPayload; - if (anchorReplace != null) - { - var anchorPayloadIndex = seString.Payloads.IndexOf(anchorReplace); - seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads); - seString.Remove(anchorReplace); - } - else - { - seString.Payloads.Clear(); - seString.Payloads.AddRange(stringChange.Payloads); - } + if (anchorReplace != null) + { + var anchorPayloadIndex = seString.Payloads.IndexOf(anchorReplace); + seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads); + seString.Remove(anchorReplace); + } + else + { + seString.Payloads.Clear(); + seString.Payloads.AddRange(stringChange.Payloads); } } } } } - - private static void AddSpacesBetweenTextPayloads(List payloads, StringPosition tagPosition) - { - if (payloads != null && payloads.Any()) - { - var indicesToInsertSpacesAt = new List(); - var lastTextPayloadIndex = -1; - - static TextPayload getNewTextPayload() => new(" "); - - foreach (var payload in payloads.Reverse()) - { - if (payload is IconPayload iconPayload) - lastTextPayloadIndex = -1; - else if (payload is TextPayload textPayload) - { - if (lastTextPayloadIndex != -1) - indicesToInsertSpacesAt.Add(payloads.IndexOf(textPayload) + 1); - lastTextPayloadIndex = payloads.IndexOf(textPayload); - } - } - - foreach (var indexToInsertSpaceAt in indicesToInsertSpacesAt) - payloads.Insert(indexToInsertSpaceAt, getNewTextPayload()); - - // Decide whether to add a space to the end - if (tagPosition == StringPosition.Before) - { - var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload); - if (significantPayloads.LastOrDefault() is TextPayload) - payloads.Add(getNewTextPayload()); - } - // Decide whether to add a space to the beginning - else if (tagPosition == StringPosition.After) - { - var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload); - if (significantPayloads.FirstOrDefault() is TextPayload) - payloads.Insert(0, getNewTextPayload()); - } - } - } - - private static List GetOrderedStringPositions(StringChangesProps props) - { - var tagPositionsOrdered = new List(); - - // If there's no anchor payload, do replaces first so that befores and afters are based on the replaced data - if (props.AnchorPayloads == null || !props.AnchorPayloads.Any()) - tagPositionsOrdered.Add(StringPosition.Replace); - - tagPositionsOrdered.Add(StringPosition.Before); - tagPositionsOrdered.Add(StringPosition.After); - - // If there is an anchor payload, do replaces last so that we still know which payload needs to be removed - if (props.AnchorPayloads != null && props.AnchorPayloads.Any()) - tagPositionsOrdered.Add(StringPosition.Replace); - - return tagPositionsOrdered; - } + } + + private static void AddSpacesBetweenTextPayloads(List payloads, StringPosition tagPosition) + { + if (payloads != null && payloads.Any()) + { + var indicesToInsertSpacesAt = new List(); + var lastTextPayloadIndex = -1; + + static TextPayload getNewTextPayload() => new(" "); + + foreach (var payload in payloads.Reverse()) + { + if (payload is IconPayload iconPayload) + lastTextPayloadIndex = -1; + else if (payload is TextPayload textPayload) + { + if (lastTextPayloadIndex != -1) + indicesToInsertSpacesAt.Add(payloads.IndexOf(textPayload) + 1); + lastTextPayloadIndex = payloads.IndexOf(textPayload); + } + } + + foreach (var indexToInsertSpaceAt in indicesToInsertSpacesAt) + payloads.Insert(indexToInsertSpaceAt, getNewTextPayload()); + + // Decide whether to add a space to the end + if (tagPosition == StringPosition.Before) + { + var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload); + if (significantPayloads.LastOrDefault() is TextPayload) + payloads.Add(getNewTextPayload()); + } + // Decide whether to add a space to the beginning + else if (tagPosition == StringPosition.After) + { + var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload); + if (significantPayloads.FirstOrDefault() is TextPayload) + payloads.Insert(0, getNewTextPayload()); + } + } + } + + private static List GetOrderedStringPositions(StringChangesProps props) + { + var tagPositionsOrdered = new List(); + + // If there's no anchor payload, do replaces first so that befores and afters are based on the replaced data + if (props.AnchorPayloads == null || !props.AnchorPayloads.Any()) + tagPositionsOrdered.Add(StringPosition.Replace); + + tagPositionsOrdered.Add(StringPosition.Before); + tagPositionsOrdered.Add(StringPosition.After); + + // If there is an anchor payload, do replaces last so that we still know which payload needs to be removed + if (props.AnchorPayloads != null && props.AnchorPayloads.Any()) + tagPositionsOrdered.Add(StringPosition.Replace); + + return tagPositionsOrdered; } } diff --git a/Pilz.Dalamud/XivApi.cs b/Pilz.Dalamud/XivApi.cs index 5d2a35c..45d8c3e 100644 --- a/Pilz.Dalamud/XivApi.cs +++ b/Pilz.Dalamud/XivApi.cs @@ -1,39 +1,33 @@ using FFXIVClientStructs.FFXIV.Client.System.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Pilz.Dalamud.Nameplates.Model; -namespace Pilz.Dalamud +namespace Pilz.Dalamud; + +public class XivApi { - public class XivApi + private static IntPtr _RaptureAtkModulePtr = IntPtr.Zero; + + public static IntPtr RaptureAtkModulePtr { - private static IntPtr _RaptureAtkModulePtr = IntPtr.Zero; - - public static IntPtr RaptureAtkModulePtr + get { - get + if (_RaptureAtkModulePtr == IntPtr.Zero) { - if (_RaptureAtkModulePtr == IntPtr.Zero) + unsafe { - unsafe - { - var framework = Framework.Instance(); - var uiModule = framework->GetUiModule(); + var framework = Framework.Instance(); + var uiModule = framework->GetUiModule(); - _RaptureAtkModulePtr = new IntPtr(uiModule->GetRaptureAtkModule()); - } + _RaptureAtkModulePtr = new IntPtr(uiModule->GetRaptureAtkModule()); } - - return _RaptureAtkModulePtr; } - } - public static SafeAddonNameplate GetSafeAddonNamePlate() - { - return new(PluginServices.PluginInterface); + return _RaptureAtkModulePtr; } } + + public static SafeAddonNameplate GetSafeAddonNamePlate() + { + return new(PluginServices.PluginInterface); + } }