3095: Disallow player name changes when the player is muted r=def- a=heinrich5991



Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
bors[bot] 2020-10-20 15:56:16 +00:00 committed by GitHub
commit 2709afb007
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 46 deletions

View file

@ -190,6 +190,7 @@ public:
virtual void GetMapInfo(char *pMapName, int MapNameSize, int *pMapSize, SHA256_DIGEST *pSha256, int *pMapCrc) = 0; virtual void GetMapInfo(char *pMapName, int MapNameSize, int *pMapSize, SHA256_DIGEST *pSha256, int *pMapCrc) = 0;
virtual bool WouldClientNameChange(int ClientID, const char *pNameRequest) = 0;
virtual void SetClientName(int ClientID, char const *pName) = 0; virtual void SetClientName(int ClientID, char const *pName) = 0;
virtual void SetClientClan(int ClientID, char const *pClan) = 0; virtual void SetClientClan(int ClientID, char const *pClan) = 0;
virtual void SetClientCountry(int ClientID, int Country) = 0; virtual void SetClientCountry(int ClientID, int Country) = 0;

View file

@ -329,82 +329,96 @@ CServer::CServer() :
Init(); Init();
} }
int CServer::TrySetClientName(int ClientID, const char *pName) bool CServer::IsClientNameAvailable(int ClientID, const char *pNameRequest)
{ {
char aTrimmedName[64];
// trim the name
str_copy(aTrimmedName, str_utf8_skip_whitespaces(pName), sizeof(aTrimmedName));
str_utf8_trim_right(aTrimmedName);
// check for empty names // check for empty names
if(!aTrimmedName[0]) if(!pNameRequest[0])
return -1; return false;
// check for names starting with /, as they can be abused to make people // check for names starting with /, as they can be abused to make people
// write chat commands // write chat commands
if(aTrimmedName[0] == '/') if(pNameRequest[0] == '/')
return -1; return false;
// make sure that two clients don't have the same name // make sure that two clients don't have the same name
for(int i = 0; i < MAX_CLIENTS; i++) for(int i = 0; i < MAX_CLIENTS; i++)
{ {
if(i != ClientID && m_aClients[i].m_State >= CClient::STATE_READY) if(i != ClientID && m_aClients[i].m_State >= CClient::STATE_READY)
{ {
if(str_utf8_comp_confusable(aTrimmedName, m_aClients[i].m_aName) == 0) if(str_utf8_comp_confusable(pNameRequest, m_aClients[i].m_aName) == 0)
return -1; return false;
} }
} }
char aBuf[256]; return true;
str_format(aBuf, sizeof(aBuf), "'%s' -> '%s'", pName, aTrimmedName);
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
pName = aTrimmedName;
// set the client name
str_copy(m_aClients[ClientID].m_aName, pName, MAX_NAME_LENGTH);
return 0;
} }
void CServer::SetClientName(int ClientID, const char *pName) bool CServer::SetClientNameImpl(int ClientID, const char *pNameRequest, bool Set)
{ {
if(ClientID < 0 || ClientID >= MAX_CLIENTS || m_aClients[ClientID].m_State < CClient::STATE_READY) dbg_assert(0 <= ClientID && ClientID < MAX_CLIENTS, "invalid client id");
return; if(m_aClients[ClientID].m_State < CClient::STATE_READY)
return false;
if(!pName) if(Set)
return;
CNameBan *pBanned = IsNameBanned(pName, m_aNameBans.base_ptr(), m_aNameBans.size());
if(pBanned)
{ {
if(m_aClients[ClientID].m_State == CClient::STATE_READY) CNameBan *pBanned = IsNameBanned(pNameRequest, m_aNameBans.base_ptr(), m_aNameBans.size());
if(pBanned)
{ {
char aBuf[256]; if(m_aClients[ClientID].m_State == CClient::STATE_READY)
if(pBanned->m_aReason[0])
{ {
str_format(aBuf, sizeof(aBuf), "Kicked (your name is banned: %s)", pBanned->m_aReason); char aBuf[256];
if(pBanned->m_aReason[0])
{
str_format(aBuf, sizeof(aBuf), "Kicked (your name is banned: %s)", pBanned->m_aReason);
}
else
{
str_copy(aBuf, "Kicked (your name is banned)", sizeof(aBuf));
}
Kick(ClientID, aBuf);
} }
else return true;
{
str_copy(aBuf, "Kicked (your name is banned)", sizeof(aBuf));
}
Kick(ClientID, aBuf);
} }
return;
} }
// trim the name
char aTrimmedName[MAX_NAME_LENGTH];
str_copy(aTrimmedName, str_utf8_skip_whitespaces(pNameRequest), sizeof(aTrimmedName));
str_utf8_trim_right(aTrimmedName);
char aNameTry[MAX_NAME_LENGTH]; char aNameTry[MAX_NAME_LENGTH];
str_copy(aNameTry, pName, sizeof(aNameTry)); str_copy(aNameTry, aTrimmedName, sizeof(aNameTry));
if(TrySetClientName(ClientID, aNameTry))
if(!IsClientNameAvailable(ClientID, aNameTry))
{ {
// auto rename // auto rename
for(int i = 1;; i++) for(int i = 1;; i++)
{ {
str_format(aNameTry, sizeof(aNameTry), "(%d)%s", i, pName); str_format(aNameTry, sizeof(aNameTry), "(%d)%s", i, aTrimmedName);
if(TrySetClientName(ClientID, aNameTry) == 0) if(IsClientNameAvailable(ClientID, aNameTry))
break; break;
} }
} }
bool Changed = str_comp(m_aClients[ClientID].m_aName, aNameTry) != 0;
if(Set)
{
// set the client name
str_copy(m_aClients[ClientID].m_aName, aNameTry, MAX_NAME_LENGTH);
}
return Changed;
}
bool CServer::WouldClientNameChange(int ClientID, const char *pNameRequest)
{
return SetClientNameImpl(ClientID, pNameRequest, false);
}
void CServer::SetClientName(int ClientID, const char *pName)
{
SetClientNameImpl(ClientID, pName, true);
} }
void CServer::SetClientClan(int ClientID, const char *pClan) void CServer::SetClientClan(int ClientID, const char *pClan)

