diff --git a/PlayerTags/Configuration/PluginConfiguration.cs b/PlayerTags/Configuration/PluginConfiguration.cs index e04432f..8be1661 100644 --- a/PlayerTags/Configuration/PluginConfiguration.cs +++ b/PlayerTags/Configuration/PluginConfiguration.cs @@ -23,6 +23,7 @@ namespace PlayerTags.Configuration public int RootVersion { get; private set; } = DEFAULT_CONFIG_VERSION; public int Version { get; set; } = DEFAULT_CONFIG_VERSION; public bool IsVisible = false; + public bool EnabledGlobal = true; [JsonProperty("GeneralOptionsV2")] public Dictionary GeneralOptions = new() diff --git a/PlayerTags/Features/ChatTagTargetFeature.cs b/PlayerTags/Features/ChatTagTargetFeature.cs index fe11e31..67d63d2 100644 --- a/PlayerTags/Features/ChatTagTargetFeature.cs +++ b/PlayerTags/Features/ChatTagTargetFeature.cs @@ -102,14 +102,8 @@ namespace PlayerTags.Features } } - private PluginConfiguration m_PluginConfiguration; - private PluginData m_PluginData; - - public ChatTagTargetFeature(PluginConfiguration pluginConfiguration, PluginData pluginData) + public ChatTagTargetFeature(PluginConfiguration pluginConfiguration, PluginData pluginData) : base(pluginConfiguration, pluginData) { - m_PluginConfiguration = pluginConfiguration; - m_PluginData = pluginData; - PluginServices.ChatGui.ChatMessage += Chat_ChatMessage; } @@ -121,7 +115,7 @@ namespace PlayerTags.Features private void Chat_ChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { - if (m_PluginConfiguration.GeneralOptions[ActivityContextManager.CurrentActivityContext.ActivityType].IsApplyTagsToAllChatMessagesEnabled) + if (EnableGlobal && pluginConfiguration.GeneralOptions[ActivityContextManager.CurrentActivityContext.ActivityType].IsApplyTagsToAllChatMessagesEnabled) { AddTagsToChat(sender, type, true); AddTagsToChat(message, type, false); @@ -347,7 +341,7 @@ namespace PlayerTags.Features if (stringMatch.GameObject is PlayerCharacter playerCharacter) { // Add the job tag - if (playerCharacter.ClassJob.GameData != null && m_PluginData.JobTags.TryGetValue(playerCharacter.ClassJob.GameData.Abbreviation, out var jobTag)) + if (playerCharacter.ClassJob.GameData != null && pluginData.JobTags.TryGetValue(playerCharacter.ClassJob.GameData.Abbreviation, out var jobTag)) { if (isTagEnabled(jobTag)) { @@ -361,7 +355,7 @@ namespace PlayerTags.Features } // Add randomly generated name tag payload - if (m_PluginConfiguration.IsPlayerNameRandomlyGenerated) + if (pluginConfiguration.IsPlayerNameRandomlyGenerated) { var playerName = stringMatch.GetMatchText(); if (playerName != null) @@ -378,10 +372,10 @@ namespace PlayerTags.Features // Add custom tags if (stringMatch.PlayerPayload != null) { - Identity identity = m_PluginData.GetIdentity(stringMatch.PlayerPayload); + Identity identity = pluginData.GetIdentity(stringMatch.PlayerPayload); foreach (var customTagId in identity.CustomTagIds) { - var customTag = m_PluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); + var customTag = pluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); if (customTag != null) { if (isTagEnabled(customTag)) @@ -407,17 +401,17 @@ namespace PlayerTags.Features // An additional step to apply text color to additional locations if (stringMatch.PlayerPayload != null && stringMatch.DisplayTextPayloads.Any()) { - Identity identity = m_PluginData.GetIdentity(stringMatch.PlayerPayload); + Identity identity = pluginData.GetIdentity(stringMatch.PlayerPayload); if (stringMatch.GameObject is PlayerCharacter playerCharacter1) { - if (playerCharacter1.ClassJob.GameData != null && m_PluginData.JobTags.TryGetValue(playerCharacter1.ClassJob.GameData.Abbreviation, out var jobTag) && isTagEnabled(jobTag)) + if (playerCharacter1.ClassJob.GameData != null && pluginData.JobTags.TryGetValue(playerCharacter1.ClassJob.GameData.Abbreviation, out var jobTag) && isTagEnabled(jobTag)) applyTextFormatting(jobTag); } foreach (var customTagId in identity.CustomTagIds) { - var customTag = m_PluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); + var customTag = pluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); if (customTag != null && isTagEnabled(customTag)) applyTextFormatting(customTag); } diff --git a/PlayerTags/Features/CustomTagsContextMenuFeature.cs b/PlayerTags/Features/CustomTagsContextMenuFeature.cs index dbfb362..9c7d524 100644 --- a/PlayerTags/Features/CustomTagsContextMenuFeature.cs +++ b/PlayerTags/Features/CustomTagsContextMenuFeature.cs @@ -13,7 +13,7 @@ namespace PlayerTags.Features /// /// A feature that adds options for the management of custom tags to context menus. /// - public class CustomTagsContextMenuFeature : IDisposable + public class CustomTagsContextMenuFeature : FeatureBase, IDisposable { private string?[] SupportedAddonNames = new string?[] { @@ -31,15 +31,10 @@ namespace PlayerTags.Features "SocialList", }; - private PluginConfiguration m_PluginConfiguration; - private PluginData m_PluginData; private DalamudContextMenu? m_ContextMenu; - public CustomTagsContextMenuFeature(PluginConfiguration pluginConfiguration, PluginData pluginData) + public CustomTagsContextMenuFeature(PluginConfiguration pluginConfiguration, PluginData pluginData) : base(pluginConfiguration, pluginData) { - m_PluginConfiguration = pluginConfiguration; - m_PluginData = pluginData; - m_ContextMenu = new DalamudContextMenu(); m_ContextMenu.OnOpenGameObjectContextMenu += ContextMenuHooks_ContextMenuOpened; } @@ -56,17 +51,17 @@ namespace PlayerTags.Features private void ContextMenuHooks_ContextMenuOpened(GameObjectContextMenuOpenArgs contextMenuOpenedArgs) { - if (!m_PluginConfiguration.IsCustomTagsContextMenuEnabled + if (!EnableGlobal || !pluginConfiguration.IsCustomTagsContextMenuEnabled || !SupportedAddonNames.Contains(contextMenuOpenedArgs.ParentAddonName)) { return; } - Identity? identity = m_PluginData.GetIdentity(contextMenuOpenedArgs); + Identity? identity = pluginData.GetIdentity(contextMenuOpenedArgs); if (identity != null) { var allTags = new Dictionary(); - foreach (var customTag in m_PluginData.CustomTags) + foreach (var customTag in pluginData.CustomTags) { var isAdded = identity.CustomTagIds.Contains(customTag.CustomId.Value); allTags.Add(customTag, isAdded); @@ -86,10 +81,10 @@ namespace PlayerTags.Features new GameObjectContextMenuItem(menuItemText, openedEventArgs => { if (tag.Value) - m_PluginData.RemoveCustomTagFromIdentity(tag.Key, identity); + pluginData.RemoveCustomTagFromIdentity(tag.Key, identity); else - m_PluginData.AddCustomTagToIdentity(tag.Key, identity); - m_PluginConfiguration.Save(m_PluginData); + pluginData.AddCustomTagToIdentity(tag.Key, identity); + pluginConfiguration.Save(pluginData); }) { IsSubMenu = false diff --git a/PlayerTags/Features/FeatureBase.cs b/PlayerTags/Features/FeatureBase.cs new file mode 100644 index 0000000..f49cce7 --- /dev/null +++ b/PlayerTags/Features/FeatureBase.cs @@ -0,0 +1,24 @@ +using PlayerTags.Configuration; +using PlayerTags.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PlayerTags.Features +{ + public class FeatureBase + { + protected readonly PluginConfiguration pluginConfiguration; + protected readonly PluginData pluginData; + + public virtual bool EnableGlobal => pluginConfiguration.EnabledGlobal; + + protected FeatureBase(PluginConfiguration pluginConfiguration, PluginData pluginData) + { + this.pluginConfiguration = pluginConfiguration; + this.pluginData = pluginData; + } + } +} diff --git a/PlayerTags/Features/NameplateTagTargetFeature.cs b/PlayerTags/Features/NameplateTagTargetFeature.cs index 37f4d83..37c48ab 100644 --- a/PlayerTags/Features/NameplateTagTargetFeature.cs +++ b/PlayerTags/Features/NameplateTagTargetFeature.cs @@ -24,16 +24,12 @@ namespace PlayerTags.Features /// public class NameplateTagTargetFeature : TagTargetFeature { - private readonly PluginConfiguration m_PluginConfiguration; - private readonly PluginData m_PluginData; private readonly StatusIconPriorizer statusiconPriorizer; private readonly JobIconSets jobIconSets = new(); private Nameplate? m_Nameplate; - public NameplateTagTargetFeature(PluginConfiguration pluginConfiguration, PluginData pluginData) + public NameplateTagTargetFeature(PluginConfiguration pluginConfiguration, PluginData pluginData) : base(pluginConfiguration, pluginData) { - m_PluginConfiguration = pluginConfiguration; - m_PluginData = pluginData; statusiconPriorizer = new(pluginConfiguration.StatusIconPriorizerSettings); PluginServices.ClientState.Login += ClientState_Login; @@ -111,9 +107,11 @@ namespace PlayerTags.Features private unsafe void Nameplate_PlayerNameplateUpdated(PlayerNameplateUpdatedArgs args) { + if (!EnableGlobal) return; + var beforeTitleBytes = args.Title.Encode(); var iconID = args.IconId; - var generalOptions = m_PluginConfiguration.GeneralOptions[ActivityContextManager.CurrentActivityContext.ActivityType]; + var generalOptions = pluginConfiguration.GeneralOptions[ActivityContextManager.CurrentActivityContext.ActivityType]; AddTagsToNameplate(args.PlayerCharacter, args.Name, args.Title, args.FreeCompany, ref iconID, generalOptions); @@ -184,14 +182,14 @@ namespace PlayerTags.Features var classJobGameData = classJob?.GameData; // Add the job tags - if (classJobGameData != null && m_PluginData.JobTags.TryGetValue(classJobGameData.Abbreviation, out var jobTag)) + if (classJobGameData != null && pluginData.JobTags.TryGetValue(classJobGameData.Abbreviation, out var jobTag)) { if (jobTag.TagTargetInNameplates.InheritedValue != null && jobTag.TagPositionInNameplates.InheritedValue != null) checkTag(jobTag); } // Add the randomly generated name tag payload - if (m_PluginConfiguration.IsPlayerNameRandomlyGenerated) + if (pluginConfiguration.IsPlayerNameRandomlyGenerated) { var characterName = playerCharacter.Name.TextValue; if (characterName != null) @@ -203,10 +201,10 @@ namespace PlayerTags.Features } // Add custom tags - Identity identity = m_PluginData.GetIdentity(playerCharacter); + Identity identity = pluginData.GetIdentity(playerCharacter); foreach (var customTagId in identity.CustomTagIds) { - var customTag = m_PluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); + var customTag = pluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); if (customTag != null) checkTag(customTag); } @@ -228,7 +226,7 @@ namespace PlayerTags.Features if (newStatusIcon != null) { var change = nameplateChanges.GetChange(NameplateElements.Name, StringPosition.Before); - NameplateUpdateFactory.ApplyStatusIconWithPrio(ref statusIcon, (int)newStatusIcon, change, ActivityContextManager.CurrentActivityContext, statusiconPriorizer, m_PluginConfiguration.MoveStatusIconToNameplateTextIfPossible); + NameplateUpdateFactory.ApplyStatusIconWithPrio(ref statusIcon, (int)newStatusIcon, change, ActivityContextManager.CurrentActivityContext, statusiconPriorizer, pluginConfiguration.MoveStatusIconToNameplateTextIfPossible); } // Gray out the nameplate @@ -241,15 +239,15 @@ namespace PlayerTags.Features if (playerCharacter != null && (!playerCharacter.IsDead || generalOptions.NameplateDeadPlayerHandling == DeadPlayerHandling.Include)) { // An additional step to apply text color to additional locations - Identity identity = m_PluginData.GetIdentity(playerCharacter); + Identity identity = pluginData.GetIdentity(playerCharacter); foreach (var customTagId in identity.CustomTagIds) { - var customTag = m_PluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); + var customTag = pluginData.CustomTags.FirstOrDefault(tag => tag.CustomId.Value == customTagId); if (customTag != null) applyTextFormatting(customTag); } - if (playerCharacter.ClassJob.GameData != null && m_PluginData.JobTags.TryGetValue(playerCharacter.ClassJob.GameData.Abbreviation, out var jobTag)) + if (playerCharacter.ClassJob.GameData != null && pluginData.JobTags.TryGetValue(playerCharacter.ClassJob.GameData.Abbreviation, out var jobTag)) applyTextFormatting(jobTag); void applyTextFormatting(Tag tag) diff --git a/PlayerTags/Features/TagTargetFeature.cs b/PlayerTags/Features/TagTargetFeature.cs index a0e6c0b..272aae5 100644 --- a/PlayerTags/Features/TagTargetFeature.cs +++ b/PlayerTags/Features/TagTargetFeature.cs @@ -6,6 +6,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Object; using Lumina.Excel.GeneratedSheets; using Pilz.Dalamud.ActivityContexts; using Pilz.Dalamud.Tools.Strings; +using PlayerTags.Configuration; using PlayerTags.Configuration.GameConfig; using PlayerTags.Data; using PlayerTags.Inheritables; @@ -20,11 +21,11 @@ namespace PlayerTags.Features /// /// The base of a feature that adds tags to UI elements. /// - public abstract class TagTargetFeature : IDisposable + public abstract class TagTargetFeature : FeatureBase, IDisposable { public ActivityContextManager ActivityContextManager { get; init; } - public TagTargetFeature() + protected TagTargetFeature(PluginConfiguration pluginConfiguration, PluginData pluginData) : base(pluginConfiguration, pluginData) { ActivityContextManager = new(); } diff --git a/PlayerTags/Plugin.cs b/PlayerTags/Plugin.cs index 2fc7d8c..0839ed2 100644 --- a/PlayerTags/Plugin.cs +++ b/PlayerTags/Plugin.cs @@ -10,6 +10,7 @@ using System; using System.IO; using System.Linq; using System.Reflection; +using System.Security.Cryptography; namespace PlayerTags { @@ -17,6 +18,10 @@ namespace PlayerTags { public string Name => "Player Tags"; private const string c_CommandName = "/playertags"; + private const string c_SubCommandName_EnableGlobal = "enableglobal"; + private const string c_CommandArg_On = "on"; + private const string c_CommandArg_Off = "off"; + private const string c_CommandArg_toggle = "toggle"; private PluginConfiguration m_PluginConfiguration; private PluginData m_PluginData; @@ -40,9 +45,9 @@ namespace PlayerTags PluginServices.DalamudPluginInterface.UiBuilder.Draw += UiBuilder_Draw; PluginServices.DalamudPluginInterface.UiBuilder.OpenConfigUi += UiBuilder_OpenConfigUi; - PluginServices.CommandManager.AddHandler(c_CommandName, new CommandInfo((string command, string arguments) => UiBuilder_OpenConfigUi()) + PluginServices.CommandManager.AddHandler(c_CommandName, new CommandInfo(CommandManager_Handler) { - HelpMessage = Resources.Strings.Loc_Command_playertags + HelpMessage = Resources.Strings.Loc_Command_playertags_v2 }); m_CustomTagsContextMenuFeature = new CustomTagsContextMenuFeature(m_PluginConfiguration, m_PluginData); m_NameplatesTagTargetFeature = new NameplateTagTargetFeature(m_PluginConfiguration, m_PluginData); @@ -65,6 +70,44 @@ namespace PlayerTags Localizer.SetLanguage(langCode); } + private void CommandManager_Handler(string command, string arguments) + { + switch (command) + { + case c_CommandName: + if (string.IsNullOrWhiteSpace(command)) + UiBuilder_OpenConfigUi(); + else + { + var lowerArgs = arguments.ToLower().Split(' '); + if (lowerArgs.Length >= 1) + { + switch (lowerArgs[0]) + { + case c_SubCommandName_EnableGlobal: + if (lowerArgs.Length >= 2) + { + switch (lowerArgs[0]) + { + case c_CommandArg_On: + m_PluginConfiguration.EnabledGlobal = true; + break; + case c_CommandArg_Off: + m_PluginConfiguration.EnabledGlobal = false; + break; + case c_CommandArg_toggle: + m_PluginConfiguration.EnabledGlobal = !m_PluginConfiguration.EnabledGlobal; + break; + } + } + break; + } + } + } + break; + } + } + private void UiBuilder_Draw() { if (m_PluginConfiguration.IsVisible) diff --git a/PlayerTags/Resources/Strings.resx b/PlayerTags/Resources/Strings.resx index 96deaf9..826a24b 100644 --- a/PlayerTags/Resources/Strings.resx +++ b/PlayerTags/Resources/Strings.resx @@ -829,7 +829,9 @@ Use this if you want to to have every option under your control or just want to When enabled the Tag will apply to all Chat messages that has not a defined type. This case can happen either if the Game updates and the Enumeration of all Chat Types gets invalid due to shifted values, or plugins creates a custom chat type for whatever reason. - - Shows the config window for Player Tags + + Shows the config window for Player Tags +Subcommands: +enableglobal on|of|toggle -> Set a global master switch that enables or disables all plugin features without changing the current configuration. \ No newline at end of file