Bot generation performance (#231)
* chore: Bot generation performance improvements (#227) * Bot generation performance improvements * Revert debug logging logic * Get rid of Info log which is bound to be printed inevitably at each bot wave generation * Use assault const * Removed comments Removed lowercase side constants Renamed equipment role to better explain its purpose Fixed `Blocks` property being serialised to client Updated `_slotsWithNoCompatIssues` to use existing enum type Reduced log line to be debug * Fixed `GetRandomTextThatMatchesPartialKey` incorrectly checking eft locales instead of spt locales * Updated various methods to be protected --------- Co-authored-by: hulkhan22 <clandestine984@gmail.com> Co-authored-by: Chomp <dev@dev.sp-tarkov.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Common.Annotations;
|
||||
using SPTarkov.Server.Core.Constants;
|
||||
using SPTarkov.Server.Core.Context;
|
||||
using SPTarkov.Server.Core.Generators;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
@@ -125,10 +126,10 @@ public class BotController(
|
||||
if (!botTypesDb.TryGetValue(botTypeLower, out var botDetails))
|
||||
{
|
||||
// No bot of this type found, copy details from assault
|
||||
result[botTypeLower] = result["assault"];
|
||||
result[botTypeLower] = result[Roles.Assault];
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Unable to find bot: {botTypeLower} in db, copying 'assault'");
|
||||
_logger.Debug($"Unable to find bot: {botTypeLower} in db, copying '{Roles.Assault}'");
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -180,13 +181,12 @@ public class BotController(
|
||||
/// <returns>List of generated bots</returns>
|
||||
protected List<BotBase> GenerateBotWaves(GenerateBotsRequestData request, PmcData? pmcProfile, string sessionId)
|
||||
{
|
||||
var result = new List<BotBase>();
|
||||
|
||||
var generatedBotList = new List<BotBase>();
|
||||
var raidSettings = GetMostRecentRaidSettings();
|
||||
|
||||
var allPmcsHaveSameNameAsPlayer = _randomUtil.GetChance100(
|
||||
_pmcConfig.AllPMCsHavePlayerNameWithRandomPrefixChance
|
||||
);
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
// Map conditions to promises for bot generation
|
||||
|
||||
@@ -197,24 +197,19 @@ public class BotController(
|
||||
condition,
|
||||
pmcProfile,
|
||||
allPmcsHaveSameNameAsPlayer,
|
||||
raidSettings,
|
||||
Math.Max(GetBotPresetGenerationLimit(condition.Role),
|
||||
condition.Limit), // Choose largest between value passed in from request vs what's in bot.config
|
||||
_botHelper.IsBotPmc(condition.Role));
|
||||
raidSettings);
|
||||
|
||||
lock (_botListLock)
|
||||
{
|
||||
result.AddRange(GenerateBotWave(condition, botWaveGenerationDetails, sessionId));
|
||||
}
|
||||
GenerateBotWave(condition, botWaveGenerationDetails, generatedBotList, sessionId);
|
||||
})).ToArray());
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache()");
|
||||
}
|
||||
|
||||
return result;
|
||||
return generatedBotList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -222,9 +217,14 @@ public class BotController(
|
||||
/// </summary>
|
||||
/// <param name="generateRequest"></param>
|
||||
/// <param name="botGenerationDetails"></param>
|
||||
/// <param name="botList">List of bots to fill</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
protected List<BotBase> GenerateBotWave(GenerateCondition generateRequest, BotGenerationDetails botGenerationDetails, string sessionId)
|
||||
protected void GenerateBotWave(
|
||||
GenerateCondition generateRequest,
|
||||
BotGenerationDetails botGenerationDetails,
|
||||
List<BotBase> botList,
|
||||
string sessionId)
|
||||
{
|
||||
var isEventBot = generateRequest.Role?.Contains("event", StringComparison.OrdinalIgnoreCase);
|
||||
if (isEventBot.GetValueOrDefault(false))
|
||||
@@ -243,30 +243,36 @@ public class BotController(
|
||||
_logger.Debug($"Generating wave of: {botGenerationDetails.BotCountToGenerate} bots of type: {role} {botGenerationDetails.BotDifficulty}");
|
||||
}
|
||||
|
||||
var results = new List<BotBase>();
|
||||
for (var i = 0; i < botGenerationDetails.BotCountToGenerate; i++)
|
||||
Parallel.For(0, botGenerationDetails.BotCountToGenerate.Value, (i) =>
|
||||
{
|
||||
BotBase bot = null;
|
||||
|
||||
try
|
||||
{
|
||||
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(bot);
|
||||
bot = _botGenerator.PrepareAndGenerateBot(sessionId, _cloner.Clone(botGenerationDetails));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}");
|
||||
_logger.Error(
|
||||
$"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 Sides.Bear or Sides.Usec)
|
||||
{
|
||||
bot.Info.Side = Sides.Savage;
|
||||
}
|
||||
|
||||
lock (_botListLock)
|
||||
{
|
||||
botList.Add(bot);
|
||||
}
|
||||
|
||||
// Store bot details in cache so post-raid PMC messages can use data
|
||||
_matchBotDetailsCacheService.CacheBot(bot);
|
||||
});
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
@@ -275,8 +281,6 @@ public class BotController(
|
||||
$"({botGenerationDetails.EventRole ?? botGenerationDetails.Role ?? ""}) {botGenerationDetails.BotDifficulty} bots"
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -314,17 +318,15 @@ public class BotController(
|
||||
/// <param name="pmcProfile">Player who is generating bots</param>
|
||||
/// <param name="allPmcsHaveSameNameAsPlayer">Should all PMCs have same name as player</param>
|
||||
/// <param name="raidSettings">Settings chosen pre-raid by player in client</param>
|
||||
/// <param name="botCountToGenerate">How many bots to generate</param>
|
||||
/// <param name="generateAsPmc">Force bot being generated to be a PMC</param>
|
||||
/// <returns>BotGenerationDetails</returns>
|
||||
protected BotGenerationDetails GetBotGenerationDetailsForWave(
|
||||
GenerateCondition condition,
|
||||
PmcData? pmcProfile,
|
||||
bool allPmcsHaveSameNameAsPlayer,
|
||||
GetRaidConfigurationRequestData? raidSettings,
|
||||
int? botCountToGenerate,
|
||||
bool generateAsPmc)
|
||||
GetRaidConfigurationRequestData? raidSettings)
|
||||
{
|
||||
var generateAsPmc = _botHelper.IsBotPmc(condition.Role);
|
||||
|
||||
return new BotGenerationDetails
|
||||
{
|
||||
IsPmc = generateAsPmc,
|
||||
@@ -334,7 +336,7 @@ public class BotController(
|
||||
PlayerName = pmcProfile?.Info?.Nickname,
|
||||
BotRelativeLevelDeltaMax = _pmcConfig.BotRelativeLevelDeltaMax,
|
||||
BotRelativeLevelDeltaMin = _pmcConfig.BotRelativeLevelDeltaMin,
|
||||
BotCountToGenerate = botCountToGenerate,
|
||||
BotCountToGenerate = Math.Max(GetBotPresetGenerationLimit(condition.Role), condition.Limit), // Choose largest between value passed in from request vs what's in bot.config
|
||||
BotDifficulty = condition.Difficulty,
|
||||
LocationSpecificPmcLevelOverride = GetPmcLevelRangeForMap(raidSettings?.Location), // Min/max levels for PMCs to generate within
|
||||
IsPlayerScav = false,
|
||||
|
||||
Reference in New Issue
Block a user