View file

@ -258,8 +258,10 @@ public:
CServer(); CServer();
int TrySetClientName(int ClientID, const char *pName); bool IsClientNameAvailable(int ClientID, const char *pNameRequest);
bool SetClientNameImpl(int ClientID, const char *pNameRequest, bool Set);
virtual bool WouldClientNameChange(int ClientID, const char *pNameRequest);
virtual void SetClientName(int ClientID, const char *pName); virtual void SetClientName(int ClientID, const char *pName);
virtual void SetClientClan(int ClientID, char const *pClan); virtual void SetClientClan(int ClientID, char const *pClan);
virtual void SetClientCountry(int ClientID, int Country); virtual void SetClientCountry(int ClientID, int Country);

View file

@ -2173,9 +2173,10 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
// set infos // set infos
char aOldName[MAX_NAME_LENGTH]; char aOldName[MAX_NAME_LENGTH];
str_copy(aOldName, Server()->ClientName(ClientID), sizeof(aOldName)); str_copy(aOldName, Server()->ClientName(ClientID), sizeof(aOldName));
Server()->SetClientName(ClientID, pMsg->m_pName); if(Server()->WouldClientNameChange(ClientID, pMsg->m_pName) && !ProcessSpamProtection(ClientID))
if(str_comp(aOldName, Server()->ClientName(ClientID)) != 0)
{ {
Server()->SetClientName(ClientID, pMsg->m_pName);
char aChatText[256]; char aChatText[256];
str_format(aChatText, sizeof(aChatText), "'%s' changed name to '%s'", aOldName, Server()->ClientName(ClientID)); str_format(aChatText, sizeof(aChatText), "'%s' changed name to '%s'", aOldName, Server()->ClientName(ClientID));
SendChat(-1, CGameContext::CHAT_ALL, aChatText); SendChat(-1, CGameContext::CHAT_ALL, aChatText);