Skip to content

Commit

Permalink
Merge pull request ddnet#9299 from Robyt3/Server-Whisper-Fix
Browse files Browse the repository at this point in the history
Fix crashes with whisper command
  • Loading branch information
def- authored Nov 29, 2024
2 parents cf48128 + a2e3905 commit 3277223
Showing 1 changed file with 42 additions and 39 deletions.
81 changes: 42 additions & 39 deletions src/game/server/gamecontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1853,13 +1853,18 @@ bool CGameContext::OnClientDDNetVersionKnown(int ClientId)
return false;
}

bool CheckClientId2(int ClientId)
{
return ClientId >= 0 && ClientId < MAX_CLIENTS;
}

void *CGameContext::PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientId)
{
if(Server()->IsSixup(ClientId) && *pMsgId < OFFSET_UUID)
{
void *pRawMsg = m_NetObjHandler7.SecureUnpackMsg(*pMsgId, pUnpacker);
if(!pRawMsg)
return 0;
return nullptr;

CPlayer *pPlayer = m_apPlayers[ClientId];
static char s_aRawMsg[1024];
Expand All @@ -1870,18 +1875,21 @@ void *CGameContext::PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientI
// Should probably use a placement new to start the lifetime of the object to avoid future weirdness
::CNetMsg_Cl_Say *pMsg = (::CNetMsg_Cl_Say *)s_aRawMsg;

if(pMsg7->m_Target >= 0)
if(pMsg7->m_Mode == protocol7::CHAT_WHISPER)
{
if(!CheckClientId2(pMsg7->m_Target) || !Server()->ClientIngame(pMsg7->m_Target))
return nullptr;
if(ProcessSpamProtection(ClientId))
return 0;
return nullptr;

// Should we maybe recraft the message so that it can go through the usual path?
WhisperId(ClientId, pMsg7->m_Target, pMsg7->m_pMessage);
return 0;
return nullptr;
}
else
{
pMsg->m_Team = pMsg7->m_Mode == protocol7::CHAT_TEAM;
pMsg->m_pMessage = pMsg7->m_pMessage;
}

pMsg->m_Team = pMsg7->m_Mode == protocol7::CHAT_TEAM;
pMsg->m_pMessage = pMsg7->m_pMessage;
}
else if(*pMsgId == protocol7::NETMSGTYPE_CL_STARTINFO)
{
Expand All @@ -1908,7 +1916,7 @@ void *CGameContext::PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientI
protocol7::CNetMsg_Cl_SkinChange *pMsg = (protocol7::CNetMsg_Cl_SkinChange *)pRawMsg;
if(g_Config.m_SvSpamprotection && pPlayer->m_LastChangeInfo &&
pPlayer->m_LastChangeInfo + Server()->TickSpeed() * g_Config.m_SvInfoChangeDelay > Server()->Tick())
return 0;
return nullptr;

pPlayer->m_LastChangeInfo = Server()->Tick();

Expand All @@ -1927,7 +1935,7 @@ void *CGameContext::PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientI

Server()->SendPackMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_NORECORD, -1);

return 0;
return nullptr;
}
else if(*pMsgId == protocol7::NETMSGTYPE_CL_SETSPECTATORMODE)
{
Expand Down Expand Up @@ -1955,7 +1963,6 @@ void *CGameContext::PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientI

str_format(s_aRawMsg + sizeof(*pMsg), sizeof(s_aRawMsg) - sizeof(*pMsg), "/%s %s", pMsg7->m_pName, pMsg7->m_pArguments);
pMsg->m_pMessage = s_aRawMsg + sizeof(*pMsg);
dbg_msg("debug", "line='%s'", s_aRawMsg + sizeof(*pMsg));
pMsg->m_Team = 0;

*pMsgId = NETMSGTYPE_CL_SAY;
Expand All @@ -1973,7 +1980,7 @@ void *CGameContext::PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientI
Console()->SetAccessLevel(Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : Authed == AUTHED_MOD ? IConsole::ACCESS_LEVEL_MOD : IConsole::ACCESS_LEVEL_HELPER);
Console()->ExecuteLine(s_aRawMsg, ClientId, false);
Console()->SetAccessLevel(IConsole::ACCESS_LEVEL_ADMIN);
return 0;
return nullptr;
}

