fix(pool): Fix InstanceBotPool account_id persistence and login failures

PROBLEM 1: "Pool bot failed to login via BotSpawner"
- Bots in maintenance state after warmup failure

PROBLEM 2: "No account ID for bot (not in slot or CharacterCache)"
- Bots with account_id = 0 in playerbot_instance_pool table
- CharacterCache doesn't have the account association

ROOT CAUSE:
The ON DUPLICATE KEY UPDATE clause in SyncToDatabase() did NOT include
`account_id`, so:
1. Bot initially saved with account_id = 0 (bug in some code path)
2. WarmUpBot corrects it from CharacterCache and updates the slot
3. SyncToDatabase INSERTs the correct account_id, BUT
4. ON DUPLICATE KEY UPDATE doesn't update account_id column
5. On restart, LoadFromDatabase loads account_id = 0 again

SOLUTION:
1. Add `account_id = VALUES(account_id)` to ON DUPLICATE KEY UPDATE
   - Now account_id corrections are persisted properly

2. Add account_id repair in LoadFromDatabase()
   - If account_id = 0, try to get it from CharacterCache
   - Log warning if CharacterCache also has no account

This ensures bots with previously corrupted account_id values
will be repaired on next load and the fix will be persisted.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: luis <[email protected]>
This commit is contained in:
agatho
2026-02-02 13:26:40 -03:00
committed by luis
co-authored by Claude Opus 4.5
parent 323ff2021f
commit 5e9d455b5c
@@ -2327,7 +2327,12 @@ void InstanceBotPool::SyncToDatabase()
// Execute any remaining rows
if (batchCount > 0)
{
// CRITICAL FIX: Include account_id in ON DUPLICATE KEY UPDATE
// Previously, if a bot was saved with account_id = 0, it would never
// be updated even after WarmUpBot corrected it from CharacterCache.
// This caused "No account ID for bot" errors after server restart.
query << " ON DUPLICATE KEY UPDATE "
<< "`account_id` = VALUES(`account_id`), "
<< "`slot_state` = VALUES(`slot_state`), "
<< "`assignment_count` = VALUES(`assignment_count`), "
<< "`successful_completions` = VALUES(`successful_completions`), "
@@ -2411,6 +2416,26 @@ void InstanceBotPool::LoadFromDatabase()
slot.accountId = fields[1].GetUInt32();
slot.botName = fields[2].GetString();
// CRITICAL FIX: Repair account_id = 0 from CharacterCache
// This fixes bots that were previously saved with account_id = 0
// The character exists (we checked above), so CharacterCache should have it
if (slot.accountId == 0)
{
CharacterCacheEntry const* charInfo = sCharacterCache->GetCharacterCacheByGuid(guid);
if (charInfo && charInfo->AccountId > 0)
{
slot.accountId = charInfo->AccountId;
TC_LOG_INFO("playerbot.pool", "LoadFromDatabase: Repaired account_id for {} from CharacterCache (accountId={})",
guid.ToString(), slot.accountId);
}
else
{
// Character cache doesn't have account - this bot won't be able to login
TC_LOG_WARN("playerbot.pool", "LoadFromDatabase: Bot {} has account_id=0 and CharacterCache has no account, bot may fail to login",
guid.ToString());
}
}
// Parse role enum
std::string roleStr = fields[3].GetString();
if (roleStr == "TANK")