diff options
author | Rafael Ferreira | 2015-06-20 13:40:59 -0300 |
---|---|---|
committer | Rafael Ferreira | 2015-06-20 13:40:59 -0300 |
commit | 020ba5f1e8f80197fafc31a6dc8f7f70b7562f8d (patch) | |
tree | d8e4ef7c740f264e64b2f68bd9ecd6ef0c710c6a /0001-Enabled-mastersrv-and-versionsrv-as-they-are-require.patch | |
download | aur-teeworlds-hunter.tar.gz |
Initial import
Diffstat (limited to '0001-Enabled-mastersrv-and-versionsrv-as-they-are-require.patch')
-rw-r--r-- | 0001-Enabled-mastersrv-and-versionsrv-as-they-are-require.patch | 835 |
1 files changed, 835 insertions, 0 deletions
diff --git a/0001-Enabled-mastersrv-and-versionsrv-as-they-are-require.patch b/0001-Enabled-mastersrv-and-versionsrv-as-they-are-require.patch new file mode 100644 index 000000000000..36f0f7dea13d --- /dev/null +++ b/0001-Enabled-mastersrv-and-versionsrv-as-they-are-require.patch @@ -0,0 +1,835 @@ +From b560395a680471426dc2e93a68eb3be79bb1b8f9 Mon Sep 17 00:00:00 2001 +From: Rafael Ferreira <rafael.f.f1@gmail.com> +Date: Fri, 22 Aug 2014 06:14:03 -0300 +Subject: [PATCH] Enabled mastersrv and versionsrv as they are required + +--- + .gitignore | 3 +- + src/mastersrv/mastersrv.cpp | 542 ++++++++++++++++++++++++++++++++++++++++++ + src/mastersrv/mastersrv.h | 52 ++++ + src/versionsrv/mapversions.h | 22 ++ + src/versionsrv/versionsrv.cpp | 133 +++++++++++ + src/versionsrv/versionsrv.h | 19 ++ + 6 files changed, 769 insertions(+), 2 deletions(-) + create mode 100644 src/mastersrv/mastersrv.cpp + create mode 100644 src/mastersrv/mastersrv.h + create mode 100644 src/versionsrv/mapversions.h + create mode 100644 src/versionsrv/versionsrv.cpp + create mode 100644 src/versionsrv/versionsrv.h + +diff --git a/.gitignore b/.gitignore +index 4b1a4ad..93efac2 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -16,9 +16,8 @@ dilate* + fake_server* + map_resave* + map_version* +-mastersrv* + packetgen* + teeworlds* + teeworlds_srv* + tileset_border* +-versionsrv* ++ +diff --git a/src/mastersrv/mastersrv.cpp b/src/mastersrv/mastersrv.cpp +new file mode 100644 +index 0000000..954650a +--- /dev/null ++++ b/src/mastersrv/mastersrv.cpp +@@ -0,0 +1,542 @@ ++/* (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/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 m_TryTime; ++}; ++ ++static CCheckServer m_aCheckServers[MAX_SERVERS]; ++static int m_NumCheckServers = 0; ++ ++struct CServerEntry ++{ ++ enum ServerType m_Type; ++ NETADDR m_Address; ++ int64 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 unsigned char s_aIPV4Mapping[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}; ++ ++ mem_copy(m_aPackets[m_NumPackets-1].m_Data.m_aServers[PacketIndex].m_aIp, s_aIPV4Mapping, sizeof(s_aIPV4Mapping)); ++ 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 Now = time_get(); ++ int64 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 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"); ++} ++ ++int main(int argc, const char **argv) // ignore_convention ++{ ++ int64 LastBuild = 0, LastBanReload = 0; ++ ServerType Type = SERVERTYPE_INVALID; ++ NETADDR BindAddr; ++ ++ dbg_logger_stdout(); ++ 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("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); ++ IConfig *pConfig = CreateConfig(); ++ m_pConsole = CreateConsole(CFGFLAG_MASTER); ++ ++ bool RegisterFail = !pKernel->RegisterInterface(pStorage); ++ RegisterFail |= !pKernel->RegisterInterface(m_pConsole); ++ RegisterFail |= !pKernel->RegisterInterface(pConfig); ++ ++ if(RegisterFail) ++ return -1; ++ ++ pConfig->Init(); ++ m_NetBan.Init(m_pConsole, pStorage); ++ if(argc > 1) // ignore_convention ++ m_pConsole->ParseArguments(argc-1, &argv[1]); // ignore_convention ++ ++ 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, 0)) ++ { ++ dbg_msg("mastersrv", "couldn't start network (op)"); ++ return -1; ++ } ++ BindAddr.port = MASTERSERVER_PORT+1; ++ if(!m_NetChecker.Open(BindAddr, 0)) ++ { ++ dbg_msg("mastersrv", "couldn't start network (checker)"); ++ return -1; ++ } ++ ++ // process pending commands ++ m_pConsole->StoreCommands(false); ++ ++ dbg_msg("mastersrv", "started"); ++ ++ while(1) ++ { ++ 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(1); ++ } ++ ++ return 0; ++} +diff --git a/src/mastersrv/mastersrv.h b/src/mastersrv/mastersrv.h +new file mode 100644 +index 0000000..38e5ab2 +--- /dev/null ++++ b/src/mastersrv/mastersrv.h +@@ -0,0 +1,52 @@ ++/* (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. */ ++#ifndef MASTERSRV_MASTERSRV_H ++#define MASTERSRV_MASTERSRV_H ++static const int MASTERSERVER_PORT = 8300; ++ ++enum ServerType ++{ ++ SERVERTYPE_INVALID = -1, ++ SERVERTYPE_NORMAL, ++ SERVERTYPE_LEGACY ++}; ++ ++struct CMastersrvAddr ++{ ++ unsigned char m_aIp[16]; ++ unsigned char m_aPort[2]; ++}; ++ ++static const unsigned char SERVERBROWSE_HEARTBEAT[] = {255, 255, 255, 255, 'b', 'e', 'a', '2'}; ++ ++static const unsigned char SERVERBROWSE_GETLIST[] = {255, 255, 255, 255, 'r', 'e', 'q', '2'}; ++static const unsigned char SERVERBROWSE_LIST[] = {255, 255, 255, 255, 'l', 'i', 's', '2'}; ++ ++static const unsigned char SERVERBROWSE_GETCOUNT[] = {255, 255, 255, 255, 'c', 'o', 'u', '2'}; ++static const unsigned char SERVERBROWSE_COUNT[] = {255, 255, 255, 255, 's', 'i', 'z', '2'}; ++ ++static const unsigned char SERVERBROWSE_GETINFO[] = {255, 255, 255, 255, 'g', 'i', 'e', '3'}; ++static const unsigned char SERVERBROWSE_INFO[] = {255, 255, 255, 255, 'i', 'n', 'f', '3'}; ++ ++static const unsigned char SERVERBROWSE_FWCHECK[] = {255, 255, 255, 255, 'f', 'w', '?', '?'}; ++static const unsigned char SERVERBROWSE_FWRESPONSE[] = {255, 255, 255, 255, 'f', 'w', '!', '!'}; ++static const unsigned char SERVERBROWSE_FWOK[] = {255, 255, 255, 255, 'f', 'w', 'o', 'k'}; ++static const unsigned char SERVERBROWSE_FWERROR[] = {255, 255, 255, 255, 'f', 'w', 'e', 'r'}; ++ ++ ++// packet headers for the 0.5 branch ++ ++struct CMastersrvAddrLegacy ++{ ++ unsigned char m_aIp[4]; ++ unsigned char m_aPort[2]; ++}; ++ ++static const unsigned char SERVERBROWSE_HEARTBEAT_LEGACY[] = {255, 255, 255, 255, 'b', 'e', 'a', 't'}; ++ ++static const unsigned char SERVERBROWSE_GETLIST_LEGACY[] = {255, 255, 255, 255, 'r', 'e', 'q', 't'}; ++static const unsigned char SERVERBROWSE_LIST_LEGACY[] = {255, 255, 255, 255, 'l', 'i', 's', 't'}; ++ ++static const unsigned char SERVERBROWSE_GETCOUNT_LEGACY[] = {255, 255, 255, 255, 'c', 'o', 'u', 'n'}; ++static const unsigned char SERVERBROWSE_COUNT_LEGACY[] = {255, 255, 255, 255, 's', 'i', 'z', 'e'}; ++#endif +diff --git a/src/versionsrv/mapversions.h b/src/versionsrv/mapversions.h +new file mode 100644 +index 0000000..1d62681 +--- /dev/null ++++ b/src/versionsrv/mapversions.h +@@ -0,0 +1,22 @@ ++/* (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. */ ++#ifndef VERSIONSRV_MAPVERSIONS_H ++#define VERSIONSRV_MAPVERSIONS_H ++ ++static CMapVersion s_aMapVersionList[] = { ++ {"ctf1", {0x06, 0xb5, 0xf1, 0x17}, {0x00, 0x00, 0x12, 0x38}}, ++ {"ctf2", {0x27, 0xbc, 0x5e, 0xac}, {0x00, 0x00, 0x64, 0x1a}}, ++ {"ctf3", {0xa3, 0x73, 0x9d, 0x41}, {0x00, 0x00, 0x17, 0x0f}}, ++ {"ctf4", {0xbe, 0x7c, 0x4d, 0xb9}, {0x00, 0x00, 0x2e, 0xfe}}, ++ {"ctf5", {0xd9, 0x21, 0x29, 0xa0}, {0x00, 0x00, 0x2f, 0x4c}}, ++ {"ctf6", {0x28, 0xc8, 0x43, 0x51}, {0x00, 0x00, 0x69, 0x2f}}, ++ {"ctf7", {0x1d, 0x35, 0x98, 0x72}, {0x00, 0x00, 0x15, 0x87}}, ++ {"dm1", {0xf2, 0x15, 0x9e, 0x6e}, {0x00, 0x00, 0x16, 0xad}}, ++ {"dm2", {0x71, 0x83, 0x98, 0x78}, {0x00, 0x00, 0x21, 0xdf}}, ++ {"dm6", {0x47, 0x4d, 0xa2, 0x35}, {0x00, 0x00, 0x1e, 0x95}}, ++ {"dm7", {0x42, 0x6d, 0xa1, 0x67}, {0x00, 0x00, 0x27, 0x2a}}, ++ {"dm8", {0x2f, 0x74, 0xd9, 0x18}, {0x00, 0x00, 0xa1, 0xa1}}, ++ {"dm9", {0x42, 0xd4, 0x77, 0x7e}, {0x00, 0x00, 0x20, 0x11}}, ++}; ++static const int s_NumMapVersionItems = sizeof(s_aMapVersionList)/sizeof(CMapVersion); ++#endif +diff --git a/src/versionsrv/versionsrv.cpp b/src/versionsrv/versionsrv.cpp +new file mode 100644 +index 0000000..9d6e296 +--- /dev/null ++++ b/src/versionsrv/versionsrv.cpp +@@ -0,0 +1,133 @@ ++/* (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 <game/version.h> ++ ++#include "versionsrv.h" ++#include "mapversions.h" ++ ++enum { ++ MAX_MAPS_PER_PACKET=48, ++ MAX_PACKETS=16, ++ MAX_MAPS=MAX_MAPS_PER_PACKET*MAX_PACKETS, ++}; ++ ++struct CPacketData ++{ ++ int m_Size; ++ struct { ++ unsigned char m_aHeader[sizeof(VERSIONSRV_MAPLIST)]; ++ CMapVersion m_aMaplist[MAX_MAPS_PER_PACKET]; ++ } m_Data; ++}; ++ ++CPacketData m_aPackets[MAX_PACKETS]; ++static int m_NumPackets = 0; ++ ++static CNetClient g_NetOp; // main ++ ++void BuildPackets() ++{ ++ CMapVersion *pCurrent = &s_aMapVersionList[0]; ++ int ServersLeft = s_NumMapVersionItems; ++ m_NumPackets = 0; ++ while(ServersLeft && m_NumPackets < MAX_PACKETS) ++ { ++ int Chunk = ServersLeft; ++ if(Chunk > MAX_MAPS_PER_PACKET) ++ Chunk = MAX_MAPS_PER_PACKET; ++ ServersLeft -= Chunk; ++ ++ // copy header ++ mem_copy(m_aPackets[m_NumPackets].m_Data.m_aHeader, VERSIONSRV_MAPLIST, sizeof(VERSIONSRV_MAPLIST)); ++ ++ // copy map versions ++ for(int i = 0; i < Chunk; i++) ++ { ++ m_aPackets[m_NumPackets].m_Data.m_aMaplist[i] = *pCurrent; ++ pCurrent++; ++ } ++ ++ m_aPackets[m_NumPackets].m_Size = sizeof(VERSIONSRV_MAPLIST) + sizeof(CMapVersion)*Chunk; ++ ++ m_NumPackets++; ++ } ++} ++ ++void SendVer(NETADDR *pAddr) ++{ ++ CNetChunk p; ++ unsigned char aData[sizeof(VERSIONSRV_VERSION) + sizeof(GAME_RELEASE_VERSION)]; ++ ++ mem_copy(aData, VERSIONSRV_VERSION, sizeof(VERSIONSRV_VERSION)); ++ mem_copy(aData + sizeof(VERSIONSRV_VERSION), GAME_RELEASE_VERSION, sizeof(GAME_RELEASE_VERSION)); ++ ++ p.m_ClientID = -1; ++ p.m_Address = *pAddr; ++ p.m_Flags = NETSENDFLAG_CONNLESS; ++ p.m_pData = aData; ++ p.m_DataSize = sizeof(aData); ++ ++ g_NetOp.Send(&p); ++} ++ ++int main(int argc, char **argv) // ignore_convention ++{ ++ NETADDR BindAddr; ++ ++ dbg_logger_stdout(); ++ net_init(); ++ ++ mem_zero(&BindAddr, sizeof(BindAddr)); ++ BindAddr.type = NETTYPE_ALL; ++ BindAddr.port = VERSIONSRV_PORT; ++ if(!g_NetOp.Open(BindAddr, 0)) ++ { ++ dbg_msg("mastersrv", "couldn't start network"); ++ return -1; ++ } ++ ++ BuildPackets(); ++ ++ dbg_msg("versionsrv", "started"); ++ ++ while(1) ++ { ++ g_NetOp.Update(); ++ ++ // process packets ++ CNetChunk Packet; ++ while(g_NetOp.Recv(&Packet)) ++ { ++ if(Packet.m_DataSize == sizeof(VERSIONSRV_GETVERSION) && ++ mem_comp(Packet.m_pData, VERSIONSRV_GETVERSION, sizeof(VERSIONSRV_GETVERSION)) == 0) ++ { ++ SendVer(&Packet.m_Address); ++ } ++ ++ if(Packet.m_DataSize == sizeof(VERSIONSRV_GETMAPLIST) && ++ mem_comp(Packet.m_pData, VERSIONSRV_GETMAPLIST, sizeof(VERSIONSRV_GETMAPLIST)) == 0) ++ { ++ 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; ++ g_NetOp.Send(&p); ++ } ++ } ++ } ++ ++ // be nice to the CPU ++ thread_sleep(1); ++ } ++ ++ return 0; ++} +diff --git a/src/versionsrv/versionsrv.h b/src/versionsrv/versionsrv.h +new file mode 100644 +index 0000000..46f6425 +--- /dev/null ++++ b/src/versionsrv/versionsrv.h +@@ -0,0 +1,19 @@ ++/* (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. */ ++#ifndef VERSIONSRV_VERSIONSRV_H ++#define VERSIONSRV_VERSIONSRV_H ++static const int VERSIONSRV_PORT = 8302; ++ ++struct CMapVersion ++{ ++ char m_aName[8]; ++ unsigned char m_aCrc[4]; ++ unsigned char m_aSize[4]; ++}; ++ ++static const unsigned char VERSIONSRV_GETVERSION[] = {255, 255, 255, 255, 'v', 'e', 'r', 'g'}; ++static const unsigned char VERSIONSRV_VERSION[] = {255, 255, 255, 255, 'v', 'e', 'r', 's'}; ++ ++static const unsigned char VERSIONSRV_GETMAPLIST[] = {255, 255, 255, 255, 'v', 'm', 'l', 'g'}; ++static const unsigned char VERSIONSRV_MAPLIST[] = {255, 255, 255, 255, 'v', 'm', 'l', 's'}; ++#endif +-- +2.1.0 + |