This commit is contained in:
Liza 2023-10-03 21:29:16 +02:00
parent 4b59c71815
commit b2baa1bd37
Signed by: liza
GPG Key ID: 7199F8D727D55F67
9 changed files with 73 additions and 95 deletions

@ -1 +1 @@
Subproject commit 427a252eceaa274c48f79f1d9aa0a2c2d898cbf9 Subproject commit 1ad0decf6d6a169dc0d5779b1c40a5ca733a51d0

View File

@ -1,11 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud.Game.Gui;
using Dalamud.Logging;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc;
using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Ipc.Exceptions;
using Dalamud.Plugin.Services;
using ECommons.Reflection; using ECommons.Reflection;
using ECommons.Schedulers; using ECommons.Schedulers;
@ -13,23 +12,21 @@ namespace Influx.AllaganTools;
internal sealed class AllaganToolsIpc : IDisposable internal sealed class AllaganToolsIpc : IDisposable
{ {
private readonly DalamudPluginInterface _pluginInterface; private readonly IChatGui _chatGui;
private readonly ChatGui _chatGui; private readonly IPluginLog _pluginLog;
private readonly Configuration _configuration;
private readonly ICallGateSubscriber<bool, bool>? _initalized; private readonly ICallGateSubscriber<bool, bool>? _initalized;
private readonly ICallGateSubscriber<bool>? _isInitialized; private readonly ICallGateSubscriber<bool>? _isInitialized;
public ICharacterMonitor Characters { get; private set; } = new UnavailableCharacterMonitor(); public ICharacterMonitor Characters { get; private set; } = new UnavailableCharacterMonitor();
public IInventoryMonitor Inventories { get; private set; } = new UnavailableInventoryMonitor(); public IInventoryMonitor Inventories { get; private set; } = new UnavailableInventoryMonitor();
public AllaganToolsIpc(DalamudPluginInterface pluginInterface, ChatGui chatGui, Configuration configuration) public AllaganToolsIpc(DalamudPluginInterface pluginInterface, IChatGui chatGui, IPluginLog pluginLog)
{ {
_pluginInterface = pluginInterface;
_chatGui = chatGui; _chatGui = chatGui;
_configuration = configuration; _pluginLog = pluginLog;
_initalized = _pluginInterface.GetIpcSubscriber<bool, bool>("AllaganTools.Initialized"); _initalized = pluginInterface.GetIpcSubscriber<bool, bool>("AllaganTools.Initialized");
_isInitialized = _pluginInterface.GetIpcSubscriber<bool>("AllaganTools.IsInitialized"); _isInitialized = pluginInterface.GetIpcSubscriber<bool>("AllaganTools.IsInitialized");
_initalized.Subscribe(ConfigureIpc); _initalized.Subscribe(ConfigureIpc);
try try
@ -40,13 +37,13 @@ internal sealed class AllaganToolsIpc : IDisposable
} }
catch (IpcNotReadyError e) catch (IpcNotReadyError e)
{ {
PluginLog.Error(e, "Not initializing ATools yet, ipc not ready"); _pluginLog.Error(e, "Not initializing ATools yet, ipc not ready");
} }
} }
private void ConfigureIpc(bool initialized) private void ConfigureIpc(bool initialized)
{ {
PluginLog.Information("Configuring Allagan tools IPC"); _pluginLog.Information("Configuring Allagan tools IPC");
_ = new TickScheduler(() => _ = new TickScheduler(() =>
{ {
try try
@ -61,12 +58,12 @@ internal sealed class AllaganToolsIpc : IDisposable
} }
else else
{ {
PluginLog.Warning("Reflection was unsuccessful"); _pluginLog.Warning("Reflection was unsuccessful");
} }
} }
catch (Exception e) catch (Exception e)
{ {
PluginLog.Error(e, "Could not initialize IPC"); _pluginLog.Error(e, "Could not initialize IPC");
_chatGui.PrintError(e.ToString()); _chatGui.PrintError(e.ToString());
} }
}, 100); }, 100);
@ -74,7 +71,7 @@ internal sealed class AllaganToolsIpc : IDisposable
public Dictionary<Character, Currencies> CountCurrencies() public Dictionary<Character, Currencies> CountCurrencies()
{ {
PluginLog.Debug($"{Characters.GetType()}, {Inventories.GetType()}"); _pluginLog.Debug($"{Characters.GetType()}, {Inventories.GetType()}");
var characters = Characters.All.ToDictionary(x => x.CharacterId, x => x); var characters = Characters.All.ToDictionary(x => x.CharacterId, x => x);
return Inventories.All return Inventories.All
.Where(x => characters.ContainsKey(x.Value.CharacterId)) .Where(x => characters.ContainsKey(x.Value.CharacterId))

View File

@ -22,7 +22,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.11"/> <PackageReference Include="DalamudPackager" Version="2.1.12"/>
<PackageReference Include="InfluxDB.Client" Version="4.13.0"/> <PackageReference Include="InfluxDB.Client" Version="4.13.0"/>
</ItemGroup> </ItemGroup>
@ -35,10 +35,6 @@
<HintPath>$(DalamudLibPath)ImGui.NET.dll</HintPath> <HintPath>$(DalamudLibPath)ImGui.NET.dll</HintPath>
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="ImGuiScene">
<HintPath>$(DalamudLibPath)ImGuiScene.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Lumina"> <Reference Include="Lumina">
<HintPath>$(DalamudLibPath)Lumina.dll</HintPath> <HintPath>$(DalamudLibPath)Lumina.dll</HintPath>
<Private>false</Private> <Private>false</Private>

View File

@ -1,12 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Data; using Dalamud.Plugin.Services;
using Dalamud.Game.ClientState;
using Dalamud.Game.Gui;
using Dalamud.Logging;
using Influx.AllaganTools; using Influx.AllaganTools;
using InfluxDB.Client; using InfluxDB.Client;
using InfluxDB.Client.Api.Domain; using InfluxDB.Client.Api.Domain;
@ -16,20 +12,18 @@ using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
namespace Influx.Influx; namespace Influx.Influx;
internal class InfluxStatisticsClient : IDisposable internal sealed class InfluxStatisticsClient : IDisposable
{ {
private const string MutexName = "Global\\c31c89b5-5efb-4c7e-bf87-21717a2814ef";
private readonly InfluxDBClient _influxClient; private readonly InfluxDBClient _influxClient;
private readonly ChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly Configuration _configuration; private readonly Configuration _configuration;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly IReadOnlyDictionary<byte, byte> _classJobToArrayIndex; private readonly IReadOnlyDictionary<byte, byte> _classJobToArrayIndex;
private readonly IReadOnlyDictionary<byte, string> _classJobNames; private readonly IReadOnlyDictionary<byte, string> _classJobNames;
private readonly Dictionary<sbyte, string> _expToJobs; private readonly Dictionary<sbyte, string> _expToJobs;
public InfluxStatisticsClient(ChatGui chatGui, Configuration configuration, DataManager dataManager, public InfluxStatisticsClient(IChatGui chatGui, Configuration configuration, IDataManager dataManager,
ClientState clientState) IClientState clientState)
{ {
_influxClient = new InfluxDBClient(configuration.Server.Server, configuration.Server.Token); _influxClient = new InfluxDBClient(configuration.Server.Server, configuration.Server.Token);
_chatGui = chatGui; _chatGui = chatGui;
@ -111,7 +105,7 @@ internal class InfluxStatisticsClient : IDisposable
11 => 90_000, 11 => 90_000,
_ => 0, _ => 0,
}) })
.Field("squadron_unlocked", localStats.SquadronUnlocked == true ? 1 : 0) .Field("squadron_unlocked", localStats.SquadronUnlocked ? 1 : 0)
.Timestamp(date, WritePrecision.S)); .Timestamp(date, WritePrecision.S));
if (localStats.ClassJobLevels.Count > 0) if (localStats.ClassJobLevels.Count > 0)

View File

@ -2,13 +2,10 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using Dalamud.Data;
using Dalamud.Game.ClientState;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Logging;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ECommons; using ECommons;
using Influx.AllaganTools; using Influx.AllaganTools;
using Influx.Influx; using Influx.Influx;
@ -21,12 +18,11 @@ namespace Influx;
[SuppressMessage("ReSharper", "UnusedType.Global")] [SuppressMessage("ReSharper", "UnusedType.Global")]
public class InfluxPlugin : IDalamudPlugin public class InfluxPlugin : IDalamudPlugin
{ {
public string Name => "Influx";
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly Configuration _configuration; private readonly Configuration _configuration;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly CommandManager _commandManager; private readonly ICommandManager _commandManager;
private readonly IPluginLog _pluginLog;
private readonly AllaganToolsIpc _allaganToolsIpc; private readonly AllaganToolsIpc _allaganToolsIpc;
private readonly SubmarineTrackerIpc _submarineTrackerIpc; private readonly SubmarineTrackerIpc _submarineTrackerIpc;
private readonly LocalStatsCalculator _localStatsCalculator; private readonly LocalStatsCalculator _localStatsCalculator;
@ -36,8 +32,8 @@ public class InfluxPlugin : IDalamudPlugin
private readonly ConfigurationWindow _configurationWindow; private readonly ConfigurationWindow _configurationWindow;
private readonly Timer _timer; private readonly Timer _timer;
public InfluxPlugin(DalamudPluginInterface pluginInterface, ClientState clientState, public InfluxPlugin(DalamudPluginInterface pluginInterface, IClientState clientState, IPluginLog pluginLog,
CommandManager commandManager, ChatGui chatGui, DataManager dataManager) ICommandManager commandManager, IChatGui chatGui, IDataManager dataManager)
{ {
ECommonsMain.Init(pluginInterface, this, Module.DalamudReflector); ECommonsMain.Init(pluginInterface, this, Module.DalamudReflector);
@ -45,9 +41,10 @@ public class InfluxPlugin : IDalamudPlugin
_configuration = LoadConfig(); _configuration = LoadConfig();
_clientState = clientState; _clientState = clientState;
_commandManager = commandManager; _commandManager = commandManager;
_allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, _configuration); _pluginLog = pluginLog;
_submarineTrackerIpc = new SubmarineTrackerIpc(chatGui); _allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, _pluginLog);
_localStatsCalculator = new LocalStatsCalculator(pluginInterface, clientState, chatGui, dataManager); _submarineTrackerIpc = new SubmarineTrackerIpc();
_localStatsCalculator = new LocalStatsCalculator(pluginInterface, clientState, pluginLog, dataManager);
_influxStatisticsClient = new InfluxStatisticsClient(chatGui, _configuration, dataManager, clientState); _influxStatisticsClient = new InfluxStatisticsClient(chatGui, _configuration, dataManager, clientState);
_windowSystem = new WindowSystem(typeof(InfluxPlugin).FullName); _windowSystem = new WindowSystem(typeof(InfluxPlugin).FullName);
@ -74,8 +71,13 @@ public class InfluxPlugin : IDalamudPlugin
private void ProcessCommand(string command, string arguments) private void ProcessCommand(string command, string arguments)
{ {
UpdateStatistics(); if (arguments == "c" || arguments == "config")
_statisticsWindow.IsOpen = true; _configurationWindow.Toggle();
else
{
UpdateStatistics();
_statisticsWindow.IsOpen = true;
}
} }
private void UpdateStatistics() private void UpdateStatistics()
@ -114,7 +116,7 @@ public class InfluxPlugin : IDalamudPlugin
} }
catch (Exception e) catch (Exception e)
{ {
PluginLog.LogError(e, "failed to update statistics"); _pluginLog.Error(e, "failed to update statistics");
} }
} }

