diff --git a/Libraries/SPTarkov.Server.Core/Callbacks/BotCallbacks.cs b/Libraries/SPTarkov.Server.Core/Callbacks/BotCallbacks.cs
index 792e9841..f8322707 100644
--- a/Libraries/SPTarkov.Server.Core/Callbacks/BotCallbacks.cs
+++ b/Libraries/SPTarkov.Server.Core/Callbacks/BotCallbacks.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Controllers;
using SPTarkov.Server.Core.Models.Eft.Bot;
using SPTarkov.Server.Core.Models.Eft.Common;
@@ -11,8 +10,7 @@ namespace SPTarkov.Server.Core.Callbacks;
[Injectable]
public class BotCallbacks(
BotController _botController,
- HttpResponseUtil _httpResponseUtil,
- ApplicationContext _applicationContext
+ HttpResponseUtil _httpResponseUtil
)
{
///
@@ -41,10 +39,7 @@ public class BotCallbacks(
return _httpResponseUtil.NoBody(_botController.GetBotCoreDifficulty());
}
- var raidConfig = _applicationContext.GetLatestValue(ContextVariableType.RAID_CONFIGURATION)
- ?.GetValue();
-
- return _httpResponseUtil.NoBody(_botController.GetBotDifficulty(type, difficulty, raidConfig));
+ return _httpResponseUtil.NoBody(_botController.GetBotDifficulty(sessionID, type, difficulty));
}
///
diff --git a/Libraries/SPTarkov.Server.Core/Callbacks/HttpCallbacks.cs b/Libraries/SPTarkov.Server.Core/Callbacks/HttpCallbacks.cs
index 4c92ea28..1461e016 100644
--- a/Libraries/SPTarkov.Server.Core/Callbacks/HttpCallbacks.cs
+++ b/Libraries/SPTarkov.Server.Core/Callbacks/HttpCallbacks.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Servers;
diff --git a/Libraries/SPTarkov.Server.Core/Context/ApplicationContext.cs b/Libraries/SPTarkov.Server.Core/Context/ApplicationContext.cs
deleted file mode 100644
index 1b21019e..00000000
--- a/Libraries/SPTarkov.Server.Core/Context/ApplicationContext.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Models.Utils;
-
-namespace SPTarkov.Server.Core.Context;
-
-[Injectable(InjectionType.Singleton)]
-public class ApplicationContext
-{
- private const short MaxSavedValues = 10;
-
- private static ApplicationContext? _applicationContext;
- private readonly ISptLogger _logger;
- private readonly Dictionary> _variables = new();
- private readonly Lock _lockObject = new();
-
- ///
- /// When ApplicationContext gets created by the DI container we store the singleton reference so we can provide it
- /// statically for harmony patches!
- ///
- public ApplicationContext(ISptLogger logger)
- {
- _logger = logger;
- _applicationContext = this;
- }
-
- public static ApplicationContext? GetInstance()
- {
- return _applicationContext;
- }
-
- public ContextVariable? GetLatestValue(ContextVariableType type)
- {
- lock (_lockObject)
- {
- if (_variables.TryGetValue(type, out var savedValues))
- {
- return savedValues.Last!.Value;
- }
-
- return null;
- }
- }
-
- public ICollection GetValues(ContextVariableType type)
- {
- lock (_lockObject)
- {
- var values = new List();
- if (_variables.TryGetValue(type, out var savedValues))
- {
- values.AddRange(savedValues);
- }
-
- return values;
- }
- }
-
- public void AddValue(ContextVariableType type, object value)
- {
- lock (_lockObject)
- {
- if (!_variables.TryGetValue(type, out var savedValues))
- {
- savedValues = [];
- if (!_variables.TryAdd(type, savedValues))
- {
- _logger.Error($"Unable to add context variable type: {type}");
- }
- }
-
- if (savedValues.Count >= MaxSavedValues)
- {
- savedValues.RemoveFirst();
- }
-
- savedValues.AddLast(new ContextVariable(value, type));
- }
- }
-
- public void ClearValues(ContextVariableType type)
- {
- lock (_lockObject)
- {
- if (!_variables.Remove(type, out _))
- {
- _logger.Error($"Unable to clear context variable type: {type}");
- }
- }
- }
-}
diff --git a/Libraries/SPTarkov.Server.Core/Context/ContextVariable.cs b/Libraries/SPTarkov.Server.Core/Context/ContextVariable.cs
deleted file mode 100644
index d328ebe2..00000000
--- a/Libraries/SPTarkov.Server.Core/Context/ContextVariable.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace SPTarkov.Server.Core.Context;
-
-public class ContextVariable(object value, ContextVariableType contextVariableInternalType)
-{
- private readonly DateTime _timestamp = DateTime.UtcNow;
-
- public T GetValue()
- {
- return (T) value;
- }
-
- public DateTime GetTimestamp()
- {
- return _timestamp;
- }
-
- public ContextVariableType GetContextType()
- {
- return contextVariableInternalType;
- }
-}
diff --git a/Libraries/SPTarkov.Server.Core/Context/ContextVariableType.cs b/Libraries/SPTarkov.Server.Core/Context/ContextVariableType.cs
deleted file mode 100644
index 919fdccc..00000000
--- a/Libraries/SPTarkov.Server.Core/Context/ContextVariableType.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace SPTarkov.Server.Core.Context;
-
-public enum ContextVariableType
-{
- // Logged-in users session id
- SESSION_ID = 0,
-
- // Currently active raid information
- RAID_CONFIGURATION = 1,
-
- // SessionID + Timestamp when client first connected, has _ between values
- CLIENT_START_TIMESTAMP = 2,
-
- // When player is loading into map and loot is requested
- REGISTER_PLAYER_REQUEST = 3,
- RAID_ADJUSTMENTS = 4,
-
- // Data returned from client request object from endLocalRaid()
- TRANSIT_INFO = 5,
- SERVICE_PROVIDER = 9
-}
diff --git a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs
index 80564295..a6188b8e 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs
@@ -2,7 +2,6 @@ using System.Diagnostics;
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Constants;
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Generators;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Common;
@@ -33,7 +32,7 @@ public class BotController(
MatchBotDetailsCacheService _matchBotDetailsCacheService,
ProfileHelper _profileHelper,
ConfigServer _configServer,
- ApplicationContext _applicationContext,
+ ProfileActivityService _profileActivityService,
RandomUtil _randomUtil,
ICloner _cloner
)
@@ -73,15 +72,18 @@ public class BotController(
/// Get bot difficulty settings
/// Adjust PMC settings to ensure they engage the correct bot types
///
+ /// Which user is requesting his bot settings
/// what bot the server is requesting settings for
/// difficulty level server requested settings for
/// OPTIONAL - applicationContext Data stored at start of raid
/// OPTIONAL - should raid settings chosen pre-raid be ignored
/// Difficulty object
- public DifficultyCategories GetBotDifficulty(string type, string diffLevel, GetRaidConfigurationRequestData? raidConfig, bool ignoreRaidSettings = false)
+ public DifficultyCategories GetBotDifficulty(string sessionId, string type, string diffLevel, bool ignoreRaidSettings = false)
{
var difficulty = diffLevel.ToLower();
+ var raidConfig = _profileActivityService.GetProfileActivityRaidData(sessionId)?.RaidConfiguration;
+
if (!(raidConfig != null || ignoreRaidSettings))
{
_logger.Error(_localisationService.GetText("bot-missing_application_context", "RAID_CONFIGURATION"));
@@ -152,7 +154,7 @@ public class BotController(
}
// Store all difficulty values in dict keyed by difficulty type e.g. easy/normal/impossible
- result[botNameKey].Add(difficultyName, GetBotDifficulty(botNameKey, difficultyName, null, true));
+ result[botNameKey].Add(difficultyName, GetBotDifficulty(string.Empty, botNameKey, difficultyName, true));
}
}
@@ -182,7 +184,7 @@ public class BotController(
protected List GenerateBotWaves(GenerateBotsRequestData request, PmcData? pmcProfile, string sessionId)
{
var generatedBotList = new List();
- var raidSettings = GetMostRecentRaidSettings();
+ var raidSettings = GetMostRecentRaidSettings(sessionId);
var allPmcsHaveSameNameAsPlayer = _randomUtil.GetChance100(
_pmcConfig.AllPMCsHavePlayerNameWithRandomPrefixChance
);
@@ -287,18 +289,16 @@ public class BotController(
/// Pull raid settings from Application context
///
/// GetRaidConfigurationRequestData if it exists
- protected GetRaidConfigurationRequestData? GetMostRecentRaidSettings()
+ protected GetRaidConfigurationRequestData? GetMostRecentRaidSettings(string sessionId)
{
- var raidSettings = _applicationContext
- .GetLatestValue(ContextVariableType.RAID_CONFIGURATION)
- ?.GetValue();
+ var raidConfiguration = _profileActivityService.GetProfileActivityRaidData(sessionId)?.RaidConfiguration;
- if (raidSettings is null)
+ if (raidConfiguration is null)
{
_logger.Warning(_localisationService.GetText("bot-unable_to_load_raid_settings_from_appcontext"));
}
- return raidSettings;
+ return raidConfiguration;
}
///
diff --git a/Libraries/SPTarkov.Server.Core/Controllers/GameController.cs b/Libraries/SPTarkov.Server.Core/Controllers/GameController.cs
index 353928e1..60fedbf8 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/GameController.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/GameController.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Eft.Game;
@@ -42,7 +41,6 @@ public class GameController(
RaidTimeAdjustmentService _raidTimeAdjustmentService,
ProfileActivityService _profileActivityService,
CreateProfileService _createProfileService,
- ApplicationContext _applicationContext,
ICloner _cloner
)
{
@@ -61,8 +59,7 @@ public class GameController(
///
public void GameStart(string url, string? sessionId, long startTimeStampMs)
{
- // Store client start time in app context
- _applicationContext.AddValue(ContextVariableType.CLIENT_START_TIMESTAMP, $"{sessionId}_{startTimeStampMs}");
+ _profileActivityService.AddActiveProfile(sessionId, startTimeStampMs);
if (sessionId is null)
{
diff --git a/Libraries/SPTarkov.Server.Core/Controllers/InRaidController.cs b/Libraries/SPTarkov.Server.Core/Controllers/InRaidController.cs
index b529759a..38b0db8a 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/InRaidController.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/InRaidController.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.InRaid;
using SPTarkov.Server.Core.Models.Spt.Config;
@@ -12,7 +11,7 @@ namespace SPTarkov.Server.Core.Controllers;
public class InRaidController(
ISptLogger _logger,
ProfileHelper _profileHelper,
- ApplicationContext _applicationContext,
+ //ApplicationContext _applicationContext,
ConfigServer _configServer
)
{
@@ -26,7 +25,7 @@ public class InRaidController(
/// Register player request
public void AddPlayer(string sessionId, RegisterPlayerRequestData info)
{
- _applicationContext.AddValue(ContextVariableType.REGISTER_PLAYER_REQUEST, info);
+ // _applicationContext.AddValue(ContextVariableType.REGISTER_PLAYER_REQUEST, info);
}
///
diff --git a/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs b/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs
index ab0624fb..3e14e649 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs
@@ -1,6 +1,5 @@
using SPTarkov.Common.Extensions;
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Launcher;
@@ -27,8 +26,7 @@ public class LauncherController(
ProfileHelper _profileHelper,
DatabaseService _databaseService,
LocalisationService _localisationService,
- ConfigServer _configServer,
- ApplicationContext _applicationContext
+ ConfigServer _configServer
)
{
protected CoreConfig _coreConfig = _configServer.GetConfig();
diff --git a/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs b/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs
index 4e056f00..67f42dd4 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs
@@ -1,6 +1,5 @@
using SPTarkov.Common.Extensions;
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Launcher;
using SPTarkov.Server.Core.Models.Eft.Profile;
@@ -25,8 +24,7 @@ public class LauncherV2Controller(
DatabaseService _databaseService,
LocalisationService _localisationService,
ConfigServer _configServer,
- Watermark _watermark,
- ApplicationContext _applicationContext
+ Watermark _watermark
)
{
protected CoreConfig _coreConfig = _configServer.GetConfig();
diff --git a/Libraries/SPTarkov.Server.Core/Controllers/MatchController.cs b/Libraries/SPTarkov.Server.Core/Controllers/MatchController.cs
index d507a69e..f5c078c7 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/MatchController.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/MatchController.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.Match;
using SPTarkov.Server.Core.Models.Spt.Config;
@@ -17,8 +16,8 @@ public class MatchController(
SaveServer _saveServer,
MatchLocationService _matchLocationService,
ConfigServer _configServer,
- ApplicationContext _applicationContext,
LocationLifecycleService _locationLifecycleService,
+ ProfileActivityService _profileActivityService,
WeatherHelper _weatherHelper,
ICloner _cloner
)
@@ -104,7 +103,7 @@ public class MatchController(
request.IsNightRaid = _weatherHelper.IsNightTime(request.TimeVariant, request.Location);
// Store request data for access during bot generation
- _applicationContext.AddValue(ContextVariableType.RAID_CONFIGURATION, request);
+ _profileActivityService.GetProfileActivityRaidData(sessionId).RaidConfiguration = request;
// TODO: add code to strip PMC of equipment now they've started the raid
diff --git a/Libraries/SPTarkov.Server.Core/DI/ServiceLocator.cs b/Libraries/SPTarkov.Server.Core/DI/ServiceLocator.cs
new file mode 100644
index 00000000..e30392c4
--- /dev/null
+++ b/Libraries/SPTarkov.Server.Core/DI/ServiceLocator.cs
@@ -0,0 +1,22 @@
+namespace SPTarkov.Server.Core.DI
+{
+ ///
+ /// A service locator designed specifically for Harmony patches and other
+ /// parts of the application that do not have direct access to the Dependency Injection (DI) system.
+ ///
+ /// This should not be used at all when having direct access to DI.
+ ///
+ public static class ServiceLocator
+ {
+ public static IServiceProvider ServiceProvider
+ {
+ get;
+ private set;
+ }
+
+ internal static void SetServiceProvider(IServiceProvider provider)
+ {
+ ServiceProvider = provider;
+ }
+ }
+}
diff --git a/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs
index 40f6881a..8a65ab5a 100644
--- a/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs
+++ b/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs
@@ -1,6 +1,5 @@
using System.Collections.Frozen;
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Match;
@@ -21,7 +20,7 @@ public class BotInventoryGenerator(
HashUtil _hashUtil,
RandomUtil _randomUtil,
DatabaseService _databaseService,
- ApplicationContext _applicationContext,
+ ProfileActivityService _profileActivityService,
BotWeaponGenerator _botWeaponGenerator,
BotLootGenerator _botLootGenerator,
BotGeneratorHelper _botGeneratorHelper,
@@ -75,9 +74,7 @@ public class BotInventoryGenerator(
var botInventory = GenerateInventoryBase();
// Get generated raid details bot will be spawned in
- var raidConfig = _applicationContext
- .GetLatestValue(ContextVariableType.RAID_CONFIGURATION)
- ?.GetValue();
+ var raidConfig = _profileActivityService.GetProfileActivityRaidData(sessionId).RaidConfiguration;
GenerateAndAddEquipmentToBot(
sessionId,
diff --git a/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs
index 1c7475d4..587f1aa4 100644
--- a/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs
+++ b/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs
@@ -1,7 +1,6 @@
using System.Collections.Frozen;
using SPTarkov.Server.Core.Constants;
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Match;
@@ -24,7 +23,7 @@ public class BotGeneratorHelper(
ItemHelper _itemHelper,
InventoryHelper _inventoryHelper,
ContainerHelper _containerHelper,
- ApplicationContext _applicationContext,
+ ProfileActivityService _profileActivityService,
LocalisationService _localisationService,
ConfigServer _configServer
) : IOnLoad
@@ -59,9 +58,7 @@ public class BotGeneratorHelper(
public Upd GenerateExtraPropertiesForItem(TemplateItem? itemTemplate, string? botRole = null)
{
// Get raid settings, if no raid, default to day
- var raidSettings = _applicationContext
- .GetLatestValue(ContextVariableType.RAID_CONFIGURATION)
- ?.GetValue();
+ var raidSettings = _profileActivityService.GetFirstProfileActivityRaidData()?.RaidConfiguration;
RandomisedResourceDetails randomisationSettings = null;
if (botRole is not null)
diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Services/ProfileActivityData.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Services/ProfileActivityData.cs
new file mode 100644
index 00000000..9b527c3a
--- /dev/null
+++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Services/ProfileActivityData.cs
@@ -0,0 +1,20 @@
+using SPTarkov.Server.Core.Models.Eft.Match;
+using SPTarkov.Server.Core.Models.Spt.Location;
+
+namespace SPTarkov.Server.Core.Models.Spt.Services
+{
+ public class ProfileActivityData
+ {
+ public long ClientStartedTimestamp { get; set; }
+ public long LastActive { get; set; }
+ public ProfileActivityRaidData? RaidData { get; set; } = null;
+ }
+
+ public class ProfileActivityRaidData
+ {
+ public GetRaidConfigurationRequestData? RaidConfiguration { get; set; } = null;
+ public RaidChanges? RaidAdjustments { get; set; } = null;
+ public LocationTransit? LocationTransit { get; set; } = null;
+ }
+
+}
diff --git a/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs b/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs
index 88c1d316..f872b4cc 100644
--- a/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs
+++ b/Libraries/SPTarkov.Server.Core/Servers/HttpServer.cs
@@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Primitives;
using SPTarkov.Common.Extensions;
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Spt.Config;
using SPTarkov.Server.Core.Models.Utils;
diff --git a/Libraries/SPTarkov.Server.Core/Services/BackupService.cs b/Libraries/SPTarkov.Server.Core/Services/BackupService.cs
index a60e440d..aea47c39 100644
--- a/Libraries/SPTarkov.Server.Core/Services/BackupService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/BackupService.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Models.Spt.Config;
using SPTarkov.Server.Core.Models.Spt.Mod;
using SPTarkov.Server.Core.Models.Utils;
@@ -15,7 +14,6 @@ public class BackupService
protected const string _profileDir = "./user/profiles";
protected readonly List _activeServerMods;
- protected ApplicationContext _applicationContext;
protected BackupConfig _backupConfig;
// Runs Init() every x minutes
@@ -32,15 +30,13 @@ public class BackupService
JsonUtil jsonUtil,
TimeUtil timeUtil,
ConfigServer configServer,
- FileUtil fileUtil,
- ApplicationContext applicationContext
+ FileUtil fileUtil
)
{
_logger = logger;
_jsonUtil = jsonUtil;
_timeUtil = timeUtil;
_fileUtil = fileUtil;
- _applicationContext = applicationContext;
_loadedMods = loadedMods;
_activeServerMods = GetActiveServerMods();
diff --git a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs
index 407da4bb..bbf207f2 100644
--- a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Generators;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.Common;
@@ -21,7 +20,7 @@ namespace SPTarkov.Server.Core.Services;
[Injectable(InjectionType.Singleton)]
public class LocationLifecycleService
{
- protected ApplicationContext _applicationContext;
+ protected ProfileActivityService _profileActivityService;
protected BotGenerationCacheService _botGenerationCacheService;
protected BotLootCacheService _botLootCacheService;
protected BotNameService _botNameService;
@@ -64,7 +63,7 @@ public class LocationLifecycleService
DatabaseService databaseService,
ProfileHelper profileHelper,
HashUtil hashUtil,
- ApplicationContext applicationContext,
+ ProfileActivityService profileActivityService,
BotGenerationCacheService botGenerationCacheService,
BotNameService botNameService,
ICloner cloner,
@@ -94,7 +93,7 @@ public class LocationLifecycleService
_databaseService = databaseService;
_profileHelper = profileHelper;
_hashUtil = hashUtil;
- _applicationContext = applicationContext;
+ _profileActivityService = profileActivityService;
_botGenerationCacheService = botGenerationCacheService;
_botNameService = botNameService;
_cloner = cloner;
@@ -150,7 +149,7 @@ public class LocationLifecycleService
{
InsuredItems = playerProfile.CharacterData.PmcData.InsuredItems
},
- LocationLoot = GenerateLocationAndLoot(request.Location, !request.ShouldSkipLootGeneration ?? true),
+ LocationLoot = GenerateLocationAndLoot(sessionId, request.Location, !request.ShouldSkipLootGeneration ?? true),
TransitionType = TransitionType.NONE,
Transition = new Transition
{
@@ -169,9 +168,7 @@ public class LocationLifecycleService
}
// Get data stored at end of previous raid (if any)
- var transitionData = _applicationContext
- .GetLatestValue(ContextVariableType.TRANSIT_INFO)
- ?.GetValue();
+ var transitionData = _profileActivityService.GetProfileActivityRaidData(sessionId)?.LocationTransit;
if (transitionData is not null)
{
@@ -184,7 +181,7 @@ public class LocationLifecycleService
result.Transition.VisitedLocations.Add(transitionData.SptLastVisitedLocation);
// Complete, clean up as no longer needed
- _applicationContext.ClearValues(ContextVariableType.TRANSIT_INFO);
+ _profileActivityService.GetProfileActivityRaidData(sessionId).LocationTransit = null;
}
// Apply changes from pmcConfig to bot hostility values
@@ -338,7 +335,7 @@ public class LocationLifecycleService
///
/// Generate a maps base location (cloned) and loot
///
- public virtual LocationBase GenerateLocationAndLoot(string name, bool generateLoot = true)
+ public virtual LocationBase GenerateLocationAndLoot(string sessionId, string name, bool generateLoot = true)
{
var location = _databaseService.GetLocation(name);
var locationBaseClone = _cloner.Clone(location.Base);
@@ -363,9 +360,7 @@ public class LocationLifecycleService
// Adjust raid based on whether this is a scav run
LocationConfig? locationConfigClone = null;
- var raidAdjustments = _applicationContext
- .GetLatestValue(ContextVariableType.RAID_ADJUSTMENTS)
- ?.GetValue();
+ var raidAdjustments = _profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments;
if (raidAdjustments is not null)
{
locationConfigClone = _cloner.Clone(_locationConfig); // Clone values so they can be used to reset originals later
@@ -405,7 +400,7 @@ public class LocationLifecycleService
_locationConfig.StaticLootMultiplier = locationConfigClone.StaticLootMultiplier;
_locationConfig.LooseLootMultiplier = locationConfigClone.LooseLootMultiplier;
- _applicationContext.ClearValues(ContextVariableType.RAID_ADJUSTMENTS);
+ _profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments = null;
}
return locationBaseClone;
@@ -457,7 +452,7 @@ public class LocationLifecycleService
// TODO - Persist each players last visited location history over multiple transits, e.g using InMemoryCacheService, need to take care to not let data get stored forever
// Store transfer data for later use in `startLocalRaid()` when next raid starts
request.LocationTransit.SptExitName = request.Results.ExitName;
- _applicationContext.AddValue(ContextVariableType.TRANSIT_INFO, request.LocationTransit);
+ _profileActivityService.GetProfileActivityRaidData(sessionId).LocationTransit = request.LocationTransit;
}
if (!isPmc)
diff --git a/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs b/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs
index b1b097cf..5b17d768 100644
--- a/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/ProfileActivityService.cs
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using SPTarkov.DI.Annotations;
+using SPTarkov.Server.Core.Models.Spt.Services;
using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Services;
@@ -9,7 +10,50 @@ public class ProfileActivityService(
TimeUtil timeUtil
)
{
- private readonly ConcurrentDictionary _profileActivityTimestamps = new();
+ private readonly ConcurrentDictionary _activeProfiles = [];
+
+ public void AddActiveProfile(string sessionId, long clientStartedTimestamp)
+ {
+ _activeProfiles.AddOrUpdate(
+ sessionId,
+ // On add value
+ key => new ProfileActivityData
+ {
+ ClientStartedTimestamp = clientStartedTimestamp,
+ LastActive = timeUtil.GetTimeStamp()
+ },
+ // On Update value, client was started before but crashed or user restarted
+ (key, existingValue) =>
+ {
+ existingValue.ClientStartedTimestamp = clientStartedTimestamp;
+ existingValue.LastActive = timeUtil.GetTimeStamp();
+ existingValue.RaidData = null;
+ return existingValue;
+ });
+ }
+
+ // Yes this is terrible, the other alternative is re-doing half of bot-gen which is currently doing guess-work anyway
+ public ProfileActivityRaidData? GetFirstProfileActivityRaidData()
+ {
+ if (!_activeProfiles.IsEmpty)
+ {
+ return _activeProfiles.First().Value.RaidData;
+ }
+
+ return null;
+ }
+
+ public ProfileActivityRaidData? GetProfileActivityRaidData(string sessionId)
+ {
+ if (_activeProfiles.TryGetValue(sessionId, out var currentActiveProfile))
+ {
+ currentActiveProfile.RaidData ??= new();
+
+ return currentActiveProfile.RaidData;
+ }
+
+ return null;
+ }
///
/// Was the requested profile active within the last x minutes
@@ -19,13 +63,13 @@ public class ProfileActivityService(
/// True when profile was active within past x minutes
public bool ActiveWithinLastMinutes(string sessionId, int minutes)
{
- if (!_profileActivityTimestamps.TryGetValue(sessionId, out var storedActivityTimestamp))
+ if (!_activeProfiles.TryGetValue(sessionId, out var profileActivity))
{
// No record, exit early
return false;
}
- return timeUtil.GetTimeStamp() - storedActivityTimestamp < minutes * 60;
+ return timeUtil.GetTimeStamp() - profileActivity.LastActive < minutes * 60;
}
///
@@ -38,10 +82,10 @@ public class ProfileActivityService(
var currentTimestamp = timeUtil.GetTimeStamp();
var result = new List();
- foreach (var (sessionId, lastActivityTimestamp) in _profileActivityTimestamps)
+ foreach (var (sessionId, activeProfile) in _activeProfiles)
{
// Profile was active in last x minutes, add to return list
- if (currentTimestamp - lastActivityTimestamp < minutes * 60)
+ if (currentTimestamp - activeProfile.LastActive < minutes * 60)
{
result.Add(sessionId);
}
@@ -56,9 +100,9 @@ public class ProfileActivityService(
/// Profile to update
public void SetActivityTimestamp(string sessionId)
{
- if(!_profileActivityTimestamps.TryAdd(sessionId, timeUtil.GetTimeStamp()))
+ if(_activeProfiles.TryGetValue(sessionId, out var currentActiveProfile))
{
- _profileActivityTimestamps[sessionId] = timeUtil.GetTimeStamp();
+ currentActiveProfile.LastActive = timeUtil.GetTimeStamp();
}
}
}
diff --git a/Libraries/SPTarkov.Server.Core/Services/RaidTimeAdjustmentService.cs b/Libraries/SPTarkov.Server.Core/Services/RaidTimeAdjustmentService.cs
index b45e80ff..f6998a95 100644
--- a/Libraries/SPTarkov.Server.Core/Services/RaidTimeAdjustmentService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/RaidTimeAdjustmentService.cs
@@ -1,5 +1,4 @@
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Context;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Eft.Game;
@@ -18,7 +17,7 @@ public class RaidTimeAdjustmentService(
DatabaseService _databaseService,
RandomUtil _randomUtil,
WeightedRandomHelper _weightedRandomHelper,
- ApplicationContext _applicationContext,
+ ProfileActivityService _profileActivityService,
ConfigServer _configServer
)
{
@@ -206,7 +205,7 @@ public class RaidTimeAdjustmentService(
}
// Store state to use in loot generation
- _applicationContext.AddValue(ContextVariableType.RAID_ADJUSTMENTS, result);
+ _profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments = result;
return result;
}
diff --git a/Libraries/SPTarkov.Server.Core/Utils/App.cs b/Libraries/SPTarkov.Server.Core/Utils/App.cs
index 89106664..b7c22e3f 100644
--- a/Libraries/SPTarkov.Server.Core/Utils/App.cs
+++ b/Libraries/SPTarkov.Server.Core/Utils/App.cs
@@ -11,6 +11,7 @@ namespace SPTarkov.Server.Core.Utils;
[Injectable(InjectionType.Singleton)]
public class App(
+ IServiceProvider _serviceProvider,
ISptLogger _logger,
TimeUtil _timeUtil,
RandomUtil _randomUtil,
@@ -30,6 +31,8 @@ public class App(
public async Task InitializeAsync()
{
+ ServiceLocator.SetServiceProvider(_serviceProvider);
+
// execute onLoad callbacks
_logger.Info(_localisationService.GetText("executing_startup_callbacks"));
diff --git a/SPTarkov.Server/Program.cs b/SPTarkov.Server/Program.cs
index 2ae6662a..8bead8f3 100644
--- a/SPTarkov.Server/Program.cs
+++ b/SPTarkov.Server/Program.cs
@@ -3,9 +3,6 @@ using System.Runtime.InteropServices;
using SPTarkov.Common.Semver;
using SPTarkov.Common.Semver.Implementations;
using SPTarkov.DI;
-using SPTarkov.Server.Core.Context;
-using SPTarkov.Server.Core.Helpers;
-using SPTarkov.Server.Core.Models.External;
using SPTarkov.Server.Core.Models.Spt.Mod;
using SPTarkov.Server.Core.Models.Utils;
using SPTarkov.Server.Core.Servers;
@@ -52,9 +49,6 @@ public static class Program
{
SetConsoleOutputMode();
- var appContext = serviceProvider.GetService();
- appContext?.AddValue(ContextVariableType.SERVICE_PROVIDER, serviceProvider);
-
// Get the Built app and run it
var app = serviceProvider.GetService();