fix(jit): Fix instance bot marking timing - defer until session exists

The issue: AddPlayerBot() only queues spawn to _pendingSpawns and returns
immediately. MarkAsInstanceBot() was called right after, but the session
doesn't exist yet, causing "session not found" errors and bots not being
properly tracked as instance bots.

The fix:
- Add markAsInstanceBot field to BotPendingConfiguration
- Set markAsInstanceBot=true in BotCloneEngine and InstanceBotPool
- Apply marking in BotPostLoginConfigurator::ApplyPendingConfiguration()
  AFTER the session is guaranteed to exist
- Remove premature MarkAsInstanceBot() call from JITBotFactory

This ensures JIT/warm pool bots get:
- Proper idle timeout (60 seconds)
- Restricted behavior (no questing, BattlePetManager, etc.)
- Correct instance bot tracking

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: luis <[email protected]>
This commit is contained in:
agatho
2026-02-04 20:18:24 -03:00
committed by luis
co-authored by Claude Opus 4.5
parent 8ea5a7ffd2
commit 6c812394cb
5 changed files with 34 additions and 12 deletions
@@ -620,6 +620,10 @@ CloneResult BotCloneEngine::ExecuteClone(
pendingConfig.battlegroundIdToQueue = battlegroundIdToQueue;
pendingConfig.arenaTypeToQueue = arenaTypeToQueue;
// Mark as instance bot - this will be applied after login by BotPostLoginConfigurator
// CRITICAL: This ensures JIT bots get proper idle timeout and restricted behavior
pendingConfig.markAsInstanceBot = true;
sBotPostLoginConfigurator->RegisterPendingConfig(std::move(pendingConfig));
TC_LOG_DEBUG("playerbot.clone",
@@ -12,6 +12,7 @@
#include "Equipment/BotGearFactory.h"
#include "LFG/LFGBotManager.h"
#include "PvP/BGBotManager.h"
#include "Session/BotWorldSessionMgr.h"
#include "BattlegroundMgr.h"
#include "Player.h"
#include "Item.h"
@@ -434,6 +435,19 @@ bool BotPostLoginConfigurator::ApplyPendingConfiguration(Player* player)
player->GetName(), durationMs);
}
// Step 9: Mark as instance bot if flagged
// CRITICAL FIX (2026-02-03): Instance bot marking must happen AFTER login completes
// Previously, MarkAsInstanceBot() was called immediately after AddPlayerBot() in JITBotFactory,
// but AddPlayerBot() only queues the spawn - the session doesn't exist yet!
// Now we mark the bot here, where the session is guaranteed to exist.
if (config.markAsInstanceBot)
{
sBotWorldSessionMgr->MarkAsInstanceBot(playerGuid);
TC_LOG_INFO("module.playerbot.configurator",
"Marked bot {} as INSTANCE BOT (idle timeout enabled, restricted behavior)",
player->GetName());
}
// CRITICAL: Add to recently configured set BEFORE removing pending config
// This prevents the race condition where:
// 1. We remove pending config
@@ -47,6 +47,9 @@ struct BotPendingConfiguration
uint32 battlegroundIdToQueue = 0; // If > 0, queue bot for this BG after configuration
uint32 arenaTypeToQueue = 0; // If > 0, queue bot for this arena type after configuration
// Instance Bot Flag - marks bot for idle timeout and restricted behavior
bool markAsInstanceBot = false; // If true, mark as instance bot after login
// Timing
std::chrono::steady_clock::time_point createdAt;
@@ -1687,6 +1687,10 @@ bool InstanceBotPool::WarmUpBot(ObjectGuid botGuid)
}
}
// Mark as instance bot - this will be applied after login by BotPostLoginConfigurator
// CRITICAL: This ensures warm pool bots get proper idle timeout and restricted behavior
pendingConfig.markAsInstanceBot = true;
sBotPostLoginConfigurator->RegisterPendingConfig(std::move(pendingConfig));
TC_LOG_INFO("playerbot.pool", "InstanceBotPool::WarmUpBot - Registered pending config for bot {} (level={}, spec={}, gearScore={}, contentId={}, type={})",
@@ -1022,21 +1022,18 @@ RequestProgress JITBotFactory::ProcessRequest(FactoryRequest& request)
++loginSuccessCount;
// ====================================================================
// CRITICAL FIX (2026-01-22): Mark JIT bots as INSTANCE BOTS!
// NOTE: Instance bot marking is now handled via BotPostLoginConfigurator!
// ====================================================================
// Without this, JIT bots would:
// - NOT get the 60-second idle logout timeout
// - Stay online forever causing bot explosion (1500+ bots)
// - Do quests and other activities (pool flag not set)
// - Cause massive server lag (50s+ response times)
// Previously, we called MarkAsInstanceBot() here, but AddPlayerBot()
// only queues the spawn to _pendingSpawns - the session doesn't exist yet!
// This caused "session not found" errors and bots not being properly tracked.
//
// By marking as instance bot, they get:
// - Auto-logout after 60 seconds if not in queue/group/instance
// - Restricted behavior (no questing, just queue and fight)
// The fix: Set markAsInstanceBot=true in BotPendingConfiguration (done in
// BotCloneEngine.cpp), and BotPostLoginConfigurator::ApplyPendingConfiguration()
// will call MarkAsInstanceBot() AFTER the session is created.
// ====================================================================
sBotWorldSessionMgr->MarkAsInstanceBot(botGuid);
TC_LOG_DEBUG("playerbot.jit", "JITBotFactory::ProcessRequest - Logged in bot {} (account {}), marked as INSTANCE BOT",
TC_LOG_DEBUG("playerbot.jit", "JITBotFactory::ProcessRequest - Logged in bot {} (account {}), will be marked as INSTANCE BOT after login completes",
botGuid.ToString(), accountId);
BOT_TRACK_SUCCESS(BotOperationCategory::SPAWN, "JITBotFactory::LoginBot", botGuid);
}
@@ -1052,7 +1049,7 @@ RequestProgress JITBotFactory::ProcessRequest(FactoryRequest& request)
}
}
TC_LOG_INFO("playerbot.jit", "JITBotFactory::ProcessRequest - Logged in {}/{} bots (all marked as INSTANCE BOTS)",
TC_LOG_INFO("playerbot.jit", "JITBotFactory::ProcessRequest - Logged in {}/{} bots (will be marked as INSTANCE BOTS after post-login config)",
loginSuccessCount, progress.created);
// Determine status - STRICT requirements to ensure full groups