diff options
| author | Teetime <TeetimeTW@yahoo.de> | 2012-03-10 22:58:38 +0100 |
|---|---|---|
| committer | Teetime <TeetimeTW@yahoo.de> | 2012-03-10 22:58:38 +0100 |
| commit | b297f0995a8e097c60e67d6372128e65c22f908b (patch) | |
| tree | e52e59632841995e94724a9c7ad123b78afdf640 /src | |
| parent | 66c44fc229bf8f2f029985a3d712c2518e4e38a9 (diff) | |
| download | zcatch-b297f0995a8e097c60e67d6372128e65c22f908b.tar.gz zcatch-b297f0995a8e097c60e67d6372128e65c22f908b.zip | |
Extended banmaster, now its easier and more comfortable to ban"
Diffstat (limited to 'src')
| -rw-r--r-- | src/banmaster/banmaster.cpp | 349 | ||||
| -rw-r--r-- | src/banmaster/banmaster.h | 1 | ||||
| -rw-r--r-- | src/engine/server/server.cpp | 59 | ||||
| -rw-r--r-- | src/engine/shared/config.h | 1 | ||||
| -rw-r--r-- | src/engine/shared/network.h | 12 | ||||
| -rw-r--r-- | src/engine/shared/network_server.cpp | 33 |
6 files changed, 304 insertions, 151 deletions
diff --git a/src/banmaster/banmaster.cpp b/src/banmaster/banmaster.cpp index d0487763..97eb2aee 100644 --- a/src/banmaster/banmaster.cpp +++ b/src/banmaster/banmaster.cpp @@ -1,234 +1,299 @@ /* (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. */ #include <base/system.h> -#include <engine/shared/network.h> +#include <cstdlib> /* atexit() */ + #include <engine/console.h> #include <engine/storage.h> +#include <engine/config.h> + +#include <engine/shared/config.h> +#include <engine/shared/netban.h> +#include <engine/shared/network.h> +#include <engine/shared/econ.h> +#include <engine/shared/packer.h> #include "banmaster.h" enum { - MAX_BANS=1024, BAN_REREAD_TIME=300, - CFGFLAG_BANMASTER=32 + MAX_BAN_ENTRIES = 10, + MAX_REASON_LENGTH = 128, }; static const char BANMASTER_BANFILE[] = "bans.cfg"; +static const char BANMASTER_BANSSAVEFILE[] = "saved_bans.cfg"; -struct CBan +class CBanmasterBan : public CNetBan { - NETADDR m_Address; - char m_aReason[256]; - int64 m_Expire; +public: + //returns true if address is banned + + bool GetBanInfo(const NETADDR *pAddr, char *pReason, int BufferSize, int *pExpires) + { + CNetHash aHash[17]; + int Length = CNetHash::MakeHashArray(pAddr, aHash); + + // check ban adresses + CBanAddr *pBan = m_BanAddrPool.Find(pAddr, &aHash[Length]); + if(pBan) + { + str_format(pReason, BufferSize, "%s", pBan->m_Info.m_aReason); + *pExpires = pBan->m_Info.m_Expires; + return true; + } + // check ban ranges + for(int i = Length-1; i >= 0; --i) + { + for(CBanRange *pBan = m_BanRangePool.First(&aHash[i]); pBan; pBan = pBan->m_pHashNext) + { + if(NetMatch(&pBan->m_Data, pAddr, i, Length)) + { + str_format(pReason, BufferSize, "%s", pBan->m_Info.m_aReason); + *pExpires = pBan->m_Info.m_Expires; + return true; + } + } + } + + return false; + } +}; + +struct CBanInfo { + char m_aName[16]; + char m_aReason[MAX_REASON_LENGTH]; + NETADDR m_Addr; + int m_RecvTime; +}; + +struct CStats { + unsigned int m_StartTime; + int m_HitsBannedPlayers; + int m_NumRecvBans; + int m_NumRequests; }; -static CBan m_aBans[MAX_BANS]; -static int m_NumBans = 0; -static CNetClient m_Net; -static IConsole *m_pConsole; -static char m_aBindAddr[64] = ""; +CEcon m_Econ; +CNetClient m_Net; +CBanmasterBan m_NetBan; +CBanInfo m_RecvBans[MAX_BAN_ENTRIES]; +CStats m_Stats; + +IConsole *m_pConsole; +IStorage *m_pStorage; +IKernel *m_pKernel; +IConfig *m_pConfig; -CBan* CheckBan(NETADDR *pCheck) +void CleanUp() { - for(int i = 0; i < m_NumBans; i++) - if(net_addr_comp(&m_aBans[i].m_Address, pCheck) == 0) - return &m_aBans[i]; + // Better: RAII? + m_Econ.Shutdown(); - return 0; + delete m_pConsole; + delete m_pConfig; + delete m_pKernel; + delete m_pStorage; } int SendResponse(NETADDR *pAddr, NETADDR *pCheck) { static char aIpBan[sizeof(BANMASTER_IPBAN) + NETADDR_MAXSTRSIZE] = { 0 }; static char *pIpBanContent = aIpBan + sizeof(BANMASTER_IPBAN); + if (!aIpBan[0]) mem_copy(aIpBan, BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)); - + static CNetChunk p; - + p.m_ClientID = -1; p.m_Address = *pAddr; p.m_Flags = NETSENDFLAG_CONNLESS; - CBan* pBan = CheckBan(pCheck); - if(pBan) + int Expires; + char aReason[128]; + + if(m_NetBan.GetBanInfo(pCheck, aReason, sizeof(aReason), &Expires)) { - net_addr_str(pCheck, pIpBanContent, NETADDR_MAXSTRSIZE, 0); + net_addr_str(pCheck, pIpBanContent, NETADDR_MAXSTRSIZE, false); char *pIpBanReason = pIpBanContent + (str_length(pIpBanContent) + 1); - str_copy(pIpBanReason, pBan->m_aReason, 256); + str_copy(pIpBanReason, aReason, 256); p.m_pData = aIpBan; p.m_DataSize = sizeof(BANMASTER_IPBAN) + str_length(pIpBanContent) + 1 + str_length(pIpBanReason) + 1; m_Net.Send(&p); return 1; } - + return 0; - /*else - { - p.m_DataSize = sizeof(BANMASTER_IPOK); - p.m_pData = BANMASTER_IPOK; - m_Net.Send(&p); - return 0; - }*/ } -void AddBan(NETADDR *pAddr, const char *pReason) +void AddRecvBan(NETADDR *pFromAddr, unsigned char *pData, int Size) { - pAddr->port = 0; + CUnpacker Up; + const char *pIP, *pName, *pReason; - CBan *pBan = CheckBan(pAddr); - char aAddressStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pAddr, aAddressStr, sizeof(aAddressStr), 0); + Up.Reset(pData + sizeof(BANMASTER_IPREPORT), Size - sizeof(BANMASTER_IPREPORT)); - if(pBan) + pName = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + pIP = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + pReason = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + + NETADDR ReportAddr; + if(net_addr_from_str(&ReportAddr, pIP) == 0 && pName[0] && pReason[0]) { - char aAddressStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pAddr, aAddressStr, sizeof(aAddressStr), 0); - dbg_msg("banmaster", "updated ban, ip=%s oldreason='%s' reason='%s'", aAddressStr, pBan->m_aReason, pReason); - - str_copy(pBan->m_aReason, pReason, sizeof(m_aBans[m_NumBans].m_aReason)); - pBan->m_Expire = -1; + for(int i = MAX_BAN_ENTRIES-1; i > 0; i--) + mem_copy(&m_RecvBans[i], &m_RecvBans[i-1], sizeof(m_RecvBans[i])); + + m_RecvBans[0].m_Addr = ReportAddr; + str_copy(m_RecvBans[0].m_aName, pName, sizeof(m_RecvBans[0].m_aName)); + str_copy(m_RecvBans[0].m_aReason, pReason, sizeof(m_RecvBans[0].m_aReason)); + m_RecvBans[0].m_RecvTime = time_timestamp(); + + char aAddr[NETADDR_MAXSTRSIZE]; + char aBuf[256]; + net_addr_str(pFromAddr, aAddr, sizeof(aAddr), false); + str_format(aBuf, sizeof(aBuf), "Received ban from '%s', Name: %s, IP: %s, Reason: %s", aAddr, pName, pIP, pReason); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); + m_Stats.m_NumRecvBans++; } else - { - if(m_NumBans == MAX_BANS) - { - dbg_msg("banmaster", "error: banmaster is full"); - return; - } - - m_aBans[m_NumBans].m_Address = *pAddr; - str_copy(m_aBans[m_NumBans].m_aReason, pReason, sizeof(m_aBans[m_NumBans].m_aReason)); - m_aBans[m_NumBans].m_Expire = -1; - - dbg_msg("banmaster", "added ban, ip=%s reason='%s'", aAddressStr, m_aBans[m_NumBans].m_aReason); - - m_NumBans++; - } + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", "dropped weird ban message"); } -void ClearBans() +void ReloadBans() { - m_NumBans = 0; + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "bans_save %s", BANMASTER_BANSSAVEFILE); + m_pConsole->ExecuteLine(aBuf); } -void PurgeBans() +void ConRecvBans(IConsole::IResult *pResult, void *pUser) { - int64 Now = time_get(); - int i = 0; - while(i < m_NumBans) + int Count = 0; + char aBuf[256]; + for(int i = MAX_BAN_ENTRIES-1; i >= 0; i--) { - if(m_aBans[i].m_Expire != -1 && m_aBans[i].m_Expire < Now) - { - // remove ban - char aBuf[NETADDR_MAXSTRSIZE]; - net_addr_str(&m_aBans[i].m_Address, aBuf, sizeof(aBuf), 0); - dbg_msg("banmaster", "ban expired, ip=%s reason='%s'", aBuf, m_aBans[i].m_aReason); - m_aBans[i] = m_aBans[m_NumBans - 1]; - m_NumBans--; - } - else - i++; + if(!m_RecvBans[i].m_aName[0]) + continue; + + char aIP[NETADDR_MAXSTRSIZE]; + net_addr_str(&m_RecvBans[i].m_Addr, aIP, sizeof(aIP), false); + int RecvTime = time_timestamp() - m_RecvBans[i].m_RecvTime; + str_format(aBuf, sizeof(aBuf), "#%d - Name: %s | Reason: %s | IP: %s | Received %d min and %d sec. ago", i, m_RecvBans[i].m_aName, m_RecvBans[i].m_aReason, aIP, RecvTime/60, RecvTime%60); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); + Count++; } + str_format(aBuf, sizeof(aBuf), "%d Ban(s)", Count); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); } -void ConBan(IConsole::IResult *pResult, void *pUser) +void ConAddBan(IConsole::IResult *pResult, void *pUser) { - NETADDR Addr; - const char *pStr = pResult->GetString(0); - const char *pReason = ""; - - if(pResult->NumArguments() > 1) - pReason = pResult->GetString(1); - - if(!net_addr_from_str(&Addr, pStr)) - AddBan(&Addr, pReason); + int Index = pResult->GetInteger(0); + if(Index >= 0 && Index < MAX_BAN_ENTRIES && m_RecvBans[Index].m_aName[0]) + { + m_NetBan.BanAddr(&m_RecvBans[Index].m_Addr, pResult->GetInteger(1)*60, pResult->GetString(2)); + } else - dbg_msg("banmaster", "invalid network address to ban, str='%s'", pStr); -} - -void ConUnbanAll(IConsole::IResult *pResult, void *pUser) -{ - ClearBans(); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", "Invalid index"); } -void ConSetBindAddr(IConsole::IResult *pResult, void *pUser) -{ - if(m_aBindAddr[0]) - return; - str_copy(m_aBindAddr, pResult->GetString(0), sizeof(m_aBindAddr)); - dbg_msg("banmaster/network", "bound to %s", m_aBindAddr); -} - -void StandardOutput(const char *pLine, void *pUser) +void ConStatus(IConsole::IResult *pResult, void *pUser) { + unsigned int Running = time_timestamp() - m_Stats.m_StartTime; + int Hours = Running / 3600; + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "Running since %d hours %d min and %d sec. Total received requests: %d (%d hits). %d received bans (%.3f/hour).", + Hours, (Running-Hours*3600) / 60, Running % 60, m_Stats.m_NumRequests, m_Stats.m_HitsBannedPlayers, m_Stats.m_NumRecvBans, (Hours != 0) ? (float)m_Stats.m_NumRecvBans/Hours : m_Stats.m_NumRecvBans); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); } int main(int argc, const char **argv) // ignore_convention { + atexit(CleanUp); int64 LastUpdate = time_get(); dbg_logger_stdout(); net_init(); - IKernel *pKernel = IKernel::Create(); - IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); // ignore_convention + m_pKernel = IKernel::Create(); + m_pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); // ignore_convention + m_pConfig = CreateConfig(); - m_pConsole = CreateConsole(CFGFLAG_BANMASTER); - m_pConsole->RegisterPrintCallback(2, StandardOutput, 0); - m_pConsole->Register("ban", "s?r", CFGFLAG_BANMASTER, ConBan, 0, "Bans the specified ip"); - m_pConsole->Register("unban_all", "", CFGFLAG_BANMASTER, ConUnbanAll, 0, "Unbans all ips"); - m_pConsole->Register("bind", "s", CFGFLAG_BANMASTER, ConSetBindAddr, 0, "Binds to the specified address"); + m_pConsole = CreateConsole(CFGFLAG_BANMASTER|CFGFLAG_ECON); { bool RegisterFail = false; - RegisterFail = RegisterFail || !pKernel->RegisterInterface(m_pConsole); - RegisterFail = RegisterFail || !pKernel->RegisterInterface(pStorage); + RegisterFail = RegisterFail || !m_pKernel->RegisterInterface(m_pConsole); + RegisterFail = RegisterFail || !m_pKernel->RegisterInterface(m_pStorage); + RegisterFail = RegisterFail || !m_pKernel->RegisterInterface(m_pConfig); if(RegisterFail) return -1; } + //Reset strings + m_pConfig->Init(); + + // Register Commands + m_pConsole->Register("recvbans", "", CFGFLAG_BANMASTER, ConRecvBans, 0, "Show the last received bans"); + m_pConsole->Register("addban", "iir", CFGFLAG_BANMASTER, ConAddBan, 0, "Ban IP by index"); + m_pConsole->Register("status", "", CFGFLAG_BANMASTER, ConStatus, 0, "Show some statistics"); + + + m_NetBan.Init(m_pConsole, m_pStorage); m_pConsole->ExecuteFile(BANMASTER_BANFILE); - + m_Econ.Init(m_pConsole, &m_NetBan); + + m_pConsole->ExecuteFile(BANMASTER_BANSSAVEFILE); + + m_pConsole->StoreCommands(false); + + mem_zero(&m_RecvBans, sizeof(CBanInfo)*MAX_BAN_ENTRIES); + mem_zero(&m_Stats, sizeof(CStats)); + m_Stats.m_StartTime = time_timestamp(); + NETADDR BindAddr; - if(m_aBindAddr[0] && net_host_lookup(m_aBindAddr, &BindAddr, NETTYPE_IPV4) == 0) - { - if(BindAddr.port == 0) - BindAddr.port = BANMASTER_PORT; - } + if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0) + BindAddr.port = BANMASTER_PORT; else { mem_zero(&BindAddr, sizeof(BindAddr)); + BindAddr.type = NETTYPE_ALL; BindAddr.port = BANMASTER_PORT; } - - m_Net.Open(BindAddr, 0); - // TODO: check socket for errors + + if(!m_Net.Open(BindAddr, 0)) + { + dbg_msg("banmaster", "couldn't start network"); + return -1; + } dbg_msg("banmaster", "started"); while(1) { m_Net.Update(); - - // process m_aPackets + + // process m_Packets CNetChunk Packet; while(m_Net.Recv(&Packet)) { char aAddressStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Packet.m_Address, aAddressStr, sizeof(aAddressStr), 0); + net_addr_str(&Packet.m_Address, aAddressStr, sizeof(aAddressStr), false); - if(Packet.m_DataSize >= sizeof(BANMASTER_IPCHECK) && mem_comp(Packet.m_pData, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)) == 0) + if(Packet.m_DataSize >= (int)sizeof(BANMASTER_IPCHECK) && mem_comp(Packet.m_pData, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)) == 0) { char *pAddr = (char *)Packet.m_pData + sizeof(BANMASTER_IPCHECK); NETADDR CheckAddr; if(net_addr_from_str(&CheckAddr, pAddr)) { - dbg_msg("banmaster", "dropped weird message, ip=%s checkaddr='%s'", aAddressStr, pAddr); + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "dropped weird message, ip='%s' checkaddr='%s'", aAddressStr, pAddr); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", aBuf); } else { @@ -236,26 +301,46 @@ int main(int argc, const char **argv) // ignore_convention int Banned = SendResponse(&Packet.m_Address, &CheckAddr); - char aBuf[NETADDR_MAXSTRSIZE]; - net_addr_str(&CheckAddr, aBuf, sizeof(aBuf), 0); - dbg_msg("banmaster", "responded to checkmsg, ip=%s checkaddr=%s result=%s", aAddressStr, aBuf, (Banned) ? "ban" : "ok"); + char aIP[NETADDR_MAXSTRSIZE]; + char aBuf[256]; + net_addr_str(&CheckAddr, aIP, sizeof(aIP), false); + str_format(aBuf, sizeof(aBuf), "responded to checkmsg, ip='%s' checkaddr='%s' result=%s", aAddressStr, aIP, (Banned) ? "ban" : "ok"); + if(Banned) + { + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); + m_Stats.m_HitsBannedPlayers++; + } + else + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", aBuf); + + m_Stats.m_NumRequests++; } } + else if(Packet.m_DataSize >= (int)sizeof(BANMASTER_IPREPORT) && mem_comp(Packet.m_pData, BANMASTER_IPREPORT, sizeof(BANMASTER_IPREPORT)) == 0) + { + //info of a banned client + AddRecvBan(&Packet.m_Address, (unsigned char*)Packet.m_pData, Packet.m_DataSize); + } else - dbg_msg("banmaster", "dropped weird packet, ip=%s", aAddressStr, (char *)Packet.m_pData); + { + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "dropped weird packet, ip='%s'", aAddressStr, (char *)Packet.m_pData); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", aBuf); + } } - + if(time_get() - LastUpdate > time_freq() * BAN_REREAD_TIME) { - ClearBans(); + ReloadBans(); LastUpdate = time_get(); - m_pConsole->ExecuteFile(BANMASTER_BANFILE); } + + m_NetBan.Update(); + m_Econ.Update(); // be nice to the CPU thread_sleep(1); } - + return 0; } - diff --git a/src/banmaster/banmaster.h b/src/banmaster/banmaster.h index f7c645f7..296dc14d 100644 --- a/src/banmaster/banmaster.h +++ b/src/banmaster/banmaster.h @@ -8,5 +8,6 @@ static const int BANMASTER_PORT = 8302; //static const char BANMASTER_IPOK[] = {255, 255, 255, 255, 'i', 'p', 'o', 'k'}; static const char BANMASTER_IPBAN[] = {255, 255, 255, 255, 'i', 'p', 'b', 'a'}; static const char BANMASTER_IPCHECK[] = {255, 255, 255, 255, 'i', 'p', 'c', 'h'}; +static const char BANMASTER_IPREPORT[] = {255, 255, 255, 255, 'i', 'p', 'r', 'e'}; #endif diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 2cb33f36..cd73c5a7 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -266,6 +266,45 @@ void CServerBan::ConBanExt(IConsole::IResult *pResult, void *pUser) int Minutes = pResult->NumArguments()>1 ? clamp(pResult->GetInteger(1), 0, 44640) : 30; const char *pReason = pResult->NumArguments()>2 ? pResult->GetString(2) : "No reason given"; + int CID = -1; + if(StrAllnum(pStr)) + CID = str_toint(pStr); + else + { + NETADDR Addr; + if(net_addr_from_str(&Addr, pStr) == 0) + for(int i = 0; i < MAX_CLIENTS; i++) + if(pThis->NetMatch(&Addr, pThis->Server()->m_NetServer.ClientAddr(i))) + { + CID = i; + break; + } + } + + if(g_Config.m_SvGlobalBantime && CID >= 0 && CID < MAX_CLIENTS && pThis->Server()->m_aClients[CID].m_State == CServer::CClient::STATE_INGAME) + { + char aIP[NETADDR_MAXSTRSIZE]; + net_addr_str(pThis->Server()->m_NetServer.ClientAddr(CID), aIP, sizeof(aIP), 0); + + CPacker P; + P.Reset(); + P.AddRaw(BANMASTER_IPREPORT, sizeof(BANMASTER_IPREPORT)); + P.AddString(pThis->Server()->ClientName(CID), -1); + P.AddString(aIP, -1); + P.AddString(pReason, -1); + + if(!P.Error()) + { + CNetChunk Packet; + Packet.m_ClientID = -1; + Packet.m_Flags = NETSENDFLAG_CONNLESS; + Packet.m_pData = P.Data(); + Packet.m_DataSize = P.Size(); + pThis->Server()->m_NetServer.SendToBanmasters(&Packet); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "banmaster", "Reported ban to banmasters"); + } + } + if(StrAllnum(pStr)) { int ClientID = str_toint(pStr); @@ -1207,12 +1246,14 @@ void CServer::PumpNetwork() str_copy(aReason, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(aReason)); if(net_addr_from_str(&Addr, aIp)) { - dbg_msg("globalbans", "dropped weird message from banmaster"); + Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "globalbans", "dropped weird message from banmaster"); return; } m_ServerBan.BanAddr(&Addr, g_Config.m_SvGlobalBantime * 60, aReason); - dbg_msg("globalbans", "added ban, ip=%s, reason='%s'", aIp, aReason); + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "added ban, ip=%s, reason='%s'", aIp, aReason); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "globalbans", aBuf); } } } @@ -1578,10 +1619,12 @@ void CServer::ConAddBanmaster(IConsole::IResult *pResult, void *pUser) if(Result == 0) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "succesfully added banmaster"); - else if (Result == 1) + else if(Result == 1) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "invalid address for banmaster / net lookup failed"); - else + else if(Result == 2) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "too many banmasters"); + else + pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "banmaster already exists"); } void CServer::ConBanmasters(IConsole::IResult *pResult, void *pUser) @@ -1789,6 +1832,14 @@ int main(int argc, const char **argv) // ignore_convention pServer->RegisterCommands(); pGameServer->OnConsoleInit(); + /* This banmaster is added into the source of the server that i'm able to ban players even if no banmaster.cfg is used. + * Often serverhoster doesn't add this file because they don't know what it is for and remove it, not + * because they don't want it. If so, set sv_global_bantime to 0 or use a custom banmasters.cfg with "clear_banmasters" + * in first line or in normal config. + * ## For a Teeworlds without bots \o/ ## + */ + pConsole->ExecuteLine("add_banmaster banmaster.teetw.de"); + // execute autoexec file pConsole->ExecuteFile("autoexec.cfg"); diff --git a/src/engine/shared/config.h b/src/engine/shared/config.h index c6d8437f..4200303e 100644 --- a/src/engine/shared/config.h +++ b/src/engine/shared/config.h @@ -22,6 +22,7 @@ enum CFGFLAG_STORE=8, CFGFLAG_MASTER=16, CFGFLAG_ECON=32, + CFGFLAG_BANMASTER=64|CFGFLAG_MASTER, }; #endif diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 385f21f2..ea5ed98f 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -248,14 +248,6 @@ public: MAX_BANMASTERS=16 }; - struct CBanInfo - { - NETADDR m_Addr; - int m_Expires; - char m_Reason[128]; - }; - -private: struct CSlot { public: @@ -278,6 +270,7 @@ private: CNetRecvUnpacker m_RecvUnpacker; public: + CNetServer(); int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); // @@ -301,11 +294,14 @@ public: // void SetMaxClientsPerIP(int Max); + + // int BanmasterAdd(const char *pAddrStr); int BanmasterNum() const; NETADDR* BanmasterGet(int Index); int BanmasterCheck(NETADDR *pAddr); void BanmastersClear(); + void SendToBanmasters(CNetChunk *pP); }; class CNetConsole diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index 32525802..98b88ac5 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -8,11 +8,15 @@ #include "netban.h" #include "network.h" +CNetServer::CNetServer() +{ + mem_zero(this, sizeof(*this)); +} bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags) { // zero out the whole structure - mem_zero(this, sizeof(*this)); + //mem_zero(this, sizeof(*this)); // open socket m_Socket = net_udp_create(BindAddr); @@ -271,13 +275,20 @@ int CNetServer::BanmasterAdd(const char *pAddrStr) { if(m_NumBanmasters >= MAX_BANMASTERS) return 2; - - if(net_host_lookup(pAddrStr, &m_aBanmasters[m_NumBanmasters], NETTYPE_IPV4)) + + NETADDR Addr; + if(net_host_lookup(pAddrStr, &Addr, NETTYPE_ALL)) return 1; - - if(m_aBanmasters[m_NumBanmasters].port == 0) - m_aBanmasters[m_NumBanmasters].port = BANMASTER_PORT; - + + if(Addr.port == 0) + Addr.port = BANMASTER_PORT; + + for(int i = 0; i < m_NumBanmasters; i++) + if(mem_comp(&Addr, &m_aBanmasters[i], sizeof(NETADDR)) == 0) + return 3; + + m_aBanmasters[m_NumBanmasters] = Addr; + m_NumBanmasters++; return 0; } @@ -309,3 +320,11 @@ void CNetServer::BanmastersClear() m_NumBanmasters = 0; } +void CNetServer::SendToBanmasters(CNetChunk *pP) +{ + for(int i = 0; i < m_NumBanmasters; i++) + { + pP->m_Address = m_aBanmasters[i]; + Send(pP); + } +} |