Fix 'Include FC statistics' not properly excluding subs, improve error message

master v0.16
Liza 2024-04-28 11:13:22 +02:00
parent 874948f674
commit bb44f02ade
Signed by: liza
GPG Key ID: 7199F8D727D55F67
6 changed files with 72 additions and 29 deletions

View File

@ -28,8 +28,11 @@ internal sealed class Character
public CharacterType CharacterType { get; } public CharacterType CharacterType { get; }
public byte ClassJob { get; } public byte ClassJob { get; }
public ulong OwnerId { get; } public ulong OwnerId { get; }
public ulong FreeCompanyId { get; } public ulong FreeCompanyId { get; set; }
public uint WorldId { get; } public uint WorldId { get; }
public string Name => (string)_name.GetValue(_delegate)!; public string Name => (string)_name.GetValue(_delegate)!;
public uint Level => (uint)_level.GetValue(_delegate)!; public uint Level => (uint)_level.GetValue(_delegate)!;
public override string ToString() =>
$"{nameof(Character)}[{CharacterId}, {(CharacterType == CharacterType.FreeCompanyChest ? "FC" : CharacterType)}, {Name}, {WorldId}]";
} }

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<Version>0.15</Version> <Version>0.16</Version>
<LangVersion>12</LangVersion> <LangVersion>12</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

View File

