ddnet/src/engine/shared/masterserver.cpp

229 lines
5.1 KiB
C++
Raw Normal View History

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. */
#include <stdio.h> // sscanf
2010-05-29 07:25:38 +00:00
#include <base/system.h>
2011-02-27 14:03:57 +00:00
#include <engine/engine.h>
2010-05-29 07:25:38 +00:00
#include <engine/masterserver.h>
#include <engine/storage.h>
2011-02-27 14:03:57 +00:00
2010-05-29 07:25:38 +00:00
#include "linereader.h"
class CMasterServer : public IEngineMasterServer
{
public:
// master server functions
struct CMasterInfo
{
char m_aHostname[128];
NETADDR m_Addr;
bool m_Valid;
int m_Count;
2010-05-29 07:25:38 +00:00
CHostLookup m_Lookup;
2011-07-11 10:00:13 +00:00
};
enum
{
STATE_INIT,
STATE_UPDATE,
STATE_READY,
};
2010-05-29 07:25:38 +00:00
CMasterInfo m_aMasterServers[MAX_MASTERSERVERS];
2011-07-11 10:00:13 +00:00
int m_State;
2011-02-27 14:03:57 +00:00
IEngine *m_pEngine;
IStorage *m_pStorage;
2010-05-29 07:25:38 +00:00
CMasterServer()
{
SetDefault();
2011-07-11 10:00:13 +00:00
m_State = STATE_INIT;
2010-05-29 07:25:38 +00:00
m_pEngine = 0;
2011-07-11 10:00:13 +00:00
m_pStorage = 0;
2010-05-29 07:25:38 +00:00
}
virtual int RefreshAddresses(int Nettype)
2010-05-29 07:25:38 +00:00
{
if(m_State != STATE_INIT && m_State != STATE_READY)
2011-07-11 10:00:13 +00:00
return -1;
2010-05-29 07:25:38 +00:00
dbg_msg("engine/mastersrv", "refreshing master server addresses");
// add lookup jobs
2011-07-11 10:00:13 +00:00
for(int i = 0; i < MAX_MASTERSERVERS; i++)
{
m_pEngine->HostLookup(&m_aMasterServers[i].m_Lookup, m_aMasterServers[i].m_aHostname, Nettype);
m_aMasterServers[i].m_Valid = false;
2014-01-03 15:14:41 +00:00
m_aMasterServers[i].m_Count = 0;
//dbg_msg("MasterServer", "Lookup id: %d, name: %s, nettype: %d", i, m_aMasterServers[i].m_aHostname, Nettype);
}
2011-07-11 10:00:13 +00:00
m_State = STATE_UPDATE;
2010-05-29 07:25:38 +00:00
return 0;
}
virtual void Update()
{
// check if we need to update
2011-07-11 10:00:13 +00:00
if(m_State != STATE_UPDATE)
2010-05-29 07:25:38 +00:00
return;
2011-07-11 10:00:13 +00:00
m_State = STATE_READY;
2010-05-29 07:25:38 +00:00
for(int i = 0; i < MAX_MASTERSERVERS; i++)
{
if(m_aMasterServers[i].m_Lookup.m_Job.Status() != CJob::STATE_DONE)
2011-07-11 10:00:13 +00:00
m_State = STATE_UPDATE;
2010-05-29 07:25:38 +00:00
else
{
if(m_aMasterServers[i].m_Lookup.m_Job.Result() == 0)
{
m_aMasterServers[i].m_Addr = m_aMasterServers[i].m_Lookup.m_Addr;
m_aMasterServers[i].m_Addr.port = 8300;
m_aMasterServers[i].m_Valid = true;
2014-01-03 15:14:41 +00:00
//dbg_msg("MasterServer", "Set server %d, name: %s with addr-port: %d addr-ip %s addr-type %d", i, m_aMasterServers[i].m_aHostname, m_aMasterServers[i].m_Addr.port, m_aMasterServers[i].m_Addr.ip, m_aMasterServers[i].m_Addr.type);
}
else
2014-01-03 15:14:41 +00:00
{
m_aMasterServers[i].m_Valid = false;
2014-01-03 15:14:41 +00:00
// dbg_msg("MasterServer", "Dropped %d, name: %s with addr-port: %d addr-ip %s addr-type %d", i, m_aMasterServers[i].m_aHostname);
}
2010-05-29 07:25:38 +00:00
}
}
2011-07-11 10:00:13 +00:00
if(m_State == STATE_READY)
2010-05-29 07:25:38 +00:00
{
dbg_msg("engine/mastersrv", "saving addresses");
Save();
}
}
virtual int IsRefreshing()
{
2011-07-11 10:00:13 +00:00
return m_State != STATE_READY;
2010-05-29 07:25:38 +00:00
}
virtual NETADDR GetAddr(int Index)
2010-05-29 07:25:38 +00:00
{
return m_aMasterServers[Index].m_Addr;
}
virtual void SetCount(int Index, int Count)
{
m_aMasterServers[Index].m_Count = Count;
}
virtual int GetCount(int Index)
{
return m_aMasterServers[Index].m_Count;
}
virtual const char *GetName(int Index)
2010-05-29 07:25:38 +00:00
{
return m_aMasterServers[Index].m_aHostname;
}
virtual bool IsValid(int Index)
{
return m_aMasterServers[Index].m_Valid;
}
2011-02-27 14:03:57 +00:00
virtual void Init()
2010-05-29 07:25:38 +00:00
{
2011-02-27 14:03:57 +00:00
m_pEngine = Kernel()->RequestInterface<IEngine>();
m_pStorage = Kernel()->RequestInterface<IStorage>();
2010-05-29 07:25:38 +00:00
}
virtual void SetDefault()
{
mem_zero(m_aMasterServers, sizeof(m_aMasterServers));
for(int i = 0; i < MAX_MASTERSERVERS; i++)
str_format(m_aMasterServers[i].m_aHostname, sizeof(m_aMasterServers[i].m_aHostname), "master%d.teeworlds.com", i+1);
}
virtual int Load()
{
2011-02-27 14:03:57 +00:00
if(!m_pStorage)
2010-05-29 07:25:38 +00:00
return -1;
2010-05-29 07:25:38 +00:00
// try to open file
2011-07-11 10:00:13 +00:00
IOHANDLE File = m_pStorage->OpenFile("masters.cfg", IOFLAG_READ, IStorage::TYPE_SAVE);
2010-05-29 07:25:38 +00:00
if(!File)
return -1;
2011-07-11 10:00:13 +00:00
CLineReader LineReader;
2010-05-29 07:25:38 +00:00
LineReader.Init(File);
while(1)
{
CMasterInfo Info = {{0}};
const char *pLine = LineReader.Get();
if(!pLine)
break;
// parse line
char aAddrStr[NETADDR_MAXSTRSIZE];
2011-07-11 10:00:13 +00:00
if(sscanf(pLine, "%127s %47s", Info.m_aHostname, aAddrStr) == 2 && net_addr_from_str(&Info.m_Addr, aAddrStr) == 0)
2010-05-29 07:25:38 +00:00
{
Info.m_Addr.port = 8300;
2011-07-11 10:00:13 +00:00
bool Added = false;
for(int i = 0; i < MAX_MASTERSERVERS; ++i)
if(str_comp(m_aMasterServers[i].m_aHostname, Info.m_aHostname) == 0)
{
m_aMasterServers[i] = Info;
Added = true;
break;
}
2011-08-11 08:59:14 +00:00
2011-07-11 10:00:13 +00:00
if(!Added)
2010-05-29 07:25:38 +00:00
{
2011-07-11 10:00:13 +00:00
for(int i = 0; i < MAX_MASTERSERVERS; ++i)
if(m_aMasterServers[i].m_Addr.type == NETTYPE_INVALID)
{
m_aMasterServers[i] = Info;
Added = true;
break;
}
2010-05-29 07:25:38 +00:00
}
2011-07-11 10:00:13 +00:00
if(!Added)
break;
2010-05-29 07:25:38 +00:00
}
}
2010-05-29 07:25:38 +00:00
io_close(File);
return 0;
}
virtual int Save()
{
2011-02-27 14:03:57 +00:00
if(!m_pStorage)
2010-05-29 07:25:38 +00:00
return -1;
2010-05-29 07:25:38 +00:00
// try to open file
2011-07-11 10:00:13 +00:00
IOHANDLE File = m_pStorage->OpenFile("masters.cfg", IOFLAG_WRITE, IStorage::TYPE_SAVE);
2010-05-29 07:25:38 +00:00
if(!File)
return -1;
for(int i = 0; i < MAX_MASTERSERVERS; i++)
{
char aAddrStr[NETADDR_MAXSTRSIZE];
2011-07-11 10:00:13 +00:00
if(m_aMasterServers[i].m_Addr.type != NETTYPE_INVALID)
2011-12-29 22:36:53 +00:00
net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr), true);
2011-07-11 10:00:13 +00:00
else
aAddrStr[0] = 0;
char aBuf[256];
2011-12-29 22:36:53 +00:00
str_format(aBuf, sizeof(aBuf), "%s %s", m_aMasterServers[i].m_aHostname, aAddrStr);
2010-05-29 07:25:38 +00:00
io_write(File, aBuf, str_length(aBuf));
2011-12-29 22:36:53 +00:00
io_write_newline(File);
2010-05-29 07:25:38 +00:00
}
2010-05-29 07:25:38 +00:00
io_close(File);
return 0;
}
};
IEngineMasterServer *CreateEngineMasterServer() { return new CMasterServer; }