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_pSound->Shutdown();
|
||||
|
||||
m_ServerBrowser.SaveServerlist();
|
||||
|
||||
// shutdown SDL
|
||||
{
|
||||
SDL_Quit();
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <base/math.h>
|
||||
#include <base/system.h>
|
||||
|
||||
#include <engine/external/json-parser/json.h>
|
||||
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/shared/memheap.h>
|
||||
#include <engine/shared/network.h>
|
||||
|
@ -13,12 +15,15 @@
|
|||
#include <engine/engine.h>
|
||||
#include <engine/friends.h>
|
||||
#include <engine/masterserver.h>
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include <mastersrv/mastersrv.h>
|
||||
|
||||
#include "serverbrowser.h"
|
||||
|
||||
|
||||
static char *s_pFilename = "serverlist.json";
|
||||
|
||||
inline int AddrHash(const NETADDR *pAddr)
|
||||
{
|
||||
if(pAddr->type==NETTYPE_IPV4)
|
||||
|
@ -66,11 +71,13 @@ CServerBrowser::CServerBrowser()
|
|||
|
||||
m_ActServerlistType = 0;
|
||||
m_BroadcastTime = 0;
|
||||
m_MasterRefreshTime = 0;
|
||||
}
|
||||
|
||||
void CServerBrowser::Init(class CNetClient *pNetClient, const char *pNetVersion)
|
||||
{
|
||||
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
||||
m_pStorage = Kernel()->RequestInterface<IStorage>();
|
||||
m_pMasterServer = Kernel()->RequestInterface<IMasterServer>();
|
||||
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))
|
||||
return;
|
||||
|
||||
m_MasterRefreshTime = 0;
|
||||
|
||||
if(!Find(IServerBrowser::TYPE_INTERNET, Addr))
|
||||
{
|
||||
pEntry = Add(IServerBrowser::TYPE_INTERNET, Addr);
|
||||
|
@ -173,10 +182,22 @@ void CServerBrowser::Update(bool ForceResort)
|
|||
m_pNetClient->Send(&Packet);
|
||||
}
|
||||
|
||||
m_MasterRefreshTime = Now;
|
||||
|
||||
if(g_Config.m_Debug)
|
||||
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
|
||||
pEntry = m_pFirstReqServer;
|
||||
while(1)
|
||||
|
@ -527,3 +548,69 @@ void CServerBrowser::SetInfo(int ServerlistType, CServerEntry *pEntry, const CSe
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -49,15 +49,22 @@ public:
|
|||
void RemoveFilter(int Index) { m_ServerBrowserFilter.RemoveFilter(Index); };
|
||||
|
||||
static void CBFTrackPacket(int TrackID, void *pUser);
|
||||
|
||||
void LoadServerlist();
|
||||
void SaveServerlist();
|
||||
|
||||
private:
|
||||
class CNetClient *m_pNetClient;
|
||||
class IConsole *m_pConsole;
|
||||
class IStorage *m_pStorage;
|
||||
class IMasterServer *m_pMasterServer;
|
||||
|
||||
class CServerBrowserFavorites m_ServerBrowserFavorites;
|
||||
class CServerBrowserFilter m_ServerBrowserFilter;
|
||||
|
||||
class IConsole *Console() const { return m_pConsole; }
|
||||
class IStorage *Storage() const { return m_pStorage; }
|
||||
|
||||
// serverlist
|
||||
int m_ActServerlistType;
|
||||
class CServerlist
|
||||
|
@ -86,6 +93,7 @@ private:
|
|||
|
||||
int m_RefreshFlags;
|
||||
int64 m_BroadcastTime;
|
||||
int64 m_MasterRefreshTime;
|
||||
|
||||
CServerEntry *Add(int ServerlistType, const NETADDR &Addr);
|
||||
CServerEntry *Find(int ServerlistType, const NETADDR &Addr);
|
||||
|
|
Loading…
Reference in a new issue