diff --git a/Influx/AllaganTools/Character.cs b/Influx/AllaganTools/Character.cs index 8534a4a..8bb421a 100644 --- a/Influx/AllaganTools/Character.cs +++ b/Influx/AllaganTools/Character.cs @@ -28,8 +28,11 @@ internal sealed class Character public CharacterType CharacterType { get; } public byte ClassJob { get; } public ulong OwnerId { get; } - public ulong FreeCompanyId { get; } + public ulong FreeCompanyId { get; set; } public uint WorldId { get; } public string Name => (string)_name.GetValue(_delegate)!; public uint Level => (uint)_level.GetValue(_delegate)!; + + public override string ToString() => + $"{nameof(Character)}[{CharacterId}, {(CharacterType == CharacterType.FreeCompanyChest ? "FC" : CharacterType)}, {Name}, {WorldId}]"; } diff --git a/Influx/Influx.csproj b/Influx/Influx.csproj index a41b562..4f64b12 100644 --- a/Influx/Influx.csproj +++ b/Influx/Influx.csproj @@ -1,7 +1,7 @@ net8.0-windows - 0.15 + 0.16 12 enable true diff --git a/Influx/InfluxPlugin.cs b/Influx/InfluxPlugin.cs index d3cb21e..4983167 100644 --- a/Influx/InfluxPlugin.cs +++ b/Influx/InfluxPlugin.cs @@ -50,7 +50,7 @@ internal sealed class InfluxPlugin : IDalamudPlugin _pluginLog = pluginLog; DalamudReflector dalamudReflector = new DalamudReflector(pluginInterface, framework, pluginLog); _allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, dalamudReflector, framework, _pluginLog); - _submarineTrackerIpc = new SubmarineTrackerIpc(dalamudReflector); + _submarineTrackerIpc = new SubmarineTrackerIpc(dalamudReflector, chatGui, pluginLog); _localStatsCalculator = new LocalStatsCalculator(pluginInterface, clientState, addonLifecycle, pluginLog, dataManager); _fcStatsCalculator = new FcStatsCalculator(this, pluginInterface, clientState, addonLifecycle, gameGui, @@ -119,6 +119,17 @@ internal sealed class InfluxPlugin : IDalamudPlugin return; } + foreach (Character character in characters) + { + if (character.CharacterType == CharacterType.Character && character.FreeCompanyId != default) + { + bool isFcEnabled = _configuration.IncludedCharacters + .FirstOrDefault(x => x.LocalContentId == character.CharacterId)?.IncludeFreeCompany ?? true; + if (!isFcEnabled) + character.FreeCompanyId = default; + } + } + Dictionary> inventoryItems = _configuration.IncludedInventoryFilters.Select(c => c.Name) .Distinct() @@ -165,8 +176,8 @@ internal sealed class InfluxPlugin : IDalamudPlugin } } - private Dictionary> UpdateEnabledSubs( - Dictionary> allSubs, List characters) + private IReadOnlyDictionary> UpdateEnabledSubs( + IReadOnlyDictionary> allSubs, List characters) { foreach (var (character, subs) in allSubs) { diff --git a/Influx/StatisticsUpdate.cs b/Influx/StatisticsUpdate.cs index 049cc1d..a11d8ab 100644 --- a/Influx/StatisticsUpdate.cs +++ b/Influx/StatisticsUpdate.cs @@ -9,7 +9,7 @@ internal sealed class StatisticsUpdate { public required IReadOnlyDictionary Currencies { get; init; } public required IReadOnlyDictionary> InventoryItems { get; init; } - public required Dictionary> Submarines { get; init; } - public required Dictionary LocalStats { get; init; } - public required Dictionary FcStats { get; init; } + public required IReadOnlyDictionary> Submarines { get; init; } + public required IReadOnlyDictionary LocalStats { get; init; } + public required IReadOnlyDictionary FcStats { get; init; } } diff --git a/Influx/SubmarineTracker/SubmarineTrackerIpc.cs b/Influx/SubmarineTracker/SubmarineTrackerIpc.cs index a1d8a2c..a4f1b22 100644 --- a/Influx/SubmarineTracker/SubmarineTrackerIpc.cs +++ b/Influx/SubmarineTracker/SubmarineTrackerIpc.cs @@ -1,8 +1,10 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Dalamud.Plugin; +using Dalamud.Plugin.Services; using Influx.AllaganTools; using LLib; @@ -11,14 +13,18 @@ namespace Influx.SubmarineTracker; internal sealed class SubmarineTrackerIpc { private readonly DalamudReflector _dalamudReflector; + private readonly IChatGui _chatGui; + private readonly IPluginLog _pluginLog; - public SubmarineTrackerIpc(DalamudReflector dalamudReflector) + public SubmarineTrackerIpc(DalamudReflector dalamudReflector, IChatGui chatGui, IPluginLog pluginLog) { _dalamudReflector = dalamudReflector; + _chatGui = chatGui; + _pluginLog = pluginLog; } [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")] - public Dictionary> GetSubmarineStats(List characters) + public IReadOnlyDictionary> GetSubmarineStats(List characters) { if (_dalamudReflector.TryGetDalamudPlugin("Submarine Tracker", out IDalamudPlugin? it, false, true)) { @@ -42,25 +48,48 @@ internal sealed class SubmarineTrackerIpc Fc = characters.FirstOrDefault(y => y.CharacterId == x.Owner!.FreeCompanyId) }) .Where(x => x.Fc != null) - .ToDictionary( - x => x.Fc!, - x => x.Subs.Select(y => new SubmarineStats + .Select(x => new SubmarineInfo(x.Fc!, x.Subs)) + .GroupBy(x => x.Fc) + .ToDictionary(x => x.Key, x => + { + if (x.Count() != 1) { - Id = x.Subs.IndexOf(y), - Name = y.Name, - WorldId = x.Fc!.WorldId, - Level = y.Level, - PredictedLevel = y.PredictedLevel, - Hull = y.Build.HullIdentifier, - Stern = y.Build.SternIdentifier, - Bow = y.Build.BowIdentifier, - Bridge = y.Build.BridgeIdentifier, - Build = y.Build.FullIdentifier, - State = y.State, - ReturnTime = y.ReturnTime, - }).ToList()); + _chatGui.PrintError($"[Influx] Unable to collect data, FC '{x.Key.Name}' is included in statistics through multiple characters/owners."); + var characterNames = characters.Where(y => y.FreeCompanyId == x.Key.CharacterId).Select(y => y.Name).ToList(); + throw new InvalidOperationException($"Unable to collect FC data for FC '{x.Key}'{Environment.NewLine}Multiple characters include the same FC ({string.Join(", ", characterNames)}), only one of them should have 'Include Free Company Statistics' set"); + } + + return x.Single().Subs; + }); } else return new Dictionary>(); } + + private sealed record SubmarineInfo(Character Fc, List Subs) + { + public SubmarineInfo(Character fc, IList subs) + : this(fc, subs.Select(x => Convert(fc, subs.IndexOf(x), x)).ToList()) + { + } + + private static SubmarineStats Convert(Character fc, int index, Submarine y) + { + return new SubmarineStats + { + Id = index, + Name = y.Name, + WorldId = fc.WorldId, + Level = y.Level, + PredictedLevel = y.PredictedLevel, + Hull = y.Build.HullIdentifier, + Stern = y.Build.SternIdentifier, + Bow = y.Build.BowIdentifier, + Bridge = y.Build.BridgeIdentifier, + Build = y.Build.FullIdentifier, + State = y.State, + ReturnTime = y.ReturnTime, + }; + } + } } diff --git a/Influx/Windows/StatisticsWindow.cs b/Influx/Windows/StatisticsWindow.cs index 2c3cca3..94140f7 100644 --- a/Influx/Windows/StatisticsWindow.cs +++ b/Influx/Windows/StatisticsWindow.cs @@ -24,10 +24,10 @@ internal sealed class StatisticsWindow : Window public override void Draw() { - if (ImGui.BeginTable("Currencies###InfluxStatisticsCurrencies", 4)) + if (ImGui.BeginTable("Currencies###InfluxStatisticsCurrencies", 2)) { ImGui.TableSetupColumn("Name"); - ImGui.TableSetupColumn("Gil"); + ImGui.TableSetupColumn($"Gil ({_rows.Sum(x => x.Gil):N0})##Gil"); ImGui.TableHeadersRow(); foreach (var row in _rows)