Retainer Stats
This commit is contained in:
parent
87d6dbad28
commit
76822cd50a
@ -6,21 +6,26 @@ internal sealed class Character
|
|||||||
{
|
{
|
||||||
private readonly object _delegate;
|
private readonly object _delegate;
|
||||||
private readonly FieldInfo _name;
|
private readonly FieldInfo _name;
|
||||||
|
private readonly FieldInfo _level;
|
||||||
|
|
||||||
public Character(object @delegate)
|
public Character(object @delegate)
|
||||||
{
|
{
|
||||||
_delegate = @delegate;
|
_delegate = @delegate;
|
||||||
_name = _delegate.GetType().GetField("Name")!;
|
_name = _delegate.GetType().GetField("Name")!;
|
||||||
|
_level = _delegate.GetType().GetField("Level")!;
|
||||||
|
|
||||||
CharacterId = (ulong)_delegate.GetType().GetField("CharacterId")!.GetValue(_delegate)!;
|
CharacterId = (ulong)_delegate.GetType().GetField("CharacterId")!.GetValue(_delegate)!;
|
||||||
CharacterType = (CharacterType)_delegate.GetType().GetProperty("CharacterType")!.GetValue(_delegate)!;
|
CharacterType = (CharacterType)_delegate.GetType().GetProperty("CharacterType")!.GetValue(_delegate)!;
|
||||||
|
ClassJob = (byte)_delegate.GetType().GetField("ClassJob")!.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)!;
|
FreeCompanyId = (ulong)_delegate.GetType().GetField("FreeCompanyId")!.GetValue(_delegate)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong CharacterId { get; }
|
public ulong CharacterId { get; }
|
||||||
public CharacterType CharacterType { get; }
|
public CharacterType CharacterType { get; }
|
||||||
|
public byte ClassJob { get; }
|
||||||
public ulong OwnerId { get; }
|
public ulong OwnerId { get; }
|
||||||
public ulong FreeCompanyId { get; }
|
public ulong FreeCompanyId { get; }
|
||||||
public string Name => (string)_name.GetValue(_delegate)!;
|
public string Name => (string)_name.GetValue(_delegate)!;
|
||||||
|
public uint Level => (uint)_level.GetValue(_delegate)!;
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,15 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.Gui;
|
using Dalamud.Game.Gui;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
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;
|
||||||
using InfluxDB.Client.Writes;
|
using InfluxDB.Client.Writes;
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
|
||||||
|
|
||||||
namespace Influx.Influx;
|
namespace Influx.Influx;
|
||||||
|
|
||||||
@ -21,13 +24,19 @@ internal class InfluxStatisticsClient : IDisposable
|
|||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly Mutex _mutex;
|
private readonly Mutex _mutex;
|
||||||
private readonly bool _mutexCreated;
|
private readonly bool _mutexCreated;
|
||||||
|
private readonly IReadOnlyDictionary<byte, byte> _classJobToArrayIndex;
|
||||||
|
private readonly IReadOnlyDictionary<byte, string> _classJobNames;
|
||||||
|
|
||||||
public InfluxStatisticsClient(ChatGui chatGui, Configuration configuration)
|
public InfluxStatisticsClient(ChatGui chatGui, Configuration configuration, DataManager dataManager)
|
||||||
{
|
{
|
||||||
_influxClient = new InfluxDBClient(configuration.Server.Server, configuration.Server.Token);
|
_influxClient = new InfluxDBClient(configuration.Server.Server, configuration.Server.Token);
|
||||||
_chatGui = chatGui;
|
_chatGui = chatGui;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_mutex = new Mutex(true, MutexName, out _mutexCreated);
|
_mutex = new Mutex(true, MutexName, out _mutexCreated);
|
||||||
|
_classJobToArrayIndex = dataManager.GetExcelSheet<ClassJob>()!.Where(x => x.RowId > 0)
|
||||||
|
.ToDictionary(x => (byte)x.RowId, x => (byte)x.ExpArrayIndex);
|
||||||
|
_classJobNames = dataManager.GetExcelSheet<ClassJob>()!.Where(x => x.RowId > 0)
|
||||||
|
.ToDictionary(x => (byte)x.RowId, x => x.Abbreviation.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Enabled => _configuration.Server.Enabled;
|
public bool Enabled => _configuration.Server.Enabled;
|
||||||
@ -109,6 +118,30 @@ internal class InfluxStatisticsClient : IDisposable
|
|||||||
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
.Field("ceruleum_tanks", currencies.CeruleumTanks)
|
||||||
.Field("repair_kits", currencies.RepairKits)
|
.Field("repair_kits", currencies.RepairKits)
|
||||||
.Timestamp(date, WritePrecision.S));
|
.Timestamp(date, WritePrecision.S));
|
||||||
|
|
||||||
|
if (update.LocalStats.TryGetValue(owner, out var ownerStats) && character.ClassJob != 0)
|
||||||
|
{
|
||||||
|
values.Add(PointData.Measurement("retainer")
|
||||||
|
.Tag("id", character.CharacterId.ToString())
|
||||||
|
.Tag("player_name", owner.Name)
|
||||||
|
.Tag("type", character.CharacterType.ToString())
|
||||||
|
.Tag("retainer_name", character.Name)
|
||||||
|
.Tag("class", _classJobNames[character.ClassJob])
|
||||||
|
.Field("level", character.Level)
|
||||||
|
.Field("is_max_level", character.Level == ownerStats.MaxLevel ? 1 : 0)
|
||||||
|
.Field("can_reach_max_level",
|
||||||
|
ownerStats.ClassJobLevels.Count > 0 &&
|
||||||
|
ownerStats.ClassJobLevels[_classJobToArrayIndex[character.ClassJob]] ==
|
||||||
|
ownerStats.MaxLevel
|
||||||
|
? 1
|
||||||
|
: 0)
|
||||||
|
.Field("levels_before_cap",
|
||||||
|
ownerStats.ClassJobLevels.Count > 0
|
||||||
|
? ownerStats.ClassJobLevels[_classJobToArrayIndex[character.ClassJob]] -
|
||||||
|
character.Level
|
||||||
|
: 0)
|
||||||
|
.Timestamp(date, WritePrecision.S));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (character.CharacterType == CharacterType.FreeCompanyChest &&
|
else if (character.CharacterType == CharacterType.FreeCompanyChest &&
|
||||||
validFcIds.Contains(character.CharacterId))
|
validFcIds.Contains(character.CharacterId))
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
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.ClientState;
|
||||||
using Dalamud.Game.Command;
|
using Dalamud.Game.Command;
|
||||||
using Dalamud.Game.Gui;
|
using Dalamud.Game.Gui;
|
||||||
@ -36,7 +37,7 @@ public class InfluxPlugin : IDalamudPlugin
|
|||||||
private readonly Timer _timer;
|
private readonly Timer _timer;
|
||||||
|
|
||||||
public InfluxPlugin(DalamudPluginInterface pluginInterface, ClientState clientState,
|
public InfluxPlugin(DalamudPluginInterface pluginInterface, ClientState clientState,
|
||||||
CommandManager commandManager, ChatGui chatGui)
|
CommandManager commandManager, ChatGui chatGui, DataManager dataManager)
|
||||||
{
|
{
|
||||||
ECommonsMain.Init(pluginInterface, this, Module.DalamudReflector);
|
ECommonsMain.Init(pluginInterface, this, Module.DalamudReflector);
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ public class InfluxPlugin : IDalamudPlugin
|
|||||||
_allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, _configuration);
|
_allaganToolsIpc = new AllaganToolsIpc(pluginInterface, chatGui, _configuration);
|
||||||
_submarineTrackerIpc = new SubmarineTrackerIpc(chatGui);
|
_submarineTrackerIpc = new SubmarineTrackerIpc(chatGui);
|
||||||
_localStatsCalculator = new LocalStatsCalculator(pluginInterface, clientState, chatGui);
|
_localStatsCalculator = new LocalStatsCalculator(pluginInterface, clientState, chatGui);
|
||||||
_influxStatisticsClient = new InfluxStatisticsClient(chatGui, _configuration);
|
_influxStatisticsClient = new InfluxStatisticsClient(chatGui, _configuration, dataManager);
|
||||||
|
|
||||||
_windowSystem = new WindowSystem(typeof(InfluxPlugin).FullName);
|
_windowSystem = new WindowSystem(typeof(InfluxPlugin).FullName);
|
||||||
_statisticsWindow = new StatisticsWindow();
|
_statisticsWindow = new StatisticsWindow();
|
||||||
@ -85,11 +86,15 @@ public class InfluxPlugin : IDalamudPlugin
|
|||||||
{
|
{
|
||||||
var currencies = _allaganToolsIpc.CountCurrencies();
|
var currencies = _allaganToolsIpc.CountCurrencies();
|
||||||
var characters = currencies.Keys.ToList();
|
var characters = currencies.Keys.ToList();
|
||||||
|
if (characters.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
var update = new StatisticsUpdate
|
var update = new StatisticsUpdate
|
||||||
{
|
{
|
||||||
Currencies = currencies,
|
Currencies = currencies,
|
||||||
Submarines = _submarineTrackerIpc.GetSubmarineStats(characters),
|
Submarines = _submarineTrackerIpc.GetSubmarineStats(characters),
|
||||||
LocalStats = _localStatsCalculator.GetAllCharacterStats()
|
LocalStats = _localStatsCalculator.GetAllCharacterStats()
|
||||||
|
.Where(x => characters.Any(y => y.CharacterId == x.Key))
|
||||||
.ToDictionary(x => characters.First(y => y.CharacterId == x.Key), x => x.Value),
|
.ToDictionary(x => characters.First(y => y.CharacterId == x.Key), x => x.Value),
|
||||||
};
|
};
|
||||||
_statisticsWindow.OnStatisticsUpdate(update);
|
_statisticsWindow.OnStatisticsUpdate(update);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Influx.LocalStatistics;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Influx.LocalStatistics;
|
||||||
|
|
||||||
public record LocalStats
|
public record LocalStats
|
||||||
{
|
{
|
||||||
@ -6,4 +8,6 @@ public record LocalStats
|
|||||||
public byte GrandCompany { get; init; }
|
public byte GrandCompany { get; init; }
|
||||||
public byte GcRank { get; init; }
|
public byte GcRank { get; init; }
|
||||||
public bool SquadronUnlocked { get; init; }
|
public bool SquadronUnlocked { get; init; }
|
||||||
|
public byte MaxLevel { get; init; } = 90;
|
||||||
|
public List<short> ClassJobLevels { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.Gui;
|
using Dalamud.Game.Gui;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
@ -19,7 +20,10 @@ public class LocalStatsCalculator : IDisposable
|
|||||||
private readonly ChatGui _chatGui;
|
private readonly ChatGui _chatGui;
|
||||||
private readonly Dictionary<ulong, LocalStats> _cache = new();
|
private readonly Dictionary<ulong, LocalStats> _cache = new();
|
||||||
|
|
||||||
public LocalStatsCalculator(DalamudPluginInterface pluginInterface, ClientState clientState, ChatGui chatGui)
|
public LocalStatsCalculator(
|
||||||
|
DalamudPluginInterface pluginInterface,
|
||||||
|
ClientState clientState,
|
||||||
|
ChatGui chatGui)
|
||||||
{
|
{
|
||||||
_pluginInterface = pluginInterface;
|
_pluginInterface = pluginInterface;
|
||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
@ -87,6 +91,8 @@ public class LocalStatsCalculator : IDisposable
|
|||||||
GrandCompany.ImmortalFlames => QuestManager.IsQuestComplete(67927),
|
GrandCompany.ImmortalFlames => QuestManager.IsQuestComplete(67927),
|
||||||
_ => false
|
_ => false
|
||||||
},
|
},
|
||||||
|
MaxLevel = playerState->MaxLevel,
|
||||||
|
ClassJobLevels = ExtractClassJobLevels(playerState),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_cache.TryGetValue(localContentId, out var existingStats))
|
if (_cache.TryGetValue(localContentId, out var existingStats))
|
||||||
@ -113,5 +119,13 @@ public class LocalStatsCalculator : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private unsafe List<short> ExtractClassJobLevels(PlayerState* playerState)
|
||||||
|
{
|
||||||
|
List<short> levels = new();
|
||||||
|
for (int i = 0; i < 30; ++i)
|
||||||
|
levels.Add(playerState->ClassJobLevelArray[i]);
|
||||||
|
return levels;
|
||||||
|
}
|
||||||
|
|
||||||
public IReadOnlyDictionary<ulong, LocalStats> GetAllCharacterStats() => _cache.AsReadOnly();
|
public IReadOnlyDictionary<ulong, LocalStats> GetAllCharacterStats() => _cache.AsReadOnly();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user