From fc282fda54187492f6d52ec0e205b15c5ab7b197 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 13:43:49 +0000 Subject: [PATCH] fix: null-session crash when broadcasting event start/end messages StartEvent() and EndEvent() both used ChatHandler(nullptr).SendWorldText() to announce Gold Rush events server-wide. ChatHandler::SendWorldText() (core Chat.cpp) unconditionally calls GetSession()->SendPacket() on the handler's session -- with a null session, that's an immediate null-pointer dereference. This crashed the live server twice within ~24 hours (confirmed via a symbolized gdb backtrace against a captured coredump): WorldSession::GetPlayer (this=0x0) WorldSession::SendPacket (this=0x0, ...) ChatHandler::SendWorldText (...) GoldRushManager::StartEvent (...) at GoldRush.cpp:880 ChatHandler is meant to wrap a real player/GM session; it was only being constructed here to reuse SendWorldText's string formatting, with no actual session behind it. Fix: use sWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, text) instead -- the core-provided, session-free broadcast path (the same one the built-in .announce GM command uses in cs_message.cpp). No session required, so no crash regardless of whether the event is triggered automatically or by a player. Fixed all three call sites using this broken pattern: the event-start announcement (two locations -- StartEvent has what looks like an earlier duplicate/preview announcement plus the main one) and the event-end announcement in EndEvent(). The EndEvent() site had not crashed yet but is the exact same bug and would have crashed the first time any event completed naturally. --- src/GoldRush.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/GoldRush.cpp b/src/GoldRush.cpp index dadd0d5..31ec8c2 100644 --- a/src/GoldRush.cpp +++ b/src/GoldRush.cpp @@ -5,6 +5,7 @@ #include "DBCStores.h" #include "GameObject.h" #include "Log.h" +#include "WorldSessionMgr.h" #include "Map.h" #include "MapMgr.h" #include "ObjectAccessor.h" @@ -324,7 +325,7 @@ public: _currentSite.MapId, _currentSite.ZoneId, _currentSite.AreaId, anchor->GetName()); } - ChatHandler(nullptr).SendWorldText(Acore::StringFormat(_config.StartMessage, FormatLocationForAnnouncement(_currentSite, anchor))); + sWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, Acore::StringFormat(_config.StartMessage, FormatLocationForAnnouncement(_currentSite, anchor))); if (_config.Debug) { @@ -877,7 +878,7 @@ private: } std::string announcementLocation = FormatLocationForAnnouncement(_currentSite, anchor); - ChatHandler(nullptr).SendWorldText(Acore::StringFormat(_config.StartMessage, announcementLocation)); + sWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, Acore::StringFormat(_config.StartMessage, announcementLocation)); if (_config.Debug) { @@ -898,7 +899,7 @@ private: return; std::string location = BuildLocationText(_currentSite); - ChatHandler(nullptr).SendWorldText(Acore::StringFormat(_config.EndMessage, location)); + sWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, Acore::StringFormat(_config.EndMessage, location)); if (_config.Debug) LOG_INFO(GoldRushLogFilter, "Gold Rush ended in {}{}.", location, forced ? " (forced)" : ""); -- 2.49.1