mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Added external linkage instead of static const
This commit is contained in:
parent
04f51a55bb
commit
21e64cbdcb
|
@ -1764,7 +1764,10 @@ set(GAME_GENERATED_SHARED
|
|||
src/game/generated/protocol7.h
|
||||
src/game/generated/protocolglue.h
|
||||
)
|
||||
|
||||
set_src(MASTERSRV_SHARED GLOB src/mastersrv
|
||||
mastersrv.cpp
|
||||
mastersrv.h
|
||||
)
|
||||
set(DEPS ${DEP_JSON} ${DEP_MD5} ${ZLIB_DEP})
|
||||
|
||||
# Libraries
|
||||
|
@ -1782,7 +1785,8 @@ set(LIBS
|
|||
# Targets
|
||||
add_library(engine-shared EXCLUDE_FROM_ALL OBJECT ${ENGINE_INTERFACE} ${ENGINE_SHARED} ${ENGINE_UUID_SHARED} ${BASE})
|
||||
add_library(game-shared EXCLUDE_FROM_ALL OBJECT ${GAME_SHARED} ${GAME_GENERATED_SHARED})
|
||||
list(APPEND TARGETS_OWN engine-shared game-shared)
|
||||
add_library(mastersrv-shared EXCLUDE_FROM_ALL OBJECT ${MASTERSRV_SHARED})
|
||||
list(APPEND TARGETS_OWN engine-shared game-shared mastersrv-shared)
|
||||
|
||||
if(DISCORD AND NOT DISCORD_DYNAMIC)
|
||||
add_library(discord-shared SHARED IMPORTED)
|
||||
|
@ -2064,6 +2068,7 @@ if(CLIENT)
|
|||
${DEPS_CLIENT}
|
||||
$<TARGET_OBJECTS:engine-shared>
|
||||
$<TARGET_OBJECTS:game-shared>
|
||||
$<TARGET_OBJECTS:mastersrv-shared>
|
||||
)
|
||||
else()
|
||||
add_executable(${TARGET_CLIENT} WIN32
|
||||
|
@ -2073,6 +2078,7 @@ if(CLIENT)
|
|||
${DEPS_CLIENT}
|
||||
$<TARGET_OBJECTS:engine-shared>
|
||||
$<TARGET_OBJECTS:game-shared>
|
||||
$<TARGET_OBJECTS:mastersrv-shared>
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(${TARGET_CLIENT} ${LIBS_CLIENT})
|
||||
|
@ -2260,6 +2266,7 @@ if(SERVER)
|
|||
${SERVER_ICON}
|
||||
$<TARGET_OBJECTS:engine-shared>
|
||||
$<TARGET_OBJECTS:game-shared>
|
||||
$<TARGET_OBJECTS:mastersrv-shared>
|
||||
)
|
||||
target_link_libraries(${TARGET_SERVER} ${LIBS_SERVER})
|
||||
list(APPEND TARGETS_OWN ${TARGET_SERVER})
|
||||
|
@ -2280,13 +2287,14 @@ endif()
|
|||
########################################################################
|
||||
|
||||
if(TOOLS)
|
||||
set_src(MASTERSRV_SRC GLOB src/mastersrv mastersrv.cpp mastersrv.h)
|
||||
set_src(MASTERSRV_SRC GLOB src/mastersrv main_mastersrv.cpp)
|
||||
set_src(TWPING_SRC GLOB src/twping twping.cpp)
|
||||
|
||||
set(TARGET_MASTERSRV mastersrv)
|
||||
set(TARGET_TWPING twping)
|
||||
|
||||
add_executable(${TARGET_MASTERSRV} EXCLUDE_FROM_ALL ${MASTERSRV_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
|
||||
add_executable(${TARGET_MASTERSRV} EXCLUDE_FROM_ALL ${MASTERSRV_SRC} $<TARGET_OBJECTS:engine-shared> $<TARGET_OBJECTS:mastersrv-shared> ${DEPS})
|
||||
|
||||
add_executable(${TARGET_TWPING} EXCLUDE_FROM_ALL ${TWPING_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
|
||||
|
||||
target_link_libraries(${TARGET_MASTERSRV} ${LIBS})
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "system.h"
|
||||
|
||||
const SHA256_DIGEST SHA256_ZEROED = {{0}};
|
||||
|
||||
static void digest_str(const unsigned char *digest, size_t digest_len, char *str, size_t max_len)
|
||||
{
|
||||
unsigned i;
|
||||
|
|
|
@ -31,8 +31,7 @@ void md5_str(MD5_DIGEST digest, char *str, size_t max_len);
|
|||
int md5_from_str(MD5_DIGEST *out, const char *str);
|
||||
int md5_comp(MD5_DIGEST digest1, MD5_DIGEST digest2);
|
||||
|
||||
static const SHA256_DIGEST SHA256_ZEROED = {{0}};
|
||||
static const MD5_DIGEST MD5_ZEROED = {{0}};
|
||||
extern const SHA256_DIGEST SHA256_ZEROED;
|
||||
|
||||
inline bool operator==(const SHA256_DIGEST &that, const SHA256_DIGEST &other)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -13,16 +13,15 @@ enum
|
|||
MAX_TIMELINE_MARKERS = 64
|
||||
};
|
||||
|
||||
const double g_aSpeeds[] = {0.1, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0, 20.0, 24.0, 28.0, 32.0, 40.0, 48.0, 56.0, 64.0};
|
||||
constexpr int g_DemoSpeeds = 22;
|
||||
extern const double g_aSpeeds[g_DemoSpeeds];
|
||||
|
||||
typedef bool (*DEMOFUNC_FILTER)(const void *pData, int DataSize, void *pUser);
|
||||
|
||||
// TODO: Properly extend demo format using uuids
|
||||
// "6be6da4a-cebd-380c-9b5b-1289c842d780"
|
||||
// "demoitem-sha256@ddnet.tw"
|
||||
static const CUuid SHA256_EXTENSION =
|
||||
{{0x6b, 0xe6, 0xda, 0x4a, 0xce, 0xbd, 0x38, 0x0c,
|
||||
0x9b, 0x5b, 0x12, 0x89, 0xc8, 0x42, 0xd7, 0x80}};
|
||||
extern const CUuid SHA256_EXTENSION;
|
||||
|
||||
struct CDemoHeader
|
||||
{
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#include "network.h"
|
||||
#include "snapshot.h"
|
||||
|
||||
const double g_aSpeeds[g_DemoSpeeds] = {0.1, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0, 20.0, 24.0, 28.0, 32.0, 40.0, 48.0, 56.0, 64.0};
|
||||
const CUuid SHA256_EXTENSION =
|
||||
{{0x6b, 0xe6, 0xda, 0x4a, 0xce, 0xbd, 0x38, 0x0c,
|
||||
0x9b, 0x5b, 0x12, 0x89, 0xc8, 0x42, 0xd7, 0x80}};
|
||||
|
||||
static const unsigned char s_aHeaderMarker[7] = {'T', 'W', 'D', 'E', 'M', 'O', 0};
|
||||
static const unsigned char s_CurVersion = 6;
|
||||
static const unsigned char s_OldVersion = 3;
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "huffman.h"
|
||||
#include "network.h"
|
||||
|
||||
const unsigned char SECURITY_TOKEN_MAGIC[4] = {'T', 'K', 'E', 'N'};
|
||||
|
||||
void CNetRecvUnpacker::Clear()
|
||||
{
|
||||
m_Valid = false;
|
||||
|
|
|
@ -96,7 +96,7 @@ typedef int SECURITY_TOKEN;
|
|||
|
||||
SECURITY_TOKEN ToSecurityToken(unsigned char *pData);
|
||||
|
||||
static const unsigned char SECURITY_TOKEN_MAGIC[] = {'T', 'K', 'E', 'N'};
|
||||
extern const unsigned char SECURITY_TOKEN_MAGIC[4];
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -14,6 +14,16 @@
|
|||
|
||||
#include <game/client/gameclient.h>
|
||||
|
||||
const char *const gs_aModEntitiesNames[] = {
|
||||
"ddnet",
|
||||
"ddrace",
|
||||
"race",
|
||||
"blockworlds",
|
||||
"fng",
|
||||
"vanilla",
|
||||
"f-ddrace",
|
||||
};
|
||||
|
||||
CMapImages::CMapImages() :
|
||||
CMapImages(100)
|
||||
{
|
||||
|
|
|
@ -29,14 +29,7 @@ enum EMapImageModType
|
|||
MAP_IMAGE_MOD_TYPE_COUNT,
|
||||
};
|
||||
|
||||
static const char *const gs_aModEntitiesNames[] = {
|
||||
"ddnet",
|
||||
"ddrace",
|
||||
"race",
|
||||
"blockworlds",
|
||||
"fng",
|
||||
"vanilla",
|
||||
"f-ddrace"};
|
||||
extern const char *const gs_aModEntitiesNames[];
|
||||
|
||||
class CMapImages : public CComponent
|
||||
{
|
||||
|
|
|
@ -2077,9 +2077,9 @@ int CMenus::Render()
|
|||
UI()->DoLabel(&Part, aBuffer, 12.8f, TEXTALIGN_LEFT);
|
||||
|
||||
if(IncDemoSpeed)
|
||||
m_Speed = clamp(m_Speed + 1, 0, (int)(std::size(g_aSpeeds) - 1));
|
||||
m_Speed = clamp(m_Speed + 1, 0, (int)(g_DemoSpeeds - 1));
|
||||
else if(DecDemoSpeed)
|
||||
m_Speed = clamp(m_Speed - 1, 0, (int)(std::size(g_aSpeeds) - 1));
|
||||
m_Speed = clamp(m_Speed - 1, 0, (int)(g_DemoSpeeds - 1));
|
||||
|
||||
Part.VSplitLeft(207.0f, 0, &Part);
|
||||
if(DoButton_CheckBox(&g_Config.m_ClVideoShowhud, Localize("Show ingame HUD"), g_Config.m_ClVideoShowhud, &Part))
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include <game/client/prediction/entity.h>
|
||||
|
||||
const int PickupPhysSize = 14;
|
||||
|
||||
class CPickup : public CEntity
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "character.h"
|
||||
|
||||
static constexpr int PickupPhysSize = 14;
|
||||
|
||||
CPickup::CPickup(CGameWorld *pGameWorld, int Type, int SubType, int Layer, int Number) :
|
||||
CEntity(pGameWorld, CGameWorld::ENTTYPE_PICKUP, vec2(0, 0), PickupPhysSize)
|
||||
{
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include <game/server/entity.h>
|
||||
|
||||
const int PickupPhysSize = 14;
|
||||
|
||||
class CPickup : public CEntity
|
||||
{
|
||||
public:
|
||||
|
|
545
src/mastersrv/main_mastersrv.cpp
Normal file
545
src/mastersrv/main_mastersrv.cpp
Normal file
|
@ -0,0 +1,545 @@
|
|||
/* (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_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);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
|
@ -1,545 +1,34 @@
|
|||
/* (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
|
||||
};
|
||||
const int MASTERSERVER_PORT = 8300;
|
||||
|
||||
struct CCheckServer
|
||||
{
|
||||
enum ServerType m_Type;
|
||||
NETADDR m_Address;
|
||||
NETADDR m_AltAddress;
|
||||
int m_TryCount;
|
||||
int64_t m_TryTime;
|
||||
};
|
||||
const unsigned char SERVERBROWSE_HEARTBEAT[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'b', 'e', 'a', '2'};
|
||||
|
||||
static CCheckServer m_aCheckServers[MAX_SERVERS];
|
||||
static int m_NumCheckServers = 0;
|
||||
const unsigned char SERVERBROWSE_GETLIST[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'r', 'e', 'q', '2'};
|
||||
const unsigned char SERVERBROWSE_LIST[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'l', 'i', 's', '2'};
|
||||
|
||||
struct CServerEntry
|
||||
{
|
||||
enum ServerType m_Type;
|
||||
NETADDR m_Address;
|
||||
int64_t m_Expire;
|
||||
};
|
||||
const unsigned char SERVERBROWSE_GETCOUNT[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'c', 'o', 'u', '2'};
|
||||
const unsigned char SERVERBROWSE_COUNT[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 's', 'i', 'z', '2'};
|
||||
|
||||
static CServerEntry m_aServers[MAX_SERVERS];
|
||||
static int m_NumServers = 0;
|
||||
const unsigned char SERVERBROWSE_GETINFO[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'g', 'i', 'e', '3'};
|
||||
const unsigned char SERVERBROWSE_INFO[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'i', 'n', 'f', '3'};
|
||||
|
||||
struct CPacketData
|
||||
{
|
||||
int m_Size;
|
||||
struct
|
||||
{
|
||||
unsigned char m_aHeader[sizeof(SERVERBROWSE_LIST)];
|
||||
CMastersrvAddr m_aServers[MAX_SERVERS_PER_PACKET];
|
||||
} m_Data;
|
||||
};
|
||||
const unsigned char SERVERBROWSE_GETINFO_64_LEGACY[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'f', 's', 't', 'd'};
|
||||
const unsigned char SERVERBROWSE_INFO_64_LEGACY[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'd', 't', 's', 'f'};
|
||||
|
||||
CPacketData m_aPackets[MAX_PACKETS];
|
||||
static int m_NumPackets = 0;
|
||||
const unsigned char SERVERBROWSE_INFO_EXTENDED[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'i', 'e', 'x', 't'};
|
||||
const unsigned char SERVERBROWSE_INFO_EXTENDED_MORE[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'i', 'e', 'x', '+'};
|
||||
|
||||
// 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;
|
||||
};
|
||||
const unsigned char SERVERBROWSE_FWCHECK[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'f', 'w', '?', '?'};
|
||||
const unsigned char SERVERBROWSE_FWRESPONSE[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'f', 'w', '!', '!'};
|
||||
const unsigned char SERVERBROWSE_FWOK[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'f', 'w', 'o', 'k'};
|
||||
const unsigned char SERVERBROWSE_FWERROR[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'f', 'w', 'e', 'r'};
|
||||
|
||||
CPacketDataLegacy m_aPacketsLegacy[MAX_PACKETS];
|
||||
static int m_NumPacketsLegacy = 0;
|
||||
const unsigned char SERVERBROWSE_HEARTBEAT_LEGACY[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'b', 'e', 'a', 't'};
|
||||
|
||||
struct CCountPacketData
|
||||
{
|
||||
unsigned char m_Header[sizeof(SERVERBROWSE_COUNT)];
|
||||
unsigned char m_High;
|
||||
unsigned char m_Low;
|
||||
};
|
||||
const unsigned char SERVERBROWSE_GETLIST_LEGACY[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'r', 'e', 'q', 't'};
|
||||
const unsigned char SERVERBROWSE_LIST_LEGACY[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'l', 'i', 's', 't'};
|
||||
|
||||
static CCountPacketData m_CountData;
|
||||
static CCountPacketData m_CountDataLegacy;
|
||||
const unsigned char SERVERBROWSE_GETCOUNT_LEGACY[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 'c', 'o', 'u', 'n'};
|
||||
const unsigned char SERVERBROWSE_COUNT_LEGACY[SERVERBROWSE_SIZE] = {255, 255, 255, 255, 's', 'i', 'z', 'e'};
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* 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;
|
||||
extern const int MASTERSERVER_PORT;
|
||||
|
||||
enum ServerType
|
||||
{
|
||||
|
@ -17,27 +17,28 @@ struct CMastersrvAddr
|
|||
unsigned char m_aPort[2];
|
||||
};
|
||||
|
||||
static const unsigned char SERVERBROWSE_HEARTBEAT[] = {255, 255, 255, 255, 'b', 'e', 'a', '2'};
|
||||
#define SERVERBROWSE_SIZE 8
|
||||
extern const unsigned char SERVERBROWSE_HEARTBEAT[SERVERBROWSE_SIZE];
|
||||
|
||||
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'};
|
||||
extern const unsigned char SERVERBROWSE_GETLIST[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_LIST[SERVERBROWSE_SIZE];
|
||||
|
||||
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'};
|
||||
extern const unsigned char SERVERBROWSE_GETCOUNT[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_COUNT[SERVERBROWSE_SIZE];
|
||||
|
||||
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'};
|
||||
extern const unsigned char SERVERBROWSE_GETINFO[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_INFO[SERVERBROWSE_SIZE];
|
||||
|
||||
static const unsigned char SERVERBROWSE_GETINFO_64_LEGACY[] = {255, 255, 255, 255, 'f', 's', 't', 'd'};
|
||||
static const unsigned char SERVERBROWSE_INFO_64_LEGACY[] = {255, 255, 255, 255, 'd', 't', 's', 'f'};
|
||||
extern const unsigned char SERVERBROWSE_GETINFO_64_LEGACY[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_INFO_64_LEGACY[SERVERBROWSE_SIZE];
|
||||
|
||||
static const unsigned char SERVERBROWSE_INFO_EXTENDED[] = {255, 255, 255, 255, 'i', 'e', 'x', 't'};
|
||||
static const unsigned char SERVERBROWSE_INFO_EXTENDED_MORE[] = {255, 255, 255, 255, 'i', 'e', 'x', '+'};
|
||||
extern const unsigned char SERVERBROWSE_INFO_EXTENDED[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_INFO_EXTENDED_MORE[SERVERBROWSE_SIZE];
|
||||
|
||||
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'};
|
||||
extern const unsigned char SERVERBROWSE_FWCHECK[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_FWRESPONSE[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_FWOK[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_FWERROR[SERVERBROWSE_SIZE];
|
||||
|
||||
// packet headers for the 0.5 branch
|
||||
|
||||
|
@ -47,13 +48,13 @@ struct CMastersrvAddrLegacy
|
|||
unsigned char m_aPort[2];
|
||||
};
|
||||
|
||||
static const unsigned char SERVERBROWSE_HEARTBEAT_LEGACY[] = {255, 255, 255, 255, 'b', 'e', 'a', 't'};
|
||||
extern const unsigned char SERVERBROWSE_HEARTBEAT_LEGACY[SERVERBROWSE_SIZE];
|
||||
|
||||
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'};
|
||||
extern const unsigned char SERVERBROWSE_GETLIST_LEGACY[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_LIST_LEGACY[SERVERBROWSE_SIZE];
|
||||
|
||||
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'};
|
||||
extern const unsigned char SERVERBROWSE_GETCOUNT_LEGACY[SERVERBROWSE_SIZE];
|
||||
extern const unsigned char SERVERBROWSE_COUNT_LEGACY[SERVERBROWSE_SIZE];
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue