mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
rewritten mutes
This commit is contained in:
parent
90d93ba7b2
commit
3d0aab503f
|
@ -29,6 +29,7 @@ public:
|
|||
virtual bool ClientIngame(int ClientID) = 0;
|
||||
virtual int GetClientInfo(int ClientID, CClientInfo *pInfo) = 0;
|
||||
virtual void GetClientIP(int ClientID, char *pIPString, int Size) = 0;
|
||||
virtual void GetClientAddr(int ClientID, NETADDR *pAddr) = 0;
|
||||
virtual int *LatestInput(int ClientID, int *pSize) = 0;
|
||||
|
||||
virtual void SetRconLevel(int ClientID, int Level) = 0;
|
||||
|
|
|
@ -348,7 +348,12 @@ void CServer::GetClientIP(int ClientID, char *pIPString, int Size)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CServer::GetClientAddr(int ClientID, NETADDR *pAddr)
|
||||
{
|
||||
if(ClientID >= 0 && ClientID < MAX_CLIENTS && m_aClients[ClientID].m_State == CClient::STATE_INGAME)
|
||||
*pAddr = m_NetServer.ClientAddr(ClientID);
|
||||
}
|
||||
|
||||
int *CServer::LatestInput(int ClientID, int *size)
|
||||
{
|
||||
if(ClientID < 0 || ClientID >= MAX_CLIENTS || m_aClients[ClientID].m_State < CServer::CClient::STATE_READY)
|
||||
|
|
|
@ -158,6 +158,7 @@ public:
|
|||
|
||||
int IsAuthed(int ClientID);
|
||||
int GetClientInfo(int ClientID, CClientInfo *pInfo);
|
||||
void GetClientAddr(int ClientID, NETADDR *pAddr);
|
||||
void GetClientIP(int ClientID, char *pIPString, int Size);
|
||||
const char *ClientName(int ClientID);
|
||||
bool ClientIngame(int ClientID);
|
||||
|
|
|
@ -1277,41 +1277,51 @@ void CGameContext::ConToggleStrict(IConsole::IResult *pResult, void *pUserData,
|
|||
return;
|
||||
}
|
||||
|
||||
void CGameContext::Mute(const char *pIP, int Secs, const char *pDisplayName)
|
||||
void CGameContext::Mute(NETADDR *Addr, int Secs, const char *pDisplayName)
|
||||
{
|
||||
char aBuf[128];
|
||||
// purge expired mutes first
|
||||
for(int z = 0; z < MAX_MUTES; ++z)
|
||||
if (m_aMutes[z].m_IP[0] && m_aMutes[z].m_Expire <= Server()->Tick())
|
||||
m_aMutes[z].m_IP[0] = 0;
|
||||
|
||||
int FoundInd = -1;
|
||||
for(int i = 0; i < m_NumMutes; i++)
|
||||
{
|
||||
if(m_aMutes[i].m_Expire <= Server()->Tick())
|
||||
{
|
||||
m_NumMutes--;
|
||||
m_aMutes[i] = m_aMutes[m_NumMutes];
|
||||
}
|
||||
}
|
||||
|
||||
int Found = 0;
|
||||
// find a matching mute for this ip, update expiration time if found
|
||||
for(int z = 0; z < MAX_MUTES; ++z)
|
||||
if (m_aMutes[z].m_IP[0] && str_comp(m_aMutes[z].m_IP, pIP) == 0)
|
||||
m_aMutes[FoundInd = z].m_Expire = Server()->Tick() + Secs * Server()->TickSpeed();
|
||||
for(int i = 0; i < m_NumMutes; i++)
|
||||
{
|
||||
if(net_addr_comp(&m_aMutes[i].m_Addr, Addr) == 0)
|
||||
{
|
||||
m_aMutes[i].m_Expire = Server()->Tick() + Secs * Server()->TickSpeed();
|
||||
Found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundInd == -1) // nothing found so far, find a free slot..
|
||||
for(int z = 0; z < MAX_MUTES; ++z) //..in order to add a new mute
|
||||
if (!m_aMutes[z].m_IP[0])
|
||||
{
|
||||
str_copy(m_aMutes[z].m_IP, pIP, str_length(pIP)+1);
|
||||
m_aMutes[FoundInd = z].m_Expire = Server()->Tick() + Secs * Server()->TickSpeed();
|
||||
break;
|
||||
}
|
||||
|
||||
if (FoundInd != -1)
|
||||
if(!Found) // nothing found so far, find a free slot..
|
||||
{
|
||||
if(m_NumMutes < MAX_MUTES)
|
||||
{
|
||||
m_aMutes[m_NumMutes].m_Addr = *Addr;
|
||||
m_aMutes[m_NumMutes].m_Expire = Server()->Tick() + Secs * Server()->TickSpeed();
|
||||
Found = 1;
|
||||
}
|
||||
}
|
||||
if(Found)
|
||||
{
|
||||
str_format(aBuf, sizeof aBuf, "'%s' has been muted for %d seconds.", pDisplayName, Secs);
|
||||
SendChat(-1, CHAT_ALL, aBuf);
|
||||
}
|
||||
else // no free slot found
|
||||
Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "server", "mute array is full");
|
||||
Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "mute array is full");
|
||||
}
|
||||
|
||||
void CGameContext::ConMute(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
((CGameContext *)pUserData)->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "server", "Use either 'muteid <client_id> <seconds>' or 'muteip <ip> <seconds>'");
|
||||
((CGameContext *)pUserData)->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "Use either 'muteid <client_id> <seconds>' or 'muteip <ip> <seconds>'");
|
||||
}
|
||||
|
||||
// mute through client id
|
||||
|
@ -1319,54 +1329,56 @@ void CGameContext::ConMuteID(IConsole::IResult *pResult, void *pUserData, int Cl
|
|||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
int Victim = pResult->GetVictim();
|
||||
if (Victim < 0 || Victim >= MAX_CLIENTS || !pSelf->m_apPlayers[Victim])
|
||||
return;
|
||||
|
||||
char aIP[16];
|
||||
pSelf->Server()->GetClientIP(Victim, aIP, sizeof aIP);
|
||||
NETADDR Addr;
|
||||
pSelf->Server()->GetClientAddr(Victim, &Addr);
|
||||
|
||||
pSelf->Mute(aIP, clamp(pResult->GetInteger(0), 1, 60*60*24*365), pSelf->Server()->ClientName(Victim));
|
||||
pSelf->Mute(&Addr, clamp(pResult->GetInteger(0), 1, 86400), pSelf->Server()->ClientName(Victim));
|
||||
}
|
||||
|
||||
// mute through ip, arguments reversed to workaround parsing
|
||||
void CGameContext::ConMuteIP(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
pSelf->Mute(pResult->GetString(0), clamp(pResult->GetInteger(1), 1, 60*60*24*365), pResult->GetString(0));
|
||||
NETADDR Addr;
|
||||
if(net_addr_from_str(&Addr, pResult->GetString(0)))
|
||||
{
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "Invalid network address to mute");
|
||||
}
|
||||
pSelf->Mute(&Addr, clamp(pResult->GetInteger(1), 1, 86400), pResult->GetString(0));
|
||||
}
|
||||
|
||||
// unmute by mute list index
|
||||
void CGameContext::ConUnmute(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
char aBuf[32];
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
int Ind = pResult->GetInteger(0);
|
||||
char aIpBuf[64];
|
||||
char aBuf[64];
|
||||
int Index = pResult->GetInteger(0);
|
||||
|
||||
if (Ind < 0 || Ind >= MAX_MUTES || !m_aMutes[Ind].m_IP[0])
|
||||
if(Index < 0 || Index >= pSelf->m_NumMutes)
|
||||
return;
|
||||
|
||||
pSelf->m_NumMutes--;
|
||||
pSelf->m_aMutes[Index] = pSelf->m_aMutes[pSelf->m_NumMutes];
|
||||
|
||||
str_format(aBuf, sizeof aBuf, "Unmuted %s" , m_aMutes[Ind].m_IP);
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
|
||||
m_aMutes[Ind].m_IP[0] = 0;
|
||||
net_addr_str(&pSelf->m_aMutes[Index].m_Addr, aIpBuf, sizeof(aIpBuf));
|
||||
str_format(aBuf, sizeof(aBuf), "Unmuted %s" , aIpBuf);
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", aBuf);
|
||||
}
|
||||
|
||||
// list mutes
|
||||
void CGameContext::ConMutes(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
char aBuf[128];
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "server", "Active mutes:");
|
||||
for(int z = 0; z < MAX_MUTES; ++z)
|
||||
if (m_aMutes[z].m_IP[0])
|
||||
{
|
||||
int Exp = (m_aMutes[z].m_Expire - pSelf->Server()->Tick()) / pSelf->Server()->TickSpeed();
|
||||
if (Exp > 0)
|
||||
str_format(aBuf, sizeof aBuf, "%d: \"%s\", %d seconds left", z, m_aMutes[z].m_IP, Exp);
|
||||
else
|
||||
str_format(aBuf, sizeof aBuf, "%d: \"%s\", expired (pending)", z, m_aMutes[z].m_IP);
|
||||
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
}
|
||||
char aIpBuf[64];
|
||||
char aBuf[128];
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "Active mutes:");
|
||||
for(int i = 0; i < pSelf->m_NumMutes; i++)
|
||||
{
|
||||
net_addr_str(&pSelf->m_aMutes[i].m_Addr, aIpBuf, sizeof(aIpBuf));
|
||||
str_format(aBuf, sizeof aBuf, "%d: \"%s\", %d seconds left", i, aIpBuf, (pSelf->m_aMutes[i].m_Expire - pSelf->Server()->Tick()) / pSelf->Server()->TickSpeed());
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", aBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include "score/sql_score.h"
|
||||
#endif
|
||||
|
||||
struct CMute CGameContext::m_aMutes[MAX_MUTES];
|
||||
|
||||
enum
|
||||
{
|
||||
RESET,
|
||||
|
@ -51,9 +49,8 @@ void CGameContext::Construct(int Resetting)
|
|||
if(Resetting==NO_RESET)
|
||||
{
|
||||
m_pVoteOptionHeap = new CHeap();
|
||||
m_pScore = 0;
|
||||
for(int z = 0; z < MAX_MUTES; ++z)
|
||||
m_aMutes[z].m_IP[0] = 0;
|
||||
m_pScore = 0;
|
||||
m_NumMutes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,15 +239,48 @@ void CGameContext::SendChatTarget(int To, const char *pText)
|
|||
}
|
||||
|
||||
|
||||
int CGameContext::ProcessSpamProtection(int ClientID)
|
||||
{
|
||||
if(g_Config.m_SvSpamprotection && m_apPlayers[ClientID]->m_Last_Chat
|
||||
&& m_apPlayers[ClientID]->m_Last_Chat + Server()->TickSpeed() + g_Config.m_SvChatDelay > Server()->Tick())
|
||||
return 1;
|
||||
else
|
||||
m_apPlayers[ClientID]->m_Last_Chat = Server()->Tick();
|
||||
|
||||
NETADDR Addr;
|
||||
Server()->GetClientAddr(ClientID, &Addr);
|
||||
int Muted = 0;
|
||||
|
||||
for(int i = 0; i < m_NumMutes && !Muted; i++)
|
||||
{
|
||||
if(!net_addr_comp(&Addr, &m_aMutes[i].m_Addr))
|
||||
Muted = (m_aMutes[i].m_Expire - Server()->Tick()) / Server()->TickSpeed();
|
||||
}
|
||||
|
||||
if (Muted > 0)
|
||||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof aBuf, "You are not permitted to talk for the next %d seconds.", Muted);
|
||||
SendChatTarget(ClientID, aBuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((m_apPlayers[ClientID]->m_ChatScore += g_Config.m_SvChatPenalty) > g_Config.m_SvChatThreshold)
|
||||
{
|
||||
Mute(&Addr, g_Config.m_SvSpamMuteDuration, Server()->ClientName(ClientID));
|
||||
m_apPlayers[ClientID]->m_ChatScore = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CGameContext::SendChat(int ChatterClientID, int Team, const char *pText, int SpamProtectionClientID)
|
||||
{
|
||||
if(SpamProtectionClientID >= 0 && SpamProtectionClientID < MAX_CLIENTS)
|
||||
{
|
||||
if(g_Config.m_SvSpamprotection && m_apPlayers[SpamProtectionClientID]->m_Last_Chat
|
||||
&& m_apPlayers[SpamProtectionClientID]->m_Last_Chat + Server()->TickSpeed() + g_Config.m_SvChatDelay > Server()->Tick())
|
||||
if(ProcessSpamProtection(SpamProtectionClientID))
|
||||
return;
|
||||
else
|
||||
m_apPlayers[SpamProtectionClientID]->m_Last_Chat = Server()->Tick();
|
||||
}
|
||||
|
||||
char aBuf[256], aText[256];
|
||||
|
@ -545,34 +575,42 @@ void CGameContext::OnTick()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if(Server()->Tick() % (g_Config.m_SvAnnouncementInterval * Server()->TickSpeed() * 60) == 0)
|
||||
{
|
||||
char *Line = ((CServer *) Server())->GetAnnouncementLine(g_Config.m_SvAnnouncementFileName);
|
||||
if(Line)
|
||||
SendChat(-1, CGameContext::CHAT_ALL, Line);
|
||||
}
|
||||
|
||||
if(Collision()->m_NumSwitchers > 0)
|
||||
for (int i = 0; i < Collision()->m_NumSwitchers+1; ++i)
|
||||
for(int i = 0; i < m_NumMutes; i++)
|
||||
{
|
||||
for (int j = 0; j < 16; ++j)
|
||||
if(m_aMutes[i].m_Expire <= Server()->Tick())
|
||||
{
|
||||
if(Collision()->m_pSwitchers[i].m_EndTick[j] <= Server()->Tick() && Collision()->m_pSwitchers[i].m_Type[j] == TILE_SWITCHTIMEDOPEN)
|
||||
{
|
||||
Collision()->m_pSwitchers[i].m_Status[j] = false;
|
||||
Collision()->m_pSwitchers[i].m_EndTick[j] = 0;
|
||||
Collision()->m_pSwitchers[i].m_Type[j] = TILE_SWITCHCLOSE;
|
||||
}
|
||||
else if(Collision()->m_pSwitchers[i].m_EndTick[j] <= Server()->Tick() && Collision()->m_pSwitchers[i].m_Type[j] == TILE_SWITCHTIMEDCLOSE)
|
||||
{
|
||||
Collision()->m_pSwitchers[i].m_Status[j] = true;
|
||||
Collision()->m_pSwitchers[i].m_EndTick[j] = 0;
|
||||
Collision()->m_pSwitchers[i].m_Type[j] = TILE_SWITCHOPEN;
|
||||
}
|
||||
m_NumMutes--;
|
||||
m_aMutes[i] = m_aMutes[m_NumMutes];
|
||||
}
|
||||
}
|
||||
|
||||
if(Server()->Tick() % (g_Config.m_SvAnnouncementInterval * Server()->TickSpeed() * 60) == 0)
|
||||
{
|
||||
char *Line = ((CServer *) Server())->GetAnnouncementLine(g_Config.m_SvAnnouncementFileName);
|
||||
if(Line)
|
||||
SendChat(-1, CGameContext::CHAT_ALL, Line);
|
||||
}
|
||||
|
||||
if(Collision()->m_NumSwitchers > 0)
|
||||
for (int i = 0; i < Collision()->m_NumSwitchers+1; ++i)
|
||||
{
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
if(Collision()->m_pSwitchers[i].m_EndTick[j] <= Server()->Tick() && Collision()->m_pSwitchers[i].m_Type[j] == TILE_SWITCHTIMEDOPEN)
|
||||
{
|
||||
Collision()->m_pSwitchers[i].m_Status[j] = false;
|
||||
Collision()->m_pSwitchers[i].m_EndTick[j] = 0;
|
||||
Collision()->m_pSwitchers[i].m_Type[j] = TILE_SWITCHCLOSE;
|
||||
}
|
||||
else if(Collision()->m_pSwitchers[i].m_EndTick[j] <= Server()->Tick() && Collision()->m_pSwitchers[i].m_Type[j] == TILE_SWITCHTIMEDCLOSE)
|
||||
{
|
||||
Collision()->m_pSwitchers[i].m_Status[j] = true;
|
||||
Collision()->m_pSwitchers[i].m_EndTick[j] = 0;
|
||||
Collision()->m_pSwitchers[i].m_Type[j] = TILE_SWITCHOPEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONF_DEBUG
|
||||
if(g_Config.m_DbgDummies)
|
||||
{
|
||||
|
@ -711,35 +749,6 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientID)
|
|||
return;
|
||||
}
|
||||
|
||||
char aIP[16];
|
||||
int MuteTicks = 0;
|
||||
|
||||
Server()->GetClientIP(ClientID, aIP, sizeof aIP);
|
||||
|
||||
for(int z = 0; z < MAX_MUTES && MuteTicks <= 0; ++z) //find a mute, remove it, if expired.
|
||||
if (m_aMutes[z].m_IP[0] && str_comp(aIP, m_aMutes[z].m_IP) == 0 && (MuteTicks = m_aMutes[z].m_Expire - Server()->Tick()) <= 0)
|
||||
m_aMutes[z].m_IP[0] = 0;
|
||||
|
||||
if(pMsg->m_pMessage[0]!='/')
|
||||
{
|
||||
if (MuteTicks > 0)
|
||||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof aBuf, "You are not permitted to talk for the next %d seconds.", MuteTicks / Server()->TickSpeed());
|
||||
SendChatTarget(ClientID, aBuf);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p->m_ChatScore += g_Config.m_SvChatPenalty) > g_Config.m_SvChatThreshold)
|
||||
{
|
||||
char aIP[16];
|
||||
Server()->GetClientIP(ClientID, aIP, sizeof aIP);
|
||||
Mute(aIP, g_Config.m_SvSpamMuteDuration, Server()->ClientName(ClientID));
|
||||
p->m_ChatScore = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check for invalid chars
|
||||
unsigned char *pMessage = (unsigned char *)pMsg->m_pMessage;
|
||||
while (*pMessage)
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
#include "player.h"
|
||||
#include "score.h"
|
||||
|
||||
#define MAX_MUTES 32
|
||||
|
||||
/*
|
||||
Tick
|
||||
Game Context (CGameContext::tick)
|
||||
|
@ -141,6 +139,7 @@ public:
|
|||
void SendEmoticon(int ClientID, int Emoticon);
|
||||
void SendWeaponPickup(int ClientID, int Weapon);
|
||||
void SendBroadcast(const char *pText, int ClientID);
|
||||
int ProcessSpamProtection(int ClientID);
|
||||
|
||||
|
||||
//
|
||||
|
@ -254,8 +253,20 @@ private:
|
|||
static void ConUnmute(IConsole::IResult *pResult, void *pUserData, int ClientID);
|
||||
static void ConMutes(IConsole::IResult *pResult, void *pUserData, int ClientID);
|
||||
|
||||
static struct CMute m_aMutes[MAX_MUTES];
|
||||
void Mute(const char *pIP, int Secs, const char *pDisplayName);
|
||||
enum
|
||||
{
|
||||
MAX_MUTES=32,
|
||||
};
|
||||
struct CMute
|
||||
{
|
||||
NETADDR m_Addr;
|
||||
int m_Expire;
|
||||
};
|
||||
|
||||
CMute m_aMutes[MAX_MUTES];
|
||||
int m_NumMutes;
|
||||
void Mute(NETADDR *Addr, int Secs, const char *pDisplayName);
|
||||
|
||||
public:
|
||||
CLayers *Layers() { return &m_Layers; }
|
||||
class IScore *Score() { return m_pScore; }
|
||||
|
@ -278,11 +289,6 @@ public:
|
|||
virtual bool PlayerHooking();
|
||||
};
|
||||
|
||||
struct CMute {
|
||||
char m_IP[16];// TODO ipv6
|
||||
int m_Expire;
|
||||
};
|
||||
|
||||
inline int CmaskAll() { return -1; }
|
||||
inline int CmaskOne(int ClientID) { return 1<<ClientID; }
|
||||
inline int CmaskAllExceptOne(int ClientID) { return 0x7fffffff^CmaskOne(ClientID); }
|
||||
|
|
Loading…
Reference in a new issue