diff --git a/Application/EventParsers/BaseEventParser.cs b/Application/EventParsers/BaseEventParser.cs index 177c123d..13eb466c 100644 --- a/Application/EventParsers/BaseEventParser.cs +++ b/Application/EventParsers/BaseEventParser.cs @@ -75,27 +75,12 @@ namespace IW4MAdmin.Application.EventParsers public string URLProtocolFormat { get; set; } = "CoD://{{ip}}:{{port}}"; - public virtual GameEvent GetEvent(Server server, string logLine) + public virtual GameEvent GenerateGameEvent(string logLine) { logLine = Regex.Replace(logLine, @"([0-9]+:[0-9]+ |^[0-9]+ )", "").Trim(); string[] lineSplit = logLine.Split(';'); string eventType = lineSplit[0]; - // this is a "custom callback" event - if (eventType == "JoinTeam") - { - var origin = server.GetClientsAsList() - .FirstOrDefault(c => c.NetworkId == lineSplit[1].ConvertGuidToLong()); - - return new GameEvent() - { - Type = GameEvent.EventType.JoinTeam, - Data = logLine, - Origin = origin, - Owner = server - }; - } - if (eventType == "say" || eventType == "sayteam") { var matchResult = Regex.Match(logLine, Configuration.Say.Pattern); @@ -110,8 +95,7 @@ namespace IW4MAdmin.Application.EventParsers if (message.Length > 0) { - var origin = server.GetClientsAsList() - .First(c => c.NetworkId == matchResult.Groups[Configuration.Say.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong()); + long originId = matchResult.Groups[Configuration.Say.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(); if (message[0] == '!' || message[0] == '@') { @@ -119,8 +103,8 @@ namespace IW4MAdmin.Application.EventParsers { Type = GameEvent.EventType.Command, Data = message, - Origin = origin, - Owner = server, + Origin = new EFClient() { NetworkId = originId }, + Target = Utilities.IW4MAdminClient(), Message = message }; } @@ -129,8 +113,8 @@ namespace IW4MAdmin.Application.EventParsers { Type = GameEvent.EventType.Say, Data = message, - Origin = origin, - Owner = server, + Origin = new EFClient() { NetworkId = originId }, + Target = Utilities.IW4MAdminClient(), Message = message }; } @@ -139,111 +123,47 @@ namespace IW4MAdmin.Application.EventParsers if (eventType == "K") { - if (!server.CustomCallback) + + var match = Regex.Match(logLine, Configuration.Kill.Pattern); + + if (match.Success) { - var match = Regex.Match(logLine, Configuration.Kill.Pattern); + long originId = match.Groups[Configuration.Kill.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].Value.ToString().ConvertGuidToLong(1); + long targetId = match.Groups[Configuration.Kill.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].Value.ToString().ConvertGuidToLong(); - if (match.Success) + return new GameEvent() { - string originId = match.Groups[Configuration.Kill.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].Value.ToString(); - string targetId = match.Groups[Configuration.Kill.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].Value.ToString(); - - var origin = !string.IsNullOrEmpty(originId) ? server.GetClientsAsList() - .First(c => c.NetworkId == originId.ConvertGuidToLong()) : - Utilities.IW4MAdminClient(server); - - var target = !string.IsNullOrEmpty(targetId) ? server.GetClientsAsList() - .First(c => c.NetworkId == targetId.ConvertGuidToLong()) : - Utilities.IW4MAdminClient(server); - - return new GameEvent() - { - Type = GameEvent.EventType.Kill, - Data = logLine, - Origin = origin, - Target = target, - Owner = server - }; - } + Type = GameEvent.EventType.Kill, + Data = logLine, + Origin = new EFClient() { NetworkId = originId }, + Target = new EFClient() { NetworkId = targetId }, + }; } } - if (eventType == "ScriptKill") - { - long originId = lineSplit[1].ConvertGuidToLong(); - long targetId = lineSplit[2].ConvertGuidToLong(); - - var origin = originId == long.MinValue ? Utilities.IW4MAdminClient(server) : - server.GetClientsAsList().First(c => c.NetworkId == originId); - var target = targetId == long.MinValue ? Utilities.IW4MAdminClient(server) : - server.GetClientsAsList().FirstOrDefault(c => c.NetworkId == targetId) ?? Utilities.IW4MAdminClient(server); - - return new GameEvent() - { - Type = GameEvent.EventType.ScriptKill, - Data = logLine, - Origin = origin, - Target = target, - Owner = server - }; - } - - if (eventType == "ScriptDamage") - { - long originId = lineSplit[1].ConvertGuidToLong(); - long targetId = lineSplit[2].ConvertGuidToLong(); - - var origin = originId == long.MinValue ? Utilities.IW4MAdminClient(server) : - server.GetClientsAsList().First(c => c.NetworkId == originId); - var target = targetId == long.MinValue ? Utilities.IW4MAdminClient(server) : - server.GetClientsAsList().FirstOrDefault(c => c.NetworkId == targetId) ?? Utilities.IW4MAdminClient(server); - - return new GameEvent() - { - Type = GameEvent.EventType.ScriptDamage, - Data = logLine, - Origin = origin, - Target = target, - Owner = server - }; - } - - // damage if (eventType == "D") { - if (!server.CustomCallback) - { var regexMatch = Regex.Match(logLine, Configuration.Damage.Pattern); if (regexMatch.Success) { - string originId = regexMatch.Groups[Configuration.Damage.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString(); - string targetId = regexMatch.Groups[Configuration.Damage.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].ToString(); - - var origin = !string.IsNullOrEmpty(originId) ? server.GetClientsAsList() - .First(c => c.NetworkId == originId.ConvertGuidToLong()) : - Utilities.IW4MAdminClient(server); - - var target = !string.IsNullOrEmpty(targetId) ? server.GetClientsAsList() - .First(c => c.NetworkId == targetId.ConvertGuidToLong()) : - Utilities.IW4MAdminClient(server); + long originId = regexMatch.Groups[Configuration.Damage.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(1); + long targetId = regexMatch.Groups[Configuration.Damage.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].ToString().ConvertGuidToLong(); return new GameEvent() { Type = GameEvent.EventType.Damage, Data = logLine, - Origin = origin, - Target = target, - Owner = server + Origin = new EFClient() { NetworkId = originId }, + Target = new EFClient() { NetworkId = targetId } }; } - } } - // join if (eventType == "J") { var regexMatch = Regex.Match(logLine, Configuration.Join.Pattern); + if (regexMatch.Success) { bool isBot = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().Contains("bot"); @@ -252,7 +172,6 @@ namespace IW4MAdmin.Application.EventParsers { Type = GameEvent.EventType.PreConnect, Data = logLine, - Owner = server, Origin = new EFClient() { CurrentAlias = new EFAlias() @@ -262,9 +181,9 @@ namespace IW4MAdmin.Application.EventParsers NetworkId = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(), ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()), State = EFClient.ClientState.Connecting, - CurrentServer = server, IsBot = isBot - } + }, + Target = Utilities.IW4MAdminClient() }; } } @@ -278,7 +197,6 @@ namespace IW4MAdmin.Application.EventParsers { Type = GameEvent.EventType.PreDisconnect, Data = logLine, - Owner = server, Origin = new EFClient() { CurrentAlias = new EFAlias() @@ -288,7 +206,8 @@ namespace IW4MAdmin.Application.EventParsers NetworkId = regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(), ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()), State = EFClient.ClientState.Disconnecting - } + }, + Target = Utilities.IW4MAdminClient() }; } } @@ -299,9 +218,8 @@ namespace IW4MAdmin.Application.EventParsers { Type = GameEvent.EventType.MapEnd, Data = lineSplit[0], - Origin = Utilities.IW4MAdminClient(server), - Target = Utilities.IW4MAdminClient(server), - Owner = server + Origin = Utilities.IW4MAdminClient(), + Target = Utilities.IW4MAdminClient(), }; } @@ -313,19 +231,59 @@ namespace IW4MAdmin.Application.EventParsers { Type = GameEvent.EventType.MapChange, Data = lineSplit[0], - Origin = Utilities.IW4MAdminClient(server), - Target = Utilities.IW4MAdminClient(server), - Owner = server, + Origin = Utilities.IW4MAdminClient(), + Target = Utilities.IW4MAdminClient(), Extra = dump.DictionaryFromKeyValue() }; } + // this is a custom event printed out by _customcallbacks.gsc (used for team balance) + if (eventType == "JoinTeam") + { + return new GameEvent() + { + Type = GameEvent.EventType.JoinTeam, + Data = logLine, + Origin = new EFClient() { NetworkId = lineSplit[1].ConvertGuidToLong() }, + Target = Utilities.IW4MAdminClient() + }; + } + + // this is a custom event printed out by _customcallbacks.gsc (used for anticheat) + if (eventType == "ScriptKill") + { + long originId = lineSplit[1].ConvertGuidToLong(1); + long targetId = lineSplit[2].ConvertGuidToLong(); + + return new GameEvent() + { + Type = GameEvent.EventType.ScriptKill, + Data = logLine, + Origin = new EFClient() { NetworkId = originId }, + Target = new EFClient() { NetworkId = targetId } + }; + } + + // this is a custom event printed out by _customcallbacks.gsc (used for anticheat) + if (eventType == "ScriptDamage") + { + long originId = lineSplit[1].ConvertGuidToLong(1); + long targetId = lineSplit[2].ConvertGuidToLong(); + + return new GameEvent() + { + Type = GameEvent.EventType.ScriptDamage, + Data = logLine, + Origin = new EFClient() { NetworkId = originId }, + Target = new EFClient() { NetworkId = targetId } + }; + } + return new GameEvent() { Type = GameEvent.EventType.Unknown, - Origin = Utilities.IW4MAdminClient(server), - Target = Utilities.IW4MAdminClient(server), - Owner = server + Origin = Utilities.IW4MAdminClient(), + Target = Utilities.IW4MAdminClient() }; } } diff --git a/Application/IO/GameLogReader.cs b/Application/IO/GameLogReader.cs index a8c639c2..807c756c 100644 --- a/Application/IO/GameLogReader.cs +++ b/Application/IO/GameLogReader.cs @@ -3,7 +3,7 @@ using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; using System.IO; -using System.Text; +using System.Linq; using System.Threading.Tasks; namespace IW4MAdmin.Application.IO @@ -12,6 +12,7 @@ namespace IW4MAdmin.Application.IO { IEventParser Parser; readonly string LogFile; + private bool? ignoreBots; public long Length => new FileInfo(LogFile).Length; @@ -25,16 +26,20 @@ namespace IW4MAdmin.Application.IO public async Task> ReadEventsFromLog(Server server, long fileSizeDiff, long startPosition) { + if (!ignoreBots.HasValue) + { + ignoreBots = server.Manager.GetApplicationSettings().Configuration().IgnoreBots; + } + // allocate the bytes for the new log lines List logLines = new List(); // open the file as a stream using (var rd = new StreamReader(new FileStream(LogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Utilities.EncodingType)) { - // todo: max async // take the old start position and go back the number of new characters rd.BaseStream.Seek(-fileSizeDiff, SeekOrigin.End); - + string newLine; while (!string.IsNullOrEmpty(newLine = await rd.ReadLineAsync())) { @@ -51,10 +56,27 @@ namespace IW4MAdmin.Application.IO { try { - // todo: catch elsewhere - events.Add(Parser.GetEvent(server, eventLine)); + var gameEvent = Parser.GenerateGameEvent(eventLine); + // we don't want to add the even if ignoreBots is on and the event comes froma bot + if (!ignoreBots.Value || (ignoreBots.Value && (gameEvent.Origin.NetworkId != -1 || gameEvent.Target.NetworkId != -1))) + { + gameEvent.Owner = server; + // we need to pull the "live" versions of the client (only if the client id isn't IW4MAdmin + gameEvent.Origin = gameEvent.Origin.ClientId == 1 ? gameEvent.Origin : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Origin.NetworkId); + gameEvent.Target = gameEvent.Target.ClientId == 1 ? gameEvent.Target : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Target.NetworkId); + + events.Add(gameEvent); + } } - + + catch (InvalidOperationException) + { + if (!ignoreBots.Value) + { + server.Logger.WriteWarning("Could not find client in client list when parsing event line"); + } + } + catch (Exception e) { server.Logger.WriteWarning("Could not properly parse event line"); diff --git a/Application/IO/GameLogReaderHttp.cs b/Application/IO/GameLogReaderHttp.cs index de8ba742..47e112aa 100644 --- a/Application/IO/GameLogReaderHttp.cs +++ b/Application/IO/GameLogReaderHttp.cs @@ -4,6 +4,7 @@ using SharedLibraryCore; using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using static SharedLibraryCore.Utilities; @@ -18,6 +19,7 @@ namespace IW4MAdmin.Application.IO readonly IEventParser Parser; readonly IGameLogServer Api; readonly string logPath; + private bool? ignoreBots; public GameLogReaderHttp(Uri gameLogServerUri, string logPath, IEventParser parser) { @@ -35,6 +37,12 @@ namespace IW4MAdmin.Application.IO #if DEBUG == true server.Logger.WriteDebug($"Begin reading from http log"); #endif + + if (!ignoreBots.HasValue) + { + ignoreBots = server.Manager.GetApplicationSettings().Configuration().IgnoreBots; + } + var events = new List(); string b64Path = logPath; var response = await Api.Log(b64Path); @@ -52,16 +60,33 @@ namespace IW4MAdmin.Application.IO { try { - var e = Parser.GetEvent(server, eventLine); + var gameEvent = Parser.GenerateGameEvent(eventLine); + // we don't want to add the even if ignoreBots is on and the event comes froma bot + if (!ignoreBots.Value || (ignoreBots.Value && (gameEvent.Origin.NetworkId != -1 || gameEvent.Target.NetworkId != -1))) + { + gameEvent.Owner = server; + // we need to pull the "live" versions of the client (only if the client id isn't IW4MAdmin + gameEvent.Origin = gameEvent.Origin.ClientId == 1 ? gameEvent.Origin : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Origin.NetworkId); + gameEvent.Target = gameEvent.Target.ClientId == 1 ? gameEvent.Target : server.GetClientsAsList().First(_client => _client.NetworkId == gameEvent.Target.NetworkId); + + events.Add(gameEvent); + } #if DEBUG == true - server.Logger.WriteDebug($"Parsed event with id {e.Id} from http"); + server.Logger.WriteDebug($"Parsed event with id {gameEvent.Id} from http"); #endif - events.Add(e); + } + + catch (InvalidOperationException) + { + if (!ignoreBots.Value) + { + server.Logger.WriteWarning("Could not find client in client list when parsing event line"); + } } catch (Exception e) { - server.Logger.WriteWarning("Could not properly parse event line"); + server.Logger.WriteWarning("Could not properly parse remote event line"); server.Logger.WriteDebug(e.Message); server.Logger.WriteDebug(eventLine); } diff --git a/Plugins/ProfanityDeterment/Plugin.cs b/Plugins/ProfanityDeterment/Plugin.cs index 7bdd6b62..2adeac0d 100644 --- a/Plugins/ProfanityDeterment/Plugin.cs +++ b/Plugins/ProfanityDeterment/Plugin.cs @@ -1,11 +1,9 @@ -using System.Collections.Concurrent; -using System.Linq; +using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using System.Threading.Tasks; using SharedLibraryCore; using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; namespace IW4MAdmin.Plugins.ProfanityDeterment @@ -19,8 +17,6 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment public string Author => "RaidMax"; BaseConfigurationHandler Settings; - ConcurrentDictionary ProfanityCounts; - IManager Manager; public Task OnEventAsync(GameEvent E, Server S) { @@ -29,10 +25,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment if (E.Type == GameEvent.EventType.Connect) { - if (!ProfanityCounts.TryAdd(E.Origin.ClientId, new Tracking(E.Origin))) - { - S.Logger.WriteWarning("Could not add client to profanity tracking"); - } + E.Origin.SetAdditionalProperty("_profanityInfringements", 0); var objectionalWords = Settings.Configuration().OffensiveWords; bool containsObjectionalWord = objectionalWords.FirstOrDefault(w => E.Origin.Name.ToLower().Contains(w)) != null; @@ -54,10 +47,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment if (E.Type == GameEvent.EventType.Disconnect) { - if (!ProfanityCounts.TryRemove(E.Origin.ClientId, out Tracking old)) - { - S.Logger.WriteWarning("Could not remove client from profanity tracking"); - } + E.Origin.SetAdditionalProperty("_profanityInfringements", 0); } if (E.Type == GameEvent.EventType.Say) @@ -78,17 +68,17 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment if (containsObjectionalWord) { - var clientProfanity = ProfanityCounts[E.Origin.ClientId]; - if (clientProfanity.Infringements >= Settings.Configuration().KickAfterInfringementCount) + int profanityInfringments = E.Origin.GetAdditionalProperty("_profanityInfringements"); + + if (profanityInfringments >= Settings.Configuration().KickAfterInfringementCount) { - clientProfanity.Client.Kick(Settings.Configuration().ProfanityKickMessage, Utilities.IW4MAdminClient(E.Owner)); + E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, Utilities.IW4MAdminClient(E.Owner)); } - else if (clientProfanity.Infringements < Settings.Configuration().KickAfterInfringementCount) + else if (profanityInfringments < Settings.Configuration().KickAfterInfringementCount) { - clientProfanity.Infringements++; - - clientProfanity.Client.Warn(Settings.Configuration().ProfanityWarningMessage, Utilities.IW4MAdminClient(E.Owner)); + E.Origin.SetAdditionalProperty("_profanityInfringements", profanityInfringments + 1); + E.Origin.Warn(Settings.Configuration().ProfanityWarningMessage, Utilities.IW4MAdminClient(E.Owner)); } } } @@ -104,9 +94,6 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment Settings.Set((Configuration)new Configuration().Generate()); await Settings.Save(); } - - ProfanityCounts = new ConcurrentDictionary(); - Manager = manager; } public Task OnTickAsync(Server S) => Task.CompletedTask; diff --git a/Plugins/ProfanityDeterment/Tracking.cs b/Plugins/ProfanityDeterment/Tracking.cs deleted file mode 100644 index 440a8528..00000000 --- a/Plugins/ProfanityDeterment/Tracking.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using SharedLibraryCore.Database.Models; -using SharedLibraryCore.Objects; - -namespace IW4MAdmin.Plugins.ProfanityDeterment -{ - class Tracking - { - public EFClient Client { get; private set; } - public int Infringements { get; set; } - - public Tracking(EFClient client) - { - Client = client; - Infringements = 0; - } - } -} diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs index 5aea63a9..ace642c3 100644 --- a/Plugins/Stats/Helpers/StatManager.cs +++ b/Plugins/Stats/Helpers/StatManager.cs @@ -568,7 +568,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers ctx.Set().Add(hit); } - if (Plugin.Config.Configuration().EnableAntiCheat && !attacker.IsBot) + if (Plugin.Config.Configuration().EnableAntiCheat && !attacker.IsBot && attacker.ClientId != victim.ClientId) { if (clientDetection.QueuedHits.Count > Detection.QUEUE_COUNT) { @@ -577,8 +577,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers clientDetection.QueuedHits = clientDetection.QueuedHits.OrderBy(_hits => _hits.TimeOffset).ToList(); var oldestHit = clientDetection.QueuedHits.First(); clientDetection.QueuedHits.RemoveAt(0); - await ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), clientDetection, attacker, ctx); + await ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), attacker, ctx); } + + await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), attacker, ctx); } else @@ -586,7 +588,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers clientDetection.QueuedHits.Add(hit); } - await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx); + if (clientDetection.Tracker.HasChanges) + { + SaveTrackedSnapshots(clientDetection, ctx); + } } ctx.Set().UpdateRange(clientStats.HitLocations); @@ -604,7 +609,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } } - async Task ApplyPenalty(DetectionPenaltyResult penalty, Detection clientDetection, EFClient attacker, DatabaseContext ctx) + async Task ApplyPenalty(DetectionPenaltyResult penalty, EFClient attacker, DatabaseContext ctx) { var penaltyClient = Utilities.IW4MAdminClient(attacker.CurrentServer); switch (penalty.ClientPenalty) @@ -626,11 +631,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers }; await attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], penaltyClient, false).WaitAsync(Utilities.DefaultCommandTimeout, attacker.CurrentServer.Manager.CancellationToken); - - if (clientDetection.Tracker.HasChanges) - { - SaveTrackedSnapshots(clientDetection, ctx); - } break; case Penalty.PenaltyType.Flag: if (attacker.Level != EFClient.Permission.User) @@ -643,11 +643,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}"; await attacker.Flag(flagReason, penaltyClient).WaitAsync(Utilities.DefaultCommandTimeout, attacker.CurrentServer.Manager.CancellationToken); - - if (clientDetection.Tracker.HasChanges) - { - SaveTrackedSnapshots(clientDetection, ctx); - } break; } } @@ -655,7 +650,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers void SaveTrackedSnapshots(Detection clientDetection, DatabaseContext ctx) { // todo: why does this cause duplicate primary key - var change = clientDetection.Tracker.GetNextChange(); + _ = clientDetection.Tracker.GetNextChange(); + EFACSnapshot change; while ((change = clientDetection.Tracker.GetNextChange()) != default(EFACSnapshot)) { diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index 08fc5d4b..f4b1fefe 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -80,16 +80,11 @@ namespace IW4MAdmin.Plugins.Stats if (killInfo.Length >= 14 && !ShouldIgnoreEvent(E.Origin, E.Target)) { // this treats "world" damage as self damage - if (E.Origin.ClientId <= 1) + if (E.Origin.ClientId == 1) { E.Origin = E.Target; } - if (E.Target.ClientId <= 1) - { - E.Target = E.Origin; - } - await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, await StatManager.GetIdForServer(E.Owner), S.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]); } @@ -98,16 +93,11 @@ namespace IW4MAdmin.Plugins.Stats if (!E.Owner.CustomCallback && !ShouldIgnoreEvent(E.Origin, E.Target)) { // this treats "world" damage as self damage - if (E.Origin.ClientId <= 1) + if (E.Origin.ClientId == 1) { E.Origin = E.Target; } - if (E.Target.ClientId <= 1) - { - E.Target = E.Origin; - } - await Manager.AddStandardKill(E.Origin, E.Target); } break; @@ -115,16 +105,11 @@ namespace IW4MAdmin.Plugins.Stats if (!E.Owner.CustomCallback && !ShouldIgnoreEvent(E.Origin, E.Target)) { // this treats "world" damage as self damage - if (E.Origin.ClientId <= 1) + if (E.Origin.ClientId == 1) { E.Origin = E.Target; } - if (E.Target.ClientId <= 1) - { - E.Target = E.Origin; - } - Manager.AddDamageEvent(E.Data, E.Origin.ClientId, E.Target.ClientId, await StatManager.GetIdForServer(E.Owner)); } break; @@ -133,16 +118,11 @@ namespace IW4MAdmin.Plugins.Stats if (killInfo.Length >= 14 && !ShouldIgnoreEvent(E.Origin, E.Target)) { // this treats "world" damage as self damage - if (E.Origin.ClientId <= 1) + if (E.Origin.ClientId == 1) { E.Origin = E.Target; } - if (E.Target.ClientId <= 1) - { - E.Target = E.Origin; - } - await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, await StatManager.GetIdForServer(E.Owner), S.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]); } diff --git a/SharedLibraryCore/Interfaces/IEventParser.cs b/SharedLibraryCore/Interfaces/IEventParser.cs index 4f05ccd5..fc12944e 100644 --- a/SharedLibraryCore/Interfaces/IEventParser.cs +++ b/SharedLibraryCore/Interfaces/IEventParser.cs @@ -7,11 +7,10 @@ namespace SharedLibraryCore.Interfaces /// /// Generates a game event based on log line input /// - /// server the event occurred on /// single log line string /// /// todo: make this integrate without needing the server - GameEvent GetEvent(Server server, string logLine); + GameEvent GenerateGameEvent(string logLine); /// /// Get game specific folder prefix for log files /// diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index 65b9e30f..12befaf8 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -268,11 +268,16 @@ namespace SharedLibraryCore } } - public static long ConvertGuidToLong(this string str) + public static long ConvertGuidToLong(this string str, long? fallback = null) { str = str.Substring(0, Math.Min(str.Length, 16)); var bot = Regex.Match(str, @"bot[0-9]+").Value; + if (string.IsNullOrWhiteSpace(str) && fallback.HasValue) + { + return fallback.Value; + } + // this is a special case for Plutonium T6 if (str.Length <= 11 && long.TryParse(str, NumberStyles.Integer, CultureInfo.InvariantCulture, out long id)) // 10 numeric characters + signed character diff --git a/WebfrontCore/Controllers/ClientController.cs b/WebfrontCore/Controllers/ClientController.cs index cdb5ca6d..9fd35a40 100644 --- a/WebfrontCore/Controllers/ClientController.cs +++ b/WebfrontCore/Controllers/ClientController.cs @@ -121,6 +121,11 @@ namespace WebfrontCore.Controllers public async Task FindAsync(string clientName) { + if (string.IsNullOrWhiteSpace(clientName)) + { + return StatusCode(400); + } + var clientsDto = await Manager.GetClientService().FindClientsByIdentifier(clientName); ViewBag.Title = $"{clientsDto.Count} {Localization["WEBFRONT_CLIENT_SEARCH_MATCHING"]} \"{clientName}\"";