mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge pull request #1443 from ChillerDragon/AutobanKnownBots
Add autoban depending on client version
This commit is contained in:
commit
698a3f1c5a
|
@ -3041,6 +3041,50 @@ unsigned str_quickhash(const char *str)
|
|||
return hash;
|
||||
}
|
||||
|
||||
static const char *str_token_next(const char *str, const char *delim, size_t *length)
|
||||
{
|
||||
str += strspn(str, delim);
|
||||
if(!*str)
|
||||
return NULL;
|
||||
|
||||
*length = strcspn(str, delim);
|
||||
return str;
|
||||
}
|
||||
|
||||
int str_tokenize(const char *str, const char *delim, const char **state, char *buf, size_t bufsz)
|
||||
{
|
||||
const char *ret = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if((!str && !state) || !buf)
|
||||
return -1;
|
||||
|
||||
str = str ? str : *state;
|
||||
|
||||
if(!(ret = str_token_next(str, delim, &len)))
|
||||
return -1;
|
||||
|
||||
*state = ret + len;
|
||||
len = bufsz > len ? len : bufsz - 1;
|
||||
mem_copy(buf, ret, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int str_in_list(const char *list, const char *delim, const char *needle)
|
||||
{
|
||||
const char *tok = list;
|
||||
size_t len = 0, notfound = 1;
|
||||
|
||||
while(notfound && (tok = str_token_next(tok, delim, &len))){
|
||||
notfound = str_comp_num(tok, needle, len);
|
||||
tok = tok + len;
|
||||
}
|
||||
|
||||
return !notfound;
|
||||
}
|
||||
|
||||
int pid()
|
||||
{
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
|
|
|
@ -1831,6 +1831,40 @@ int str_utf16le_encode(char *ptr, int chr);
|
|||
*/
|
||||
int str_utf8_check(const char *str);
|
||||
|
||||
/*
|
||||
Function: str_tokenize
|
||||
Tokenizes a string.
|
||||
|
||||
Parameters:
|
||||
str - Pointer to string.
|
||||
delim - Delimiter for tokenization.
|
||||
state - Pointer to remaining string
|
||||
buf - Buffer to store token in.
|
||||
bufsz - Size of the buffer.
|
||||
|
||||
Returns:
|
||||
The number of characters written to buf or -1 for end of string
|
||||
|
||||
Remarks:
|
||||
- The token is always null-terminated.
|
||||
*/
|
||||
int str_tokenize(const char *str, const char *delim, const char **state, char *buf, size_t bufsz);
|
||||
|
||||
/*
|
||||
Function: str_in_list
|
||||
Checks if needle is in list delimited by delim
|
||||
|
||||
Parameters:
|
||||
list - List
|
||||
delim - List delimiter.
|
||||
needle - Item that is being looked for.
|
||||
|
||||
Returns:
|
||||
1 - Item is in list.
|
||||
0 - Item isn't in list.
|
||||
*/
|
||||
int str_in_list(const char *list, const char *delim, const char *needle);
|
||||
|
||||
int pid();
|
||||
|
||||
/*
|
||||
|
|
|
@ -167,6 +167,8 @@ public:
|
|||
virtual int GetAuthedState(int ClientID) = 0;
|
||||
virtual const char *GetAuthName(int ClientID) = 0;
|
||||
virtual void Kick(int ClientID, const char *pReason) = 0;
|
||||
virtual void Ban(int ClientID, int Seconds, const char *pReason) = 0;
|
||||
|
||||
|
||||
virtual void DemoRecorder_HandleAutoStart() = 0;
|
||||
virtual bool DemoRecorder_IsRecording() = 0;
|
||||
|
|
|
@ -428,6 +428,13 @@ void CServer::Kick(int ClientID, const char *pReason)
|
|||
m_NetServer.Drop(ClientID, pReason);
|
||||
}
|
||||
|
||||
void CServer::Ban(int ClientID, int Seconds, const char *pReason)
|
||||
{
|
||||
NETADDR Addr;
|
||||
GetClientAddr(ClientID, &Addr);
|
||||
m_NetServer.NetBan()->BanAddr(&Addr, Seconds, pReason);
|
||||
}
|
||||
|
||||
/*int CServer::Tick()
|
||||
{
|
||||
return m_CurrentGameTick;
|
||||
|
|
|
@ -238,6 +238,7 @@ public:
|
|||
virtual void SetClientScore(int ClientID, int Score);
|
||||
|
||||
void Kick(int ClientID, const char *pReason);
|
||||
void Ban(int ClientID, int Seconds, const char *pReason);
|
||||
|
||||
void DemoRecorder_HandleAutoStart();
|
||||
bool DemoRecorder_IsRecording();
|
||||
|
|
|
@ -359,6 +359,7 @@ MACRO_CONFIG_INT(SvSoloServer, sv_solo_server, 0, 0, 1, CFGFLAG_SERVER|CFGFLAG_G
|
|||
MACRO_CONFIG_STR(SvClientSuggestion, sv_client_suggestion, 128, "Get DDNet client from DDNet.tw to use all features on DDNet!", CFGFLAG_SERVER, "Broadcast to display to players without DDNet client")
|
||||
MACRO_CONFIG_STR(SvClientSuggestionOld, sv_client_suggestion_old, 128, "Your DDNet client is old, update it on DDNet.tw!", CFGFLAG_SERVER, "Broadcast to display to players with an old version of DDNet client")
|
||||
MACRO_CONFIG_STR(SvClientSuggestionBot, sv_client_suggestion_bot, 128, "Your client has bots and can be remotely controlled!\nPlease use another client like DDNet client from DDNet.tw", CFGFLAG_SERVER, "Broadcast to display to players with a known botting client")
|
||||
MACRO_CONFIG_STR(SvBannedVersions, sv_banned_versions, 128, "", CFGFLAG_SERVER, "Comma seperated list of banned clients to be kicked on join")
|
||||
|
||||
// netlimit
|
||||
MACRO_CONFIG_INT(SvNetlimit, sv_netlimit, 0, 0, 10000, CFGFLAG_SERVER, "Netlimit: Maximum amount of traffic a client is allowed to use (in kb/s)")
|
||||
|
|
|
@ -193,7 +193,7 @@ void CGameContext::ConSettings(IConsole::IResult *pResult, void *pUserData)
|
|||
{
|
||||
str_format(aBuf, sizeof(aBuf),
|
||||
"Players are banned for %d minute(s) if they get voted off", g_Config.m_SvVoteKickBantime);
|
||||
|
||||
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "settings",
|
||||
g_Config.m_SvVoteKickBantime ?
|
||||
aBuf :
|
||||
|
@ -620,28 +620,19 @@ void CGameContext::ConSave(IConsole::IResult *pResult, void *pUserData)
|
|||
str_copy(aCountry, g_Config.m_SvSqlServerName, sizeof(aCountry));
|
||||
}
|
||||
|
||||
char aValidServerNames[sizeof(g_Config.m_SvSqlValidServerNames)];
|
||||
str_copy(aValidServerNames, g_Config.m_SvSqlValidServerNames, sizeof(aValidServerNames));
|
||||
char *p = strtok(aValidServerNames, ",");;
|
||||
|
||||
while(p)
|
||||
if(str_in_list(g_Config.m_SvSqlValidServerNames, ",", aCountry))
|
||||
{
|
||||
if(str_comp(p, aCountry) == 0)
|
||||
{
|
||||
pSelf->Score()->SaveTeam(Team, pCode, pResult->m_ClientID, aCountry);
|
||||
pSelf->Score()->SaveTeam(Team, pCode, pResult->m_ClientID, aCountry);
|
||||
|
||||
if(g_Config.m_SvUseSQL)
|
||||
pPlayer->m_LastSQLQuery = pSelf->Server()->Tick();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
p = strtok(NULL, ",");
|
||||
if(g_Config.m_SvUseSQL)
|
||||
pPlayer->m_LastSQLQuery = pSelf->Server()->Tick();
|
||||
}
|
||||
else
|
||||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), "Unknown server name '%s'.", aCountry);
|
||||
pSelf->SendChatTarget(pResult->m_ClientID, aBuf);
|
||||
}
|
||||
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), "Unknown server name '%s'.", aCountry);
|
||||
pSelf->SendChatTarget(pResult->m_ClientID, aBuf);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1800,6 +1800,11 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
|
|||
//tell known bot clients that they're botting and we know it
|
||||
if (((Version >= 15 && Version < 100) || Version == 502) && g_Config.m_SvClientSuggestionBot[0] != '\0')
|
||||
SendBroadcast(g_Config.m_SvClientSuggestionBot, ClientID);
|
||||
//autoban known bot versions
|
||||
if(g_Config.m_SvBannedVersions[0] != '\0' && IsVersionBanned(Version))
|
||||
{
|
||||
Server()->Kick(ClientID, "unsupported client");
|
||||
}
|
||||
}
|
||||
else if (MsgID == NETMSGTYPE_CL_SHOWOTHERS)
|
||||
{
|
||||
|
@ -3550,6 +3555,14 @@ void CGameContext::Converse(int ClientID, char *pStr)
|
|||
}
|
||||
}
|
||||
|
||||
bool CGameContext::IsVersionBanned(int Version)
|
||||
{
|
||||
char aVersion[16];
|
||||
str_format(aVersion, sizeof(aVersion), "%d", Version);
|
||||
|
||||
return str_in_list(g_Config.m_SvBannedVersions, ",", aVersion);
|
||||
}
|
||||
|
||||
void CGameContext::List(int ClientID, const char *pFilter)
|
||||
{
|
||||
int Total = 0;
|
||||
|
|
|
@ -389,6 +389,7 @@ private:
|
|||
void Whisper(int ClientID, char *pStr);
|
||||
void WhisperID(int ClientID, int VictimID, char *pMessage);
|
||||
void Converse(int ClientID, char *pStr);
|
||||
bool IsVersionBanned(int Version);
|
||||
|
||||
public:
|
||||
CLayers *Layers() { return &m_Layers; }
|
||||
|
|
|
@ -135,3 +135,33 @@ TEST(Str, HexDecode)
|
|||
EXPECT_EQ(str_hex_decode(aOut, 1, "411"), 2); EXPECT_STREQ(aOut + 1, "bcd");
|
||||
EXPECT_EQ(str_hex_decode(aOut, 4, "41424344"), 0); EXPECT_STREQ(aOut, "ABCD");
|
||||
}
|
||||
|
||||
TEST(Str, Tokenize)
|
||||
{
|
||||
char aTest[] = "GER,RUS,ZAF,BRA,CAN";
|
||||
const char *aOut[] = {"GER", "RUS", "ZAF", "BRA", "CAN"};
|
||||
const char *pState;
|
||||
char aBuf[4];
|
||||
|
||||
int n = 0;
|
||||
str_tokenize(aTest, ",", &pState, aBuf, sizeof aBuf);
|
||||
do {
|
||||
EXPECT_STREQ(aOut[n++], aBuf);
|
||||
} while(str_tokenize(NULL, ",", &pState, aBuf, sizeof aBuf) >= 0);
|
||||
|
||||
char aTest2[] = "";
|
||||
EXPECT_EQ(str_tokenize(aTest2, ",", &pState, aBuf, sizeof aBuf), -1);
|
||||
}
|
||||
|
||||
TEST(Str, InList)
|
||||
{
|
||||
char aTest[] = "GER,RUS,ZAF,BRA,CAN";
|
||||
EXPECT_TRUE(str_in_list(aTest, ",", "GER"));
|
||||
EXPECT_TRUE(str_in_list(aTest, ",", "RUS"));
|
||||
EXPECT_TRUE(str_in_list(aTest, ",", "ZAF"));
|
||||
EXPECT_TRUE(str_in_list(aTest, ",", "BRA"));
|
||||
EXPECT_TRUE(str_in_list(aTest, ",", "CAN"));
|
||||
|
||||
EXPECT_FALSE(str_in_list(aTest, ",", "CHN"));
|
||||
EXPECT_FALSE(str_in_list(aTest, ",", "R,R"));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue