player muting by ip

This commit is contained in:
fisted 2011-02-03 13:02:32 +01:00
parent b5b33b45fa
commit 00f47c18c4
2 changed files with 136 additions and 0 deletions

View file

@ -14,6 +14,8 @@
#include "gamemodes/ctf.h"
#include "gamemodes/mod.h"
struct CMute CGameContext::m_aMutes[MAX_MUTES];
enum
{
RESET,
@ -34,7 +36,11 @@ void CGameContext::Construct(int Resetting)
m_pVoteOptionLast = 0;
if(Resetting==NO_RESET)
{
m_pVoteOptionHeap = new CHeap();
for(int z = 0; z < MAX_MUTES; ++z)
m_aMutes[z].m_IP[0] = 0;
}
}
CGameContext::CGameContext(int Resetting)
@ -577,6 +583,23 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
p->m_Last_Chat = Server()->Tick();
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;
}
// check for invalid chars
unsigned char *pMessage = (unsigned char *)pMsg->m_pMessage;
while (*pMessage)
@ -992,6 +1015,67 @@ void CGameContext::ConVote(IConsole::IResult *pResult, void *pUserData)
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
}
void CGameContext::ConMute(IConsole::IResult *pResult, void *pUserData)
{
((CGameContext *)pUserData)->Console()->Print(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)
{
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)
{
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)
{
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()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
m_aMutes[Ind].m_IP[0] = 0;
}
// list mutes
void CGameContext::ConMutes(IConsole::IResult *pResult, void *pUserData)
{
char aBuf[128];
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->Console()->Print(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()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
}
}
void CGameContext::ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
{
pfnCallback(pResult, pCallbackUserData);
@ -1026,6 +1110,12 @@ void CGameContext::OnConsoleInit()
Console()->Register("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, "");
Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, "");
Console()->Register("mute", "", CFGFLAG_SERVER, ConMute, this, "");
Console()->Register("muteid", "ii", CFGFLAG_SERVER, ConMuteID, this, "");
Console()->Register("muteip", "si", CFGFLAG_SERVER, ConMuteIP, this, "");
Console()->Register("unmute", "i", CFGFLAG_SERVER, ConUnmute, this, "");
Console()->Register("mutes", "", CFGFLAG_SERVER, ConMutes, this, "");
Console()->Chain("sv_motd", ConchainSpecialMotdupdate, this);
}
@ -1134,3 +1224,35 @@ const char *CGameContext::Version() { return GAME_VERSION; }
const char *CGameContext::NetVersion() { return GAME_NETVERSION; }
IGameServer *CreateGameServer() { return new CGameContext; }
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()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "mute array is full");
}

View file

@ -14,6 +14,8 @@
#include "gameworld.h"
#include "player.h"
#define MAX_MUTES 32
/*
Tick
Game Context (CGameContext::tick)
@ -35,6 +37,10 @@
All players (CPlayer::snap)
*/
struct CMute {
char m_IP[16];// TODO ipv6
int m_Expire;
};
class CGameContext : public IGameServer
{
IServer *m_pServer;
@ -56,12 +62,20 @@ class CGameContext : public IGameServer
static void ConAddVote(IConsole::IResult *pResult, void *pUserData);
static void ConClearVotes(IConsole::IResult *pResult, void *pUserData);
static void ConVote(IConsole::IResult *pResult, void *pUserData);
static void ConMute(IConsole::IResult *pResult, void *pUserData);
static void ConMuteID(IConsole::IResult *pResult, void *pUserData);
static void ConMuteIP(IConsole::IResult *pResult, void *pUserData);
static void ConUnmute(IConsole::IResult *pResult, void *pUserData);
static void ConMutes(IConsole::IResult *pResult, void *pUserData);
static void ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
CGameContext(int Resetting);
void Construct(int Resetting);
bool m_Resetting;
static struct CMute m_aMutes[MAX_MUTES];
void Mute(const char *pIP, int Secs, const char *pDisplayName);
public:
IServer *Server() const { return m_pServer; }
class IConsole *Console() { return m_pConsole; }