@ -50,7 +50,7 @@ internal sealed class InfluxPlugin : IDalamudPlugin
_pluginLog = pluginLog; _pluginLog = pluginLog;
DalamudReflector dalamudReflector = new DalamudReflector(pluginInterface, framework, pluginLog); DalamudReflector dalamudReflector = new DalamudReflector(pluginInterface, framework, pluginLog);
_allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, dalamudReflector, framework, _pluginLog); _allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, dalamudReflector, framework, _pluginLog);
_submarineTrackerIpc = new SubmarineTrackerIpc(dalamudReflector); _submarineTrackerIpc = new SubmarineTrackerIpc(dalamudReflector, chatGui, pluginLog);
_localStatsCalculator = _localStatsCalculator =
new LocalStatsCalculator(pluginInterface, clientState, addonLifecycle, pluginLog, dataManager); new LocalStatsCalculator(pluginInterface, clientState, addonLifecycle, pluginLog, dataManager);
_fcStatsCalculator = new FcStatsCalculator(this, pluginInterface, clientState, addonLifecycle, gameGui, _fcStatsCalculator = new FcStatsCalculator(this, pluginInterface, clientState, addonLifecycle, gameGui,
@ -119,6 +119,17 @@ internal sealed class InfluxPlugin : IDalamudPlugin
return; 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<string, IReadOnlyList<SortingResult>> inventoryItems = Dictionary<string, IReadOnlyList<SortingResult>> inventoryItems =
_configuration.IncludedInventoryFilters.Select(c => c.Name) _configuration.IncludedInventoryFilters.Select(c => c.Name)
.Distinct() .Distinct()
@ -165,8 +176,8 @@ internal sealed class InfluxPlugin : IDalamudPlugin
} }
} }
private Dictionary<Character, List<SubmarineStats>> UpdateEnabledSubs( private IReadOnlyDictionary<Character, List<SubmarineStats>> UpdateEnabledSubs(
Dictionary<Character, List<SubmarineStats>> allSubs, List<Character> characters) IReadOnlyDictionary<Character, List<SubmarineStats>> allSubs, List<Character> characters)
{ {
foreach (var (character, subs) in allSubs) foreach (var (character, subs) in allSubs)
{ {

View File

@ -9,7 +9,7 @@ internal sealed class StatisticsUpdate
{ {
public required IReadOnlyDictionary<Character, Currencies> Currencies { get; init; } public required IReadOnlyDictionary<Character, Currencies> Currencies { get; init; }
public required IReadOnlyDictionary<string, IReadOnlyList<SortingResult>> InventoryItems { get; init; } public required IReadOnlyDictionary<string, IReadOnlyList<SortingResult>> InventoryItems { get; init; }
public required Dictionary<Character, List<SubmarineStats>> Submarines { get; init; } public required IReadOnlyDictionary<Character, List<SubmarineStats>> Submarines { get; init; }
public required Dictionary<Character, LocalStats> LocalStats { get; init; } public required IReadOnlyDictionary<Character, LocalStats> LocalStats { get; init; }
public required Dictionary<ulong, FcStats> FcStats { get; init; } public required IReadOnlyDictionary<ulong, FcStats> FcStats { get; init; }
} }

View File

@ -1,8 +1,10 @@
using System.Collections; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Influx.AllaganTools; using Influx.AllaganTools;
using LLib; using LLib;
@ -11,14 +13,18 @@ namespace Influx.SubmarineTracker;
internal sealed class SubmarineTrackerIpc internal sealed class SubmarineTrackerIpc
{ {
private readonly DalamudReflector _dalamudReflector; 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; _dalamudReflector = dalamudReflector;
_chatGui = chatGui;
_pluginLog = pluginLog;
} }
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")] [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public Dictionary<Character, List<SubmarineStats>> GetSubmarineStats(List<Character> characters) public IReadOnlyDictionary<Character, List<SubmarineStats>> GetSubmarineStats(List<Character> characters)
{ {
if (_dalamudReflector.TryGetDalamudPlugin("Submarine Tracker", out IDalamudPlugin? it, false, true)) 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) Fc = characters.FirstOrDefault(y => y.CharacterId == x.Owner!.FreeCompanyId)
}) })
.Where(x => x.Fc != null) .Where(x => x.Fc != null)
.ToDictionary( .Select(x => new SubmarineInfo(x.Fc!, x.Subs))
x => x.Fc!, .GroupBy(x => x.Fc)
x => x.Subs.Select(y => new SubmarineStats .ToDictionary(x => x.Key, x =>
{
if (x.Count() != 1)
{ {
Id = x.Subs.IndexOf(y), _chatGui.PrintError($"[Influx] Unable to collect data, FC '{x.Key.Name}' is included in statistics through multiple characters/owners.");
Name = y.Name, var characterNames = characters.Where(y => y.FreeCompanyId == x.Key.CharacterId).Select(y => y.Name).ToList();
WorldId = x.Fc!.WorldId, 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");
Level = y.Level, }
PredictedLevel = y.PredictedLevel,
Hull = y.Build.HullIdentifier, return x.Single().Subs;
Stern = y.Build.SternIdentifier, });
Bow = y.Build.BowIdentifier,
Bridge = y.Build.BridgeIdentifier,
Build = y.Build.FullIdentifier,
State = y.State,
ReturnTime = y.ReturnTime,
}).ToList());
} }
else else
return new Dictionary<Character, List<SubmarineStats>>(); return new Dictionary<Character, List<SubmarineStats>>();
} }
private sealed record SubmarineInfo(Character Fc, List<SubmarineStats> Subs)
{
public SubmarineInfo(Character fc, IList<Submarine> 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,
};
}
}
} }

View File

@ -24,10 +24,10 @@ internal sealed class StatisticsWindow : Window
public override void Draw() public override void Draw()
{ {
if (ImGui.BeginTable("Currencies###InfluxStatisticsCurrencies", 4)) if (ImGui.BeginTable("Currencies###InfluxStatisticsCurrencies", 2))
{ {
ImGui.TableSetupColumn("Name"); ImGui.TableSetupColumn("Name");
ImGui.TableSetupColumn("Gil"); ImGui.TableSetupColumn($"Gil ({_rows.Sum(x => x.Gil):N0})##Gil");
ImGui.TableHeadersRow(); ImGui.TableHeadersRow();
foreach (var row in _rows) foreach (var row in _rows)