mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 22:48:18 +00:00
cache the master server list in a file and load it in case the masters are unavailable. #1154
This commit is contained in:
parent
edeb34153a
commit
a47f9faaf0
|
@ -2067,6 +2067,8 @@ void CClient::Run()
|
||||||
m_pGraphics->Shutdown();
|
m_pGraphics->Shutdown();
|
||||||
m_pSound->Shutdown();
|
m_pSound->Shutdown();
|
||||||
|
|
||||||
|
m_ServerBrowser.SaveServerlist();
|
||||||
|
|
||||||
// shutdown SDL
|
// shutdown SDL
|
||||||
{
|
{
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <base/math.h>
|
#include <base/math.h>
|
||||||
#include <base/system.h>
|
#include <base/system.h>
|
||||||
|
|
||||||
|
#include <engine/external/json-parser/json.h>
|
||||||
|
|
||||||
#include <engine/shared/config.h>
|
#include <engine/shared/config.h>
|
||||||
#include <engine/shared/memheap.h>
|
#include <engine/shared/memheap.h>
|
||||||
#include <engine/shared/network.h>
|
#include <engine/shared/network.h>
|
||||||
|
@ -13,12 +15,15 @@
|
||||||
#include <engine/engine.h>
|
#include <engine/engine.h>
|
||||||
#include <engine/friends.h>
|
#include <engine/friends.h>
|
||||||
#include <engine/masterserver.h>
|
#include <engine/masterserver.h>
|
||||||
|
#include <engine/storage.h>
|
||||||
|
|
||||||
#include <mastersrv/mastersrv.h>
|
#include <mastersrv/mastersrv.h>
|
||||||
|
|
||||||
#include "serverbrowser.h"
|
#include "serverbrowser.h"
|
||||||
|
|
||||||
|
|
||||||
|
static char *s_pFilename = "serverlist.json";
|
||||||
|
|
||||||
inline int AddrHash(const NETADDR *pAddr)
|
inline int AddrHash(const NETADDR *pAddr)
|
||||||
{
|
{
|
||||||
if(pAddr->type==NETTYPE_IPV4)
|
if(pAddr->type==NETTYPE_IPV4)
|
||||||
|
@ -66,11 +71,13 @@ CServerBrowser::CServerBrowser()
|
||||||
|
|
||||||
m_ActServerlistType = 0;
|
m_ActServerlistType = 0;
|
||||||
m_BroadcastTime = 0;
|
m_BroadcastTime = 0;
|
||||||
|
m_MasterRefreshTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerBrowser::Init(class CNetClient *pNetClient, const char *pNetVersion)
|
void CServerBrowser::Init(class CNetClient *pNetClient, const char *pNetVersion)
|
||||||
{
|
{
|
||||||
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
||||||
|
m_pStorage = Kernel()->RequestInterface<IStorage>();
|
||||||
m_pMasterServer = Kernel()->RequestInterface<IMasterServer>();
|
m_pMasterServer = Kernel()->RequestInterface<IMasterServer>();
|
||||||
m_pNetClient = pNetClient;
|
m_pNetClient = pNetClient;
|
||||||
|
|
||||||
|
@ -88,6 +95,8 @@ void CServerBrowser::Set(const NETADDR &Addr, int SetType, int Token, const CSer
|
||||||
if(!(m_RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET))
|
if(!(m_RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_MasterRefreshTime = 0;
|
||||||
|
|
||||||
if(!Find(IServerBrowser::TYPE_INTERNET, Addr))
|
if(!Find(IServerBrowser::TYPE_INTERNET, Addr))
|
||||||
{
|
{
|
||||||
pEntry = Add(IServerBrowser::TYPE_INTERNET, Addr);
|
pEntry = Add(IServerBrowser::TYPE_INTERNET, Addr);
|
||||||
|
@ -173,10 +182,22 @@ void CServerBrowser::Update(bool ForceResort)
|
||||||
m_pNetClient->Send(&Packet);
|
m_pNetClient->Send(&Packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_MasterRefreshTime = Now;
|
||||||
|
|
||||||
if(g_Config.m_Debug)
|
if(g_Config.m_Debug)
|
||||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "requesting server list");
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "requesting server list");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load server list backup from file in case the masters don't response
|
||||||
|
if(m_MasterRefreshTime && m_MasterRefreshTime+2*Timeout < Now)
|
||||||
|
{
|
||||||
|
LoadServerlist();
|
||||||
|
m_MasterRefreshTime = 0;
|
||||||
|
|
||||||
|
if(g_Config.m_Debug)
|
||||||
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "using backup server list");
|
||||||
|
}
|
||||||
|
|
||||||
// do timeouts
|
// do timeouts
|
||||||
pEntry = m_pFirstReqServer;
|
pEntry = m_pFirstReqServer;
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -527,3 +548,69 @@ void CServerBrowser::SetInfo(int ServerlistType, CServerEntry *pEntry, const CSe
|
||||||
|
|
||||||
pEntry->m_InfoState = CServerEntry::STATE_READY;
|
pEntry->m_InfoState = CServerEntry::STATE_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CServerBrowser::LoadServerlist()
|
||||||
|
{
|
||||||
|
// read file data into buffer
|
||||||
|
IOHANDLE File = Storage()->OpenFile(s_pFilename, IOFLAG_READ, IStorage::TYPE_ALL);
|
||||||
|
if(!File)
|
||||||
|
return;
|
||||||
|
int FileSize = (int)io_length(File);
|
||||||
|
char *pFileData = (char *)mem_alloc(FileSize, 1);
|
||||||
|
io_read(File, pFileData, FileSize);
|
||||||
|
io_close(File);
|
||||||
|
|
||||||
|
// parse json data
|
||||||
|
json_settings JsonSettings;
|
||||||
|
mem_zero(&JsonSettings, sizeof(JsonSettings));
|
||||||
|
char aError[256];
|
||||||
|
json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, FileSize, aError);
|
||||||
|
mem_free(pFileData);
|
||||||
|
|
||||||
|
if(pJsonData == 0)
|
||||||
|
{
|
||||||
|
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, s_pFilename, aError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract server list
|
||||||
|
const json_value &rEntry = (*pJsonData)["serverlist"];
|
||||||
|
for(unsigned i = 0; i < rEntry.u.array.length; ++i)
|
||||||
|
{
|
||||||
|
if(rEntry[i].type == json_string)
|
||||||
|
{
|
||||||
|
NETADDR Addr = { 0 };
|
||||||
|
if(!net_addr_from_str(&Addr, rEntry[i]))
|
||||||
|
Set(Addr, SET_MASTER_ADD, -1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
json_value_free(pJsonData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CServerBrowser::SaveServerlist()
|
||||||
|
{
|
||||||
|
IOHANDLE File = Storage()->OpenFile(s_pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||||
|
if(!File)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char aBuf[512];
|
||||||
|
|
||||||
|
// server list
|
||||||
|
const char *p = "{\"serverlist\": [\n";
|
||||||
|
io_write(File, p, str_length(p));
|
||||||
|
|
||||||
|
for(int i = 0; i < m_aServerlist[IServerBrowser::TYPE_INTERNET].m_NumServers; ++i)
|
||||||
|
{
|
||||||
|
// entry
|
||||||
|
str_format(aBuf, sizeof(aBuf), "\t\"%s\",\n", m_aServerlist[IServerBrowser::TYPE_INTERNET].m_ppServerlist[i]->m_Info.m_aAddress);
|
||||||
|
io_write(File, aBuf, str_length(aBuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
// server list end
|
||||||
|
p = "\t]\n}\n";
|
||||||
|
io_write(File, p, str_length(p));
|
||||||
|
|
||||||
|
io_close(File);
|
||||||
|
}
|
||||||
|
|
|
@ -50,14 +50,21 @@ public:
|
||||||
|
|
||||||
static void CBFTrackPacket(int TrackID, void *pUser);
|
static void CBFTrackPacket(int TrackID, void *pUser);
|
||||||
|
|
||||||
|
void LoadServerlist();
|
||||||
|
void SaveServerlist();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CNetClient *m_pNetClient;
|
class CNetClient *m_pNetClient;
|
||||||
class IConsole *m_pConsole;
|
class IConsole *m_pConsole;
|
||||||
|
class IStorage *m_pStorage;
|
||||||
class IMasterServer *m_pMasterServer;
|
class IMasterServer *m_pMasterServer;
|
||||||
|
|
||||||
class CServerBrowserFavorites m_ServerBrowserFavorites;
|
class CServerBrowserFavorites m_ServerBrowserFavorites;
|
||||||
class CServerBrowserFilter m_ServerBrowserFilter;
|
class CServerBrowserFilter m_ServerBrowserFilter;
|
||||||
|
|
||||||
|
class IConsole *Console() const { return m_pConsole; }
|
||||||
|
class IStorage *Storage() const { return m_pStorage; }
|
||||||
|
|
||||||
// serverlist
|
// serverlist
|
||||||
int m_ActServerlistType;
|
int m_ActServerlistType;
|
||||||
class CServerlist
|
class CServerlist
|
||||||
|
@ -86,6 +93,7 @@ private:
|
||||||
|
|
||||||
int m_RefreshFlags;
|
int m_RefreshFlags;
|
||||||
int64 m_BroadcastTime;
|
int64 m_BroadcastTime;
|
||||||
|
int64 m_MasterRefreshTime;
|
||||||
|
|
||||||
CServerEntry *Add(int ServerlistType, const NETADDR &Addr);
|
CServerEntry *Add(int ServerlistType, const NETADDR &Addr);
|
||||||
CServerEntry *Find(int ServerlistType, const NETADDR &Addr);
|
CServerEntry *Find(int ServerlistType, const NETADDR &Addr);
|
||||||
|
|
Loading…
Reference in a new issue