diff --git a/Libraries/SPTarkov.Server.Core/Context/ApplicationContext.cs b/Libraries/SPTarkov.Server.Core/Context/ApplicationContext.cs index 9bcb4951..989418e7 100644 --- a/Libraries/SPTarkov.Server.Core/Context/ApplicationContext.cs +++ b/Libraries/SPTarkov.Server.Core/Context/ApplicationContext.cs @@ -1,5 +1,4 @@ -using System.Collections.Concurrent; -using SPTarkov.Common.Annotations; +using SPTarkov.Common.Annotations; using SPTarkov.Server.Core.Models.Utils; namespace SPTarkov.Server.Core.Context; @@ -12,7 +11,7 @@ public class ApplicationContext private static ApplicationContext? _applicationContext; private readonly ISptLogger _logger; private readonly Dictionary> _variables = new(); - private readonly object _lockObject = new(); + private readonly Lock _lockObject = new(); /// /// When ApplicationContext gets created by the DI container we store the singleton reference so we can provide it @@ -62,7 +61,7 @@ public class ApplicationContext { if (!_variables.TryGetValue(type, out var savedValues)) { - savedValues = new LinkedList(); + savedValues = []; if (!_variables.TryAdd(type, savedValues)) { _logger.Error($"Unable to add context variable type: {type}"); diff --git a/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs b/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs index de07a291..2d9b232f 100644 --- a/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs +++ b/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs @@ -21,6 +21,7 @@ public class HttpServer( CertificateHelper _certificateHelper, ApplicationContext _applicationContext, WebSocketServer _webSocketServer, + ProfileActivityService _profileActivityService, IEnumerable _httpListeners ) { @@ -88,16 +89,7 @@ public class HttpServer( context.Request.Cookies.TryGetValue("PHPSESSID", out var sessionId); if (sessionId != null) { - try - { - _applicationContext.AddValue(ContextVariableType.SESSION_ID, sessionId); - } - catch (Exception ex) - { - _logger.Debug("Error while adding context value: " + ex.Message); - _logger.Critical(ex.StackTrace); - throw; - } + _profileActivityService.SetActivityTimestamp(sessionId); } // Extract header for original IP detection diff --git a/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs b/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs index c92238a8..a0102077 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs @@ -1,54 +1,49 @@ -using SPTarkov.Common.Annotations; +using System.Collections.Concurrent; +using SPTarkov.Common.Annotations; using SPTarkov.Server.Core.Utils; namespace SPTarkov.Server.Core.Services; [Injectable(InjectionType.Singleton)] public class ProfileActivityService( - TimeUtil _timeUtil + TimeUtil timeUtil ) { - private readonly Dictionary profileActivityTimestamps = new(); + private readonly ConcurrentDictionary _profileActivityTimestamps = new(); /// - /// Was the requested profile active in the last requested minutes + /// Was the requested profile active within the last x minutes /// /// Profile to check /// Minutes to check for activity in /// True when profile was active within past x minutes public bool ActiveWithinLastMinutes(string sessionId, int minutes) { - var currentTimestamp = _timeUtil.GetTimeStamp(); - if (!profileActivityTimestamps.TryGetValue(sessionId, out var storedActivityTimestamp)) + if (!_profileActivityTimestamps.TryGetValue(sessionId, out var storedActivityTimestamp)) { + // No record, exit early return false; } - return currentTimestamp - storedActivityTimestamp < minutes * 60; + return timeUtil.GetTimeStamp() - storedActivityTimestamp < minutes * 60; } /// /// Get a list of profile ids that were active in the last x minutes /// /// How many minutes from now to search for profiles - /// List of profile ids + /// List of active profile ids public List GetActiveProfileIdsWithinMinutes(int minutes) { - var currentTimestamp = _timeUtil.GetTimeStamp(); + var currentTimestamp = timeUtil.GetTimeStamp(); var result = new List(); - foreach (var activity in profileActivityTimestamps ?? new Dictionary()) + foreach (var (sessionId, lastActivityTimestamp) in _profileActivityTimestamps) { - var lastActivityTimestamp = activity.Value; - if (lastActivityTimestamp == null) - { - continue; - } - // Profile was active in last x minutes, add to return list if (currentTimestamp - lastActivityTimestamp < minutes * 60) { - result.Add(activity.Key); + result.Add(sessionId); } } @@ -61,6 +56,9 @@ public class ProfileActivityService( /// Profile to update public void SetActivityTimestamp(string sessionId) { - profileActivityTimestamps[sessionId] = _timeUtil.GetTimeStamp(); + if(!_profileActivityTimestamps.TryAdd(sessionId, timeUtil.GetTimeStamp())) + { + _profileActivityTimestamps[sessionId] = timeUtil.GetTimeStamp(); + } } }