update stats to use new meta service

This commit is contained in:
RaidMax 2022-03-23 13:54:42 -05:00
parent 7be096e0b6
commit 497c15a6a8
2 changed files with 83 additions and 87 deletions

View File

@ -59,7 +59,6 @@ namespace IW4MAdmin.Application
readonly PenaltyService PenaltySvc; readonly PenaltyService PenaltySvc;
public IConfigurationHandler<ApplicationConfiguration> ConfigHandler; public IConfigurationHandler<ApplicationConfiguration> ConfigHandler;
readonly IPageList PageList; readonly IPageList PageList;
private readonly IMetaService _metaService;
private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0); private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0);
private readonly CancellationTokenSource _tokenSource; private readonly CancellationTokenSource _tokenSource;
private readonly Dictionary<string, Task<IList>> _operationLookup = new Dictionary<string, Task<IList>>(); private readonly Dictionary<string, Task<IList>> _operationLookup = new Dictionary<string, Task<IList>>();
@ -81,7 +80,7 @@ namespace IW4MAdmin.Application
ITranslationLookup translationLookup, IConfigurationHandler<CommandConfiguration> commandConfiguration, ITranslationLookup translationLookup, IConfigurationHandler<CommandConfiguration> commandConfiguration,
IConfigurationHandler<ApplicationConfiguration> appConfigHandler, IGameServerInstanceFactory serverInstanceFactory, IConfigurationHandler<ApplicationConfiguration> appConfigHandler, IGameServerInstanceFactory serverInstanceFactory,
IEnumerable<IPlugin> plugins, IParserRegexFactory parserRegexFactory, IEnumerable<IRegisterEvent> customParserEvents, IEnumerable<IPlugin> plugins, IParserRegexFactory parserRegexFactory, IEnumerable<IRegisterEvent> customParserEvents,
IEventHandler eventHandler, IScriptCommandFactory scriptCommandFactory, IDatabaseContextFactory contextFactory, IMetaService metaService, IEventHandler eventHandler, IScriptCommandFactory scriptCommandFactory, IDatabaseContextFactory contextFactory,
IMetaRegistration metaRegistration, IScriptPluginServiceResolver scriptPluginServiceResolver, ClientService clientService, IServiceProvider serviceProvider, IMetaRegistration metaRegistration, IScriptPluginServiceResolver scriptPluginServiceResolver, ClientService clientService, IServiceProvider serviceProvider,
ChangeHistoryService changeHistoryService, ApplicationConfiguration appConfig, PenaltyService penaltyService) ChangeHistoryService changeHistoryService, ApplicationConfiguration appConfig, PenaltyService penaltyService)
{ {
@ -97,7 +96,6 @@ namespace IW4MAdmin.Application
AdditionalRConParsers = new List<IRConParser>() { new BaseRConParser(serviceProvider.GetRequiredService<ILogger<BaseRConParser>>(), parserRegexFactory) }; AdditionalRConParsers = new List<IRConParser>() { new BaseRConParser(serviceProvider.GetRequiredService<ILogger<BaseRConParser>>(), parserRegexFactory) };
TokenAuthenticator = new TokenAuthentication(); TokenAuthenticator = new TokenAuthentication();
_logger = logger; _logger = logger;
_metaService = metaService;
_tokenSource = new CancellationTokenSource(); _tokenSource = new CancellationTokenSource();
_commands = commands.ToList(); _commands = commands.ToList();
_translationLookup = translationLookup; _translationLookup = translationLookup;

View File

@ -9,6 +9,7 @@ using Stats.Dtos;
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 Data.Abstractions; using Data.Abstractions;
using Data.Models.Client.Stats; using Data.Models.Client.Stats;
@ -35,7 +36,7 @@ namespace IW4MAdmin.Plugins.Stats
private readonly IDatabaseContextFactory _databaseContextFactory; private readonly IDatabaseContextFactory _databaseContextFactory;
private readonly ITranslationLookup _translationLookup; private readonly ITranslationLookup _translationLookup;
private readonly IMetaService _metaService; private readonly IMetaServiceV2 _metaService;
private readonly IResourceQueryHelper<ChatSearchQuery, MessageResponse> _chatQueryHelper; private readonly IResourceQueryHelper<ChatSearchQuery, MessageResponse> _chatQueryHelper;
private readonly ILogger<StatManager> _managerLogger; private readonly ILogger<StatManager> _managerLogger;
private readonly ILogger<Plugin> _logger; private readonly ILogger<Plugin> _logger;
@ -43,7 +44,7 @@ namespace IW4MAdmin.Plugins.Stats
private readonly IServerDistributionCalculator _serverDistributionCalculator; private readonly IServerDistributionCalculator _serverDistributionCalculator;
public Plugin(ILogger<Plugin> logger, IConfigurationHandlerFactory configurationHandlerFactory, IDatabaseContextFactory databaseContextFactory, public Plugin(ILogger<Plugin> logger, IConfigurationHandlerFactory configurationHandlerFactory, IDatabaseContextFactory databaseContextFactory,
ITranslationLookup translationLookup, IMetaService metaService, IResourceQueryHelper<ChatSearchQuery, MessageResponse> chatQueryHelper, ILogger<StatManager> managerLogger, ITranslationLookup translationLookup, IMetaServiceV2 metaService, IResourceQueryHelper<ChatSearchQuery, MessageResponse> chatQueryHelper, ILogger<StatManager> managerLogger,
IEnumerable<IClientStatisticCalculator> statCalculators, IServerDistributionCalculator serverDistributionCalculator) IEnumerable<IClientStatisticCalculator> statCalculators, IServerDistributionCalculator serverDistributionCalculator)
{ {
Config = configurationHandlerFactory.GetConfigurationHandler<StatsConfiguration>("StatsPluginSettings"); Config = configurationHandlerFactory.GetConfigurationHandler<StatsConfiguration>("StatsPluginSettings");
@ -57,52 +58,52 @@ namespace IW4MAdmin.Plugins.Stats
_serverDistributionCalculator = serverDistributionCalculator; _serverDistributionCalculator = serverDistributionCalculator;
} }
public async Task OnEventAsync(GameEvent E, Server S) public async Task OnEventAsync(GameEvent gameEvent, Server server)
{ {
switch (E.Type) switch (gameEvent.Type)
{ {
case GameEvent.EventType.Start: case GameEvent.EventType.Start:
Manager.AddServer(S); Manager.AddServer(server);
break; break;
case GameEvent.EventType.Disconnect: case GameEvent.EventType.Disconnect:
await Manager.RemovePlayer(E.Origin); await Manager.RemovePlayer(gameEvent.Origin);
break; break;
case GameEvent.EventType.Say: case GameEvent.EventType.Say:
if (!string.IsNullOrEmpty(E.Data) && if (!string.IsNullOrEmpty(gameEvent.Data) &&
E.Origin.ClientId > 1) gameEvent.Origin.ClientId > 1)
{ {
await Manager.AddMessageAsync(E.Origin.ClientId, StatManager.GetIdForServer(S), true, E.Data); await Manager.AddMessageAsync(gameEvent.Origin.ClientId, StatManager.GetIdForServer(server), true, gameEvent.Data);
} }
break; break;
case GameEvent.EventType.MapChange: case GameEvent.EventType.MapChange:
Manager.SetTeamBased(StatManager.GetIdForServer(S), S.Gametype != "dm"); Manager.SetTeamBased(StatManager.GetIdForServer(server), server.Gametype != "dm");
Manager.ResetKillstreaks(S); Manager.ResetKillstreaks(server);
await Manager.Sync(S); await Manager.Sync(server);
break; break;
case GameEvent.EventType.MapEnd: case GameEvent.EventType.MapEnd:
Manager.ResetKillstreaks(S); Manager.ResetKillstreaks(server);
await Manager.Sync(S); await Manager.Sync(server);
break; break;
case GameEvent.EventType.Command: case GameEvent.EventType.Command:
var shouldPersist = !string.IsNullOrEmpty(E.Data) && var shouldPersist = !string.IsNullOrEmpty(gameEvent.Data) &&
E.Extra?.GetType().Name == "SayCommand"; gameEvent.Extra?.GetType().Name == "SayCommand";
if (shouldPersist) if (shouldPersist)
{ {
await Manager.AddMessageAsync(E.Origin.ClientId, StatManager.GetIdForServer(S), false, E.Data); await Manager.AddMessageAsync(gameEvent.Origin.ClientId, StatManager.GetIdForServer(server), false, gameEvent.Data);
} }
break; break;
case GameEvent.EventType.ScriptKill: case GameEvent.EventType.ScriptKill:
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0]; var killInfo = (gameEvent.Data != null) ? gameEvent.Data.Split(';') : Array.Empty<string>();
if ((S.CustomCallback || ShouldOverrideAnticheatSetting(S)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(E.Origin, E.Target)) if ((server.CustomCallback || ShouldOverrideAnticheatSetting(server)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(gameEvent.Origin, gameEvent.Target))
{ {
// this treats "world" damage as self damage // this treats "world" damage as self damage
if (IsWorldDamage(E.Origin)) if (IsWorldDamage(gameEvent.Origin))
{ {
E.Origin = E.Target; gameEvent.Origin = gameEvent.Target;
} }
await EnsureClientsAdded(E.Origin, E.Target); await EnsureClientsAdded(gameEvent.Origin, gameEvent.Target);
await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(S), S.CurrentMap.Name, killInfo[7], killInfo[8], await Manager.AddScriptHit(false, gameEvent.Time, gameEvent.Origin, gameEvent.Target, StatManager.GetIdForServer(server), server.CurrentMap.Name, killInfo[7], killInfo[8],
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]); killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]);
} }
@ -112,42 +113,42 @@ namespace IW4MAdmin.Plugins.Stats
} }
break; break;
case GameEvent.EventType.Kill: case GameEvent.EventType.Kill:
if (!ShouldIgnoreEvent(E.Origin, E.Target)) if (!ShouldIgnoreEvent(gameEvent.Origin, gameEvent.Target))
{ {
// this treats "world" damage as self damage // this treats "world" damage as self damage
if (IsWorldDamage(E.Origin)) if (IsWorldDamage(gameEvent.Origin))
{ {
E.Origin = E.Target; gameEvent.Origin = gameEvent.Target;
} }
await EnsureClientsAdded(E.Origin, E.Target); await EnsureClientsAdded(gameEvent.Origin, gameEvent.Target);
await Manager.AddStandardKill(E.Origin, E.Target); await Manager.AddStandardKill(gameEvent.Origin, gameEvent.Target);
} }
break; break;
case GameEvent.EventType.Damage: case GameEvent.EventType.Damage:
if (!ShouldIgnoreEvent(E.Origin, E.Target)) if (!ShouldIgnoreEvent(gameEvent.Origin, gameEvent.Target))
{ {
// this treats "world" damage as self damage // this treats "world" damage as self damage
if (IsWorldDamage(E.Origin)) if (IsWorldDamage(gameEvent.Origin))
{ {
E.Origin = E.Target; gameEvent.Origin = gameEvent.Target;
} }
Manager.AddDamageEvent(E.Data, E.Origin.ClientId, E.Target.ClientId, StatManager.GetIdForServer(S)); Manager.AddDamageEvent(gameEvent.Data, gameEvent.Origin.ClientId, gameEvent.Target.ClientId, StatManager.GetIdForServer(server));
} }
break; break;
case GameEvent.EventType.ScriptDamage: case GameEvent.EventType.ScriptDamage:
killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0]; killInfo = (gameEvent.Data != null) ? gameEvent.Data.Split(';') : new string[0];
if ((S.CustomCallback || ShouldOverrideAnticheatSetting(S)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(E.Origin, E.Target)) if ((server.CustomCallback || ShouldOverrideAnticheatSetting(server)) && killInfo.Length >= 18 && !ShouldIgnoreEvent(gameEvent.Origin, gameEvent.Target))
{ {
// this treats "world" damage as self damage // this treats "world" damage as self damage
if (IsWorldDamage(E.Origin)) if (IsWorldDamage(gameEvent.Origin))
{ {
E.Origin = E.Target; gameEvent.Origin = gameEvent.Target;
} }
await EnsureClientsAdded(E.Origin, E.Target); await EnsureClientsAdded(gameEvent.Origin, gameEvent.Target);
await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(S), S.CurrentMap.Name, killInfo[7], killInfo[8], await Manager.AddScriptHit(true, gameEvent.Time, gameEvent.Origin, gameEvent.Target, StatManager.GetIdForServer(server), server.CurrentMap.Name, killInfo[7], killInfo[8],
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]); killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15], killInfo[16], killInfo[17]);
} }
@ -165,7 +166,7 @@ namespace IW4MAdmin.Plugins.Stats
foreach (var calculator in _statCalculators) foreach (var calculator in _statCalculators)
{ {
await calculator.CalculateForEvent(E); await calculator.CalculateForEvent(gameEvent);
} }
} }
@ -188,23 +189,22 @@ namespace IW4MAdmin.Plugins.Stats
"/Stats/TopPlayersAsync"); "/Stats/TopPlayersAsync");
// meta data info // meta data info
async Task<IEnumerable<InformationResponse>> getStats(ClientPaginationRequest request) async Task<IEnumerable<InformationResponse>> GetStats(ClientPaginationRequest request, CancellationToken token = default)
{ {
IList<EFClientStatistics> clientStats;
await using var ctx = _databaseContextFactory.CreateContext(enableTracking: false); await using var ctx = _databaseContextFactory.CreateContext(enableTracking: false);
clientStats = await ctx.Set<EFClientStatistics>().Where(c => c.ClientId == request.ClientId).ToListAsync(); IList<EFClientStatistics> clientStats = await ctx.Set<EFClientStatistics>().Where(c => c.ClientId == request.ClientId).ToListAsync(token);
int kills = clientStats.Sum(c => c.Kills); var kills = clientStats.Sum(c => c.Kills);
int deaths = clientStats.Sum(c => c.Deaths); var deaths = clientStats.Sum(c => c.Deaths);
double kdr = Math.Round(kills / (double)deaths, 2); var kdr = Math.Round(kills / (double)deaths, 2);
var validPerformanceValues = clientStats.Where(c => c.Performance > 0); var validPerformanceValues = clientStats.Where(c => c.Performance > 0).ToList();
int performancePlayTime = validPerformanceValues.Sum(s => s.TimePlayed); var performancePlayTime = validPerformanceValues.Sum(s => s.TimePlayed);
double performance = Math.Round(validPerformanceValues.Sum(c => c.Performance * c.TimePlayed / performancePlayTime), 2); var performance = Math.Round(validPerformanceValues.Sum(c => c.Performance * c.TimePlayed / performancePlayTime), 2);
double spm = Math.Round(clientStats.Sum(c => c.SPM) / clientStats.Where(c => c.SPM > 0).Count(), 1); var spm = Math.Round(clientStats.Sum(c => c.SPM) / clientStats.Count(c => c.SPM > 0), 1);
return new List<InformationResponse>() return new List<InformationResponse>
{ {
new InformationResponse() new InformationResponse
{ {
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_RANKING"], Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_RANKING"],
Value = "#" + (await Manager.GetClientOverallRanking(request.ClientId)).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Value = "#" + (await Manager.GetClientOverallRanking(request.ClientId)).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
@ -212,7 +212,7 @@ namespace IW4MAdmin.Plugins.Stats
Order = 0, Order = 0,
Type = MetaType.Information Type = MetaType.Information
}, },
new InformationResponse() new InformationResponse
{ {
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KILLS"], Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KILLS"],
Value = kills.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Value = kills.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
@ -220,7 +220,7 @@ namespace IW4MAdmin.Plugins.Stats
Order = 1, Order = 1,
Type = MetaType.Information Type = MetaType.Information
}, },
new InformationResponse() new InformationResponse
{ {
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_DEATHS"], Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_DEATHS"],
Value = deaths.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Value = deaths.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
@ -228,7 +228,7 @@ namespace IW4MAdmin.Plugins.Stats
Order = 2, Order = 2,
Type = MetaType.Information Type = MetaType.Information
}, },
new InformationResponse() new InformationResponse
{ {
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KDR"], Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KDR"],
Value = kdr.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Value = kdr.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
@ -236,7 +236,7 @@ namespace IW4MAdmin.Plugins.Stats
Order = 3, Order = 3,
Type = MetaType.Information Type = MetaType.Information
}, },
new InformationResponse() new InformationResponse
{ {
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_PERFORMANCE"], Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_PERFORMANCE"],
Value = performance.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Value = performance.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
@ -244,7 +244,7 @@ namespace IW4MAdmin.Plugins.Stats
Order = 4, Order = 4,
Type = MetaType.Information Type = MetaType.Information
}, },
new InformationResponse() new InformationResponse
{ {
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_META_SPM"], Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_META_SPM"],
Value = spm.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Value = spm.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
@ -255,15 +255,13 @@ namespace IW4MAdmin.Plugins.Stats
}; };
} }
async Task<IEnumerable<InformationResponse>> getAnticheatInfo(ClientPaginationRequest request) async Task<IEnumerable<InformationResponse>> GetAnticheatInfo(ClientPaginationRequest request, CancellationToken token = default)
{ {
IList<EFClientStatistics> clientStats; await using var context = _databaseContextFactory.CreateContext(enableTracking: false);
IList<EFClientStatistics> clientStats = await context.Set<EFClientStatistics>()
await using var ctx = _databaseContextFactory.CreateContext(enableTracking: false);
clientStats = await ctx.Set<EFClientStatistics>()
.Include(c => c.HitLocations) .Include(c => c.HitLocations)
.Where(c => c.ClientId == request.ClientId) .Where(c => c.ClientId == request.ClientId)
.ToListAsync(); .ToListAsync(token);
double headRatio = 0; double headRatio = 0;
double chestRatio = 0; double chestRatio = 0;
@ -271,9 +269,9 @@ namespace IW4MAdmin.Plugins.Stats
double chestAbdomenRatio = 0; double chestAbdomenRatio = 0;
double hitOffsetAverage = 0; double hitOffsetAverage = 0;
double averageSnapValue = 0; double averageSnapValue = 0;
double maxStrain = clientStats.Count(c => c.MaxStrain > 0) == 0 ? 0 : clientStats.Max(cs => cs.MaxStrain); var maxStrain = clientStats.Any(c => c.MaxStrain > 0) ? 0 : clientStats.Max(cs => cs.MaxStrain);
if (clientStats.Where(cs => cs.HitLocations.Count > 0).FirstOrDefault() != null) if (clientStats.Any(cs => cs.HitLocations.Count > 0))
{ {
chestRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => chestRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(c =>
c.HitLocations.First(hl => hl.Location == (int)IW4Info.HitLocation.torso_upper).HitCount) / c.HitLocations.First(hl => hl.Location == (int)IW4Info.HitLocation.torso_upper).HitCount) /
@ -291,12 +289,12 @@ namespace IW4MAdmin.Plugins.Stats
(double)clientStats.Where(c => c.HitLocations.Count > 0) (double)clientStats.Where(c => c.HitLocations.Count > 0)
.Sum(c => c.HitLocations.Where(hl => hl.Location != (int)IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); .Sum(c => c.HitLocations.Where(hl => hl.Location != (int)IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0);
var validOffsets = clientStats.Where(c => c.HitLocations.Count(hl => hl.HitCount > 0) > 0).SelectMany(hl => hl.HitLocations); var validOffsets = clientStats.Where(c => c.HitLocations.Count(hl => hl.HitCount > 0) > 0).SelectMany(hl => hl.HitLocations).ToList();
hitOffsetAverage = validOffsets.Sum(o => o.HitCount * o.HitOffsetAverage) / (double)validOffsets.Sum(o => o.HitCount); hitOffsetAverage = validOffsets.Sum(o => o.HitCount * o.HitOffsetAverage) / (double)validOffsets.Sum(o => o.HitCount);
averageSnapValue = clientStats.Any(_stats => _stats.AverageSnapValue > 0) ? clientStats.Where(_stats => _stats.AverageSnapValue > 0).Average(_stat => _stat.AverageSnapValue) : 0; averageSnapValue = clientStats.Any(_stats => _stats.AverageSnapValue > 0) ? clientStats.Where(_stats => _stats.AverageSnapValue > 0).Average(_stat => _stat.AverageSnapValue) : 0;
} }
return new List<InformationResponse>() return new List<InformationResponse>
{ {
new InformationResponse() new InformationResponse()
{ {
@ -372,9 +370,9 @@ namespace IW4MAdmin.Plugins.Stats
}; };
} }
async Task<IEnumerable<MessageResponse>> getMessages(ClientPaginationRequest request) async Task<IEnumerable<MessageResponse>> GetMessages(ClientPaginationRequest request, CancellationToken token = default)
{ {
var query = new ChatSearchQuery() var query = new ChatSearchQuery
{ {
ClientId = request.ClientId, ClientId = request.ClientId,
Before = request.Before, Before = request.Before,
@ -388,49 +386,49 @@ namespace IW4MAdmin.Plugins.Stats
if (Config.Configuration().AnticheatConfiguration.Enable) if (Config.Configuration().AnticheatConfiguration.Enable)
{ {
_metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information, getAnticheatInfo); _metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information, GetAnticheatInfo);
} }
_metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information, getStats); _metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information, GetStats);
_metaService.AddRuntimeMeta<ClientPaginationRequest, MessageResponse>(MetaType.ChatMessage, getMessages); _metaService.AddRuntimeMeta<ClientPaginationRequest, MessageResponse>(MetaType.ChatMessage, GetMessages);
async Task<string> totalKills(Server server) async Task<string> TotalKills(Server server)
{ {
await using var context = _databaseContextFactory.CreateContext(false); await using var context = _databaseContextFactory.CreateContext(false);
long kills = await context.Set<EFServerStatistics>().Where(s => s.Active).SumAsync(s => s.TotalKills); var kills = await context.Set<EFServerStatistics>().Where(s => s.Active).SumAsync(s => s.TotalKills);
return kills.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)); return kills.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName));
} }
async Task<string> totalPlayTime(Server server) async Task<string> TotalPlayTime(Server server)
{ {
await using var context = _databaseContextFactory.CreateContext(false); await using var context = _databaseContextFactory.CreateContext(false);
long playTime = await context.Set<EFServerStatistics>().Where(s => s.Active).SumAsync(s => s.TotalPlayTime); var playTime = await context.Set<EFServerStatistics>().Where(s => s.Active).SumAsync(s => s.TotalPlayTime);
return (playTime / 3600.0).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)); return (playTime / 3600.0).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName));
} }
async Task<string> topStats(Server s) async Task<string> TopStats(Server s)
{ {
// todo: this needs to needs to be updated when we DI the lookup // todo: this needs to needs to be updated when we DI the lookup
return string.Join(Environment.NewLine, await Commands.TopStats.GetTopStats(s, Utilities.CurrentLocalization.LocalizationIndex)); return string.Join(Environment.NewLine, await Commands.TopStats.GetTopStats(s, Utilities.CurrentLocalization.LocalizationIndex));
} }
async Task<string> mostPlayed(Server s) async Task<string> MostPlayed(Server s)
{ {
// todo: this needs to needs to be updated when we DI the lookup // todo: this needs to needs to be updated when we DI the lookup
return string.Join(Environment.NewLine, await Commands.MostPlayedCommand.GetMostPlayed(s, Utilities.CurrentLocalization.LocalizationIndex, _databaseContextFactory)); return string.Join(Environment.NewLine, await Commands.MostPlayedCommand.GetMostPlayed(s, Utilities.CurrentLocalization.LocalizationIndex, _databaseContextFactory));
} }
async Task<string> mostKills(Server gameServer) async Task<string> MostKills(Server gameServer)
{ {
return string.Join(Environment.NewLine, return string.Join(Environment.NewLine,
await Commands.MostKillsCommand.GetMostKills(StatManager.GetIdForServer(gameServer), Config.Configuration(), _databaseContextFactory, _translationLookup)); await Commands.MostKillsCommand.GetMostKills(StatManager.GetIdForServer(gameServer), Config.Configuration(), _databaseContextFactory, _translationLookup));
} }
manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills)); manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", TotalKills));
manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", totalPlayTime)); manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", TotalPlayTime));
manager.GetMessageTokens().Add(new MessageToken("TOPSTATS", topStats)); manager.GetMessageTokens().Add(new MessageToken("TOPSTATS", TopStats));
manager.GetMessageTokens().Add(new MessageToken("MOSTPLAYED", mostPlayed)); manager.GetMessageTokens().Add(new MessageToken("MOSTPLAYED", MostPlayed));
manager.GetMessageTokens().Add(new MessageToken("MOSTKILLS", mostKills)); manager.GetMessageTokens().Add(new MessageToken("MOSTKILLS", MostKills));
if (Config.Configuration().EnableAdvancedMetrics) if (Config.Configuration().EnableAdvancedMetrics)
{ {
@ -445,7 +443,7 @@ namespace IW4MAdmin.Plugins.Stats
await _serverDistributionCalculator.Initialize(); await _serverDistributionCalculator.Initialize();
} }
public Task OnTickAsync(Server S) public Task OnTickAsync(Server server)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }