45 lines
1.8 KiB
Diff
45 lines
1.8 KiB
Diff
# UNDF: UNDF-2026-000001005
|
|
--- a/regamedll/game_shared/bot/bot_profile.cpp
|
|
+++ b/regamedll/game_shared/bot/bot_profile.cpp
|
|
@@ -590,13 +590,24 @@
|
|
}
|
|
|
|
// Return random unused profile that matches the given difficulty level
|
|
+// DEFECT: UTIL_IsNameTaken called per-profile O(P*C) where P=profiles, C=clients
|
|
+// FIX: build taken-name set once O(C), then check O(1) per profile
|
|
const BotProfile *BotProfileManager::GetRandomProfile(BotDifficultyType difficulty, BotProfileTeamType team) const
|
|
{
|
|
#ifdef RANDOM_LONG
|
|
BotProfileList::const_iterator iter;
|
|
|
|
+ // Build set of taken names once, instead of scanning players per profile
|
|
+ std::set<std::string> takenNames;
|
|
+ for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
+ {
|
|
+ CBasePlayer *player = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
|
+ if (player && player->IsBot())
|
|
+ takenNames.insert(static_cast<CBot *>(player)->GetProfile()->GetName());
|
|
+ else if (player && !FNullEnt(player->pev) && STRING(player->pev->netname)[0])
|
|
+ takenNames.insert(STRING(player->pev->netname));
|
|
+ }
|
|
+
|
|
// count up valid profiles
|
|
int validCount = 0;
|
|
for (iter = m_profileList.begin(); iter != m_profileList.end(); ++iter)
|
|
@@ -604,7 +615,7 @@
|
|
const BotProfile *profile = (*iter);
|
|
|
|
- if (profile->IsDifficulty(difficulty) && !UTIL_IsNameTaken(profile->GetName()) && profile->IsValidForTeam(team))
|
|
+ if (profile->IsDifficulty(difficulty) && takenNames.find(profile->GetName()) == takenNames.end() && profile->IsValidForTeam(team))
|
|
++validCount;
|
|
}
|
|
|
|
@@ -616,7 +627,7 @@
|
|
{
|
|
const BotProfile *profile = (*iter);
|
|
|
|
- if (profile->IsDifficulty(difficulty) && !UTIL_IsNameTaken(profile->GetName()) && profile->IsValidForTeam(team))
|
|
+ if (profile->IsDifficulty(difficulty) && takenNames.find(profile->GetName()) == takenNames.end() && profile->IsValidForTeam(team))
|
|
{
|
|
if (which-- == 0)
|
|
return profile;
|