From 02622ea7de6f31ee503ac68355e9e167843158a1 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Thu, 25 Apr 2019 13:00:54 -0500 Subject: [PATCH] update application version ignore stat events of bots if they are ignored limit max number of bot profiles to 18, greater than 18 wraps prevent anti cheat from running on bot events create localization folder on publish so copying over doesn't fail include quick message mapping on webfront server history chat make gravatar on profile not repeat --- Application/Application.csproj | 6 +-- Application/ApplicationManager.cs | 2 +- Application/BuildScripts/PostPublish.bat | 10 ++++ Application/IW4MServer.cs | 33 ++++++++----- Plugins/Stats/Controllers/StatsController.cs | 1 - Plugins/Stats/Helpers/StatManager.cs | 49 ++++++++------------ Plugins/Stats/Plugin.cs | 41 +++++++--------- SharedLibraryCore/Server.cs | 2 +- SharedLibraryCore/Utilities.cs | 3 +- WebfrontCore/wwwroot/css/profile.css | 2 + 10 files changed, 78 insertions(+), 71 deletions(-) diff --git a/Application/Application.csproj b/Application/Application.csproj index c781f165..176c3398 100644 --- a/Application/Application.csproj +++ b/Application/Application.csproj @@ -6,7 +6,7 @@ 2.2.2 false RaidMax.IW4MAdmin.Application - 2.2.6.4 + 2.2.6.5 RaidMax Forever None IW4MAdmin @@ -31,8 +31,8 @@ true true - 2.2.6.4 - 2.2.6.4 + 2.2.6.5 + 2.2.6.5 diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs index 2ca81957..a94b01af 100644 --- a/Application/ApplicationManager.cs +++ b/Application/ApplicationManager.cs @@ -133,7 +133,7 @@ namespace IW4MAdmin.Application catch (Exception ex) { newEvent.FailReason = GameEvent.EventFailReason.Exception; - Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_EXCEPTION"]} {newEvent.Owner}"); + Logger.WriteError(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_EXCEPTION"].FormatExt(newEvent.Owner)); Logger.WriteDebug(ex.GetExceptionInfo()); } diff --git a/Application/BuildScripts/PostPublish.bat b/Application/BuildScripts/PostPublish.bat index f9c4d92a..0f159edc 100644 --- a/Application/BuildScripts/PostPublish.bat +++ b/Application/BuildScripts/PostPublish.bat @@ -97,6 +97,16 @@ if "%CurrentConfiguration%" == "Release" ( if exist "%SolutionDir%Publish\Windows\refs" move "%SolutionDir%Publish\Windows\refs" "%SolutionDir%Publish\Windows\Lib\refs" ) +if "%CurrentConfiguration%" == "Prerelease" ( + echo PR-LOC + if not exist "%SolutionDir%Publish\WindowsPrerelease\Localization" md "%SolutionDir%Publish\WindowsPrerelease\Localization" +) + +if "%CurrentConfiguration%" == "Release" ( + echo R-LOC + if not exist "%SolutionDir%Publish\Windows\Localization" md "%SolutionDir%Publish\Windows\Localization" +) + echo making start scripts @(echo @echo off && echo @title IW4MAdmin && echo dotnet Lib\IW4MAdmin.dll && echo pause) > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.cmd" @(echo @echo off && echo @title IW4MAdmin && echo dotnet Lib\IW4MAdmin.dll && echo pause) > "%SolutionDir%Publish\Windows\StartIW4MAdmin.cmd" diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index b2524429..30f1825d 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -189,6 +189,10 @@ namespace IW4MAdmin if (E.Type == GameEvent.EventType.ConnectionRestored) { + if (Throttled) + { + Logger.WriteVerbose(loc["MANAGER_CONNECTION_REST"].FormatExt($"[{IP}:{Port}]")); + } Logger.WriteInfo("Connection restored to server, so we are no longer throttling the poll rate"); Throttled = false; } @@ -390,18 +394,27 @@ namespace IW4MAdmin { E.Data = E.Data.StripColors(); - if (E.Data.Length > 0) + if (E.Data?.Length > 0) { - // this may be a fix for a hard to reproduce null exception error - lock (ChatHistory) + string message = E.Data; + if (E.Data.IsQuickMessage()) { - ChatHistory.Add(new ChatInfo() + try { - Name = E.Origin.Name, - Message = E.Data ?? "NULL", - Time = DateTime.UtcNow - }); + message = Manager.GetApplicationSettings().Configuration() + .QuickMessages + .First(_qm => _qm.Game == GameName) + .Messages[E.Data.Substring(1)]; + } + catch { } } + + ChatHistory.Add(new ChatInfo() + { + Name = E.Origin.Name, + Message = message, + Time = DateTime.UtcNow + }); } } @@ -649,8 +662,6 @@ namespace IW4MAdmin if (ConnectionErrors > 0) { - Logger.WriteVerbose(loc["MANAGER_CONNECTION_REST"].FormatExt($"[{IP}:{Port}]")); - var _event = new GameEvent() { Type = GameEvent.EventType.ConnectionRestored, @@ -921,7 +932,7 @@ namespace IW4MAdmin #if !DEBUG else { - string formattedKick = String.Format(RconParser.Configuration.CommandPrefixes.Kick, Target.ClientNumber, $"{loc["SERVER_KICK_TEXT"]} - ^5{Reason}^7"); + string formattedKick = string.Format(RconParser.Configuration.CommandPrefixes.Kick, Target.ClientNumber, $"{loc["SERVER_KICK_TEXT"]} - ^5{Reason}^7"); await Target.CurrentServer.ExecuteCommandAsync(formattedKick); } #endif diff --git a/Plugins/Stats/Controllers/StatsController.cs b/Plugins/Stats/Controllers/StatsController.cs index 1874736b..28554a4a 100644 --- a/Plugins/Stats/Controllers/StatsController.cs +++ b/Plugins/Stats/Controllers/StatsController.cs @@ -91,7 +91,6 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers .First(_qm => _qm.Game == message.ServerGame); message.Message = quickMessages.Messages[message.Message.Substring(1)]; message.IsQuickMessage = true; - } catch { } } diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs index edc3a0d6..27a6b098 100644 --- a/Plugins/Stats/Helpers/StatManager.cs +++ b/Plugins/Stats/Helpers/StatManager.cs @@ -13,7 +13,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -537,7 +536,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers return; } - // incase the add palyer event get delayed + // incase the add player event get delayed if (!Servers[serverId].PlayerStats.ContainsKey(attacker.ClientId)) { await AddPlayer(attacker); @@ -571,7 +570,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers ctx.Set().Add(hit); } - if (Plugin.Config.Configuration().EnableAntiCheat) + if (Plugin.Config.Configuration().EnableAntiCheat && !attacker.IsBot) { if (clientDetection.QueuedHits.Count > Detection.QUEUE_COUNT) { @@ -580,7 +579,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers clientDetection.QueuedHits = clientDetection.QueuedHits.OrderBy(_hits => _hits.TimeOffset).ToList(); var oldestHit = clientDetection.QueuedHits.First(); clientDetection.QueuedHits.RemoveAt(0); - ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), clientDetection, attacker, ctx); + await ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), clientDetection, attacker, ctx); } } @@ -589,7 +588,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers clientDetection.QueuedHits.Add(hit); } - ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx); + await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx); } ctx.Set().UpdateRange(clientStats.HitLocations); @@ -607,8 +606,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } } - void ApplyPenalty(DetectionPenaltyResult penalty, Detection clientDetection, EFClient attacker, DatabaseContext ctx) + async Task ApplyPenalty(DetectionPenaltyResult penalty, Detection clientDetection, EFClient attacker, DatabaseContext ctx) { + var penaltyClient = Utilities.IW4MAdminClient(attacker.CurrentServer); switch (penalty.ClientPenalty) { case Penalty.PenaltyType.Ban: @@ -616,22 +616,19 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { break; } - attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], new EFClient() - { - ClientId = 1, - AdministeredPenalties = new List() - { - new EFPenalty() - { - AutomatedOffense = penalty.Type == Cheat.Detection.DetectionType.Bone ? - $"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" : - $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}", - } - }, - Level = EFClient.Permission.Console, - CurrentServer = attacker.CurrentServer, - }, false); + penaltyClient.AdministeredPenalties = new List() + { + new EFPenalty() + { + AutomatedOffense = penalty.Type == Detection.DetectionType.Bone ? + $"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" : + $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}", + } + }; + + await attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], penaltyClient, false).WaitAsync(); + if (clientDetection.Tracker.HasChanges) { SaveTrackedSnapshots(clientDetection, ctx); @@ -647,23 +644,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers $"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" : $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}"; - attacker.Flag(flagReason, new EFClient() - { - ClientId = 1, - Level = EFClient.Permission.Console, - CurrentServer = attacker.CurrentServer, - }); + await attacker.Flag(flagReason, penaltyClient).WaitAsync(); if (clientDetection.Tracker.HasChanges) { SaveTrackedSnapshots(clientDetection, ctx); } - break; } } - void SaveTrackedSnapshots(Cheat.Detection clientDetection, DatabaseContext ctx) + void SaveTrackedSnapshots(Detection clientDetection, DatabaseContext ctx) { // todo: why does this cause duplicate primary key var change = clientDetection.Tracker.GetNextChange(); diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index 211b8ecb..3fade2cc 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore; using SharedLibraryCore; using SharedLibraryCore.Configuration; using SharedLibraryCore.Database; +using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; @@ -76,13 +77,8 @@ namespace IW4MAdmin.Plugins.Stats break; case GameEvent.EventType.ScriptKill: string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0]; - if (killInfo.Length >= 14) + if (killInfo.Length >= 14 && !ShouldIgnoreEvent(E.Origin, E.Target)) { - if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1) - { - return; - } - // this treats "world" damage as self damage if (E.Origin.ClientId <= 1) { @@ -99,13 +95,8 @@ namespace IW4MAdmin.Plugins.Stats } break; case GameEvent.EventType.Kill: - if (!E.Owner.CustomCallback) + if (!E.Owner.CustomCallback && !ShouldIgnoreEvent(E.Origin, E.Target)) { - if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1) - { - return; - } - // this treats "world" damage as self damage if (E.Origin.ClientId <= 1) { @@ -121,13 +112,8 @@ namespace IW4MAdmin.Plugins.Stats } break; case GameEvent.EventType.Damage: - if (!E.Owner.CustomCallback) + if (!E.Owner.CustomCallback && !ShouldIgnoreEvent(E.Origin, E.Target)) { - if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1) - { - return; - } - // this treats "world" damage as self damage if (E.Origin.ClientId <= 1) { @@ -144,13 +130,8 @@ namespace IW4MAdmin.Plugins.Stats break; case GameEvent.EventType.ScriptDamage: killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0]; - if (killInfo.Length >= 14) + if (killInfo.Length >= 14 && !ShouldIgnoreEvent(E.Origin, E.Target)) { - if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1) - { - return; - } - // this treats "world" damage as self damage if (E.Origin.ClientId <= 1) { @@ -500,5 +481,17 @@ namespace IW4MAdmin.Plugins.Stats await Manager.Sync(sv); } } + + /// + /// Indicates if the event should be ignored + /// (If the client id or target id is not a real client or the target/origin is a bot and ignore bots is turned on) + /// + /// + /// + /// + private bool ShouldIgnoreEvent(EFClient origin, EFClient target) + { + return ((origin.ClientId <= 1 && target.ClientId <= 1) || (target.IsBot || origin.IsBot) && ServerManager.GetApplicationSettings().Configuration().IgnoreBots); + } } } diff --git a/SharedLibraryCore/Server.cs b/SharedLibraryCore/Server.cs index 68102fa9..3bb26ba5 100644 --- a/SharedLibraryCore/Server.cs +++ b/SharedLibraryCore/Server.cs @@ -267,7 +267,7 @@ namespace SharedLibraryCore public override string ToString() { - return $"{IP}-{Port}"; + return $"{IP}:{Port}"; } protected async Task ScriptLoaded() diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index 18acdefa..8e451ffd 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -269,6 +269,7 @@ namespace SharedLibraryCore public static long ConvertLong(this string str) { str = str.Substring(0, Math.Min(str.Length, 16)); + int maxBots = 18; long id; if (str.Length <= 11) // 10 numeric characters + signed character @@ -288,7 +289,7 @@ namespace SharedLibraryCore if (!string.IsNullOrEmpty(bot)) { // should set their GUID to the negation of their 1 based index (-1 - -18) - return -(Convert.ToInt64(bot.Substring(3)) + 1); + return -(Convert.ToInt64(bot.Substring(3)) + 1) % maxBots; } return long.MinValue; diff --git a/WebfrontCore/wwwroot/css/profile.css b/WebfrontCore/wwwroot/css/profile.css index 55cf2e01..64127515 100644 --- a/WebfrontCore/wwwroot/css/profile.css +++ b/WebfrontCore/wwwroot/css/profile.css @@ -153,6 +153,8 @@ min-width: 8rem; min-height: 8rem; background-size: contain; + background-repeat: no-repeat; + background-position: center; } .profile-shortcode {