View File

@ -3,12 +3,8 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Data;
using Dalamud.Game.ClientState;
using Dalamud.Game.Gui;
using Dalamud.Logging;
using Dalamud.Plugin; using Dalamud.Plugin;
using ECommons.Schedulers; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.Game.UI;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
@ -17,7 +13,7 @@ using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
namespace Influx.LocalStatistics; namespace Influx.LocalStatistics;
public class LocalStatsCalculator : IDisposable internal sealed class LocalStatsCalculator : IDisposable
{ {
private const uint ComingToGridania = 65575; private const uint ComingToGridania = 65575;
private const uint ComingToLimsa = 65643; private const uint ComingToLimsa = 65643;
@ -30,8 +26,8 @@ public class LocalStatsCalculator : IDisposable
private const uint JointQuest = 65781; private const uint JointQuest = 65781;
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly ChatGui _chatGui; private readonly IPluginLog _pluginLog;
private readonly Dictionary<ulong, LocalStats> _cache = new(); private readonly Dictionary<ulong, LocalStats> _cache = new();
private IReadOnlyList<QuestInfo>? _gridaniaStart; private IReadOnlyList<QuestInfo>? _gridaniaStart;
@ -42,13 +38,13 @@ public class LocalStatsCalculator : IDisposable
public LocalStatsCalculator( public LocalStatsCalculator(
DalamudPluginInterface pluginInterface, DalamudPluginInterface pluginInterface,
ClientState clientState, IClientState clientState,
ChatGui chatGui, IPluginLog pluginLog,
DataManager dataManager) IDataManager dataManager)
{ {
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_clientState = clientState; _clientState = clientState;
_chatGui = chatGui; _pluginLog = pluginLog;
_clientState.Login += UpdateStatistics; _clientState.Login += UpdateStatistics;
_clientState.Logout += UpdateStatistics; _clientState.Logout += UpdateStatistics;
@ -77,10 +73,9 @@ public class LocalStatsCalculator : IDisposable
sortedQuests.Add(msq.First(x => x.RowId == JointQuest)); sortedQuests.Add(msq.First(x => x.RowId == JointQuest));
msq.Remove(sortedQuests[0]); msq.Remove(sortedQuests[0]);
QuestInfo? qq = msq.FirstOrDefault(); while (msq.FirstOrDefault(quest => quest.PreviousQuestIds.Count == 0 ||
while ((qq = msq.FirstOrDefault(quest => quest.PreviousQuestIds.Count == 0 || quest.PreviousQuestIds.All(x => sortedQuests.Any(y => x == y.RowId))) is
quest.PreviousQuestIds.All( { } qq)
x => sortedQuests.Any(y => x == y.RowId)))) != null)
{ {
sortedQuests.Add(qq); sortedQuests.Add(qq);
msq.Remove(qq); msq.Remove(qq);
@ -101,7 +96,7 @@ public class LocalStatsCalculator : IDisposable
} }
catch (Exception e) catch (Exception e)
{ {
PluginLog.Warning(e, $"Could not parse file {file.FullName}"); _pluginLog.Warning(e, $"Could not parse file {file.FullName}");
} }
} }
@ -149,16 +144,14 @@ public class LocalStatsCalculator : IDisposable
_clientState.TerritoryChanged -= UpdateStatistics; _clientState.TerritoryChanged -= UpdateStatistics;
} }
private void UpdateStatistics(object? sender, EventArgs e) => UpdateStatistics(); private void UpdateStatistics(ushort territoryType) => UpdateStatistics();
private void UpdateStatistics(object? sender, ushort territoryType) => UpdateStatistics();
private unsafe void UpdateStatistics() private unsafe void UpdateStatistics()
{ {
var localContentId = _clientState.LocalContentId; var localContentId = _clientState.LocalContentId;
if (localContentId == 0) if (localContentId == 0)
{ {
PluginLog.Warning("No local character id"); _pluginLog.Warning("No local character id");
return; return;
} }
@ -196,7 +189,7 @@ public class LocalStatsCalculator : IDisposable
} }
else else
{ {
PluginLog.Information($"XX → {playerState->StartTown}"); _pluginLog.Information($"XX → {playerState->StartTown}");
IReadOnlyList<QuestInfo> cityQuests = playerState->StartTown switch IReadOnlyList<QuestInfo> cityQuests = playerState->StartTown switch
{ {
1 => _limsaStart!, 1 => _limsaStart!,
@ -217,7 +210,7 @@ public class LocalStatsCalculator : IDisposable
localStats.MsqGenre = 0; localStats.MsqGenre = 0;
} }
PluginLog.Information($"ls → {localStats.MsqCount}, {localStats.MsqName}"); _pluginLog.Information($"ls → {localStats.MsqCount}, {localStats.MsqName}");
if (_cache.TryGetValue(localContentId, out var existingStats)) if (_cache.TryGetValue(localContentId, out var existingStats))
{ {
@ -239,7 +232,7 @@ public class LocalStatsCalculator : IDisposable
} }
catch (Exception e) catch (Exception e)
{ {
PluginLog.Error(e, "Failed to update local stats"); _pluginLog.Error(e, "Failed to update local stats");
} }
} }

