diff --git a/Influx/AllaganTools/AllaganToolsIpc.cs b/Influx/AllaganTools/AllaganToolsIpc.cs index 1ffac2e..e1fded6 100644 --- a/Influx/AllaganTools/AllaganToolsIpc.cs +++ b/Influx/AllaganTools/AllaganToolsIpc.cs @@ -77,7 +77,6 @@ internal sealed class AllaganToolsIpc : IDisposable PluginLog.Debug($"{Characters.GetType()}, {Inventories.GetType()}"); var characters = Characters.All.ToDictionary(x => x.CharacterId, x => x); return Inventories.All - .Where(x => !_configuration.ExcludedCharacters.Contains(x.Key)) .Where(x => characters.ContainsKey(x.Value.CharacterId)) .ToDictionary( x => characters[x.Value.CharacterId], diff --git a/Influx/Configuration.cs b/Influx/Configuration.cs index d0b2dc9..6c9e812 100644 --- a/Influx/Configuration.cs +++ b/Influx/Configuration.cs @@ -9,7 +9,7 @@ public sealed class Configuration : IPluginConfiguration public ServerConfiguration Server { get; set; } = new(); - public List ExcludedCharacters { get; set; } = new(); + public List IncludedCharacters { get; set; } = new(); public sealed class ServerConfiguration { @@ -19,4 +19,11 @@ public sealed class Configuration : IPluginConfiguration public string Organization { get; set; } = "org"; public string Bucket { get; set; } = "bucket"; } + + public sealed class CharacterInfo + { + public ulong LocalContentId { get; set; } + public string? CachedPlayerName { get; set; } + public string? CachedWorldName { get; set; } + } } diff --git a/Influx/Influx.csproj b/Influx/Influx.csproj index ee08837..455bd8e 100644 --- a/Influx/Influx.csproj +++ b/Influx/Influx.csproj @@ -22,8 +22,8 @@ - - + + @@ -58,10 +58,10 @@ - + - + diff --git a/Influx/Influx/InfluxStatisticsClient.cs b/Influx/Influx/InfluxStatisticsClient.cs index b1829f5..b1c01b0 100644 --- a/Influx/Influx/InfluxStatisticsClient.cs +++ b/Influx/Influx/InfluxStatisticsClient.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Dalamud.Data; +using Dalamud.Game.ClientState; using Dalamud.Game.Gui; using Dalamud.Logging; using Influx.AllaganTools; @@ -22,17 +23,18 @@ internal class InfluxStatisticsClient : IDisposable private readonly InfluxDBClient _influxClient; private readonly ChatGui _chatGui; private readonly Configuration _configuration; - private readonly Mutex _mutex; - private readonly bool _mutexCreated; + private readonly ClientState _clientState; private readonly IReadOnlyDictionary _classJobToArrayIndex; private readonly IReadOnlyDictionary _classJobNames; - public InfluxStatisticsClient(ChatGui chatGui, Configuration configuration, DataManager dataManager) + public InfluxStatisticsClient(ChatGui chatGui, Configuration configuration, DataManager dataManager, + ClientState clientState) { _influxClient = new InfluxDBClient(configuration.Server.Server, configuration.Server.Token); _chatGui = chatGui; _configuration = configuration; - _mutex = new Mutex(true, MutexName, out _mutexCreated); + _clientState = clientState; + _classJobToArrayIndex = dataManager.GetExcelSheet()!.Where(x => x.RowId > 0) .ToDictionary(x => (byte)x.RowId, x => (byte)x.ExpArrayIndex); _classJobNames = dataManager.GetExcelSheet()!.Where(x => x.RowId > 0) @@ -43,7 +45,7 @@ internal class InfluxStatisticsClient : IDisposable public void OnStatisticsUpdate(StatisticsUpdate update) { - if (!Enabled || !_mutexCreated) + if (!Enabled || _configuration.IncludedCharacters.All(x => x.LocalContentId != _clientState.LocalContentId)) return; DateTime date = DateTime.UtcNow; @@ -113,7 +115,8 @@ internal class InfluxStatisticsClient : IDisposable .Tag("id", character.CharacterId.ToString()) .Tag("player_name", character.Name) .Tag("msq_name", localStats.MsqName) - .Tag("fc_id", character.FreeCompanyId > 0 ? character.FreeCompanyId.ToString() : null) + .Tag("fc_id", + character.FreeCompanyId > 0 ? character.FreeCompanyId.ToString() : null) .Field("msq_count", localStats.MsqCount) .Field("msq_genre", localStats.MsqGenre) .Timestamp(date, WritePrecision.S)); @@ -205,7 +208,6 @@ internal class InfluxStatisticsClient : IDisposable public void Dispose() { - _mutex.Dispose(); _influxClient.Dispose(); } } diff --git a/Influx/InfluxPlugin.cs b/Influx/InfluxPlugin.cs index 3c0110d..8eda0da 100644 --- a/Influx/InfluxPlugin.cs +++ b/Influx/InfluxPlugin.cs @@ -48,17 +48,18 @@ public class InfluxPlugin : IDalamudPlugin _allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, _configuration); _submarineTrackerIpc = new SubmarineTrackerIpc(chatGui); _localStatsCalculator = new LocalStatsCalculator(pluginInterface, clientState, chatGui, dataManager); - _influxStatisticsClient = new InfluxStatisticsClient(chatGui, _configuration, dataManager); + _influxStatisticsClient = new InfluxStatisticsClient(chatGui, _configuration, dataManager, clientState); _windowSystem = new WindowSystem(typeof(InfluxPlugin).FullName); _statisticsWindow = new StatisticsWindow(); _windowSystem.AddWindow(_statisticsWindow); - _configurationWindow = new ConfigurationWindow(); + _configurationWindow = new ConfigurationWindow(_pluginInterface, clientState, _configuration); _windowSystem.AddWindow(_configurationWindow); _commandManager.AddHandler("/influx", new CommandInfo(ProcessCommand)); _timer = new Timer(_ => UpdateStatistics(), null, TimeSpan.Zero, TimeSpan.FromMinutes(1)); _pluginInterface.UiBuilder.Draw += _windowSystem.Draw; + _pluginInterface.UiBuilder.OpenConfigUi += _configurationWindow.Toggle; } private Configuration LoadConfig() @@ -79,7 +80,8 @@ public class InfluxPlugin : IDalamudPlugin private void UpdateStatistics() { - if (!_clientState.IsLoggedIn) + if (!_clientState.IsLoggedIn || + _configuration.IncludedCharacters.All(x => x.LocalContentId != _clientState.LocalContentId)) return; try @@ -91,11 +93,15 @@ public class InfluxPlugin : IDalamudPlugin var update = new StatisticsUpdate { - Currencies = currencies, + Currencies = currencies + .Where(x => _configuration.IncludedCharacters.Any(y => y.LocalContentId == x.Key.CharacterId || y.LocalContentId == x.Key.OwnerId)) + .ToDictionary(x => x.Key, x => x.Value), Submarines = _submarineTrackerIpc.GetSubmarineStats(characters), LocalStats = _localStatsCalculator.GetAllCharacterStats() .Where(x => characters.Any(y => y.CharacterId == x.Key)) - .ToDictionary(x => characters.First(y => y.CharacterId == x.Key), x => x.Value), + .ToDictionary(x => characters.First(y => y.CharacterId == x.Key), x => x.Value) + .Where(x => _configuration.IncludedCharacters.Any(y => y.LocalContentId == x.Key.CharacterId || y.LocalContentId == x.Key.OwnerId)) + .ToDictionary(x => x.Key, x => x.Value), }; _statisticsWindow.OnStatisticsUpdate(update); _influxStatisticsClient.OnStatisticsUpdate(update); @@ -108,6 +114,7 @@ public class InfluxPlugin : IDalamudPlugin public void Dispose() { + _pluginInterface.UiBuilder.OpenConfigUi -= _configurationWindow.Toggle; _pluginInterface.UiBuilder.Draw -= _windowSystem.Draw; _timer.Dispose(); _windowSystem.RemoveAllWindows(); diff --git a/Influx/LocalStatistics/LocalStatsCalculator.cs b/Influx/LocalStatistics/LocalStatsCalculator.cs index 2f1c891..4babcf9 100644 --- a/Influx/LocalStatistics/LocalStatsCalculator.cs +++ b/Influx/LocalStatistics/LocalStatsCalculator.cs @@ -34,10 +34,10 @@ public class LocalStatsCalculator : IDisposable private readonly ChatGui _chatGui; private readonly Dictionary _cache = new(); - private IReadOnlyList? _gridaniaStart; - private IReadOnlyList? _limsaStart; - private IReadOnlyList? _uldahStart; - private IReadOnlyList? _msqQuests; + private IReadOnlyList? _gridaniaStart; + private IReadOnlyList? _limsaStart; + private IReadOnlyList? _uldahStart; + private IReadOnlyList? _msqQuests; public LocalStatsCalculator( @@ -109,13 +109,14 @@ public class LocalStatsCalculator : IDisposable UpdateStatistics(); } - private IReadOnlyList PopulateStartingCities(List quests, uint envoyQuestId, uint startingQuestId, bool popCallOfTheSea) + private IReadOnlyList PopulateStartingCities(List quests, uint envoyQuestId, + uint startingQuestId, bool popCallOfTheSea) { QuestInfo callOfTheSea = quests.First(x => x.PreviousQuestIds.Contains(envoyQuestId)); if (popCallOfTheSea) quests.Remove(callOfTheSea); - List startingCityQuests = new List{ callOfTheSea }; + List startingCityQuests = new List { callOfTheSea }; uint? questId = envoyQuestId; QuestInfo? quest; diff --git a/Influx/Windows/ConfigurationWindow.cs b/Influx/Windows/ConfigurationWindow.cs index abcf840..d3aef9b 100644 --- a/Influx/Windows/ConfigurationWindow.cs +++ b/Influx/Windows/ConfigurationWindow.cs @@ -1,15 +1,107 @@ -using Dalamud.Interface.Windowing; +using System.Linq; +using Dalamud.Game.ClientState; +using Dalamud.Interface.Colors; +using Dalamud.Interface.Windowing; +using Dalamud.Plugin; +using ImGuiNET; namespace Influx.Windows; internal class ConfigurationWindow : Window { - public ConfigurationWindow() + private readonly DalamudPluginInterface _pluginInterface; + private readonly ClientState _clientState; + private readonly Configuration _configuration; + + public ConfigurationWindow(DalamudPluginInterface pluginInterface, ClientState clientState, + Configuration configuration) : base("Configuration###InfluxConfiguration") { + _pluginInterface = pluginInterface; + _clientState = clientState; + _configuration = configuration; } public override void Draw() { + if (ImGui.BeginTabBar("InfluxConfigTabs")) + { + DrawIncludedCharacters(); + + ImGui.EndTabBar(); + } + } + + private void DrawIncludedCharacters() + { + if (ImGui.BeginTabItem("Included Characters")) + { + if (_clientState is { IsLoggedIn: true, LocalContentId: > 0 }) + { + string worldName = _clientState.LocalPlayer?.HomeWorld.GameData?.Name ?? "??"; + ImGui.TextWrapped( + $"Current Character: {_clientState.LocalPlayer?.Name} @ {worldName} ({_clientState.LocalContentId:X})"); + ImGui.Indent(30); + if (_configuration.IncludedCharacters.Any(x => x.LocalContentId == _clientState.LocalContentId)) + { + ImGui.TextColored(ImGuiColors.HealerGreen, "This character is currently included."); + if (ImGui.Button("Remove inclusion")) + { + _configuration.IncludedCharacters.RemoveAll( + c => c.LocalContentId == _clientState.LocalContentId); + Save(); + } + } + else + { + ImGui.TextColored(ImGuiColors.DalamudRed, + "This character is currently excluded."); + + if (ImGui.Button("Include current character")) + { + _configuration.IncludedCharacters.Add(new Configuration.CharacterInfo + { + LocalContentId = _clientState.LocalContentId, + CachedPlayerName = _clientState.LocalPlayer?.Name.ToString() ?? "??", + CachedWorldName = worldName, + }); + Save(); + } + } + + ImGui.Unindent(30); + } + else + { + ImGui.TextColored(ImGuiColors.DalamudRed, "You are not logged in."); + } + + ImGui.Separator(); + ImGui.TextWrapped("Characters that are included:"); + ImGui.Spacing(); + + ImGui.Indent(30); + if (_configuration.IncludedCharacters.Count == 0) + { + ImGui.TextColored(ImGuiColors.DalamudGrey, "No included characters."); + } + else + { + foreach (var characterInfo in _configuration.IncludedCharacters.OrderBy(x => x.CachedWorldName).ThenBy(x => x.LocalContentId)) + { + ImGui.Text( + $"{characterInfo.CachedPlayerName} @ {characterInfo.CachedWorldName} ({characterInfo.LocalContentId:X})"); + } + } + + ImGui.Unindent(30); + + ImGui.EndTabItem(); + } + } + + private void Save() + { + _pluginInterface.SavePluginConfig(_configuration); } }