Skip to content

Commit 106b725

Browse files
committed
Early initialize CStaticFunctionDefinitions to avoid crashes when something calls into it early.
This fixes a popular crash where LunaSVG called into OutputChatBox before core and other pointers were valid
1 parent 9f95020 commit 106b725

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo())
8282
// Init the global var with ourself
8383
g_pClientGame = this;
8484

85+
CStaticFunctionDefinitions::PreInitialize(g_pCore, g_pGame, this, &m_Events);
86+
8587
// Packet handler
8688
m_pPacketHandler = new CPacketHandler();
8789

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ CStaticFunctionDefinitions::~CStaticFunctionDefinitions()
104104
{
105105
}
106106

107+
void CStaticFunctionDefinitions::PreInitialize(CCoreInterface* pCore, CGame* pGame, CClientGame* pClientGame, CEvents* pEvents)
108+
{
109+
m_pCore = pCore;
110+
m_pGame = pGame;
111+
m_pClientGame = pClientGame;
112+
m_pEvents = pEvents;
113+
}
114+
107115
bool CStaticFunctionDefinitions::AddEvent(CLuaMain& LuaMain, const char* szName, bool bAllowRemoteTrigger)
108116
{
109117
assert(szName);
@@ -263,23 +271,27 @@ bool CStaticFunctionDefinitions::ClearChatBox()
263271

264272
bool CStaticFunctionDefinitions::OutputChatBox(const char* szText, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue, bool bColorCoded)
265273
{
266-
if (!szText || szText[0] == '\0')
274+
// Early null-safety checks to prevent crashes when called before initialization
275+
if (!m_pCore || !g_pClientGame || !szText || szText[0] == '\0')
267276
return false;
268277

278+
// Calculate length without color codes when bColorCoded is true for accurate visible text length
269279
SString textToProcess = bColorCoded ? RemoveColorCodes(szText) : SStringX(szText);
270280

271-
if (textToProcess.length() > MAX_OUTPUTCHATBOX_LENGTH) {
281+
// Reject messages that exceed the maximum length
282+
if (textToProcess.length() > MAX_OUTPUTCHATBOX_LENGTH)
272283
return false;
273-
}
274284

285+
// Fire the onClientChatMessage event
275286
CLuaArguments Arguments;
276287
Arguments.PushString(szText);
277288
Arguments.PushNumber(ucRed);
278289
Arguments.PushNumber(ucGreen);
279290
Arguments.PushNumber(ucBlue);
280291

281292
bool bCancelled = !g_pClientGame->GetRootEntity()->CallEvent("onClientChatMessage", Arguments, false);
282-
if (!bCancelled) {
293+
if (!bCancelled)
294+
{
283295
m_pCore->ChatPrintfColor("%s", bColorCoded, ucRed, ucGreen, ucBlue, szText);
284296
return true;
285297
}

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class CStaticFunctionDefinitions
2727
CClientManager* pManager);
2828
~CStaticFunctionDefinitions();
2929

30+
static void PreInitialize(CCoreInterface* pCore, CGame* pGame, CClientGame* pClientGame, CEvents* pEvents);
31+
3032
static bool AddEvent(CLuaMain& LuaMain, const char* szName, bool bAllowRemoteTrigger);
3133
static bool AddEventHandler(CLuaMain& LuaMain, const char* szName, CClientEntity& Entity, const CLuaFunctionRef& iLuaFunction, bool bPropagated,
3234
EEventPriorityType eventPriority, float fPriorityMod);

0 commit comments

Comments
 (0)