View File

@ -1,7 +1,6 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud.Game.Gui;
using ECommons.Reflection; using ECommons.Reflection;
using Influx.AllaganTools; using Influx.AllaganTools;
@ -9,13 +8,6 @@ namespace Influx.SubmarineTracker;
internal sealed class SubmarineTrackerIpc internal sealed class SubmarineTrackerIpc
{ {
private readonly ChatGui _chatGui;
public SubmarineTrackerIpc(ChatGui chatGui)
{
_chatGui = chatGui;
}
public Dictionary<Character, List<SubmarineStats>> GetSubmarineStats(List<Character> characters) public Dictionary<Character, List<SubmarineStats>> GetSubmarineStats(List<Character> characters)
{ {
if (DalamudReflector.TryGetDalamudPlugin("Submarine Tracker", out var it, false, true)) if (DalamudReflector.TryGetDalamudPlugin("Submarine Tracker", out var it, false, true))

View File

@ -1,19 +1,19 @@
using System.Linq; using System.Linq;
using Dalamud.Game.ClientState;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ImGuiNET; using ImGuiNET;
namespace Influx.Windows; namespace Influx.Windows;
internal class ConfigurationWindow : Window internal sealed class ConfigurationWindow : Window
{ {
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly Configuration _configuration; private readonly Configuration _configuration;
public ConfigurationWindow(DalamudPluginInterface pluginInterface, ClientState clientState, public ConfigurationWindow(DalamudPluginInterface pluginInterface, IClientState clientState,
Configuration configuration) Configuration configuration)
: base("Configuration###InfluxConfiguration") : base("Configuration###InfluxConfiguration")
{ {
@ -80,22 +80,26 @@ internal class ConfigurationWindow : Window
ImGui.TextWrapped("Characters that are included:"); ImGui.TextWrapped("Characters that are included:");
ImGui.Spacing(); ImGui.Spacing();
ImGui.Indent(30);
if (_configuration.IncludedCharacters.Count == 0) if (_configuration.IncludedCharacters.Count == 0)
{ {
ImGui.TextColored(ImGuiColors.DalamudGrey, "No included characters."); ImGui.TextColored(ImGuiColors.DalamudGrey, "No included characters.");
} }
else else
{ {
foreach (var characterInfo in _configuration.IncludedCharacters.OrderBy(x => x.CachedWorldName).ThenBy(x => x.LocalContentId)) foreach (var world in _configuration.IncludedCharacters.OrderBy(x => x.CachedWorldName).ThenBy(x => x.LocalContentId).GroupBy(x => x.CachedWorldName))
{ {
ImGui.Text( ImGui.CollapsingHeader($"{world.Key} ({world.Count()})", ImGuiTreeNodeFlags.DefaultOpen | ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.Bullet);
$"{characterInfo.CachedPlayerName} @ {characterInfo.CachedWorldName} ({characterInfo.LocalContentId:X})"); ImGui.Indent(30);
foreach (var characterInfo in world)
{
ImGui.Selectable(
$"{characterInfo.CachedPlayerName} @ {characterInfo.CachedWorldName} ({characterInfo.LocalContentId:X})");
}
ImGui.Unindent(30);
} }
} }
ImGui.Unindent(30);
ImGui.EndTabItem(); ImGui.EndTabItem();
} }
} }

View File

@ -4,9 +4,9 @@
"net7.0-windows7.0": { "net7.0-windows7.0": {
"DalamudPackager": { "DalamudPackager": {
"type": "Direct", "type": "Direct",
"requested": "[2.1.11, )", "requested": "[2.1.12, )",
"resolved": "2.1.11", "resolved": "2.1.12",
"contentHash": "9qlAWoRRTiL/geAvuwR/g6Bcbrd/bJJgVnB/RurBiyKs6srsP0bvpoo8IK+Eg8EA6jWeM6/YJWs66w4FIAzqPw==" "contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
}, },
"InfluxDB.Client": { "InfluxDB.Client": {
"type": "Direct", "type": "Direct",