fix(jit): Fix JIT bots not queuing for battlegrounds

JIT-created bots were never being queued for BG because the onComplete
callback tried to use ObjectAccessor::FindPlayer() before bots entered
the world. Replaced direct callback queueing with deferred post-login
queueing via BotPostLoginConfigurator (same pattern as LFG dungeons).

Changes:
- BotPostLoginConfigurator: Implement BG queueing after bot login
- QueueStatePoller: Use battlegroundIdToQueue field instead of callback

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: luis <[email protected]>
This commit is contained in:
agatho
2026-02-03 21:31:24 -03:00
committed by luis
co-authored by Claude Opus 4.5
parent e136047f18
commit 681d2be68e
2 changed files with 68 additions and 23 deletions
@@ -11,6 +11,8 @@
#include "BotTemplateRepository.h"
#include "Equipment/BotGearFactory.h"
#include "LFG/LFGBotManager.h"
#include "PvP/BGBotManager.h"
#include "BattlegroundMgr.h"
#include "Player.h"
#include "Item.h"
#include "Log.h"
@@ -360,8 +362,55 @@ bool BotPostLoginConfigurator::ApplyPendingConfiguration(Player* player)
}
}
// TODO: Add battleground and arena queueing when needed
// if (config.battlegroundIdToQueue > 0) { ... }
// Step 8: Queue for battleground if this was a JIT-created bot
if (config.battlegroundIdToQueue > 0)
{
BattlegroundTypeId bgTypeId = static_cast<BattlegroundTypeId>(config.battlegroundIdToQueue);
TC_LOG_INFO("module.playerbot.configurator",
"Queueing JIT bot {} for battleground {} after configuration",
player->GetName(), config.battlegroundIdToQueue);
// Get the BG template to find the map ID
BattlegroundTemplate const* bgTemplate = sBattlegroundMgr->GetBattlegroundTemplateByTypeId(bgTypeId);
if (bgTemplate && !bgTemplate->MapIDs.empty())
{
// Determine bracket from bot's level
PVPDifficultyEntry const* bracketEntry = DB2Manager::GetBattlegroundBracketByLevel(
bgTemplate->MapIDs.front(), player->GetLevel());
if (bracketEntry)
{
BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
if (sBGBotManager->QueueBotForBG(player, bgTypeId, bracketId))
{
TC_LOG_INFO("module.playerbot.configurator",
"Successfully queued bot {} for BG {} bracket {}",
player->GetName(), config.battlegroundIdToQueue, static_cast<uint8>(bracketId));
}
else
{
TC_LOG_WARN("module.playerbot.configurator",
"Failed to queue bot {} for BG {}",
player->GetName(), config.battlegroundIdToQueue);
}
}
else
{
TC_LOG_WARN("module.playerbot.configurator",
"Could not determine BG bracket for bot {} (level {}) on map {}",
player->GetName(), player->GetLevel(), bgTemplate->MapIDs.front());
}
}
else
{
TC_LOG_WARN("module.playerbot.configurator",
"Could not find BG template for type {}",
config.battlegroundIdToQueue);
}
}
// TODO: Add arena queueing when needed
// if (config.arenaTypeToQueue > 0) { ... }
// Calculate timing
@@ -660,17 +660,16 @@ void QueueStatePoller::ProcessBGShortage(BGQueueSnapshot const& snapshot)
request.priority = priority;
request.createdAt = std::chrono::system_clock::now();
// Callback to queue the bot for BG after creation
request.onComplete = [bgTypeId = snapshot.bgTypeId, bracket = snapshot.bracketId](std::vector<ObjectGuid> const& botGuids) {
for (ObjectGuid const& guid : botGuids)
{
if (Player* bot = ObjectAccessor::FindPlayer(guid))
{
sBGBotManager->QueueBotForBG(bot, bgTypeId, bracket);
TC_LOG_DEBUG("playerbot.jit", "QueueStatePoller: JIT Alliance bot {} queued for BG type {}",
guid.ToString(), static_cast<uint32>(bgTypeId));
}
}
// Set BG ID for post-login queueing
// The BotPostLoginConfigurator will queue bots AFTER they're fully logged in
// This avoids the timing issue where ObjectAccessor::FindPlayer returns nullptr
// because the bots haven't entered the world yet when onComplete fires.
request.battlegroundIdToQueue = static_cast<uint32>(snapshot.bgTypeId);
// Callback for debugging (bots queue via BotPostLoginConfigurator, not here)
request.onComplete = [bgTypeId = snapshot.bgTypeId](std::vector<ObjectGuid> const& botGuids) {
TC_LOG_INFO("playerbot.jit", "QueueStatePoller: {} JIT Alliance bots created for BG {} - they will auto-queue after login",
botGuids.size(), static_cast<uint32>(bgTypeId));
};
uint32 requestId = sJITBotFactory->SubmitRequest(std::move(request));
@@ -693,16 +692,13 @@ void QueueStatePoller::ProcessBGShortage(BGQueueSnapshot const& snapshot)
request.priority = priority;
request.createdAt = std::chrono::system_clock::now();
request.onComplete = [bgTypeId = snapshot.bgTypeId, bracket = snapshot.bracketId](std::vector<ObjectGuid> const& botGuids) {
for (ObjectGuid const& guid : botGuids)
{
if (Player* bot = ObjectAccessor::FindPlayer(guid))
{
sBGBotManager->QueueBotForBG(bot, bgTypeId, bracket);
TC_LOG_DEBUG("playerbot.jit", "QueueStatePoller: JIT Horde bot {} queued for BG type {}",
guid.ToString(), static_cast<uint32>(bgTypeId));
}
}
// Set BG ID for post-login queueing (same as Alliance - bracket determined by level)
request.battlegroundIdToQueue = static_cast<uint32>(snapshot.bgTypeId);
// Callback for debugging (bots queue via BotPostLoginConfigurator, not here)
request.onComplete = [bgTypeId = snapshot.bgTypeId](std::vector<ObjectGuid> const& botGuids) {
TC_LOG_INFO("playerbot.jit", "QueueStatePoller: {} JIT Horde bots created for BG {} - they will auto-queue after login",
botGuids.size(), static_cast<uint32>(bgTypeId));
};
uint32 requestId = sJITBotFactory->SubmitRequest(std::move(request));