diff options
| -rw-r--r-- | src/engine/server.h | 2 | ||||
| -rw-r--r-- | src/engine/server/server.cpp | 176 | ||||
| -rw-r--r-- | src/engine/server/server.h | 27 | ||||
| -rw-r--r-- | src/game/server/gamecontext.cpp | 65 | ||||
| -rw-r--r-- | src/game/server/gamecontext.h | 4 | ||||
| -rw-r--r-- | src/game/server/player.h | 3 |
6 files changed, 208 insertions, 69 deletions
diff --git a/src/engine/server.h b/src/engine/server.h index deb36ef5..7896f911 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -1,5 +1,6 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ +/* Modified by Teelevision for zCatch/TeeVi, see readme.txt and license.txt. */ #ifndef ENGINE_SERVER_H #define ENGINE_SERVER_H #include "kernel.h" @@ -32,6 +33,7 @@ public: virtual bool ClientIngame(int ClientID) = 0; virtual int GetClientInfo(int ClientID, CClientInfo *pInfo) = 0; virtual void GetClientAddr(int ClientID, char *pAddrStr, int Size) = 0; + virtual int ClientVotebannedTime(int ClientID) = 0; virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 4be9809b..766c4553 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -304,9 +304,22 @@ CServer::CServer() : m_DemoRecorder(&m_SnapshotDelta) // when starting there are no admins numLoggedInAdmins = 0; + m_Votebans = NULL; + Init(); } +CServer::~CServer() +{ + // delte votebans + while(m_Votebans != NULL) + { + CVoteban *tmp = m_Votebans->m_Next; + delete m_Votebans; + m_Votebans = tmp; + } +} + int CServer::TrySetClientName(int ClientID, const char *pName) { @@ -445,6 +458,7 @@ int CServer::Init() m_aClients[i].m_Snapshots.Init(); } + AdjustVotebanTime(m_CurrentGameTick); m_CurrentGameTick = 0; return 0; @@ -1357,6 +1371,7 @@ int CServer::Run() } m_GameStartTime = time_get(); + AdjustVotebanTime(m_CurrentGameTick); m_CurrentGameTick = 0; Kernel()->ReregisterInterface(GameServer()); GameServer()->OnInit(); @@ -1454,6 +1469,163 @@ int CServer::Run() return 0; } +// returns the time in seconds that the client is votebanned or 0 if he isn't +int CServer::ClientVotebannedTime(int ClientID) +{ + CVoteban **v = IsVotebannedAddr(m_NetServer.ClientAddr(ClientID)); + if(v != NULL && (*v)->m_Expire > Tick()) + return ((*v)->m_Expire - Tick()) / TickSpeed(); + return 0; +} + +// decreases the time of all votebans by the given offset of ticks +void CServer::AdjustVotebanTime(int offset) +{ + CleanVotebans(); + CVoteban *v = m_Votebans; + while(v != NULL) + { + v->m_Expire -= offset; + v = v->m_Next; + } +} + +// adds a new voteban for a specific address +void CServer::AddVotebanAddr(const NETADDR *addr, int expire) +{ + CVoteban **v = IsVotebannedAddr(addr); + // create new + if(!v) + { + CVoteban *v = new CVoteban; + v->m_Addr = *addr; + v->m_Expire = expire; + // insert front + v->m_Next = m_Votebans; + m_Votebans = v; + } + // update existing entry + else + (*v)->m_Expire = expire; +} + +// adds a new voteban for a client's address +void CServer::AddVoteban(int ClientID, int time) +{ + int expire = Tick() + time * TickSpeed(); + AddVotebanAddr(m_NetServer.ClientAddr(ClientID), expire); +} + +// removes a voteban from a client's address +void CServer::RemoveVoteban(int ClientID) +{ + RemoveVotebanAddr(m_NetServer.ClientAddr(ClientID)); +} + +// removes a voteban on an address +void CServer::RemoveVotebanAddr(const NETADDR *addr) +{ + CVoteban **v = IsVotebannedAddr(addr); + if(*v != NULL) + { + CVoteban *next = (*v)->m_Next; + delete *v; + *v = next; + } +} + +// returns the voteban with the given address if it exists +CServer::CVoteban **CServer::IsVotebannedAddr(const NETADDR *addr) +{ + CVoteban **v = &m_Votebans; + while(*v != NULL) + { + // only check ip-type and ip, not port + if((*v)->m_Addr.type == addr->type && !mem_comp(&(*v)->m_Addr.ip, &addr->ip, sizeof(unsigned char[16]))) + return v; + v = &(*v)->m_Next; + } + return NULL; +} + +// removes expired votebans +void CServer::CleanVotebans() +{ + CVoteban **v = &m_Votebans; + while(*v != NULL) + { + if((*v)->m_Expire <= Tick()) + { + CVoteban *next = (*v)->m_Next; + delete *v; + *v = next; + } + else + v = &(*v)->m_Next; + } +} + +void CServer::ConVoteban(IConsole::IResult *pResult, void *pUser) +{ + CServer* pThis = static_cast<CServer *>(pUser); + int ClientID = pResult->GetInteger(0); + if(ClientID < 0 || ClientID >= MAX_CLIENTS || pThis->m_aClients[ClientID].m_State == CServer::CClient::STATE_EMPTY) + { + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", "Invalid ClientID"); + return; + } + int time = (pResult->NumArguments() > 1) ? pResult->GetInteger(1) : 300; + pThis->AddVoteban(ClientID, time); + // message to console and chat + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "%s has been votebanned for %d:%02d min.", pThis->ClientName(ClientID), time/60, time%60); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); + // pSelf->SendChatTarget(-1, aBuf); +} + +void CServer::ConUnvoteban(IConsole::IResult *pResult, void *pUser) +{ + CServer* pThis = static_cast<CServer *>(pUser); + int ClientID = pResult->GetInteger(0); + if(ClientID < 0 || ClientID >= MAX_CLIENTS || pThis->m_aClients[ClientID].m_State == CServer::CClient::STATE_EMPTY) + { + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", "Invalid ClientID"); + return; + } + pThis->RemoveVoteban(ClientID); + // message to console + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "%s has been un-votebanned.", pThis->ClientName(ClientID)); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); +} + +void CServer::ConVotebans(IConsole::IResult *pResult, void *pUser) +{ + CServer* pThis = static_cast<CServer *>(pUser); + char aBuf[128]; + char aAddrStr[NETADDR_MAXSTRSIZE]; + int time; + int count = 0; + + pThis->CleanVotebans(); + CVoteban *v = pThis->m_Votebans; + NETADDR addr; + while(v != NULL) + { + addr.type = v->m_Addr.type; + mem_copy(addr.ip, v->m_Addr.ip, sizeof(unsigned char[16])); + net_addr_str(&addr, aAddrStr, sizeof(aAddrStr), false); + time = (v->m_Expire - pThis->Tick()) / pThis->TickSpeed(); + str_format(aBuf, sizeof(aBuf), "addr=%s time=%d:%02d min", aAddrStr, time/60, time%60); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); + count++; + v = v->m_Next; + } + + str_format(aBuf, sizeof(aBuf), "%d votebanned ip(s)", count); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); +} + void CServer::ConKick(IConsole::IResult *pResult, void *pUser) { if(pResult->NumArguments() > 1) @@ -1652,6 +1824,10 @@ void CServer::RegisterCommands() Console()->Chain("sv_max_clients_per_ip", ConchainMaxclientsperipUpdate, this); Console()->Chain("mod_command", ConchainModCommandUpdate, this); Console()->Chain("console_output_level", ConchainConsoleOutputLevelUpdate, this); + + Console()->Register("voteban", "i?i", CFGFLAG_SERVER, ConVoteban, this, "Voteban a player by id"); + Console()->Register("unvoteban", "i", CFGFLAG_SERVER, ConUnvoteban, this, "Remove voteban on player by id"); + Console()->Register("votebans", "", CFGFLAG_SERVER, ConVotebans, this, "Show all votebans"); // register console commands in sub parts m_ServerBan.InitServerBan(Console(), Storage(), this); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 0d14d53e..3fb3bfb3 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -170,6 +170,7 @@ public: CMapChecker m_MapChecker; CServer(); + ~CServer(); int TrySetClientName(int ClientID, const char *pName); @@ -251,6 +252,32 @@ public: //zCatch virtual void MapReload(); + + // voteban system + // struct CVotebanAddr + // { + // unsigned char ip[16]; + // unsigned int type; + // }; + struct CVoteban + { + // CVotebanAddr m_Addr; + NETADDR m_Addr; + int m_Expire; + CVoteban *m_Next; + }; + CVoteban *m_Votebans; + int ClientVotebannedTime(int ClientID); + void AdjustVotebanTime(int offset); + void AddVotebanAddr(const NETADDR *addr, int expire); + void AddVoteban(int ClientID, int time); + void RemoveVoteban(int ClientID); + void RemoveVotebanAddr(const NETADDR *addr); + CVoteban **IsVotebannedAddr(const NETADDR *addr); + void CleanVotebans(); + static void ConVoteban(IConsole::IResult *pResult, void *pUser); + static void ConUnvoteban(IConsole::IResult *pResult, void *pUser); + static void ConVotebans(IConsole::IResult *pResult, void *pUser); }; #endif diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 226f9133..1160d56e 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -775,10 +775,10 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) char aChatmsg[512]; // check voteban - if(pPlayer->m_VoteBannedUntilTick > Server()->Tick()) + int left = Server()->ClientVotebannedTime(ClientID); + if(left) { - int left = (pPlayer->m_VoteBannedUntilTick - Server()->Tick()) / Server()->TickSpeed(); - str_format(aChatmsg, sizeof(aChatmsg), "You must wait %d:%02d min until you are allowed to vote again.", left/60, left%60); + str_format(aChatmsg, sizeof(aChatmsg), "You are not allowed to vote for the next %d:%02d min.", left/60, left%60); SendChatTarget(ClientID, aChatmsg); return; } @@ -1695,61 +1695,6 @@ void CGameContext::ConUnmuteIP(IConsole::IResult *pResult, void *pUserData) } } -void CGameContext::ConVoteban(IConsole::IResult *pResult, void *pUserData) -{ - CGameContext *pSelf = (CGameContext *)pUserData; - char aBuf[128]; - int CID = pResult->GetInteger(0); - if(CID < 0 || CID >= MAX_CLIENTS || !pSelf->m_apPlayers[CID]) - { - pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", "Invalid ClientID"); - return; - } - int time = (pResult->NumArguments() > 1) ? pResult->GetInteger(1) : 300; - pSelf->m_apPlayers[CID]->m_VoteBannedUntilTick = pSelf->Server()->Tick() + time * pSelf->Server()->TickSpeed(); - str_format(aBuf, sizeof(aBuf), "%s has been votebanned for %d:%02d min.", pSelf->Server()->ClientName(CID), time/60, time%60); - pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); - pSelf->SendChatTarget(-1, aBuf); -} - -void CGameContext::ConUnvoteban(IConsole::IResult *pResult, void *pUserData) -{ - CGameContext *pSelf = (CGameContext *)pUserData; - char aBuf[128]; - int CID = pResult->GetInteger(0); - if(CID < 0 || CID >= MAX_CLIENTS || !pSelf->m_apPlayers[CID]) - { - pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", "Invalid ClientID"); - return; - } - pSelf->m_apPlayers[CID]->m_VoteBannedUntilTick = 0; - str_format(aBuf, sizeof(aBuf), "%s has been un-votebanned.", pSelf->Server()->ClientName(CID)); - pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); -} - -void CGameContext::ConVotebans(IConsole::IResult *pResult, void *pUserData) -{ - CGameContext *pSelf = (CGameContext *)pUserData; - char aBuf[128]; - char aAddrStr[NETADDR_MAXSTRSIZE]; - int time; - int count = 0; - - for(int i = 0; i < MAX_CLIENTS; i++) - { - if(pSelf->m_apPlayers[i] && pSelf->m_apPlayers[i]->m_VoteBannedUntilTick > pSelf->Server()->Tick()) - { - pSelf->Server()->GetClientAddr(i, aAddrStr, sizeof(aAddrStr)); - time = (pSelf->m_apPlayers[i]->m_VoteBannedUntilTick - pSelf->Server()->Tick()) / pSelf->Server()->TickSpeed(); - str_format(aBuf, sizeof(aBuf), "id=%d addr=%s name='%s' time=%d:%02d min", i, aAddrStr, pSelf->Server()->ClientName(i), time/60, time%60); - pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); - count++; - } - } - str_format(aBuf, sizeof(aBuf), "%d voteban(s)", count); - pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); -} - void CGameContext::OnConsoleInit() { m_pServer = Kernel()->RequestInterface<IServer>(); @@ -1781,10 +1726,6 @@ void CGameContext::OnConsoleInit() Console()->Register("unmuteid", "i", CFGFLAG_SERVER, ConUnmuteID, this, "Unmutes a player by its client id"); Console()->Register("unmuteip", "i", CFGFLAG_SERVER, ConUnmuteIP, this, "Removes a mute by its index"); Console()->Register("mutes", "", CFGFLAG_SERVER, ConMutes, this, "Show all mutes"); - - Console()->Register("voteban", "i?i", CFGFLAG_SERVER, ConVoteban, this, "Voteban a player by id"); - Console()->Register("unvoteban", "i", CFGFLAG_SERVER, ConUnvoteban, this, "Remove voteban on player by id"); - Console()->Register("votebans", "", CFGFLAG_SERVER, ConVotebans, this, "Show all votebans"); Console()->Chain("sv_motd", ConchainSpecialMotdupdate, this); } diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index 6a0fd8f9..5d340613 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -72,10 +72,6 @@ class CGameContext : public IGameServer static void ConUnmuteID(IConsole::IResult *pResult, void *pUserData); static void ConUnmuteIP(IConsole::IResult *pResult, void *pUserData); static void ConMutes(IConsole::IResult *pResult, void *pUserData); - - static void ConVoteban(IConsole::IResult *pResult, void *pUserData); - static void ConUnvoteban(IConsole::IResult *pResult, void *pUserData); - static void ConVotebans(IConsole::IResult *pResult, void *pUserData); CGameContext(int Resetting); void Construct(int Resetting); diff --git a/src/game/server/player.h b/src/game/server/player.h index b7b863d6..a19209a8 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -114,9 +114,6 @@ public: int m_CampTick; vec2 m_CampPos; - // voteban system - int m_VoteBannedUntilTick; - private: CCharacter *m_pCharacter; CGameContext *m_pGameServer; |