pMsg->m_pValue = pMsg7->m_pValue;
Expand Down Expand Up @@ -2148,25 +2155,25 @@ void CGameContext::OnSayNetMessage(const CNetMsg_Cl_Say *pMsg, int ClientId, con
if(str_startswith_nocase(pMsg->m_pMessage + 1, "w "))
{
char aWhisperMsg[256];
str_copy(aWhisperMsg, pMsg->m_pMessage + 3, 256);
str_copy(aWhisperMsg, pMsg->m_pMessage + 3);
Whisper(pPlayer->GetCid(), aWhisperMsg);
}
else if(str_startswith_nocase(pMsg->m_pMessage + 1, "whisper "))
{
char aWhisperMsg[256];
str_copy(aWhisperMsg, pMsg->m_pMessage + 9, 256);
str_copy(aWhisperMsg, pMsg->m_pMessage + 9);
Whisper(pPlayer->GetCid(), aWhisperMsg);
}
else if(str_startswith_nocase(pMsg->m_pMessage + 1, "c "))
{
char aWhisperMsg[256];
str_copy(aWhisperMsg, pMsg->m_pMessage + 3, 256);
str_copy(aWhisperMsg, pMsg->m_pMessage + 3);
Converse(pPlayer->GetCid(), aWhisperMsg);
}
else if(str_startswith_nocase(pMsg->m_pMessage + 1, "converse "))
{
char aWhisperMsg[256];
str_copy(aWhisperMsg, pMsg->m_pMessage + 10, 256);
str_copy(aWhisperMsg, pMsg->m_pMessage + 10);
Converse(pPlayer->GetCid(), aWhisperMsg);
}
else
Expand Down Expand Up @@ -4559,19 +4566,14 @@ void CGameContext::ResetTuning()
SendTuningParams(-1);
}

bool CheckClientId2(int ClientId)
{
return ClientId >= 0 && ClientId < MAX_CLIENTS;
}

void CGameContext::Whisper(int ClientId, char *pStr)
{
if(ProcessSpamProtection(ClientId))
return;

pStr = str_skip_whitespaces(pStr);

char *pName;
const char *pName;
int Victim;
bool Error = false;

Expand Down Expand Up @@ -4608,35 +4610,40 @@ void CGameContext::Whisper(int ClientId, char *pStr)

if(!Error)
{
// write null termination
*pDst = 0;

*pDst = '\0';
pStr++;

for(Victim = 0; Victim < MAX_CLIENTS; Victim++)
if(str_comp(pName, Server()->ClientName(Victim)) == 0)
{
if(Server()->ClientIngame(Victim) && str_comp(pName, Server()->ClientName(Victim)) == 0)
{
break;
}
}
}
}
else
{
pName = pStr;
while(true)
{
if(pStr[0] == 0)
if(pStr[0] == '\0')
{
Error = true;
break;
}
if(pStr[0] == ' ')
{
pStr[0] = 0;
pStr[0] = '\0';
for(Victim = 0; Victim < MAX_CLIENTS; Victim++)
if(str_comp(pName, Server()->ClientName(Victim)) == 0)
{
if(Server()->ClientIngame(Victim) && str_comp(pName, Server()->ClientName(Victim)) == 0)
{
break;
}
}

pStr[0] = ' ';

if(Victim < MAX_CLIENTS)
break;
}
Expand All @@ -4649,7 +4656,7 @@ void CGameContext::Whisper(int ClientId, char *pStr)
Error = true;
}

*pStr = 0;
*pStr = '\0';
pStr++;

if(Error)
Expand All @@ -4658,7 +4665,7 @@ void CGameContext::Whisper(int ClientId, char *pStr)
return;
}

if(Victim >= MAX_CLIENTS || !CheckClientId2(Victim))
if(!CheckClientId2(Victim))
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "No player with name \"%s\" found", pName);
Expand All @@ -4671,14 +4678,10 @@ void CGameContext::Whisper(int ClientId, char *pStr)

void CGameContext::WhisperId(int ClientId, int VictimId, const char *pMessage)
{
if(!CheckClientId2(ClientId))
return;
dbg_assert(CheckClientId2(ClientId) && m_apPlayers[ClientId] != nullptr, "ClientId invalid");
dbg_assert(CheckClientId2(VictimId) && m_apPlayers[VictimId] != nullptr, "VictimId invalid");

if(!CheckClientId2(VictimId))
return;

if(m_apPlayers[ClientId])
m_apPlayers[ClientId]->m_LastWhisperTo = VictimId;
m_apPlayers[ClientId]->m_LastWhisperTo = VictimId;

char aCensoredMessage[256];
CensorMessage(aCensoredMessage, pMessage, sizeof(aCensoredMessage));
Expand Down

0 comments on commit 3277223

Please sign in to comment.