UI restructuring
This commit is contained in:
parent
947b86594a
commit
24879ccdb9
@ -216,5 +216,4 @@ internal sealed class AllaganToolsIPC : IDisposable
|
||||
|
||||
public long Sum(int itemId) => _items.Where(x => x.ItemId == itemId).Sum(x => x.Quantity);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ public sealed class Configuration : IPluginConfiguration
|
||||
|
||||
public sealed class ServerConfiguration
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public string Server { get; set; } = "http://localhost:8086";
|
||||
public string Token { get; set; } = "xxx";
|
||||
public string Organization { get; set; } = "org";
|
||||
|
111
Influx/Influx/InfluxStatisticsClient.cs
Normal file
111
Influx/Influx/InfluxStatisticsClient.cs
Normal file
@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Game.Gui;
|
||||
using InfluxDB.Client;
|
||||
using InfluxDB.Client.Api.Domain;
|
||||
using InfluxDB.Client.Writes;
|
||||
|
||||
namespace Influx.Influx;
|
||||
|
||||
internal class InfluxStatisticsClient : IDisposable
|
||||
{
|
||||
private const string MutexName = "Global\\c31c89b5-5efb-4c7e-bf87-21717a2814ef";
|
||||
|
||||
private readonly InfluxDBClient _influxClient;
|
||||
private readonly ChatGui _chatGui;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly Mutex _mutex;
|
||||
private readonly bool _mutexCreated;
|
||||
|
||||
public InfluxStatisticsClient(ChatGui chatGui, Configuration configuration)
|
||||
{
|
||||
_influxClient = new InfluxDBClient(configuration.Server.Server, configuration.Server.Token);
|
||||
_chatGui = chatGui;
|
||||
_configuration = configuration;
|
||||
_mutex = new Mutex(true, MutexName, out _mutexCreated);
|
||||
}
|
||||
|
||||
public bool Enabled => _configuration.Server.Enabled;
|
||||
|
||||
public void OnStatisticsUpdate(StatisticsUpdate update)
|
||||
{
|
||||
if (!Enabled || !_mutexCreated)
|
||||
return;
|
||||
|
||||
DateTime date = DateTime.UtcNow;
|
||||
IReadOnlyDictionary<AllaganToolsIPC.Character, AllaganToolsIPC.Currencies> stats = update.Currencies;
|
||||
|
||||
var validFcIds = stats.Keys
|
||||
.Where(x => x.CharacterType == AllaganToolsIPC.CharacterType.Character)
|
||||
.Select(x => x.FreeCompanyId)
|
||||
.ToList();
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
List<PointData> values = new();
|
||||
foreach (var (character, currencies) in stats)
|
||||
{
|
||||
if (character.CharacterType == AllaganToolsIPC.CharacterType.Character)
|
||||
{
|
||||
values.Add(PointData.Measurement("currency")
|
||||
.Tag("id", character.CharacterId.ToString())
|
||||
.Tag("player_name", character.Name)
|
||||
.Tag("type", character.CharacterType.ToString())
|
||||
.Field("gil", currencies.Gil)
|
||||
.Field("ventures", currencies.Ventures)
|
||||
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
||||
.Field("repair_kits", currencies.RepairKits)
|
||||
.Timestamp(date, WritePrecision.S));
|
||||
}
|
||||
else if (character.CharacterType == AllaganToolsIPC.CharacterType.Retainer)
|
||||
{
|
||||
var owner = stats.Keys.First(x => x.CharacterId == character.OwnerId);
|
||||
values.Add(PointData.Measurement("currency")
|
||||
.Tag("id", character.CharacterId.ToString())
|
||||
.Tag("player_name", owner.Name)
|
||||
.Tag("type", character.CharacterType.ToString())
|
||||
.Tag("retainer_name", character.Name)
|
||||
.Field("gil", currencies.Gil)
|
||||
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
||||
.Field("repair_kits", currencies.RepairKits)
|
||||
.Timestamp(date, WritePrecision.S));
|
||||
}
|
||||
else if (character.CharacterType == AllaganToolsIPC.CharacterType.FreeCompanyChest &&
|
||||
validFcIds.Contains(character.CharacterId))
|
||||
{
|
||||
values.Add(PointData.Measurement("currency")
|
||||
.Tag("id", character.CharacterId.ToString())
|
||||
.Tag("fc_name", character.Name)
|
||||
.Tag("type", character.CharacterType.ToString())
|
||||
.Field("gil", currencies.Gil)
|
||||
.Field("fccredit", currencies.FcCredits)
|
||||
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
||||
.Field("repair_kits", currencies.RepairKits)
|
||||
.Timestamp(date, WritePrecision.S));
|
||||
}
|
||||
}
|
||||
|
||||
var writeApi = _influxClient.GetWriteApiAsync();
|
||||
await writeApi.WritePointsAsync(
|
||||
values,
|
||||
_configuration.Server.Bucket, _configuration.Server.Organization);
|
||||
|
||||
//_chatGui.Print($"Influx: {values.Count} points");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_chatGui.PrintError(e.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_mutex.Dispose();
|
||||
_influxClient.Dispose();
|
||||
}
|
||||
}
|
@ -7,8 +7,12 @@ using System.Threading.Tasks;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Plugin;
|
||||
using ECommons;
|
||||
using Influx.Influx;
|
||||
using Influx.Windows;
|
||||
using InfluxDB.Client;
|
||||
using InfluxDB.Client.Api.Domain;
|
||||
using InfluxDB.Client.Writes;
|
||||
@ -24,9 +28,11 @@ public class InfluxPlugin : IDalamudPlugin
|
||||
private readonly Configuration _configuration;
|
||||
private readonly ClientState _clientState;
|
||||
private readonly CommandManager _commandManager;
|
||||
private readonly ChatGui _chatGui;
|
||||
private readonly AllaganToolsIPC _allaganToolsIpc;
|
||||
private readonly InfluxDBClient _influxClient;
|
||||
private readonly InfluxStatisticsClient _influxStatisticsClient;
|
||||
private readonly WindowSystem _windowSystem;
|
||||
private readonly StatisticsWindow _statisticsWindow;
|
||||
private readonly ConfigurationWindow _configurationWindow;
|
||||
private readonly Timer _timer;
|
||||
|
||||
public InfluxPlugin(DalamudPluginInterface pluginInterface, ClientState clientState,
|
||||
@ -38,12 +44,18 @@ public class InfluxPlugin : IDalamudPlugin
|
||||
_configuration = LoadConfig();
|
||||
_clientState = clientState;
|
||||
_commandManager = commandManager;
|
||||
_chatGui = chatGui;
|
||||
_allaganToolsIpc = new AllaganToolsIPC(pluginInterface, chatGui, _configuration);
|
||||
_influxClient = new InfluxDBClient(_configuration.Server.Server, _configuration.Server.Token);
|
||||
_influxStatisticsClient = new InfluxStatisticsClient(chatGui, _configuration);
|
||||
|
||||
_windowSystem = new WindowSystem(typeof(InfluxPlugin).FullName);
|
||||
_statisticsWindow = new StatisticsWindow();
|
||||
_windowSystem.AddWindow(_statisticsWindow);
|
||||
_configurationWindow = new ConfigurationWindow();
|
||||
_windowSystem.AddWindow(_configurationWindow);
|
||||
|
||||
_commandManager.AddHandler("/influx", new CommandInfo(ProcessCommand));
|
||||
_timer = new Timer(_ => CountGil(), null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
|
||||
_timer = new Timer(_ => UpdateStatistics(), null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
|
||||
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
||||
}
|
||||
|
||||
private Configuration LoadConfig()
|
||||
@ -58,98 +70,37 @@ public class InfluxPlugin : IDalamudPlugin
|
||||
|
||||
private void ProcessCommand(string command, string arguments)
|
||||
{
|
||||
CountGil(true);
|
||||
UpdateStatistics();
|
||||
_statisticsWindow.IsOpen = true;
|
||||
}
|
||||
|
||||
private void CountGil(bool printDebug = false)
|
||||
private void UpdateStatistics()
|
||||
{
|
||||
if (!_clientState.IsLoggedIn)
|
||||
return;
|
||||
|
||||
DateTime date = DateTime.UtcNow;
|
||||
IReadOnlyDictionary<AllaganToolsIPC.Character, AllaganToolsIPC.Currencies> stats;
|
||||
try
|
||||
{
|
||||
stats = _allaganToolsIpc.CountCurrencies();
|
||||
var update = new StatisticsUpdate
|
||||
{
|
||||
Currencies = _allaganToolsIpc.CountCurrencies(),
|
||||
};
|
||||
_statisticsWindow.OnStatisticsUpdate(update);
|
||||
_influxStatisticsClient.OnStatisticsUpdate(update);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_chatGui.PrintError(e.ToString());
|
||||
return;
|
||||
PluginLog.LogError(e, "failed to update statistics");
|
||||
}
|
||||
|
||||
|
||||
var validFcIds = stats.Keys
|
||||
.Where(x => x.CharacterType == AllaganToolsIPC.CharacterType.Character)
|
||||
.Select(x => x.FreeCompanyId)
|
||||
.ToList();
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
List<PointData> values = new();
|
||||
foreach (var (character, currencies) in stats)
|
||||
{
|
||||
if (character.CharacterType == AllaganToolsIPC.CharacterType.Character)
|
||||
{
|
||||
values.Add(PointData.Measurement("currency")
|
||||
.Tag("id", character.CharacterId.ToString())
|
||||
.Tag("player_name", character.Name)
|
||||
.Tag("type", character.CharacterType.ToString())
|
||||
.Field("gil", currencies.Gil)
|
||||
.Field("ventures", currencies.Ventures)
|
||||
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
||||
.Field("repair_kits", currencies.RepairKits)
|
||||
.Timestamp(date, WritePrecision.S));
|
||||
}
|
||||
else if (character.CharacterType == AllaganToolsIPC.CharacterType.Retainer)
|
||||
{
|
||||
var owner = stats.Keys.First(x => x.CharacterId == character.OwnerId);
|
||||
values.Add(PointData.Measurement("currency")
|
||||
.Tag("id", character.CharacterId.ToString())
|
||||
.Tag("player_name", owner.Name)
|
||||
.Tag("type", character.CharacterType.ToString())
|
||||
.Tag("retainer_name", character.Name)
|
||||
.Field("gil", currencies.Gil)
|
||||
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
||||
.Field("repair_kits", currencies.RepairKits)
|
||||
.Timestamp(date, WritePrecision.S));
|
||||
}
|
||||
else if (character.CharacterType == AllaganToolsIPC.CharacterType.FreeCompanyChest && validFcIds.Contains(character.CharacterId))
|
||||
{
|
||||
values.Add(PointData.Measurement("currency")
|
||||
.Tag("id", character.CharacterId.ToString())
|
||||
.Tag("fc_name", character.Name)
|
||||
.Tag("type", character.CharacterType.ToString())
|
||||
.Field("gil", currencies.Gil)
|
||||
.Field("fccredit", currencies.FcCredits)
|
||||
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
||||
.Field("repair_kits", currencies.RepairKits)
|
||||
.Timestamp(date, WritePrecision.S));
|
||||
}
|
||||
}
|
||||
|
||||
var writeApi = _influxClient.GetWriteApiAsync();
|
||||
await writeApi.WritePointsAsync(
|
||||
values,
|
||||
_configuration.Server.Bucket, _configuration.Server.Organization);
|
||||
|
||||
if (printDebug)
|
||||
_chatGui.Print($"Influx: {values.Count} points");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_chatGui.PrintError(e.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
|
||||
_timer.Dispose();
|
||||
_windowSystem.RemoveAllWindows();
|
||||
_commandManager.RemoveHandler("/influx");
|
||||
_influxClient.Dispose();
|
||||
_influxStatisticsClient.Dispose();
|
||||
_allaganToolsIpc.Dispose();
|
||||
|
||||
ECommonsMain.Dispose();
|
||||
|
8
Influx/StatisticsUpdate.cs
Normal file
8
Influx/StatisticsUpdate.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Influx;
|
||||
|
||||
internal sealed class StatisticsUpdate
|
||||
{
|
||||
public IReadOnlyDictionary<AllaganToolsIPC.Character, AllaganToolsIPC.Currencies> Currencies { get; init; }
|
||||
}
|
15
Influx/Windows/ConfigurationWindow.cs
Normal file
15
Influx/Windows/ConfigurationWindow.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using Dalamud.Interface.Windowing;
|
||||
|
||||
namespace Influx.Windows;
|
||||
|
||||
internal class ConfigurationWindow : Window
|
||||
{
|
||||
public ConfigurationWindow()
|
||||
: base("Configuration###InfluxConfiguration")
|
||||
{
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
}
|
||||
}
|
79
Influx/Windows/StatisticsWindow.cs
Normal file
79
Influx/Windows/StatisticsWindow.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Influx.Windows;
|
||||
|
||||
internal sealed class StatisticsWindow : Window
|
||||
{
|
||||
private List<StatisticsRow> _rows = new();
|
||||
|
||||
public StatisticsWindow()
|
||||
: base("Statistics###InfluxStatistics")
|
||||
{
|
||||
Position = new Vector2(100, 100);
|
||||
PositionCondition = ImGuiCond.FirstUseEver;
|
||||
|
||||
Size = new Vector2(400, 400);
|
||||
SizeCondition = ImGuiCond.Appearing;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
if (ImGui.BeginTable("Currencies###InfluxStatisticsCurrencies", 4))
|
||||
{
|
||||
ImGui.TableSetupColumn("Name");
|
||||
ImGui.TableSetupColumn("Gil");
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var row in _rows)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
if (ImGui.TableNextColumn())
|
||||
ImGui.Text(row.Name);
|
||||
|
||||
if (ImGui.TableNextColumn())
|
||||
ImGui.Text(row.Gil.ToString("N0"));
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnStatisticsUpdate(StatisticsUpdate update)
|
||||
{
|
||||
var retainers = update.Currencies
|
||||
.Where(x => x.Key.CharacterType == AllaganToolsIPC.CharacterType.Retainer)
|
||||
.GroupBy(x => update.Currencies.FirstOrDefault(y => y.Key.CharacterId == x.Key.OwnerId).Key)
|
||||
.ToDictionary(x => x.Key, x => x.Select(y => y.Value).ToList());
|
||||
|
||||
_rows = update.Currencies.Where(x => x.Key.CharacterType == AllaganToolsIPC.CharacterType.Character)
|
||||
.Select(x =>
|
||||
{
|
||||
var currencies = new List<AllaganToolsIPC.Currencies> { x.Value };
|
||||
if (retainers.TryGetValue(x.Key, out var retainerCurrencies))
|
||||
currencies.AddRange(retainerCurrencies);
|
||||
return new StatisticsRow
|
||||
{
|
||||
Name = x.Key.Name,
|
||||
Type = x.Key.CharacterType.ToString(),
|
||||
Gil = currencies.Sum(y => y.Gil),
|
||||
FcCredits = currencies.Sum(y => y.FcCredits),
|
||||
};
|
||||
})
|
||||
.Where(x => x.Gil > 0 || x.FcCredits > 0)
|
||||
.OrderByDescending(x => x.Gil)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public sealed class StatisticsRow
|
||||
{
|
||||
public string Name { get; init; }
|
||||
public string Type { get; init; }
|
||||
public long Gil { get; init; }
|
||||
public long FcCredits { get; init; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user