diff --git a/Influx/AllaganToolsIPC.cs b/Influx/AllaganToolsIPC.cs index cfc4544..8e94199 100644 --- a/Influx/AllaganToolsIPC.cs +++ b/Influx/AllaganToolsIPC.cs @@ -15,18 +15,18 @@ internal sealed class AllaganToolsIPC : IDisposable { private readonly DalamudPluginInterface _pluginInterface; private readonly ChatGui _chatGui; - private readonly ClientState _clientState; + private readonly Configuration _configuration; private readonly ICallGateSubscriber? _initalized; private readonly ICallGateSubscriber? _isInitialized; public CharacterMonitor Characters { get; private set; } public InventoryMonitor Inventories { get; private set; } - public AllaganToolsIPC(DalamudPluginInterface pluginInterface, ChatGui chatGui, ClientState clientState) + public AllaganToolsIPC(DalamudPluginInterface pluginInterface, ChatGui chatGui, Configuration configuration) { _pluginInterface = pluginInterface; _chatGui = chatGui; - _clientState = clientState; + _configuration = configuration; _initalized = _pluginInterface.GetIpcSubscriber("AllaganTools.Initialized"); _isInitialized = _pluginInterface.GetIpcSubscriber("AllaganTools.IsInitialized"); @@ -55,17 +55,30 @@ internal sealed class AllaganToolsIPC : IDisposable } } - public Dictionary CountGil() + public Dictionary CountCurrencies() { var characters = Characters.All.ToDictionary(x => x.CharacterId, x => x); - return Inventories.All.ToDictionary( - x => characters[x.Value.CharacterId], - y => y.Value.GetAllItems().Where(x => x.ItemId == 1).Sum(x => x.Quantity)); + return Inventories.All + .Where(x => !_configuration.ExcludedCharacters.Contains(x.Key)) + .ToDictionary( + x => characters[x.Value.CharacterId], + y => + { + var inv = new InventoryWrapper(y.Value.GetAllItems()); + return new Currencies + { + Gil = inv.Sum(1), + FcCredits = inv.Sum(80), + Ventures = inv.Sum(21072), + CeruleumTanks = inv.Sum(10155), + RepairKits = inv.Sum(10373), + }; + }); } public void Dispose() { - _initalized.Unsubscribe(ConfigureIpc); + _initalized?.Unsubscribe(ConfigureIpc); } public class CharacterMonitor @@ -106,12 +119,14 @@ internal sealed class AllaganToolsIPC : IDisposable CharacterId = (ulong)_delegate.GetType().GetField("CharacterId")!.GetValue(_delegate)!; CharacterType = (CharacterType)_delegate.GetType().GetProperty("CharacterType")!.GetValue(_delegate)!; - OwnerId = (ulong)_delegate.GetType().GetField("OwnerId").GetValue(_delegate); + OwnerId = (ulong)_delegate.GetType().GetField("OwnerId")!.GetValue(_delegate)!; + FreeCompanyId = (ulong)_delegate.GetType().GetField("FreeCompanyId")!.GetValue(_delegate)!; } public ulong CharacterId { get; } public CharacterType CharacterType { get; } public ulong OwnerId { get; } + public ulong FreeCompanyId { get; } public string Name => (string)_name.GetValue(_delegate)!; } @@ -124,6 +139,16 @@ internal sealed class AllaganToolsIPC : IDisposable Unknown, } + public struct Currencies + { + public long Gil { get; init; } + public long GcSeals { get; init; } + public long FcCredits { get; init; } + public long Ventures { get; init; } + public long CeruleumTanks { get; init; } + public long RepairKits { get; init; } + } + public sealed class InventoryMonitor { private readonly object _delegate; @@ -179,4 +204,17 @@ internal sealed class AllaganToolsIPC : IDisposable public uint ItemId { get; } public uint Quantity { get; } } + + public sealed class InventoryWrapper + { + private readonly IEnumerable _items; + + public InventoryWrapper(IEnumerable items) + { + _items = items; + } + + public long Sum(int itemId) => _items.Where(x => x.ItemId == itemId).Sum(x => x.Quantity); + } + } diff --git a/Influx/Configuration.cs b/Influx/Configuration.cs index 709ca7d..a491622 100644 --- a/Influx/Configuration.cs +++ b/Influx/Configuration.cs @@ -1,4 +1,5 @@ -using Dalamud.Configuration; +using System.Collections.Generic; +using Dalamud.Configuration; namespace Influx; @@ -8,6 +9,8 @@ public sealed class Configuration : IPluginConfiguration public ServerConfiguration Server { get; set; } = new(); + public List ExcludedCharacters { get; set; } = new(); + public sealed class ServerConfiguration { public string Server { get; set; } = "http://localhost:8086"; diff --git a/Influx/Influx.csproj b/Influx/Influx.csproj index ee08837..455bd8e 100644 --- a/Influx/Influx.csproj +++ b/Influx/Influx.csproj @@ -22,8 +22,8 @@ - - + + @@ -58,10 +58,10 @@ - + - + diff --git a/Influx/InfluxPlugin.cs b/Influx/InfluxPlugin.cs index 33cea1e..63a0703 100644 --- a/Influx/InfluxPlugin.cs +++ b/Influx/InfluxPlugin.cs @@ -39,7 +39,7 @@ public class InfluxPlugin : IDalamudPlugin _clientState = clientState; _commandManager = commandManager; _chatGui = chatGui; - _allaganToolsIpc = new AllaganToolsIPC(pluginInterface, chatGui, clientState); + _allaganToolsIpc = new AllaganToolsIPC(pluginInterface, chatGui, _configuration); _influxClient = new InfluxDBClient(_configuration.Server.Server, _configuration.Server.Token); _commandManager.AddHandler("/influx", new CommandInfo(ProcessCommand)); @@ -48,8 +48,7 @@ public class InfluxPlugin : IDalamudPlugin private Configuration LoadConfig() { - var config = _pluginInterface.GetPluginConfig() as Configuration; - if (config != null) + if (_pluginInterface.GetPluginConfig() is Configuration config) return config; config = new Configuration(); @@ -59,49 +58,85 @@ public class InfluxPlugin : IDalamudPlugin private void ProcessCommand(string command, string arguments) { - CountGil(); + CountGil(true); } - private void CountGil() + private void CountGil(bool printDebug = false) { if (!_clientState.IsLoggedIn) return; DateTime date = DateTime.UtcNow; - var stats = _allaganToolsIpc.CountGil(); + IReadOnlyDictionary stats; + try + { + stats = _allaganToolsIpc.CountCurrencies(); + } + catch (Exception e) + { + _chatGui.PrintError(e.ToString()); + return; + } + + var validFcIds = stats.Keys + .Where(x => x.CharacterType == AllaganToolsIPC.CharacterType.Character) + .Select(x => x.FreeCompanyId) + .ToList(); Task.Run(async () => { - List values = new(); - foreach (var (character, gil) in stats) - { - if (character.CharacterType == AllaganToolsIPC.CharacterType.Character) - { - values.Add(PointData.Measurement("currency") - .Tag("player_name", character.Name) - .Tag("type", character.CharacterType.ToString()) - .Field("gil", gil) - .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("player_name", owner.Name) - .Tag("type", character.CharacterType.ToString()) - .Tag("retainer_name", character.Name) - .Field("gil", gil) - .Timestamp(date, WritePrecision.S)); - } - } - var writeApi = _influxClient.GetWriteApiAsync(); try { + List 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"); + + if (printDebug) + _chatGui.Print($"Influx: {values.Count} points"); } catch (Exception e) { diff --git a/Influx/packages.lock.json b/Influx/packages.lock.json new file mode 100644 index 0000000..49453a4 --- /dev/null +++ b/Influx/packages.lock.json @@ -0,0 +1,199 @@ +{ + "version": 1, + "dependencies": { + "net7.0-windows7.0": { + "DalamudPackager": { + "type": "Direct", + "requested": "[2.1.11, )", + "resolved": "2.1.11", + "contentHash": "9qlAWoRRTiL/geAvuwR/g6Bcbrd/bJJgVnB/RurBiyKs6srsP0bvpoo8IK+Eg8EA6jWeM6/YJWs66w4FIAzqPw==" + }, + "InfluxDB.Client": { + "type": "Direct", + "requested": "[4.13.0, )", + "resolved": "4.13.0", + "contentHash": "2kDPC//sbSjm6R8lxqJrufNfF1AMhmeVw7dBnrOsMQjjxvaPrWFkITWIlL8AVtg5TdTqah9APp1laaJye6ebFg==", + "dependencies": { + "InfluxDB.Client.Core": "4.13.0", + "JsonSubTypes": "2.0.1", + "Microsoft.Extensions.ObjectPool": "7.0.9", + "Microsoft.Net.Http.Headers": "2.2.8", + "System.Collections.Immutable": "6.0.0", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Reactive": "6.0.0" + } + }, + "CsvHelper": { + "type": "Transitive", + "resolved": "30.0.1", + "contentHash": "rcZtgbWR+As4G3Vpgx0AMNmShGuQLFjkHAPIIflzrfkJCx8/AOd4m96ZRmiU1Wi39qS5UVjV0P8qdgqOo5Cwyg==" + }, + "InfluxDB.Client.Core": { + "type": "Transitive", + "resolved": "4.13.0", + "contentHash": "SS6kVhUuQTjpbCBn6ULgXz/tLSttZhMEhmr0Vxk3vnvtlce4mYjX48NLk8QHWdUEyTL195AGrSyZTqYaDTZrgA==", + "dependencies": { + "CsvHelper": "30.0.1", + "Newtonsoft.Json": "13.0.3", + "NodaTime": "3.1.9", + "NodaTime.Serialization.JsonNet": "3.0.1", + "RestSharp": "110.1.0" + } + }, + "JsonSubTypes": { + "type": "Transitive", + "resolved": "2.0.1", + "contentHash": "1Po+Ypf0SjCeEKx5+C89Nb5OgTcqNvfS3uTI46MUM+KEp6Rq/M0h+vVsTUt/6DFRwZMTpsAJM4yJrZmEObVANA==", + "dependencies": { + "Newtonsoft.Json": "13.0.1" + } + }, + "Microsoft.Extensions.ObjectPool": { + "type": "Transitive", + "resolved": "7.0.9", + "contentHash": "fFYlvFV8gle6IJ7Z0C3IydLfrzruL82pbBmn7oGsPK0zPtyN4pk2uX242ATOKbodZlRqLMAH6RE5wkRMCbkxug==" + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==", + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + } + }, + "Microsoft.Net.Http.Headers": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "wHdwMv0QDDG2NWDSwax9cjkeQceGC1Qq53a31+31XpvTXVljKXRjWISlMoS/wZYKiqdqzuEvKFKwGHl+mt2jCA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "2.2.0", + "System.Buffers": "4.5.0" + } + }, + "Microsoft.Win32.SystemEvents": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A==" + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "NodaTime": { + "type": "Transitive", + "resolved": "3.1.9", + "contentHash": "EzjwDOtsETlXWBDE6qvTQqc3guP+9xrAOf9j1mHL++UD4VeZay+dbCPNnXyZhoQMkKAOZ/+hIOtz7STl0Rkknw==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.7.1" + } + }, + "NodaTime.Serialization.JsonNet": { + "type": "Transitive", + "resolved": "3.0.1", + "contentHash": "bmw+ElaOr21HZQQVYWZKgqs0QpSb/rJcJxem3Ok6YWAdenqOi0PS2hIkvlh+QJfsl2X3VJcla9Rhya/N3JnweA==", + "dependencies": { + "Newtonsoft.Json": "13.0.1", + "NodaTime": "[3.0.0, 4.0.0)" + } + }, + "RestSharp": { + "type": "Transitive", + "resolved": "110.1.0", + "contentHash": "h9ERwfMeLp+BJ3cEwxxe1KIkTjB/yokJAjj3JNO5tKcMZI2Rx+bJe//DkVG3aX5g669Pi5Ifc4kFPrNKtTinsg==", + "dependencies": { + "System.Text.Json": "7.0.2" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "pL2ChpaRRWI/p4LXyy4RgeWlYF2sgfj/pnVMvBqwNFr5cXg7CXNnWZWxrOONLg8VGdFB8oB+EG2Qw4MLgTOe+A==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Cryptography.ProtectedData": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.Drawing.Common": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==", + "dependencies": { + "Microsoft.Win32.SystemEvents": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "sDJYJpGtTgx+23Ayu5euxG5mAXWdkDb4+b0rD0Cab0M1oQS9H0HXGPriKcqpXuiJDTV7fTp/d+fMDJmnr6sNvA==" + }, + "System.Reactive": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "31kfaW4ZupZzPsI5PVe77VhnvFF55qgma7KZr/E0iFTs6fmdhhG8j0mgEx620iLTey1EynOkEfnyTjtNEpJzGw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ==" + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0", + "System.Windows.Extensions": "6.0.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "OP6umVGxc0Z0MvZQBVigj4/U31Pw72ITihDWP9WiWDm+q5aoe0GaJivsfYGq53o6dxH7DcXWiCTl7+0o2CGdmg==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "7.0.2", + "contentHash": "/LZf/JrGyilojqwpaywb+sSz8Tew7ij4K/Sk+UW8AKfAK7KRhR6mKpKtTm06cYA7bCpGTWfYksIW+mVsdxPegQ==", + "dependencies": { + "System.Text.Encodings.Web": "7.0.0" + } + }, + "System.Windows.Extensions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==", + "dependencies": { + "System.Drawing.Common": "6.0.0" + } + }, + "ecommons": { + "type": "Project" + } + } + } +} \ No newline at end of file