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.
This commit is contained in:
Claude 2026-09-04 13:43:49 +00:00
parent 104ff733b3
commit fc282fda54

View file

@ -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)" : "");