Source characters DB name from server config in BotNamePool orphan sweep

The LEFT JOIN characters.characters cross-DB qualifier hardcoded the
characters schema name, breaking installs with a renamed characters
database. Read it from CharacterDatabase.GetConnectionInfo() (worldserver.conf
CharacterDatabaseInfo) instead, falling back to 'characters'.
This commit is contained in:
devbox
2026-08-12 13:15:36 +10:00
parent 9ed80ca65a
commit 75090e50b4
+19 -6
View File
@@ -61,10 +61,9 @@ NameEntry PopRandom_locked(std::vector<NameEntry>& v)
}
// Single config-driven home for all instance-shared playerbot data
// (Playerbot.SharedDatabase, default "wowc_playerbot"). Read once. Used to
// (Playerbot.SharedDatabase, default "playerbot"). Read once. Used to
// qualify cross-DB queries so swapping the active world/character DB never
// strands the shared bot data. NOTE: the realm-specific `characters.characters`
// join below is intentionally NOT this schema.
// strands the shared bot data.
std::string const& SharedDb()
{
static std::string const db =
@@ -72,6 +71,20 @@ std::string const& SharedDb()
return db;
}
// Config-driven home for the realm's characters database name. Pulled from
// CharacterDatabase.GetConnectionInfo(), whose connection string is loaded in
// worldserver.conf from the CharacterDatabaseInfo entry — so installs that
// renamed their characters schema keep the cross-DB orphan-sweep JOIN working.
// Falls back to "characters" if the pool hasn't been initialized yet.
std::string const& CharactersDb()
{
static std::string const db = [] {
MySQLConnectionInfo const* info = CharacterDatabase.GetConnectionInfo();
return (info && !info->database.empty()) ? info->database : std::string("characters");
}();
return db;
}
std::string EscapeForSql(std::string const& s)
{
std::string out;
@@ -205,10 +218,10 @@ void BotNamePool::ReconcileOnBoot()
// First: clean up DB orphans (is_used=1 but the character doesn't exist).
// This catches SQL-wipes / mid-create crashes that bypassed Release.
auto orphan_res = CharacterDatabase.Query(fmt::format(
"SELECT pn.name_id FROM {}.playerbots_names pn "
"LEFT JOIN characters.characters c ON c.guid = pn.used_by_guid "
"SELECT pn.name_id FROM {0}.playerbots_names pn "
"LEFT JOIN {1}.characters c ON c.guid = pn.used_by_guid "
"WHERE pn.is_used = 1 AND (pn.used_by_guid IS NULL OR c.guid IS NULL)",
SharedDb()).c_str());
SharedDb(), CharactersDb()).c_str());
uint32 released = 0;
if (orphan_res)