diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs index ef6f27df8..497b9da67 100644 --- a/Plugins/Stats/Helpers/StatManager.cs +++ b/Plugins/Stats/Helpers/StatManager.cs @@ -30,6 +30,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers private static List serverModels; public static string CLIENT_STATS_KEY = "ClientStats"; public static string CLIENT_DETECTIONS_KEY = "ClientDetections"; + private readonly SemaphoreSlim _addPlayerWaiter = new SemaphoreSlim(1, 1); public StatManager(ILogger logger, IManager mgr, IDatabaseContextFactory contextFactory, IConfigurationHandler configHandler) { @@ -39,6 +40,11 @@ namespace IW4MAdmin.Plugins.Stats.Helpers _configHandler = configHandler; } + ~StatManager() + { + _addPlayerWaiter.Dispose(); + } + private void SetupServerIds() { using (var ctx = _contextFactory.CreateContext(enableTracking: false)) @@ -283,9 +289,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { return existingStats; } - + try { + await _addPlayerWaiter.WaitAsync(); long serverId = GetIdForServer(pl.CurrentServer); if (!_servers.ContainsKey(serverId)) @@ -318,12 +325,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers Skill = 0.0, SPM = 0.0, EloRating = 200.0, - HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType().Select(hl => new EFHitLocationCount() - { - Active = true, - HitCount = 0, - Location = hl - }).ToList() + HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType() + .Select(hl => new EFHitLocationCount() + { + Active = true, + HitCount = 0, + Location = hl + }).ToList() }; // insert if they've not been added @@ -336,7 +344,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers // migration for previous existing stats if (clientStats.HitLocations.Count == 0) { - clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType() + clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)) + .OfType() .Select(hl => new EFHitLocationCount() { Active = true, @@ -378,6 +387,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers _log.LogError(ex, "Could not add client to stats {@client}", pl.ToString()); } + finally + { + if (_addPlayerWaiter.CurrentCount == 0) + { + _addPlayerWaiter.Release(1); + } + } + return null; } diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index 74983b061..4fdf4e041 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -92,8 +92,8 @@ namespace IW4MAdmin.Plugins.Stats { E.Origin = E.Target; } - await Manager.AddPlayer(E.Origin); - await Manager.AddPlayer(E.Target); + + await EnsureClientsAdded(E.Origin, E.Target); await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(S), 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], killInfo[16], killInfo[17]); } @@ -112,8 +112,7 @@ namespace IW4MAdmin.Plugins.Stats E.Origin = E.Target; } - await Manager.AddPlayer(E.Origin); - await Manager.AddPlayer(E.Target); + await EnsureClientsAdded(E.Origin, E.Target); await Manager.AddStandardKill(E.Origin, E.Target); } break; @@ -139,8 +138,7 @@ namespace IW4MAdmin.Plugins.Stats E.Origin = E.Target; } - await Manager.AddPlayer(E.Origin); - await Manager.AddPlayer(E.Target); + await EnsureClientsAdded(E.Origin, E.Target); await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, StatManager.GetIdForServer(S), 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], killInfo[16], killInfo[17]); } @@ -475,5 +473,21 @@ namespace IW4MAdmin.Plugins.Stats /// /// private bool ShouldOverrideAnticheatSetting(Server s) => Config.Configuration().AnticheatConfiguration.Enable && s.GameName == Server.Game.IW5; + + /// + /// Makes sure both clients are added + /// + /// + /// + /// + private async Task EnsureClientsAdded(EFClient origin, EFClient target) + { + await Manager.AddPlayer(origin); + + if (!origin.Equals(target)) + { + await Manager.AddPlayer(target); + } + } } }