Mute By Fisted

This commit is contained in:
GreYFoXGTi 2011-02-08 14:44:59 +02:00
commit ae06076d10
7 changed files with 160 additions and 78 deletions

View file

@ -200,5 +200,9 @@ MACRO_CONFIG_INT(ClRaceGhost, cl_race_ghost, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAV
MACRO_CONFIG_INT(ClRaceShowGhost, cl_race_show_ghost, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Show ghost",-1)
MACRO_CONFIG_INT(ClRaceSaveGhost, cl_race_save_ghost, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Save ghost",-1)
MACRO_CONFIG_INT(SvGlobalBantime, sv_global_ban_time, 60, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if the ban server reports it. 0 to disable", 4)
// these might need some fine tuning
MACRO_CONFIG_INT(SvChatPenalty, sv_chat_penalty, 250, 50, 1000, CFGFLAG_SERVER, "chatscore will be increased by this on every message, and decremented by 1 on every tick.", 3)
MACRO_CONFIG_INT(SvChatThreshold, sv_chat_threshold, 1000, 50, 10000 , CFGFLAG_SERVER, "if chatscore exceeds this, the player will be muted for sv_spam_mute_duration seconds", 3)
MACRO_CONFIG_INT(SvSpamMuteDuration, sv_spam_mute_duration, 60, 0, 3600 , CFGFLAG_SERVER, "how many seconds to mute, if player triggers mute on spam. 0 = off", 3)
#endif

View file

@ -12,9 +12,7 @@ CONSOLE_COMMAND("logout", "v", CFGFLAG_SERVER, ConLogOut, this, "Logs player v o
CONSOLE_COMMAND("helper", "v", CFGFLAG_SERVER, ConSetlvl1, this, "Authenticates player v to the level of 1", 2)
CONSOLE_COMMAND("moder", "v", CFGFLAG_SERVER, ConSetlvl2, this, "Authenticates player v to the level of 2", 3)
CONSOLE_COMMAND("admin", "v", CFGFLAG_SERVER, ConSetlvl3, this, "Authenticates player v to the level of 3 (CAUTION: Irreversible, once he is an admin you can't remove his status)", 3)
CONSOLE_COMMAND("mute", "vi", CFGFLAG_SERVER, ConMute, this, "Mutes player v for i seconds", 2)
CONSOLE_COMMAND("unmute", "v", CFGFLAG_SERVER, ConUnmute, this, "Unmutes player v", 2)
CONSOLE_COMMAND("invis", "v", CFGFLAG_SERVER|CMDFLAG_CHEAT|CMDFLAG_HELPERCMD, ConInvis, this, "Makes player v invisible", 2)
6CONSOLE_COMMAND("invis", "v", CFGFLAG_SERVER|CMDFLAG_CHEAT|CMDFLAG_HELPERCMD, ConInvis, this, "Makes player v invisible", 2)
CONSOLE_COMMAND("vis", "v", CFGFLAG_SERVER|CMDFLAG_CHEAT|CMDFLAG_HELPERCMD, ConVis, this, "Makes player v visible again", 2)
CONSOLE_COMMAND("timerstop", "v", CFGFLAG_SERVER|CMDFLAG_TIMER, ConTimerStop, this, "Stops the timer of player v", 2)
CONSOLE_COMMAND("timerstart", "v", CFGFLAG_SERVER|CMDFLAG_TIMER, ConTimerStart, this, "Starts the timer of player v", 2)
@ -64,6 +62,11 @@ CONSOLE_COMMAND("ask", "s", CFGFLAG_SERVER, ConAsk, this, "Ask to join a player
CONSOLE_COMMAND("yes", "", CFGFLAG_SERVER, ConYes, this, "Reply yes", -1)
CONSOLE_COMMAND("no", "", CFGFLAG_SERVER, ConNo, this, "Reply no", -1)
CONSOLE_COMMAND("invite", "s", CFGFLAG_SERVER, ConInvite, this, "Invite a player to your team (You must be the leader)", -1)
CONSOLE_COMMAND("mute", "", CFGFLAG_SERVER, ConMute, this, "", 2);
CONSOLE_COMMAND("muteid", "ii", CFGFLAG_SERVER, ConMuteID, this, "", 2);
CONSOLE_COMMAND("muteip", "si", CFGFLAG_SERVER, ConMuteIP, this, "", 2);
CONSOLE_COMMAND("unmute", "i", CFGFLAG_SERVER, ConUnmute, this, "", 2);
CONSOLE_COMMAND("mutes", "", CFGFLAG_SERVER, ConMutes, this, "", 2);
#undef CONSOLE_COMMAND

View file

@ -56,55 +56,6 @@ void CGameContext::MoveCharacter(int ClientId, int Victim, int X, int Y, bool Ra
pChr->m_DDRaceState = DDRACE_CHEAT;
}
void CGameContext::ConMute(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;
int Victim = pResult->GetVictim();
int Seconds = pResult->GetInteger(0);
char aBuf[512];
if(Seconds < 10)
Seconds = 10;
if(Victim == ClientId)
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can\'t mute yourself");
else
{
/*pSelf->m_apPlayers[Victim]->m_Muted = Seconds * pSelf->Server()->TickSpeed();
str_format(aBuf, sizeof(aBuf), "You have been muted by for %d seconds", pSelf->Server()->ClientName(Victim), Seconds);
pSelf->SendChatTarget(Victim, aBuf);*/
pSelf->m_apPlayers[Victim]->m_Muted = Seconds * pSelf->Server()->TickSpeed();
str_format(aBuf, sizeof(aBuf), "%s muted by %s for %d seconds", pSelf->Server()->ClientName(Victim), pSelf->Server()->ClientName(ClientId), Seconds);
pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
}
}
void CGameContext::ConUnmute(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;
int Victim = pResult->GetVictim();
char aBuf[512];
if(Victim == ClientId)
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can\'t unmute yourself");
else
{
if(pSelf->m_apPlayers[Victim]->m_Muted > 0)
{
pSelf->m_apPlayers[Victim]->m_Muted = 0;
str_format(aBuf, sizeof(aBuf), "You have been unmuted", pSelf->Server()->ClientName(Victim));
pSelf->SendChatTarget(Victim, aBuf);
}
/*if(pSelf->m_apPlayers[Victim]->m_Muted > 0)
{
pSelf->m_apPlayers[Victim]->m_Muted = 0;
str_format(aBuf, sizeof(aBuf), "%s has been unmuted", pSelf->Server()->ClientName(Victim));
pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
}*/
}
}
void CGameContext::ConSetlvl3(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;
@ -1181,7 +1132,7 @@ void CGameContext::ConInvite(IConsole::IResult *pResult, void *pUserData, int Cl
if(!pAsker || !pAsker->IsAlive())
str_format(aBuf, sizeof(aBuf), "You can\'t invite while dead.");
else if(pAsker->Team() == 0)
str_format(aBuf, sizeof(aBuf), "You are in team %d, use /leader or /ask.", pAsker->Team());
str_format(aBuf, sizeof(aBuf), "You are in team %d, use /ask.", pAsker->Team());
else if(pAsker->Team() && ClientId != Controller->m_Teams.GetTeamLeader(pAsker->Team()))
str_format(aBuf, sizeof(aBuf), "You already are in team %d, but not leader.", pAsker->Team());
else if(Matches > 1)
@ -1216,3 +1167,97 @@ void CGameContext::ConInvite(IConsole::IResult *pResult, void *pUserData, int Cl
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf);
return;
}
void CGameContext::Mute(const char *pIP, 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;
// 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();
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)
{
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");
}
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>'");
}
// mute through client id
void CGameContext::ConMuteID(IConsole::IResult *pResult, void *pUserData, int ClientID)
{
CGameContext *pSelf = (CGameContext *)pUserData;
int ClientId = pResult->GetInteger(0);
if (ClientId < 0 || ClientId >= MAX_CLIENTS || !pSelf->m_apPlayers[ClientId])
return;
char aIP[16];
pSelf->Server()->GetClientIP(ClientId, aIP, sizeof aIP);
pSelf->Mute(aIP, clamp(pResult->GetInteger(1), 1, 60*60*24*365), pSelf->Server()->ClientName(ClientId));
}
// 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));
}
// 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);
if (Ind < 0 || Ind >= MAX_MUTES || !m_aMutes[Ind].m_IP[0])
return;
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;
}
// 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);
}
}

View file

@ -27,6 +27,8 @@
#include "score/sql_score.h"
#endif
struct CMute CGameContext::m_aMutes[MAX_MUTES];
enum
{
RESET,
@ -47,8 +49,12 @@ void CGameContext::Construct(int Resetting)
m_pVoteOptionLast = 0;
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;
}
}
CGameContext::CGameContext(int Resetting)
@ -701,6 +707,32 @@ 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 (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)
@ -718,18 +750,7 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
Console()->ExecuteLine(pMsg->m_pMessage + 1, ((CServer *) Server())->m_aClients[ClientId].m_Authed, ClientId, CServer::SendRconLineAuthed, Server(), SendChatResponse, &Info);
}
else
{
if(m_apPlayers[ClientId]->m_Muted == 0)
{
SendChat(ClientId, Team, pMsg->m_pMessage, ClientId);
}
else
{
char aBuf[64];
str_format(aBuf,sizeof(aBuf), "You are muted, Please wait for %d second(s)", m_apPlayers[ClientId]->m_Muted / Server()->TickSpeed());
SendChatTarget(ClientId, aBuf);
}
}
SendChat(ClientId, Team, pMsg->m_pMessage, ClientId);
}
else if(MsgId == NETMSGTYPE_CL_CALLVOTE)
{

View file

@ -15,6 +15,8 @@
#include "player.h"
#include "score.h"
#define MAX_MUTES 32
/*
Tick
Game Context (CGameContext::tick)
@ -172,8 +174,8 @@ private:
//DDRace Console Commands
static void ConMute(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConUnmute(IConsole::IResult *pResult, void *pUserData, int ClientId);
//static void ConMute(IConsole::IResult *pResult, void *pUserData, int ClientId);
//static void ConUnmute(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConLogOut(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConSetlvl1(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConSetlvl2(IConsole::IResult *pResult, void *pUserData, int ClientId);
@ -241,6 +243,14 @@ private:
static void ConYes(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConNo(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConInvite(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConMute(IConsole::IResult *pResult, void *pUserData, int ClientID);
static void ConMuteID(IConsole::IResult *pResult, void *pUserData, int ClientID);
static void ConMuteIP(IConsole::IResult *pResult, void *pUserData, int ClientID);
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);
public:
CLayers *Layers() { return &m_Layers; }
class IScore *Score() { return m_pScore; }
@ -263,6 +273,10 @@ public:
virtual bool PlayerHooking();
};
struct CMute {
char m_IP[16];// TODO ipv6
int m_Expire;
};
bool ComparePlayers(CPlayer *pl1, CPlayer *pl2);
inline int CmaskAll() { return -1; }

View file

@ -24,8 +24,7 @@ CPlayer::CPlayer(CGameContext *pGameServer, int CID, int Team)
this->m_ClientID = CID;
m_Team = GameServer()->m_pController->ClampTeam(Team);
m_LastActionTick = Server()->Tick();
m_Muted = 0;
m_ChatScore = 0;
m_PauseInfo.m_Respawn = false;
GameServer()->Score()->PlayerData(CID)->Reset();
@ -53,6 +52,9 @@ void CPlayer::Tick()
if(!Server()->ClientIngame(m_ClientID))
return;
if (m_ChatScore > 0)
m_ChatScore--;
Server()->SetClientScore(m_ClientID, m_Score);
// do latency stuff
@ -93,7 +95,6 @@ void CPlayer::Tick()
}
else if(m_Spawning && m_RespawnTick <= Server()->Tick())
TryRespawn();
if(m_Muted > 0) m_Muted--;
}
void CPlayer::Snap(int SnappingClient)
@ -140,13 +141,6 @@ void CPlayer::OnDisconnect()
if(Server()->ClientIngame(m_ClientID))
{
if(m_Muted > 0)
{
int Temp = m_Muted;
m_Muted = 0;
((CServer *)Server())->BanAdd(((CServer *)Server())->GetClientIP(m_ClientID), ((Temp/Server()->TickSpeed())+1), "Mute evasion");
return;
}
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "'%s' has left the game", Server()->ClientName(m_ClientID));
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);

View file

@ -124,12 +124,13 @@ public:
int64 m_Last_KickVote;
int64 m_Last_Team;
bool m_Invisible;
int m_Muted;
int m_Authed;
bool m_IsUsingDDRaceClient;
bool m_ShowOthers;
bool m_RconFreeze;
int m_ChatScore;
// necessary for asking mutual exclusion
int m_Asker; // who asked this player
int m_AskedTick; // when was this player asked by another player