2010-11-20 10:37:14 +00:00
|
|
|
/* (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. */
|
2010-08-15 13:34:55 +00:00
|
|
|
#include <base/system.h>
|
|
|
|
|
|
|
|
#include <engine/shared/network.h>
|
|
|
|
|
2012-01-09 01:02:02 +00:00
|
|
|
#include <game/version.h>
|
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
#include "versionsrv.h"
|
2013-02-24 17:55:55 +00:00
|
|
|
#include "mapversions.h"
|
2010-08-15 13:34:55 +00:00
|
|
|
|
2014-09-20 09:36:46 +00:00
|
|
|
#include <zlib.h>
|
|
|
|
|
2011-03-31 13:13:49 +00:00
|
|
|
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;
|
2014-06-05 10:11:41 +00:00
|
|
|
unsigned char m_aNews[NEWS_SIZE];
|
2014-09-20 09:36:46 +00:00
|
|
|
|
2014-09-19 22:36:22 +00:00
|
|
|
unsigned char m_aServerList[DDNETLIST_SIZE];
|
2014-09-20 09:36:46 +00:00
|
|
|
int m_ServerListPlainLength = 0;
|
|
|
|
int m_ServerListCompLength = 0;
|
|
|
|
bool m_ServerListLoaded = false;
|
2011-03-31 13:13:49 +00:00
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
static CNetClient g_NetOp; // main
|
|
|
|
|
2011-03-31 13:13:49 +00:00
|
|
|
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;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
|
|
// copy header
|
2011-03-31 13:13:49 +00:00
|
|
|
mem_copy(m_aPackets[m_NumPackets].m_Data.m_aHeader, VERSIONSRV_MAPLIST, sizeof(VERSIONSRV_MAPLIST));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-03-31 13:13:49 +00:00
|
|
|
// copy map versions
|
|
|
|
for(int i = 0; i < Chunk; i++)
|
|
|
|
{
|
|
|
|
m_aPackets[m_NumPackets].m_Data.m_aMaplist[i] = *pCurrent;
|
|
|
|
pCurrent++;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-03-31 13:13:49 +00:00
|
|
|
m_aPackets[m_NumPackets].m_Size = sizeof(VERSIONSRV_MAPLIST) + sizeof(CMapVersion)*Chunk;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-03-31 13:13:49 +00:00
|
|
|
m_NumPackets++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-05 10:11:41 +00:00
|
|
|
void ReadNews()
|
|
|
|
{
|
|
|
|
IOHANDLE newsFile = io_open("news", IOFLAG_READ);
|
|
|
|
if (!newsFile)
|
|
|
|
return;
|
|
|
|
|
|
|
|
io_read(newsFile, m_aNews, NEWS_SIZE);
|
|
|
|
|
|
|
|
io_close(newsFile);
|
|
|
|
}
|
|
|
|
|
2014-09-19 22:36:22 +00:00
|
|
|
void ReadServerList()
|
|
|
|
{
|
2014-09-20 09:36:46 +00:00
|
|
|
mem_zero(m_aServerList, sizeof(m_aServerList));
|
|
|
|
|
2014-09-19 22:36:22 +00:00
|
|
|
IOHANDLE File = io_open("serverlist.json", IOFLAG_READ);
|
|
|
|
if (!File)
|
|
|
|
return;
|
|
|
|
|
2014-09-20 09:36:46 +00:00
|
|
|
int PlainLength = io_length(File);
|
2014-09-20 12:20:43 +00:00
|
|
|
char aPlain[16384];
|
2014-09-19 22:36:22 +00:00
|
|
|
|
2014-09-20 12:20:43 +00:00
|
|
|
io_read(File, aPlain, sizeof(aPlain));
|
2014-09-19 22:36:22 +00:00
|
|
|
io_close(File);
|
2014-09-20 09:36:46 +00:00
|
|
|
|
|
|
|
// compress
|
|
|
|
uLongf DstLen = DDNETLIST_SIZE;
|
|
|
|
|
|
|
|
if (compress((Bytef*)m_aServerList, &DstLen, (Bytef*)aPlain, PlainLength) == Z_OK)
|
|
|
|
{
|
|
|
|
m_ServerListLoaded = true;
|
|
|
|
m_ServerListPlainLength = PlainLength;
|
|
|
|
m_ServerListCompLength = DstLen;
|
|
|
|
}
|
2014-09-19 22:36:22 +00:00
|
|
|
}
|
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
void SendVer(NETADDR *pAddr)
|
|
|
|
{
|
|
|
|
CNetChunk p;
|
2012-01-09 01:02:02 +00:00
|
|
|
unsigned char aData[sizeof(VERSIONSRV_VERSION) + sizeof(GAME_RELEASE_VERSION)];
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
mem_copy(aData, VERSIONSRV_VERSION, sizeof(VERSIONSRV_VERSION));
|
2012-01-09 01:02:02 +00:00
|
|
|
mem_copy(aData + sizeof(VERSIONSRV_VERSION), GAME_RELEASE_VERSION, sizeof(GAME_RELEASE_VERSION));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-06-05 10:11:41 +00:00
|
|
|
void SendNews(NETADDR *pAddr)
|
|
|
|
{
|
|
|
|
CNetChunk p;
|
|
|
|
unsigned char aData[NEWS_SIZE + sizeof(VERSIONSRV_NEWS)];
|
|
|
|
|
|
|
|
mem_copy(aData, VERSIONSRV_NEWS, sizeof(VERSIONSRV_NEWS));
|
|
|
|
mem_copy(aData + sizeof(VERSIONSRV_NEWS), m_aNews, NEWS_SIZE);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-09-20 09:36:46 +00:00
|
|
|
// Packet: VERSIONSRV_DDNETLIST + char[4] Token + int16 comp_length + int16 plain_length + char[comp_length]
|
2014-09-19 22:36:22 +00:00
|
|
|
void SendServerList(NETADDR *pAddr, const char *Token)
|
|
|
|
{
|
|
|
|
CNetChunk p;
|
2014-09-20 13:25:31 +00:00
|
|
|
unsigned char aData[16384];
|
2014-09-20 09:36:46 +00:00
|
|
|
short WordCompLength = m_ServerListCompLength;
|
|
|
|
short WordPlainLength = m_ServerListPlainLength;
|
2014-09-19 22:36:22 +00:00
|
|
|
|
|
|
|
mem_copy(aData, VERSIONSRV_DDNETLIST, sizeof(VERSIONSRV_DDNETLIST));
|
2014-09-20 09:36:46 +00:00
|
|
|
mem_copy(aData + sizeof(VERSIONSRV_DDNETLIST), Token, 4); // send back token
|
|
|
|
mem_copy(aData + sizeof(VERSIONSRV_DDNETLIST)+4, &WordCompLength, 2); // compressed length
|
|
|
|
mem_copy(aData + sizeof(VERSIONSRV_DDNETLIST)+6, &WordPlainLength, 2); // plain length
|
2014-09-20 13:25:31 +00:00
|
|
|
mem_copy(aData + sizeof(VERSIONSRV_DDNETLIST)+8, m_aServerList, m_ServerListCompLength);
|
2014-09-19 22:36:22 +00:00
|
|
|
|
|
|
|
p.m_ClientID = -1;
|
|
|
|
p.m_Address = *pAddr;
|
|
|
|
p.m_Flags = NETSENDFLAG_CONNLESS;
|
|
|
|
p.m_pData = aData;
|
2014-09-20 13:25:31 +00:00
|
|
|
p.m_DataSize = sizeof(VERSIONSRV_DDNETLIST) + 4 + 2 + 2 + m_ServerListCompLength;
|
2014-09-19 22:36:22 +00:00
|
|
|
|
|
|
|
g_NetOp.Send(&p);
|
|
|
|
}
|
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
int main(int argc, char **argv) // ignore_convention
|
|
|
|
{
|
|
|
|
NETADDR BindAddr;
|
|
|
|
|
|
|
|
dbg_logger_stdout();
|
|
|
|
net_init();
|
|
|
|
|
|
|
|
mem_zero(&BindAddr, sizeof(BindAddr));
|
2011-03-31 13:13:49 +00:00
|
|
|
BindAddr.type = NETTYPE_ALL;
|
2010-08-15 13:34:55 +00:00
|
|
|
BindAddr.port = VERSIONSRV_PORT;
|
2011-03-31 13:13:49 +00:00
|
|
|
if(!g_NetOp.Open(BindAddr, 0))
|
|
|
|
{
|
|
|
|
dbg_msg("mastersrv", "couldn't start network");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildPackets();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2014-06-05 10:11:41 +00:00
|
|
|
ReadNews();
|
2014-09-19 22:36:22 +00:00
|
|
|
ReadServerList();
|
2014-06-05 10:11:41 +00:00
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
dbg_msg("versionsrv", "started");
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
g_NetOp.Update();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
// 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);
|
2014-01-27 04:33:36 +00:00
|
|
|
|
|
|
|
char aAddrStr[NETADDR_MAXSTRSIZE];
|
|
|
|
net_addr_str(&Packet.m_Address, aAddrStr, sizeof(aAddrStr), false);
|
|
|
|
char aBuf[128];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "version request by %s", aAddrStr);
|
|
|
|
dbg_msg("versionsrv", aBuf);
|
2010-08-15 13:34:55 +00:00
|
|
|
}
|
2011-03-31 13:13:49 +00:00
|
|
|
|
2014-06-05 10:11:41 +00:00
|
|
|
if(Packet.m_DataSize == sizeof(VERSIONSRV_GETNEWS) &&
|
|
|
|
mem_comp(Packet.m_pData, VERSIONSRV_GETNEWS, sizeof(VERSIONSRV_GETNEWS)) == 0)
|
|
|
|
{
|
|
|
|
SendNews(&Packet.m_Address);
|
|
|
|
}
|
|
|
|
|
2011-03-31 13:13:49 +00:00
|
|
|
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;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-03-31 13:13:49 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2014-09-19 22:36:22 +00:00
|
|
|
|
2014-09-20 09:36:46 +00:00
|
|
|
if(m_ServerListLoaded &&
|
|
|
|
Packet.m_DataSize == sizeof(VERSIONSRV_GETDDNETLIST) + 4 &&
|
2014-09-19 22:36:22 +00:00
|
|
|
mem_comp(Packet.m_pData, VERSIONSRV_GETDDNETLIST, sizeof(VERSIONSRV_GETDDNETLIST)) == 0)
|
|
|
|
{
|
|
|
|
char aToken[4];
|
|
|
|
mem_copy(aToken, (char*)Packet.m_pData+sizeof(VERSIONSRV_GETDDNETLIST), 4);
|
|
|
|
|
|
|
|
SendServerList(&Packet.m_Address, aToken);
|
|
|
|
}
|
2010-08-15 13:34:55 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2014-01-14 23:02:19 +00:00
|
|
|
// wait for input
|
2014-11-11 12:00:02 +00:00
|
|
|
net_socket_read_wait(g_NetOp.m_Socket, 1000000);
|
2010-08-15 13:34:55 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-15 13:34:55 +00:00
|
|
|
return 0;
|
|
|
|
}
|