mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-14 03:58:18 +00:00
fa4bcd5ec0
This makes the "black console window" less important on Windows (or anywhere else, for that matter), lets you see logs from other threads in the f1 console, and removes the distinction between `IConsole::Print` and `dbg_msg`.
547 lines
15 KiB
C++
547 lines
15 KiB
C++
/* (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/logger.h>
|
|
#include <base/system.h>
|
|
|
|
#include <engine/config.h>
|
|
#include <engine/console.h>
|
|
#include <engine/kernel.h>
|
|
#include <engine/storage.h>
|
|
|
|
#include <engine/shared/config.h>
|
|
#include <engine/shared/netban.h>
|
|
#include <engine/shared/network.h>
|
|
|
|
#include "mastersrv.h"
|
|
|
|
enum
|
|
{
|
|
MTU = 1400,
|
|
MAX_SERVERS_PER_PACKET = 75,
|
|
MAX_PACKETS = 16,
|
|
MAX_SERVERS = MAX_SERVERS_PER_PACKET * MAX_PACKETS,
|
|
EXPIRE_TIME = 90
|
|
};
|
|
|
|
struct CCheckServer
|
|
{
|
|
enum ServerType m_Type;
|
|
NETADDR m_Address;
|
|
NETADDR m_AltAddress;
|
|
int m_TryCount;
|
|
int64_t m_TryTime;
|
|
};
|
|
|
|
static CCheckServer m_aCheckServers[MAX_SERVERS];
|
|
static int m_NumCheckServers = 0;
|
|
|
|
struct CServerEntry
|
|
{
|
|
enum ServerType m_Type;
|
|
NETADDR m_Address;
|
|
int64_t m_Expire;
|
|
};
|
|
|
|
static CServerEntry m_aServers[MAX_SERVERS];
|
|
static int m_NumServers = 0;
|
|
|
|
struct CPacketData
|
|
{
|
|
int m_Size;
|
|
struct
|
|
{
|
|
unsigned char m_aHeader[sizeof(SERVERBROWSE_LIST)];
|
|
CMastersrvAddr m_aServers[MAX_SERVERS_PER_PACKET];
|
|
} m_Data;
|
|
};
|
|
|
|
CPacketData m_aPackets[MAX_PACKETS];
|
|
static int m_NumPackets = 0;
|
|
|
|
// legacy code
|
|
struct CPacketDataLegacy
|
|
{
|
|
int m_Size;
|
|
struct
|
|
{
|
|
unsigned char m_aHeader[sizeof(SERVERBROWSE_LIST_LEGACY)];
|
|
CMastersrvAddrLegacy m_aServers[MAX_SERVERS_PER_PACKET];
|
|
} m_Data;
|
|
};
|
|
|
|
CPacketDataLegacy m_aPacketsLegacy[MAX_PACKETS];
|
|
static int m_NumPacketsLegacy = 0;
|
|
|
|
struct CCountPacketData
|
|
{
|
|
unsigned char m_Header[sizeof(SERVERBROWSE_COUNT)];
|
|
unsigned char m_High;
|
|
unsigned char m_Low;
|
|
};
|
|
|
|
static CCountPacketData m_CountData;
|
|
static CCountPacketData m_CountDataLegacy;
|
|
|
|
CNetBan m_NetBan;
|
|
|
|
static CNetClient m_NetChecker; // NAT/FW checker
|
|
static CNetClient m_NetOp; // main
|
|
|
|
IConsole *m_pConsole;
|
|
|
|
void BuildPackets()
|
|
{
|
|
CServerEntry *pCurrent = &m_aServers[0];
|
|
int ServersLeft = m_NumServers;
|
|
m_NumPackets = 0;
|
|
m_NumPacketsLegacy = 0;
|
|
int PacketIndex = 0;
|
|
int PacketIndexLegacy = 0;
|
|
while(ServersLeft-- && (m_NumPackets + m_NumPacketsLegacy) < MAX_PACKETS)
|
|
{
|
|
if(pCurrent->m_Type == SERVERTYPE_NORMAL)
|
|
{
|
|
if(PacketIndex % MAX_SERVERS_PER_PACKET == 0)
|
|
{
|
|
PacketIndex = 0;
|
|
m_NumPackets++;
|
|
}
|
|
|
|
// copy header
|
|
mem_copy(m_aPackets[m_NumPackets - 1].m_Data.m_aHeader, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST));
|
|
|
|
// copy server addresses
|
|
if(pCurrent->m_Address.type == NETTYPE_IPV6)
|
|
{
|
|
mem_copy(m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aIp, pCurrent->m_Address.ip,
|
|
sizeof(m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aIp));
|
|
}
|
|
else
|
|
{
|
|
static char IPV4Mapping[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (char)0xFF, (char)0xFF};
|
|
|
|
mem_copy(m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aIp, IPV4Mapping, sizeof(IPV4Mapping));
|
|
m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aIp[12] = pCurrent->m_Address.ip[0];
|
|
m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aIp[13] = pCurrent->m_Address.ip[1];
|
|
m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aIp[14] = pCurrent->m_Address.ip[2];
|
|
m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aIp[15] = pCurrent->m_Address.ip[3];
|
|
}
|
|
|
|
m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aPort[0] = (pCurrent->m_Address.port >> 8) & 0xff;
|
|
m_aPackets[m_NumPackets - 1].m_Data.m_aServers[PacketIndex].m_aPort[1] = pCurrent->m_Address.port & 0xff;
|
|
|
|
PacketIndex++;
|
|
|
|
m_aPackets[m_NumPackets - 1].m_Size = sizeof(SERVERBROWSE_LIST) + sizeof(CMastersrvAddr) * PacketIndex;
|
|
|
|
pCurrent++;
|
|
}
|
|
else if(pCurrent->m_Type == SERVERTYPE_LEGACY)
|
|
{
|
|
if(PacketIndexLegacy % MAX_SERVERS_PER_PACKET == 0)
|
|
{
|
|
PacketIndexLegacy = 0;
|
|
m_NumPacketsLegacy++;
|
|
}
|
|
|
|
// copy header
|
|
mem_copy(m_aPacketsLegacy[m_NumPacketsLegacy - 1].m_Data.m_aHeader, SERVERBROWSE_LIST_LEGACY, sizeof(SERVERBROWSE_LIST_LEGACY));
|
|
|
|
// copy server addresses
|
|
mem_copy(m_aPacketsLegacy[m_NumPacketsLegacy - 1].m_Data.m_aServers[PacketIndexLegacy].m_aIp, pCurrent->m_Address.ip,
|
|
sizeof(m_aPacketsLegacy[m_NumPacketsLegacy - 1].m_Data.m_aServers[PacketIndexLegacy].m_aIp));
|
|
// 0.5 has the port in little endian on the network
|
|
m_aPacketsLegacy[m_NumPacketsLegacy - 1].m_Data.m_aServers[PacketIndexLegacy].m_aPort[0] = pCurrent->m_Address.port & 0xff;
|
|
m_aPacketsLegacy[m_NumPacketsLegacy - 1].m_Data.m_aServers[PacketIndexLegacy].m_aPort[1] = (pCurrent->m_Address.port >> 8) & 0xff;
|
|
|
|
PacketIndexLegacy++;
|
|
|
|
m_aPacketsLegacy[m_NumPacketsLegacy - 1].m_Size = sizeof(SERVERBROWSE_LIST_LEGACY) + sizeof(CMastersrvAddrLegacy) * PacketIndexLegacy;
|
|
|
|
pCurrent++;
|
|
}
|
|
else
|
|
{
|
|
*pCurrent = m_aServers[m_NumServers - 1];
|
|
m_NumServers--;
|
|
dbg_msg("mastersrv", "ERROR: server of invalid type, dropping it");
|
|
}
|
|
}
|
|
}
|
|
|
|
void SendOk(NETADDR *pAddr)
|
|
{
|
|
CNetChunk p;
|
|
p.m_ClientID = -1;
|
|
p.m_Address = *pAddr;
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
p.m_DataSize = sizeof(SERVERBROWSE_FWOK);
|
|
p.m_pData = SERVERBROWSE_FWOK;
|
|
|
|
// send on both to be sure
|
|
m_NetChecker.Send(&p);
|
|
m_NetOp.Send(&p);
|
|
}
|
|
|
|
void SendError(NETADDR *pAddr)
|
|
{
|
|
CNetChunk p;
|
|
p.m_ClientID = -1;
|
|
p.m_Address = *pAddr;
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
p.m_DataSize = sizeof(SERVERBROWSE_FWERROR);
|
|
p.m_pData = SERVERBROWSE_FWERROR;
|
|
m_NetOp.Send(&p);
|
|
}
|
|
|
|
void SendCheck(NETADDR *pAddr)
|
|
{
|
|
CNetChunk p;
|
|
p.m_ClientID = -1;
|
|
p.m_Address = *pAddr;
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
p.m_DataSize = sizeof(SERVERBROWSE_FWCHECK);
|
|
p.m_pData = SERVERBROWSE_FWCHECK;
|
|
m_NetChecker.Send(&p);
|
|
}
|
|
|
|
void AddCheckserver(NETADDR *pInfo, NETADDR *pAlt, ServerType Type)
|
|
{
|
|
// add server
|
|
if(m_NumCheckServers == MAX_SERVERS)
|
|
{
|
|
dbg_msg("mastersrv", "ERROR: mastersrv is full");
|
|
return;
|
|
}
|
|
|
|
char aAddrStr[NETADDR_MAXSTRSIZE];
|
|
net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr), true);
|
|
char aAltAddrStr[NETADDR_MAXSTRSIZE];
|
|
net_addr_str(pAlt, aAltAddrStr, sizeof(aAltAddrStr), true);
|
|
dbg_msg("mastersrv", "checking: %s (%s)", aAddrStr, aAltAddrStr);
|
|
m_aCheckServers[m_NumCheckServers].m_Address = *pInfo;
|
|
m_aCheckServers[m_NumCheckServers].m_AltAddress = *pAlt;
|
|
m_aCheckServers[m_NumCheckServers].m_TryCount = 0;
|
|
m_aCheckServers[m_NumCheckServers].m_TryTime = 0;
|
|
m_aCheckServers[m_NumCheckServers].m_Type = Type;
|
|
m_NumCheckServers++;
|
|
}
|
|
|
|
void AddServer(NETADDR *pInfo, ServerType Type)
|
|
{
|
|
// see if server already exists in list
|
|
for(int i = 0; i < m_NumServers; i++)
|
|
{
|
|
if(net_addr_comp(&m_aServers[i].m_Address, pInfo) == 0)
|
|
{
|
|
char aAddrStr[NETADDR_MAXSTRSIZE];
|
|
net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr), true);
|
|
dbg_msg("mastersrv", "updated: %s", aAddrStr);
|
|
m_aServers[i].m_Expire = time_get() + time_freq() * EXPIRE_TIME;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// add server
|
|
if(m_NumServers == MAX_SERVERS)
|
|
{
|
|
dbg_msg("mastersrv", "ERROR: mastersrv is full");
|
|
return;
|
|
}
|
|
|
|
char aAddrStr[NETADDR_MAXSTRSIZE];
|
|
net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr), true);
|
|
dbg_msg("mastersrv", "added: %s", aAddrStr);
|
|
m_aServers[m_NumServers].m_Address = *pInfo;
|
|
m_aServers[m_NumServers].m_Expire = time_get() + time_freq() * EXPIRE_TIME;
|
|
m_aServers[m_NumServers].m_Type = Type;
|
|
m_NumServers++;
|
|
}
|
|
|
|
void UpdateServers()
|
|
{
|
|
int64_t Now = time_get();
|
|
int64_t Freq = time_freq();
|
|
for(int i = 0; i < m_NumCheckServers; i++)
|
|
{
|
|
if(Now > m_aCheckServers[i].m_TryTime + Freq)
|
|
{
|
|
if(m_aCheckServers[i].m_TryCount == 10)
|
|
{
|
|
char aAddrStr[NETADDR_MAXSTRSIZE];
|
|
net_addr_str(&m_aCheckServers[i].m_Address, aAddrStr, sizeof(aAddrStr), true);
|
|
char aAltAddrStr[NETADDR_MAXSTRSIZE];
|
|
net_addr_str(&m_aCheckServers[i].m_AltAddress, aAltAddrStr, sizeof(aAltAddrStr), true);
|
|
dbg_msg("mastersrv", "check failed: %s (%s)", aAddrStr, aAltAddrStr);
|
|
|
|
// FAIL!!
|
|
SendError(&m_aCheckServers[i].m_Address);
|
|
m_aCheckServers[i] = m_aCheckServers[m_NumCheckServers - 1];
|
|
m_NumCheckServers--;
|
|
i--;
|
|
}
|
|
else
|
|
{
|
|
m_aCheckServers[i].m_TryCount++;
|
|
m_aCheckServers[i].m_TryTime = Now;
|
|
if(m_aCheckServers[i].m_TryCount & 1)
|
|
SendCheck(&m_aCheckServers[i].m_Address);
|
|
else
|
|
SendCheck(&m_aCheckServers[i].m_AltAddress);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void PurgeServers()
|
|
{
|
|
int64_t Now = time_get();
|
|
int i = 0;
|
|
while(i < m_NumServers)
|
|
{
|
|
if(m_aServers[i].m_Expire < Now)
|
|
{
|
|
// remove server
|
|
char aAddrStr[NETADDR_MAXSTRSIZE];
|
|
net_addr_str(&m_aServers[i].m_Address, aAddrStr, sizeof(aAddrStr), true);
|
|
dbg_msg("mastersrv", "expired: %s", aAddrStr);
|
|
m_aServers[i] = m_aServers[m_NumServers - 1];
|
|
m_NumServers--;
|
|
}
|
|
else
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void ReloadBans()
|
|
{
|
|
m_NetBan.UnbanAll();
|
|
m_pConsole->ExecuteFile("master.cfg", -1, true);
|
|
}
|
|
|
|
int main(int argc, const char **argv)
|
|
{
|
|
int64_t LastBuild = 0, LastBanReload = 0;
|
|
ServerType Type = SERVERTYPE_INVALID;
|
|
NETADDR BindAddr;
|
|
|
|
cmdline_fix(&argc, &argv);
|
|
|
|
log_set_global_logger_default();
|
|
net_init();
|
|
|
|
mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT));
|
|
mem_copy(m_CountDataLegacy.m_Header, SERVERBROWSE_COUNT_LEGACY, sizeof(SERVERBROWSE_COUNT_LEGACY));
|
|
|
|
IKernel *pKernel = IKernel::Create();
|
|
IStorage *pStorage = CreateStorage(IStorage::STORAGETYPE_BASIC, argc, argv);
|
|
IConfigManager *pConfigManager = CreateConfigManager();
|
|
m_pConsole = CreateConsole(CFGFLAG_MASTER);
|
|
|
|
bool RegisterFail = !pKernel->RegisterInterface(pStorage);
|
|
RegisterFail |= !pKernel->RegisterInterface(m_pConsole);
|
|
RegisterFail |= !pKernel->RegisterInterface(pConfigManager);
|
|
|
|
if(RegisterFail)
|
|
return -1;
|
|
|
|
pConfigManager->Init();
|
|
m_pConsole->Init();
|
|
m_NetBan.Init(m_pConsole, pStorage);
|
|
if(argc > 1)
|
|
m_pConsole->ParseArguments(argc - 1, &argv[1]);
|
|
|
|
if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0)
|
|
{
|
|
// got bindaddr
|
|
BindAddr.type = NETTYPE_ALL;
|
|
BindAddr.port = MASTERSERVER_PORT;
|
|
}
|
|
else
|
|
{
|
|
mem_zero(&BindAddr, sizeof(BindAddr));
|
|
BindAddr.type = NETTYPE_ALL;
|
|
BindAddr.port = MASTERSERVER_PORT;
|
|
}
|
|
|
|
if(!m_NetOp.Open(BindAddr))
|
|
{
|
|
dbg_msg("mastersrv", "couldn't start network (op)");
|
|
return -1;
|
|
}
|
|
BindAddr.port = MASTERSERVER_PORT + 1;
|
|
if(!m_NetChecker.Open(BindAddr))
|
|
{
|
|
dbg_msg("mastersrv", "couldn't start network (checker)");
|
|
return -1;
|
|
}
|
|
|
|
// process pending commands
|
|
m_pConsole->StoreCommands(false);
|
|
|
|
dbg_msg("mastersrv", "started");
|
|
|
|
while(true)
|
|
{
|
|
m_NetOp.Update();
|
|
m_NetChecker.Update();
|
|
|
|
// process m_aPackets
|
|
CNetChunk Packet;
|
|
while(m_NetOp.Recv(&Packet))
|
|
{
|
|
// check if the server is banned
|
|
if(m_NetBan.IsBanned(&Packet.m_Address, 0, 0))
|
|
continue;
|
|
|
|
if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT) + 2 &&
|
|
mem_comp(Packet.m_pData, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0)
|
|
{
|
|
NETADDR Alt;
|
|
unsigned char *d = (unsigned char *)Packet.m_pData;
|
|
Alt = Packet.m_Address;
|
|
Alt.port =
|
|
(d[sizeof(SERVERBROWSE_HEARTBEAT)] << 8) |
|
|
d[sizeof(SERVERBROWSE_HEARTBEAT) + 1];
|
|
|
|
// add it
|
|
AddCheckserver(&Packet.m_Address, &Alt, SERVERTYPE_NORMAL);
|
|
}
|
|
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT_LEGACY) + 2 &&
|
|
mem_comp(Packet.m_pData, SERVERBROWSE_HEARTBEAT_LEGACY, sizeof(SERVERBROWSE_HEARTBEAT_LEGACY)) == 0)
|
|
{
|
|
NETADDR Alt;
|
|
unsigned char *d = (unsigned char *)Packet.m_pData;
|
|
Alt = Packet.m_Address;
|
|
Alt.port =
|
|
(d[sizeof(SERVERBROWSE_HEARTBEAT)] << 8) |
|
|
d[sizeof(SERVERBROWSE_HEARTBEAT) + 1];
|
|
|
|
// add it
|
|
AddCheckserver(&Packet.m_Address, &Alt, SERVERTYPE_LEGACY);
|
|
}
|
|
|
|
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETCOUNT) &&
|
|
mem_comp(Packet.m_pData, SERVERBROWSE_GETCOUNT, sizeof(SERVERBROWSE_GETCOUNT)) == 0)
|
|
{
|
|
dbg_msg("mastersrv", "count requested, responding with %d", m_NumServers);
|
|
|
|
CNetChunk p;
|
|
p.m_ClientID = -1;
|
|
p.m_Address = Packet.m_Address;
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
p.m_DataSize = sizeof(m_CountData);
|
|
p.m_pData = &m_CountData;
|
|
m_CountData.m_High = (m_NumServers >> 8) & 0xff;
|
|
m_CountData.m_Low = m_NumServers & 0xff;
|
|
m_NetOp.Send(&p);
|
|
}
|
|
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETCOUNT_LEGACY) &&
|
|
mem_comp(Packet.m_pData, SERVERBROWSE_GETCOUNT_LEGACY, sizeof(SERVERBROWSE_GETCOUNT_LEGACY)) == 0)
|
|
{
|
|
dbg_msg("mastersrv", "count requested, responding with %d", m_NumServers);
|
|
|
|
CNetChunk p;
|
|
p.m_ClientID = -1;
|
|
p.m_Address = Packet.m_Address;
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
p.m_DataSize = sizeof(m_CountData);
|
|
p.m_pData = &m_CountDataLegacy;
|
|
m_CountDataLegacy.m_High = (m_NumServers >> 8) & 0xff;
|
|
m_CountDataLegacy.m_Low = m_NumServers & 0xff;
|
|
m_NetOp.Send(&p);
|
|
}
|
|
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETLIST) &&
|
|
mem_comp(Packet.m_pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST)) == 0)
|
|
{
|
|
// someone requested the list
|
|
dbg_msg("mastersrv", "requested, responding with %d m_aServers", m_NumServers);
|
|
|
|
CNetChunk p;
|
|
p.m_ClientID = -1;
|
|
p.m_Address = Packet.m_Address;
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
|
|
for(int i = 0; i < m_NumPackets; i++)
|
|
{
|
|
p.m_DataSize = m_aPackets[i].m_Size;
|
|
p.m_pData = &m_aPackets[i].m_Data;
|
|
m_NetOp.Send(&p);
|
|
}
|
|
}
|
|
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETLIST_LEGACY) &&
|
|
mem_comp(Packet.m_pData, SERVERBROWSE_GETLIST_LEGACY, sizeof(SERVERBROWSE_GETLIST_LEGACY)) == 0)
|
|
{
|
|
// someone requested the list
|
|
dbg_msg("mastersrv", "requested, responding with %d m_aServers", m_NumServers);
|
|
|
|
CNetChunk p;
|
|
p.m_ClientID = -1;
|
|
p.m_Address = Packet.m_Address;
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
|
|
for(int i = 0; i < m_NumPacketsLegacy; i++)
|
|
{
|
|
p.m_DataSize = m_aPacketsLegacy[i].m_Size;
|
|
p.m_pData = &m_aPacketsLegacy[i].m_Data;
|
|
m_NetOp.Send(&p);
|
|
}
|
|
}
|
|
}
|
|
|
|
// process m_aPackets
|
|
while(m_NetChecker.Recv(&Packet))
|
|
{
|
|
// check if the server is banned
|
|
if(m_NetBan.IsBanned(&Packet.m_Address, 0, 0))
|
|
continue;
|
|
|
|
if(Packet.m_DataSize == sizeof(SERVERBROWSE_FWRESPONSE) &&
|
|
mem_comp(Packet.m_pData, SERVERBROWSE_FWRESPONSE, sizeof(SERVERBROWSE_FWRESPONSE)) == 0)
|
|
{
|
|
Type = SERVERTYPE_INVALID;
|
|
// remove it from checking
|
|
for(int i = 0; i < m_NumCheckServers; i++)
|
|
{
|
|
if(net_addr_comp(&m_aCheckServers[i].m_Address, &Packet.m_Address) == 0 ||
|
|
net_addr_comp(&m_aCheckServers[i].m_AltAddress, &Packet.m_Address) == 0)
|
|
{
|
|
Type = m_aCheckServers[i].m_Type;
|
|
m_NumCheckServers--;
|
|
m_aCheckServers[i] = m_aCheckServers[m_NumCheckServers];
|
|
break;
|
|
}
|
|
}
|
|
|
|
// drops servers that were not in the CheckServers list
|
|
if(Type == SERVERTYPE_INVALID)
|
|
continue;
|
|
|
|
AddServer(&Packet.m_Address, Type);
|
|
SendOk(&Packet.m_Address);
|
|
}
|
|
}
|
|
|
|
if(time_get() - LastBanReload > time_freq() * 300)
|
|
{
|
|
LastBanReload = time_get();
|
|
|
|
ReloadBans();
|
|
}
|
|
|
|
if(time_get() - LastBuild > time_freq() * 5)
|
|
{
|
|
LastBuild = time_get();
|
|
|
|
PurgeServers();
|
|
UpdateServers();
|
|
BuildPackets();
|
|
}
|
|
|
|
// be nice to the CPU
|
|
thread_sleep(1000);
|
|
}
|
|
|
|
return 0;
|
|
}
|