UI restructuring

This commit is contained in:
Liza 2023-08-21 06:19:44 +02:00
parent 947b86594a
commit 24879ccdb9
Signed by: liza
GPG Key ID: 7199F8D727D55F67
7 changed files with 244 additions and 80 deletions

View File

@ -216,5 +216,4 @@ internal sealed class AllaganToolsIPC : IDisposable
public long Sum(int itemId) => _items.Where(x => x.ItemId == itemId).Sum(x => x.Quantity);
}
}

View File

@ -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";

View 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();
}
}

View File

@ -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();

View File

@ -0,0 +1,8 @@
using System.Collections.Generic;
namespace Influx;
internal sealed class StatisticsUpdate
{
public IReadOnlyDictionary<AllaganToolsIPC.Character, AllaganToolsIPC.Currencies> Currencies { get; init; }
}

View 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()
{
}
}

View 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; }
}
}