From 0e176aba5ff69f9ac360616161780c55918c9dc7 Mon Sep 17 00:00:00 2001 From: hulkhan22 Date: Sat, 26 Apr 2025 20:53:14 +0200 Subject: [PATCH 1/3] Fix --- .../Controllers/BotController.cs | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs index 7525b2a7..78f8ae2c 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Diagnostics; using System.Text.Json.Serialization; using SPTarkov.Common.Annotations; @@ -179,7 +180,7 @@ public class BotController( /// List of generated bots protected List GenerateBotWaves(GenerateBotsRequestData request, PmcData? pmcProfile, string sessionId) { - var result = new List(); + var result = new ConcurrentBag(); var raidSettings = GetMostRecentRaidSettings(); @@ -201,8 +202,12 @@ public class BotController( condition.Limit), // Choose largest between value passed in from request vs what's in bot.config _botHelper.IsBotPmc(condition.Role)); - result.AddRange(GenerateBotWave(condition, botWaveGenerationDetails, sessionId)); - })).ToArray()); + var wave = GenerateBotWave(condition, botWaveGenerationDetails, sessionId); + foreach (var bot in wave) + { + result.Add(bot); + } + }))); stopwatch.Stop(); if (_logger.IsLogEnabled(LogLevel.Debug)) @@ -210,7 +215,7 @@ public class BotController( _logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache()"); } - return result; + return result.ToList(); } /// @@ -239,30 +244,38 @@ public class BotController( _logger.Debug($"Generating wave of: {botGenerationDetails.BotCountToGenerate} bots of type: {role} {botGenerationDetails.BotDifficulty}"); } - var results = new List(); + var results = new ConcurrentBag(); + var tasks = new Task[botGenerationDetails.BotCountToGenerate.Value]; + for (var i = 0; i < botGenerationDetails.BotCountToGenerate; i++) { - try + var task = Task.Run(() => { - var bot = _botGenerator.PrepareAndGenerateBot(sessionId, _cloner.Clone(botGenerationDetails)); - - // The client expects the Side for PMCs to be `Savage` - // We do this here so it's after we cache the bot in the match details lookup, as when you die, they will have the right side - if (bot.Info.Side is "Bear" or "Usec") + try { - bot.Info.Side = "Savage"; - } + var bot = _botGenerator.PrepareAndGenerateBot(sessionId, _cloner.Clone(botGenerationDetails)); - results.Add(bot); - // Store bot details in cache so post-raid PMC messages can use data - _matchBotDetailsCacheService.CacheBot(_cloner.Clone(bot)); - } - catch (Exception e) - { - _logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}"); - } + // The client expects the Side for PMCs to be `Savage` + // We do this here so it's after we cache the bot in the match details lookup, as when you die, they will have the right side + if (bot.Info.Side is "Bear" or "Usec") + { + bot.Info.Side = "Savage"; + } + + results.Add(bot); + // Store bot details in cache so post-raid PMC messages can use data + _matchBotDetailsCacheService.CacheBot(_cloner.Clone(bot)); + } + catch (Exception e) + { + _logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}"); + } + }); + tasks[i] = task; } + Task.WaitAll(tasks); + if (_logger.IsLogEnabled(LogLevel.Debug)) { _logger.Debug( @@ -271,7 +284,7 @@ public class BotController( ); } - return results; + return results.ToList(); } /// From 7e13c8c4465fbc611f26e6a6c29a3a1650e89d55 Mon Sep 17 00:00:00 2001 From: hulkhan22 Date: Sat, 26 Apr 2025 23:29:12 +0200 Subject: [PATCH 2/3] Revert "Fix" This reverts commit ce97c1676198197b8c2a0ef75eaee7df869cb3bd. --- .../Controllers/BotController.cs | 55 +++++++------------ 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs index 78f8ae2c..7525b2a7 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs @@ -1,4 +1,3 @@ -using System.Collections.Concurrent; using System.Diagnostics; using System.Text.Json.Serialization; using SPTarkov.Common.Annotations; @@ -180,7 +179,7 @@ public class BotController( /// List of generated bots protected List GenerateBotWaves(GenerateBotsRequestData request, PmcData? pmcProfile, string sessionId) { - var result = new ConcurrentBag(); + var result = new List(); var raidSettings = GetMostRecentRaidSettings(); @@ -202,12 +201,8 @@ public class BotController( condition.Limit), // Choose largest between value passed in from request vs what's in bot.config _botHelper.IsBotPmc(condition.Role)); - var wave = GenerateBotWave(condition, botWaveGenerationDetails, sessionId); - foreach (var bot in wave) - { - result.Add(bot); - } - }))); + result.AddRange(GenerateBotWave(condition, botWaveGenerationDetails, sessionId)); + })).ToArray()); stopwatch.Stop(); if (_logger.IsLogEnabled(LogLevel.Debug)) @@ -215,7 +210,7 @@ public class BotController( _logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache()"); } - return result.ToList(); + return result; } /// @@ -244,38 +239,30 @@ public class BotController( _logger.Debug($"Generating wave of: {botGenerationDetails.BotCountToGenerate} bots of type: {role} {botGenerationDetails.BotDifficulty}"); } - var results = new ConcurrentBag(); - var tasks = new Task[botGenerationDetails.BotCountToGenerate.Value]; - + var results = new List(); for (var i = 0; i < botGenerationDetails.BotCountToGenerate; i++) { - var task = Task.Run(() => + try { - try - { - var bot = _botGenerator.PrepareAndGenerateBot(sessionId, _cloner.Clone(botGenerationDetails)); + var bot = _botGenerator.PrepareAndGenerateBot(sessionId, _cloner.Clone(botGenerationDetails)); - // The client expects the Side for PMCs to be `Savage` - // We do this here so it's after we cache the bot in the match details lookup, as when you die, they will have the right side - if (bot.Info.Side is "Bear" or "Usec") - { - bot.Info.Side = "Savage"; - } - - results.Add(bot); - // Store bot details in cache so post-raid PMC messages can use data - _matchBotDetailsCacheService.CacheBot(_cloner.Clone(bot)); - } - catch (Exception e) + // The client expects the Side for PMCs to be `Savage` + // We do this here so it's after we cache the bot in the match details lookup, as when you die, they will have the right side + if (bot.Info.Side is "Bear" or "Usec") { - _logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}"); + bot.Info.Side = "Savage"; } - }); - tasks[i] = task; + + results.Add(bot); + // Store bot details in cache so post-raid PMC messages can use data + _matchBotDetailsCacheService.CacheBot(_cloner.Clone(bot)); + } + catch (Exception e) + { + _logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}"); + } } - Task.WaitAll(tasks); - if (_logger.IsLogEnabled(LogLevel.Debug)) { _logger.Debug( @@ -284,7 +271,7 @@ public class BotController( ); } - return results.ToList(); + return results; } /// From baed8d2b901f0455c41f3c0b89aa894eb911ae69 Mon Sep 17 00:00:00 2001 From: hulkhan22 Date: Sat, 26 Apr 2025 23:56:48 +0200 Subject: [PATCH 3/3] Revert to a lock --- Libraries/SPTarkov.Server.Core/Controllers/BotController.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs index 7525b2a7..90397713 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs @@ -39,6 +39,7 @@ public class BotController( { private readonly BotConfig _botConfig = _configServer.GetConfig(); private readonly PmcConfig _pmcConfig = _configServer.GetConfig(); + private static readonly Lock BotListLock = new(); /// /// Return the number of bot load-out varieties to be generated @@ -201,7 +202,10 @@ public class BotController( condition.Limit), // Choose largest between value passed in from request vs what's in bot.config _botHelper.IsBotPmc(condition.Role)); - result.AddRange(GenerateBotWave(condition, botWaveGenerationDetails, sessionId)); + lock (BotListLock) + { + result.AddRange(GenerateBotWave(condition, botWaveGenerationDetails, sessionId)); + } })).ToArray()); stopwatch.Stop();