From aff19b957705a12a445929295f271bc85a710672 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Tue, 5 May 2020 18:49:30 -0500 Subject: [PATCH] [issue #129] Add most kills command/macro sneaky fix for tekno parser --- Plugins/ScriptPlugins/ParserTeknoMW3.js | 3 +- Plugins/Stats/Commands/MostKillsCommand.cs | 80 ++++++++++++++++++++++ Plugins/Stats/Config/StatsConfiguration.cs | 2 + Plugins/Stats/Plugin.cs | 12 +++- 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 Plugins/Stats/Commands/MostKillsCommand.cs diff --git a/Plugins/ScriptPlugins/ParserTeknoMW3.js b/Plugins/ScriptPlugins/ParserTeknoMW3.js index 3c7dcfa87..8f9edece9 100644 --- a/Plugins/ScriptPlugins/ParserTeknoMW3.js +++ b/Plugins/ScriptPlugins/ParserTeknoMW3.js @@ -3,7 +3,7 @@ var eventParser; var plugin = { author: 'RaidMax', - version: 0.4, + version: 0.5, name: 'Tekno MW3 Parser', isParser: true, @@ -15,6 +15,7 @@ var plugin = { eventParser = manager.GenerateDynamicEventParser(this.name); rconParser.Configuration.Status.Pattern = '^ *([0-9]+) +([0-9]+) +((?:[A-Z]+|[0-9]+)) +((?:[A-Z]|[0-9]){16,32}|0)\t +(.{0,16}) +([0-9]+) +(\\d+\\.\\d+\\.\\d+\\.\\d+\\:-?\\d{1,5}|0+\\.0+\\:-?\\d{1,5}|loopback) *$'; + rconParser.Configuration.StatusHeader.Pattern = 'num +score +ping +guid +name +lastmsg +address'; rconParser.Configuration.Status.AddMapping(104, 5); // RConName rconParser.Configuration.Status.AddMapping(103, 4); // RConNetworkId rconParser.Configuration.CommandPrefixes.RConGetInfo = undefined; diff --git a/Plugins/Stats/Commands/MostKillsCommand.cs b/Plugins/Stats/Commands/MostKillsCommand.cs new file mode 100644 index 000000000..3c57c226a --- /dev/null +++ b/Plugins/Stats/Commands/MostKillsCommand.cs @@ -0,0 +1,80 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Linq; +using System.Threading.Tasks; + +using SharedLibraryCore; +using IW4MAdmin.Plugins.Stats.Models; +using System.Collections.Generic; +using SharedLibraryCore.Database.Models; +using SharedLibraryCore.Configuration; +using SharedLibraryCore.Interfaces; +using IW4MAdmin.Plugins.Stats.Config; +using IW4MAdmin.Plugins.Stats.Helpers; + +namespace IW4MAdmin.Plugins.Stats.Commands +{ + class MostKillsCommand : Command + { + private readonly IDatabaseContextFactory _contextFactory; + + public MostKillsCommand(CommandConfiguration config, ITranslationLookup translationLookup, IDatabaseContextFactory contextFactory) : base(config, translationLookup) + { + Name = "mostkills"; + Description = translationLookup["PLUGINS_STATS_COMMANDS_MOSTKILLS_DESC"]; + Alias = "mk"; + Permission = EFClient.Permission.User; + + _contextFactory = contextFactory; + } + + public override async Task ExecuteAsync(GameEvent E) + { + var mostKills = await GetMostKills(StatManager.GetIdForServer(E.Owner), Plugin.Config.Configuration(), _contextFactory, _translationLookup); + if (!E.Message.IsBroadcastCommand()) + { + foreach (var stat in mostKills) + { + E.Origin.Tell(stat); + } + } + + else + { + foreach (var stat in mostKills) + { + E.Owner.Broadcast(stat); + } + } + } + + public static async Task> GetMostKills(long? serverId, StatsConfiguration config, IDatabaseContextFactory contextFactory, ITranslationLookup translationLookup) + { + using (var ctx = contextFactory.CreateContext(enableTracking: false)) + { + var dayInPast = DateTime.UtcNow.AddMonths(-config.MostKillsMaxInactivityDays); + + var iqStats = (from stats in ctx.Set() + join client in ctx.Clients + on stats.ClientId equals client.ClientId + join alias in ctx.Aliases + on client.CurrentAliasId equals alias.AliasId + where stats.ServerId == serverId + where client.Level != EFClient.Permission.Banned + where client.LastConnection >= dayInPast + orderby stats.Kills descending + select new + { + alias.Name, + stats.Kills + }) + .Take(config.MostKillsClientLimit); + + var iqList = await iqStats.ToListAsync(); + + return iqList.Select((stats, index) => translationLookup["PLUGINS_STATS_COMMANDS_MOSTKILLS_FORMAT"].FormatExt(index + 1, stats.Name, stats.Kills)) + .Prepend(Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_MOSTKILLS_HEADER"]); + } + } + } +} diff --git a/Plugins/Stats/Config/StatsConfiguration.cs b/Plugins/Stats/Config/StatsConfiguration.cs index 11c05b6e4..3d14423ae 100644 --- a/Plugins/Stats/Config/StatsConfiguration.cs +++ b/Plugins/Stats/Config/StatsConfiguration.cs @@ -14,6 +14,8 @@ namespace IW4MAdmin.Plugins.Stats.Config public List RecoilessWeapons { get; set; } public int TopPlayersMinPlayTime { get; set; } public bool StoreClientKills { get; set; } + public int MostKillsMaxInactivityDays { get; set; } = 30; + public int MostKillsClientLimit { get; set; } = 5; public IDictionary DetectionDistributions { get; set; } public IDictionary ServerDetectionTypes { get; set; } diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index 733439bf9..2ac9d905b 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -32,11 +32,14 @@ namespace IW4MAdmin.Plugins.Stats int scriptKillCount; #endif private readonly IDatabaseContextFactory _databaseContextFactory; + private readonly ITranslationLookup _translationLookup; - public Plugin(IConfigurationHandlerFactory configurationHandlerFactory, IDatabaseContextFactory databaseContextFactory) + public Plugin(IConfigurationHandlerFactory configurationHandlerFactory, IDatabaseContextFactory databaseContextFactory, + ITranslationLookup translationLookup) { Config = configurationHandlerFactory.GetConfigurationHandler("StatsPluginSettings"); _databaseContextFactory = databaseContextFactory; + _translationLookup = translationLookup; } public async Task OnEventAsync(GameEvent E, Server S) @@ -491,10 +494,17 @@ namespace IW4MAdmin.Plugins.Stats return string.Join(Environment.NewLine, await Commands.MostPlayedCommand.GetMostPlayed(s, Utilities.CurrentLocalization.LocalizationIndex)); } + async Task mostKills(Server gameServer) + { + return string.Join(Environment.NewLine, + await Commands.MostKillsCommand.GetMostKills(StatManager.GetIdForServer(gameServer), Config.Configuration(), _databaseContextFactory, _translationLookup)); + } + manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills)); manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", totalPlayTime)); manager.GetMessageTokens().Add(new MessageToken("TOPSTATS", topStats)); manager.GetMessageTokens().Add(new MessageToken("MOSTPLAYED", mostPlayed)); + manager.GetMessageTokens().Add(new MessageToken("MOSTKILLS", mostKills)); ServerManager = manager; Manager = new StatManager(manager, _databaseContextFactory, Config);