From ea96cb4b4d772ed3a517c72ff8570e167976c9b4 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:45:27 +0200 Subject: [PATCH] fix(Core/Realms): show realms as offline when no worldserver is running (#26658) --- src/server/apps/authserver/Main.cpp | 4 ++++ .../database/Database/Implementation/LoginDatabase.cpp | 1 + src/server/database/Database/Implementation/LoginDatabase.h | 1 + src/server/game/World/World.cpp | 6 ++++++ 4 files changed, 12 insertions(+) diff --git a/src/server/apps/authserver/Main.cpp b/src/server/apps/authserver/Main.cpp index 6d351336a..f5c3b80bc 100644 --- a/src/server/apps/authserver/Main.cpp +++ b/src/server/apps/authserver/Main.cpp @@ -129,6 +129,10 @@ int main(int argc, char** argv) std::shared_ptr dbHandle(nullptr, [](void*) { StopDB(); }); + // Mark every realm offline on startup; each worldserver clears this flag for its own realm once it is ready. + // This prevents realms from appearing online in the realm list when no worldserver is actually running. + LoginDatabase.DirectExecute("UPDATE realmlist SET flag = flag | {}", REALM_FLAG_OFFLINE); + std::shared_ptr ioContext = std::make_shared(); // Get the list of realms for the server diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index a90e1bcd7..1629b7a69 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -91,6 +91,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_UPD_LAST_ATTEMPT_IP, "UPDATE account SET last_attempt_ip = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_ONLINE, "UPDATE account SET online = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_UPTIME_PLAYERS, "UPDATE uptime SET uptime = ?, maxplayers = ? WHERE realmid = ? AND starttime = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_REALM_ONLINE, "UPDATE realmlist SET flag = flag & ~? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_OLD_LOGS, "DELETE FROM logs WHERE (time + ?) < ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS, "DELETE FROM account_access WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, "DELETE FROM account_access WHERE id = ? AND (RealmID = ? OR RealmID = -1)", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index 140166dda..a91f3dbe0 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -75,6 +75,7 @@ enum LoginDatabaseStatements : uint32 LOGIN_UPD_LAST_ATTEMPT_IP, LOGIN_UPD_ACCOUNT_ONLINE, LOGIN_UPD_UPTIME_PLAYERS, + LOGIN_UPD_REALM_ONLINE, LOGIN_DEL_OLD_LOGS, LOGIN_DEL_ACCOUNT_ACCESS, LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index c12ff71b8..2c302ba05 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1286,6 +1286,12 @@ void World::Update(uint32 diff) stmt->SetData(2, realm.Id.Realm); stmt->SetData(3, uint32(GameTime::GetStartTime().count())); LoginDatabase.Execute(stmt); + + // Re-assert this realm as online in case the offline flag was set externally (e.g. an authserver restart). + LoginDatabasePreparedStatement* onlineStmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_REALM_ONLINE); + onlineStmt->SetData(0, uint8(REALM_FLAG_OFFLINE)); + onlineStmt->SetData(1, realm.Id.Realm); + LoginDatabase.Execute(onlineStmt); } ///- Process Game events when necessary