From e84a68a1ce5c38becdb071413a3019ea1ba200e7 Mon Sep 17 00:00:00 2001 From: MadMax Date: Fri, 31 Jul 2026 12:22:10 +0100 Subject: [PATCH] Restore console title and startup beep lost in United cores PR #463 (a683a244, 1039 files, no reviews) removed two admin-visible console behaviours without mentioning either, and left a config key renamed on the code side only. This restores all three. Console title: the live "N Players - N Connections" window title added in #337 was relocated intact by #448, then deleted outright by #463. Restored into Master::PublishConsoleStatus(), which already runs on a one-second cadence, placed above that function's early-out because the window title is owned by the OS rather than by the console frame and must stay current even when the full-screen UI is off. Startup beep: #463 gated the existing beep behind !ConsoleUI::Active(), and the full-screen UI is on by default, so it never fired interactively. Removing the gate alone is not sufficient: ConsoleLogWriter::Emit() routes a raw record to ConsoleUI::PushRaw() as text when the UI is active, so a BEL sent through sLog is displayed rather than sounded. The bell now bypasses the log pipeline entirely. Config keys: #448 shipped Console.Style correctly on both sides; #463 replaced the reader with a bool Console.FullScreen and left the conf untouched, so Console.Style became dead, Console.FullScreen existed in no config file, and there was no shipped way to disable the UI. Console.Style is restored as the reader and its doc block now states honestly that "fancy" behaves as "auto". Separately, the conf still said BeepAtStart while the code read Console.BeepAtStart; the conf now matches. Verified: builds clean with 0 errors; mangosd boots against a real 1.12.1 dataset and the title was observed live as "Mangos Zero (0 Players - 0 Connections)"; the beep was confirmed audible on the rebuilt binary. Co-Authored-By: Claude Opus 5 (1M context) --- src/mangosd/CliService.cpp | 15 +++++++++++-- src/mangosd/Master.cpp | 38 ++++++++++++++++++++++++++++++++ src/mangosd/mangosd.conf.dist.in | 11 ++++----- src/mangosd/mangosd.cpp | 6 ++++- 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/mangosd/CliService.cpp b/src/mangosd/CliService.cpp index 2d4f48800..5b64769b1 100644 --- a/src/mangosd/CliService.cpp +++ b/src/mangosd/CliService.cpp @@ -133,9 +133,20 @@ void CliService::Run() // Let start-up finish printing before the prompt lands in the middle of it. std::this_thread::sleep_for(std::chrono::seconds(1)); - if (m_beep && !MaNGOS::Console::ConsoleUI::Instance().Active()) + // The bell has to bypass the log pipeline entirely. With the full-screen UI + // up, ConsoleLogWriter::Emit() folds a raw record into the UI's scrollback + // as text, so a BEL routed through sLog is displayed rather than sounded -- + // which is why gating this on !ConsoleUI::Active() silenced it outright. + if (m_beep) { - sLog.ConsoleEmitRaw("\a"); +#ifdef _WIN32 + // The system "default" sound, i.e. what the console bell used to raise. + MessageBeep(MB_OK); +#else + // Straight to the terminal: non-printing, so it cannot disturb a frame. + std::fputs("\a", stdout); + std::fflush(stdout); +#endif } Prompt(); diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp index 0405183f1..d67512a71 100644 --- a/src/mangosd/Master.cpp +++ b/src/mangosd/Master.cpp @@ -38,6 +38,7 @@ #include "Log.h" #include "MapManager.h" #include "Server/WorldNetwork.h" +#include "SystemConfig.h" #include "Timer.h" #include "World.h" @@ -98,6 +99,35 @@ namespace return db.CheckDatabaseVersion(versionKind); } + +#ifdef _WIN32 + /** + * @brief Show the live player and connection counts in the window title. + * + * The title belongs to the OS window, not to the console frame, so it stays + * readable while the server is minimised or buried in the taskbar -- which + * the in-frame status bar is not. Rewritten only when the text actually + * changes, because SetConsoleTitleA is a cross-process call. + * + * @param players Currently active sessions. + * @param connections Currently open socket connections. + */ + void UpdateConsoleTitle(uint32 players, uint32 connections) + { + static std::string s_lastTitle; + + char title[128]; + snprintf(title, sizeof(title), "%s (%u Players - %u Connections)", + MANGOS_PACKAGENAME, players, connections); + + std::string newTitle(title); + if (s_lastTitle != newTitle) + { + s_lastTitle = newTitle; + SetConsoleTitleA(title); + } + } +#endif } Master::Master() @@ -250,6 +280,14 @@ void Master::StopServices() void Master::PublishConsoleStatus(uint32 diff) { +#ifdef _WIN32 + // Before the early-out below: the window title is owned by the OS rather + // than by the console frame, so it is kept current even when the + // full-screen UI is switched off and there is no status bar to publish to. + UpdateConsoleTitle(sWorld.GetActiveSessionCount(), + sWorldNetwork.GetOpenConnectionCount()); +#endif + MaNGOS::Console::ConsoleUI& ui = MaNGOS::Console::ConsoleUI::Instance(); if (!ui.Active()) { diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 58b58da4a..54bcf5d1d 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -802,8 +802,8 @@ SD3ErrorLogFile = "scriptdev3-errors.log" # Default: 0 (false) # 1 (true) # -# BeepAtStart -# Beep at mangosd start finished (mostly work only at Unix/Linux systems) +# Console.BeepAtStart +# Beep once mangosd has finished starting and the console is ready. # Default: 1 (true) # 0 (false) # @@ -818,8 +818,9 @@ SD3ErrorLogFile = "scriptdev3-errors.log" # Default: "auto" (draw the boxed, coloured loading UI when stdout is an # interactive console; plain text when it is redirected # to a file or a pipe, or when running as a service) -# "fancy" (force the loading UI on, for a terminal that cannot be -# detected as one) +# "fancy" (currently behaves as "auto": forcing the UI on for a +# terminal that cannot be detected as one is not yet +# implemented) # "plain" (never; plain text, as older releases printed it) # # WaitAtStartupError @@ -910,7 +911,7 @@ MailDeliveryDelay = 3600 MassMailer.SendPerTick = 10 PetUnsummonAtMount = 0 Event.Announce = 0 -BeepAtStart = 1 +Console.BeepAtStart = 1 ShowProgressBars = 1 Console.Style = "auto" WaitAtStartupError = 10 diff --git a/src/mangosd/mangosd.cpp b/src/mangosd/mangosd.cpp index 3c9385411..56da7dc68 100644 --- a/src/mangosd/mangosd.cpp +++ b/src/mangosd/mangosd.cpp @@ -351,7 +351,11 @@ int main(int argc, char** argv) // Only now: until the writer thread exists, console emits take the // synchronous path and would write straight over the full-screen frame. - if (sConfig.GetBoolDefault("Console.FullScreen", true) && + // "plain" never draws the loading UI. "auto" and "fancy" both ask for it, + // and Start() declines on its own when stdout is not a real terminal. + const std::string consoleStyle = + sConfig.GetStringDefault("Console.Style", "auto"); + if (consoleStyle != "plain" && MaNGOS::Console::ConsoleUI::Instance().Start("MaNGOS Zero", "Vanilla 1.12.x")) { MaNGOS::Console::ConsoleUI::Instance().SetHeaderRight(