From 4645bd84e8fd0b950c55d6c4eb551561e3865626 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Thu, 13 Jun 2019 19:10:08 -0500 Subject: [PATCH] prevent partial client updates from setting things they shouldn't be *cough* mask *cough* setup shared library for NuGet package fix a couple things with offset detection calc get cod4x working again --- Application/EventParsers/BaseEventParser.cs | 4 +-- Plugins/ScriptPlugins/ParserCoD4x.js | 6 ++-- Plugins/ScriptPlugins/ParserIW4x.js | 2 +- Plugins/Stats/Cheat/Detection.cs | 4 +-- SharedLibraryCore/RCon/Connection.cs | 2 +- SharedLibraryCore/Services/ClientService.cs | 36 +++++++++++++-------- SharedLibraryCore/SharedLibraryCore.csproj | 8 +++++ SharedLibraryCore/Utilities.cs | 9 +++--- 8 files changed, 43 insertions(+), 28 deletions(-) diff --git a/Application/EventParsers/BaseEventParser.cs b/Application/EventParsers/BaseEventParser.cs index cb0f130b7..45dd9af20 100644 --- a/Application/EventParsers/BaseEventParser.cs +++ b/Application/EventParsers/BaseEventParser.cs @@ -36,7 +36,7 @@ namespace IW4MAdmin.Application.EventParsers Configuration.Join.AddMapping(ParserRegex.GroupType.OriginClientNumber, 3); Configuration.Join.AddMapping(ParserRegex.GroupType.OriginName, 4); - Configuration.Damage.Pattern = @"^(D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world);(.{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world);(.{1,24})?;((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$"; + Configuration.Damage.Pattern = @"^(D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world)?;(.{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world)?;(.{1,24})?;((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$"; Configuration.Damage.AddMapping(ParserRegex.GroupType.EventType, 1); Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2); Configuration.Damage.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3); @@ -51,7 +51,7 @@ namespace IW4MAdmin.Application.EventParsers Configuration.Damage.AddMapping(ParserRegex.GroupType.MeansOfDeath, 12); Configuration.Damage.AddMapping(ParserRegex.GroupType.HitLocation, 13); - Configuration.Kill.Pattern = @"^(K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world);(.{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world);(.{1,24})?;((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$"; + Configuration.Kill.Pattern = @"^(K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+);(-?[0-9]+);(axis|allies|world)?;(.{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+)?;-?([0-9]+);(axis|allies|world)?;(.{1,24})?;((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$"; Configuration.Kill.AddMapping(ParserRegex.GroupType.EventType, 1); Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetNetworkId, 2); Configuration.Kill.AddMapping(ParserRegex.GroupType.TargetClientNumber, 3); diff --git a/Plugins/ScriptPlugins/ParserCoD4x.js b/Plugins/ScriptPlugins/ParserCoD4x.js index 4e81fd901..d61670187 100644 --- a/Plugins/ScriptPlugins/ParserCoD4x.js +++ b/Plugins/ScriptPlugins/ParserCoD4x.js @@ -3,7 +3,7 @@ var eventParser; var plugin = { author: 'FrenchFry, RaidMax', - version: 0.4, + version: 0.5, name: 'CoD4x Parser', isParser: true, @@ -21,11 +21,11 @@ var plugin = { rconParser.Configuration.Dvar.Pattern = '^"(.+)" is: "(.+)?" default: "(.+)?" info: "(.+)?"$'; rconParser.Configuration.Dvar.AddMapping(109, 2); // DVAR latched value rconParser.Configuration.Dvar.AddMapping(110, 4); // dvar info - rconParser.Version = 'CoD4 X 1.8 win_mingw-x86 build 2055 May 2 2017'; + rconParser.Version = 'CoD4 X - win_mingw-x86 build 963 Mar 12 2019'; rconParser.GameName = 1; // IW3 eventParser.Configuration.GameDirectory = 'main'; - eventParser.Version = 'CoD4 X 1.8 win_mingw-x86 build 2055 May 2 2017'; + eventParser.Version = 'CoD4 X - win_mingw-x86 build 963 Mar 12 2019'; eventParser.GameName = 1; // IW3 eventParser.URLProtocolFormat = 'cod4://{{ip}}:{{port}}'; }, diff --git a/Plugins/ScriptPlugins/ParserIW4x.js b/Plugins/ScriptPlugins/ParserIW4x.js index cfcd8e9c2..70f683b2d 100644 --- a/Plugins/ScriptPlugins/ParserIW4x.js +++ b/Plugins/ScriptPlugins/ParserIW4x.js @@ -19,7 +19,7 @@ var plugin = { rconParser.Configuration.CommandPrefixes.Kick = 'clientkick {0} "{1}"'; rconParser.Configuration.CommandPrefixes.Ban = 'clientkick {0} "{1}"'; rconParser.Configuration.CommandPrefixes.TempBan = 'tempbanclient {0} "{1}"'; - eventParser.Configuration.GameDirectory = 'userraw'; + eventParser.Configuration.GameDirectory = 'userraw'; rconParser.Version = 'IW4x (v0.6.0)'; rconParser.GameName = 2; // IW4x diff --git a/Plugins/Stats/Cheat/Detection.cs b/Plugins/Stats/Cheat/Detection.cs index 008ad3b9c..26c4b2986 100644 --- a/Plugins/Stats/Cheat/Detection.cs +++ b/Plugins/Stats/Cheat/Detection.cs @@ -127,7 +127,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat int totalSessionHits = HitLocationCount.Sum(_hit => _hit.Value.Count); var weightedSessionAverage = HitLocationCount.Where(_hit => _hit.Value.Count > 0) - .Sum(_hit => _hit.Value.Offset * _hit.Value.Count) / totalHits; + .Sum(_hit => _hit.Value.Offset * _hit.Value.Count) / totalSessionHits; if (weightedSessionAverage > Thresholds.MaxOffset(totalSessionHits) && totalSessionHits > 40) @@ -206,7 +206,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat // calculate maximum bone double currentMaxBoneRatio = (HitLocationCount.Values.Select(v => v.Count / (double)HitCount).Max()); - var bone = HitLocationCount.FirstOrDefault(b => b.Value == HitLocationCount.Values.Max()).Key; + var bone = HitLocationCount.FirstOrDefault(b => b.Value.Count == HitLocationCount.Values.Max(_hit => _hit.Count)).Key; #region HEADSHOT_RATIO // flag on headshot diff --git a/SharedLibraryCore/RCon/Connection.cs b/SharedLibraryCore/RCon/Connection.cs index 13e255c74..b7f370993 100644 --- a/SharedLibraryCore/RCon/Connection.cs +++ b/SharedLibraryCore/RCon/Connection.cs @@ -160,7 +160,7 @@ namespace SharedLibraryCore.RCon string responseString = defaultEncoding.GetString(response, 0, response.Length) + '\n'; - if (responseString.Contains("Invalid password")) + if (responseString.Contains("Invalid password") || responseString.Contains("rconpassword")) { throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_INVALID"]); } diff --git a/SharedLibraryCore/Services/ClientService.cs b/SharedLibraryCore/Services/ClientService.cs index 1be23bbfe..e3f31500e 100644 --- a/SharedLibraryCore/Services/ClientService.cs +++ b/SharedLibraryCore/Services/ClientService.cs @@ -360,28 +360,36 @@ namespace SharedLibraryCore.Services { using (var context = new DatabaseContext()) { - if (temporalClient.LastConnection == DateTime.MinValue || temporalClient.FirstConnection == DateTime.MinValue) - { - throw new InvalidOperationException($"client {temporalClient} trying to update but parameters are invalid"); - } - // grab the context version of the entity var entity = context.Clients .First(client => client.ClientId == temporalClient.ClientId); - if (entity.TotalConnectionTime > temporalClient.TotalConnectionTime || entity.Connections > temporalClient.Connections || - entity.LastConnection > temporalClient.LastConnection || entity.FirstConnection > temporalClient.FirstConnection) + if (temporalClient.LastConnection > entity.LastConnection) { - throw new InvalidOperationException($"client {temporalClient} trying to update but new parameters don't match saved parameters"); + entity.LastConnection = temporalClient.LastConnection; + } + + if (temporalClient.Connections > entity.Connections) + { + entity.Connections = temporalClient.Connections; } - entity.LastConnection = temporalClient.LastConnection; - entity.Connections = temporalClient.Connections; - entity.FirstConnection = temporalClient.FirstConnection; entity.Masked = temporalClient.Masked; - entity.TotalConnectionTime = temporalClient.TotalConnectionTime; - entity.Password = temporalClient.Password; - entity.PasswordSalt = temporalClient.PasswordSalt; + + if (temporalClient.TotalConnectionTime > entity.TotalConnectionTime) + { + entity.TotalConnectionTime = temporalClient.TotalConnectionTime; + } + + if (temporalClient.Password != null) + { + entity.Password = temporalClient.Password; + } + + if (temporalClient.PasswordSalt != null) + { + entity.PasswordSalt = temporalClient.PasswordSalt; + } // update in database await context.SaveChangesAsync(); diff --git a/SharedLibraryCore/SharedLibraryCore.csproj b/SharedLibraryCore/SharedLibraryCore.csproj index d703adfa7..70b33f48f 100644 --- a/SharedLibraryCore/SharedLibraryCore.csproj +++ b/SharedLibraryCore/SharedLibraryCore.csproj @@ -13,6 +13,14 @@ Debug;Release;Prerelease false 7.1 + IW4MAdmin + https://github.com/RaidMax/IW4M-Admin/ + https://www.raidmax.org/IW4MAdmin/ + https://www.raidmax.org/IW4MAdmin/img/iw4adminicon-3.png + 2019 + true + true + MIT diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index d10f5d296..39c43dd5e 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -271,7 +271,7 @@ namespace SharedLibraryCore public static long ConvertGuidToLong(this string str, long? fallback = null) { - str = str.Substring(0, Math.Min(str.Length, 16)); + str = str.Substring(0, Math.Min(str.Length, 19)); var bot = Regex.Match(str, @"bot[0-9]+").Value; if (string.IsNullOrWhiteSpace(str) && fallback.HasValue) @@ -279,11 +279,10 @@ namespace SharedLibraryCore 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 + // this is a special case for Plutonium T6 and CoD4x + if (long.TryParse(str, NumberStyles.Integer, CultureInfo.InvariantCulture, out long id)) { - id = (uint)id; + } else if (long.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out id))