diff options
Diffstat (limited to 'src/engine/shared/masterserver.cpp')
| -rw-r--r-- | src/engine/shared/masterserver.cpp | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/src/engine/shared/masterserver.cpp b/src/engine/shared/masterserver.cpp new file mode 100644 index 00000000..beade5bf --- /dev/null +++ b/src/engine/shared/masterserver.cpp @@ -0,0 +1,187 @@ +// copyright (c) 2007 magnus auvinen, see licence.txt for more info +#include <stdio.h> + +#include <base/system.h> +#include <engine/masterserver.h> +#include <engine/storage.h> +#include "engine.h" +#include "linereader.h" + +class CMasterServer : public IEngineMasterServer +{ +public: + // master server functions + struct CMasterInfo + { + char m_aHostname[128]; + NETADDR m_Addr; + + CHostLookup m_Lookup; + } ; + + CMasterInfo m_aMasterServers[MAX_MASTERSERVERS]; + int m_NeedsUpdate; + CEngine *m_pEngine; + + CMasterServer() + { + SetDefault(); + m_NeedsUpdate = -1; + m_pEngine = 0; + } + + virtual int RefreshAddresses() + { + int i; + + if(m_NeedsUpdate != -1) + return 0; + + dbg_msg("engine/mastersrv", "refreshing master server addresses"); + + // add lookup jobs + for(i = 0; i < MAX_MASTERSERVERS; i++) + m_pEngine->HostLookup(&m_aMasterServers[i].m_Lookup, m_aMasterServers[i].m_aHostname); + + m_NeedsUpdate = 1; + return 0; + } + + virtual void Update() + { + // check if we need to update + if(m_NeedsUpdate != 1) + return; + m_NeedsUpdate = 0; + + for(int i = 0; i < MAX_MASTERSERVERS; i++) + { + if(m_aMasterServers[i].m_Lookup.m_Job.Status() != CJob::STATE_DONE) + m_NeedsUpdate = 1; + else + { + m_aMasterServers[i].m_Addr = m_aMasterServers[i].m_Lookup.m_Addr; + m_aMasterServers[i].m_Addr.port = 8300; + } + } + + if(!m_NeedsUpdate) + { + dbg_msg("engine/mastersrv", "saving addresses"); + Save(); + } + } + + virtual int IsRefreshing() + { + return m_NeedsUpdate; + } + + virtual NETADDR GetAddr(int Index) + { + return m_aMasterServers[Index].m_Addr; + } + + virtual const char *GetName(int Index) + { + return m_aMasterServers[Index].m_aHostname; + } + + virtual void DumpServers() + { + for(int i = 0; i < MAX_MASTERSERVERS; i++) + { + dbg_msg("mastersrv", "#%d = %d.%d.%d.%d", i, + m_aMasterServers[i].m_Addr.ip[0], m_aMasterServers[i].m_Addr.ip[1], + m_aMasterServers[i].m_Addr.ip[2], m_aMasterServers[i].m_Addr.ip[3]); + } + } + + virtual void Init(class CEngine *pEngine) + { + m_pEngine = pEngine; + } + + 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() + { + CLineReader LineReader; + IOHANDLE File; + int Count = 0; + IStorage *pStorage = Kernel()->RequestInterface<IStorage>(); + if(!pStorage) + return -1; + + // try to open file + File = pStorage->OpenFile("masters.cfg", IOFLAG_READ); + if(!File) + return -1; + + LineReader.Init(File); + while(1) + { + CMasterInfo Info = {{0}}; + int aIp[4]; + const char *pLine = LineReader.Get(); + if(!pLine) + break; + + // parse line + if(sscanf(pLine, "%s %d.%d.%d.%d", Info.m_aHostname, &aIp[0], &aIp[1], &aIp[2], &aIp[3]) == 5) + { + Info.m_Addr.ip[0] = (unsigned char)aIp[0]; + Info.m_Addr.ip[1] = (unsigned char)aIp[1]; + Info.m_Addr.ip[2] = (unsigned char)aIp[2]; + Info.m_Addr.ip[3] = (unsigned char)aIp[3]; + Info.m_Addr.port = 8300; + if(Count != MAX_MASTERSERVERS) + { + m_aMasterServers[Count] = Info; + Count++; + } + //else + // dbg_msg("engine/mastersrv", "warning: skipped master server '%s' due to limit of %d", pLine, MAX_MASTERSERVERS); + } + //else + // dbg_msg("engine/mastersrv", "warning: couldn't parse master server '%s'", pLine); + } + + io_close(File); + return 0; + } + + virtual int Save() + { + IOHANDLE File; + + IStorage *pStorage = Kernel()->RequestInterface<IStorage>(); + if(!pStorage) + return -1; + + // try to open file + File = pStorage->OpenFile("masters.cfg", IOFLAG_WRITE); + if(!File) + return -1; + + for(int i = 0; i < MAX_MASTERSERVERS; i++) + { + char aBuf[1024]; + str_format(aBuf, sizeof(aBuf), "%s %d.%d.%d.%d\n", m_aMasterServers[i].m_aHostname, + m_aMasterServers[i].m_Addr.ip[0], m_aMasterServers[i].m_Addr.ip[1], + m_aMasterServers[i].m_Addr.ip[2], m_aMasterServers[i].m_Addr.ip[3]); + + io_write(File, aBuf, str_length(aBuf)); + } + + io_close(File); + return 0; + } +}; + +IEngineMasterServer *CreateEngineMasterServer() { return new CMasterServer; } |