mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 01:24:18 +00:00
Introduce ddnet-info.json
- Single json file containing all information for the client - Fetched from https://info.ddnet.tw/info?name=deen - Replaces versionsrv, news, ddnet-maps.json and ddnet-ranks.json - Servers are sorted by most popular ones for respective player - Always stays < 100 ms response time, compared to occasional 50 s for old ddnet-ranks.json
This commit is contained in:
parent
27b7549bba
commit
89ed22e8d8
|
@ -399,8 +399,6 @@ set_glob(ENGINE_SHARED GLOB src/engine/shared
|
|||
linereader.cpp
|
||||
linereader.h
|
||||
map.cpp
|
||||
mapchecker.cpp
|
||||
mapchecker.h
|
||||
masterserver.cpp
|
||||
memheap.cpp
|
||||
memheap.h
|
||||
|
@ -793,26 +791,21 @@ list(APPEND TARGETS_LINK ${TARGET_SERVER})
|
|||
########################################################################
|
||||
|
||||
set_glob(MASTERSRV_SRC GLOB src/mastersrv mastersrv.cpp mastersrv.h)
|
||||
set_glob(VERSIONSRV_SRC GLOB src/versionsrv mapversions.h versionsrv.cpp versionsrv.h)
|
||||
set_glob(TWPING_SRC GLOB src/twping twping.cpp)
|
||||
|
||||
set(TARGET_MASTERSRV mastersrv)
|
||||
set(TARGET_VERSIONSRV versionsrv)
|
||||
set(TARGET_TWPING twping)
|
||||
|
||||
add_executable(${TARGET_MASTERSRV} EXCLUDE_FROM_ALL ${MASTERSRV_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
|
||||
add_executable(${TARGET_VERSIONSRV} EXCLUDE_FROM_ALL ${VERSIONSRV_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
|
||||
add_executable(${TARGET_TWPING} EXCLUDE_FROM_ALL ${TWPING_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
|
||||
|
||||
add_custom_target(generate_nethash DEPENDS src/game/generated/nethash.cpp)
|
||||
add_dependencies(${TARGET_VERSIONSRV} generate_nethash)
|
||||
|
||||
target_link_libraries(${TARGET_MASTERSRV} ${LIBS})
|
||||
target_link_libraries(${TARGET_VERSIONSRV} ${LIBS})
|
||||
target_link_libraries(${TARGET_TWPING} ${LIBS})
|
||||
|
||||
list(APPEND TARGETS_OWN ${TARGET_MASTERSRV} ${TARGET_TWPING} ${TARGET_VERSIONSRV})
|
||||
list(APPEND TARGETS_LINK ${TARGET_MASTERSRV} ${TARGET_TWPING} ${TARGET_VERSIONSRV})
|
||||
list(APPEND TARGETS_OWN ${TARGET_MASTERSRV} ${TARGET_TWPING})
|
||||
list(APPEND TARGETS_LINK ${TARGET_MASTERSRV} ${TARGET_TWPING})
|
||||
|
||||
set(TARGETS_TOOLS)
|
||||
set_glob(TOOLS GLOB src/tools
|
||||
|
|
4
bam.lua
4
bam.lua
|
@ -348,7 +348,6 @@ function build(settings)
|
|||
client = Compile(client_settings, Collect("src/engine/client/*.cpp"))
|
||||
server = Compile(server_settings, Collect("src/engine/server/*.cpp"))
|
||||
|
||||
versionserver = Compile(settings, Collect("src/versionsrv/*.cpp"))
|
||||
masterserver = Compile(settings, Collect("src/mastersrv/*.cpp"))
|
||||
twping = Compile(settings, Collect("src/twping/*.cpp"))
|
||||
game_shared = Compile(settings, Collect("src/game/*.cpp"), nethash, network_source)
|
||||
|
@ -390,9 +389,6 @@ function build(settings)
|
|||
serverlaunch = Link(launcher_settings, "serverlaunch", server_osxlaunch)
|
||||
end
|
||||
|
||||
versionserver_exe = Link(server_settings, "versionsrv", versionserver,
|
||||
engine, zlib, libwebsockets, md5, game_shared)
|
||||
|
||||
masterserver_exe = Link(server_settings, "mastersrv", masterserver,
|
||||
engine, zlib, libwebsockets, md5, game_shared)
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "message.h"
|
||||
#include <engine/friends.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <versionsrv/versionsrv.h>
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -40,7 +39,7 @@ protected:
|
|||
|
||||
int m_GameTickSpeed;
|
||||
public:
|
||||
char m_aNews[NEWS_SIZE];
|
||||
char m_aNews[3000];
|
||||
int64 m_ReconnectTime;
|
||||
|
||||
class CSnapItem
|
||||
|
@ -135,8 +134,6 @@ public:
|
|||
// server info
|
||||
virtual void GetServerInfo(class CServerInfo *pServerInfo) = 0;
|
||||
|
||||
virtual void CheckVersionUpdate() = 0;
|
||||
|
||||
virtual int GetPredictionTime() = 0;
|
||||
|
||||
// snapshot interface
|
||||
|
@ -189,8 +186,7 @@ public:
|
|||
virtual void DemoSliceEnd() = 0;
|
||||
virtual void DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void *pUser) = 0;
|
||||
|
||||
virtual void RequestDDNetSrvList() = 0;
|
||||
virtual void RequestDDNetRanks() = 0;
|
||||
virtual void RequestDDNetInfo() = 0;
|
||||
virtual bool EditorHasUnsavedData() = 0;
|
||||
|
||||
virtual void GenerateTimeoutSeed() = 0;
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include <engine/shared/datafile.h>
|
||||
#include <engine/shared/demo.h>
|
||||
#include <engine/shared/filecollection.h>
|
||||
#include <engine/shared/mapchecker.h>
|
||||
#include <engine/shared/network.h>
|
||||
#include <engine/shared/packer.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
|
@ -55,7 +54,6 @@
|
|||
#include <game/version.h>
|
||||
|
||||
#include <mastersrv/mastersrv.h>
|
||||
#include <versionsrv/versionsrv.h>
|
||||
|
||||
#include <engine/client/serverbrowser.h>
|
||||
|
||||
|
@ -302,7 +300,7 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta)
|
|||
|
||||
// version-checking
|
||||
m_aVersionStr[0] = '0';
|
||||
m_aVersionStr[1] = 0;
|
||||
m_aVersionStr[1] = '\0';
|
||||
|
||||
// pinging
|
||||
m_PingStartTime = 0;
|
||||
|
@ -320,7 +318,9 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta)
|
|||
m_MapdownloadCrc = 0;
|
||||
m_MapdownloadAmount = -1;
|
||||
m_MapdownloadTotalsize = -1;
|
||||
m_pDDNetRanksTask = NULL;
|
||||
|
||||
m_pDDNetInfoTask = NULL;
|
||||
m_aNews[0] = '\0';
|
||||
|
||||
m_CurrentServerInfoRequestTime = -1;
|
||||
|
||||
|
@ -345,7 +345,6 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta)
|
|||
if (g_Config.m_ClDummy == 0)
|
||||
m_LastDummyConnectTime = 0;
|
||||
|
||||
m_DDNetSrvListTokenSet = false;
|
||||
m_ReconnectTime = 0;
|
||||
|
||||
m_GenerateTimeoutSeed = true;
|
||||
|
@ -1133,128 +1132,6 @@ int CClient::PlayerScoreNameComp(const void *a, const void *b)
|
|||
|
||||
void CClient::ProcessConnlessPacket(CNetChunk *pPacket)
|
||||
{
|
||||
// version server
|
||||
if(m_VersionInfo.m_State == CVersionInfo::STATE_READY && net_addr_comp(&pPacket->m_Address, &m_VersionInfo.m_VersionServeraddr.m_Addr) == 0)
|
||||
{
|
||||
// version info
|
||||
if(pPacket->m_DataSize == (int)(sizeof(VERSIONSRV_VERSION) + sizeof(GAME_RELEASE_VERSION)) &&
|
||||
mem_comp(pPacket->m_pData, VERSIONSRV_VERSION, sizeof(VERSIONSRV_VERSION)) == 0)
|
||||
{
|
||||
char *pVersionData = (char*)pPacket->m_pData + sizeof(VERSIONSRV_VERSION);
|
||||
int aCurVersion[] = {0,0,0}, aNewVersion[] = {0,0,0};
|
||||
sscanf(pVersionData, "%d.%d.%d", aNewVersion, aNewVersion+1, aNewVersion+2);
|
||||
sscanf(GAME_RELEASE_VERSION, "%d.%d.%d", aCurVersion, aCurVersion+1, aCurVersion+2);
|
||||
bool VersionMatch = mem_comp(aCurVersion, aNewVersion, sizeof aCurVersion) >= 0;
|
||||
|
||||
char aVersion[sizeof(GAME_RELEASE_VERSION)];
|
||||
str_copy(aVersion, pVersionData, sizeof(aVersion));
|
||||
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "version does %s (%s)",
|
||||
VersionMatch ? "match" : "NOT match",
|
||||
aVersion);
|
||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/version", aBuf);
|
||||
|
||||
// assume version is out of date when version-data doesn't match
|
||||
if(!VersionMatch)
|
||||
str_copy(m_aVersionStr, aVersion, sizeof(m_aVersionStr));
|
||||
|
||||
// request the news
|
||||
CNetChunk Packet;
|
||||
mem_zero(&Packet, sizeof(Packet));
|
||||
Packet.m_ClientID = -1;
|
||||
Packet.m_Address = m_VersionInfo.m_VersionServeraddr.m_Addr;
|
||||
Packet.m_pData = VERSIONSRV_GETNEWS;
|
||||
Packet.m_DataSize = sizeof(VERSIONSRV_GETNEWS);
|
||||
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
||||
m_NetClient[g_Config.m_ClDummy].Send(&Packet);
|
||||
|
||||
// request the map version list now
|
||||
mem_zero(&Packet, sizeof(Packet));
|
||||
Packet.m_ClientID = -1;
|
||||
Packet.m_Address = m_VersionInfo.m_VersionServeraddr.m_Addr;
|
||||
Packet.m_pData = VERSIONSRV_GETMAPLIST;
|
||||
Packet.m_DataSize = sizeof(VERSIONSRV_GETMAPLIST);
|
||||
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
||||
m_NetClient[g_Config.m_ClDummy].Send(&Packet);
|
||||
}
|
||||
|
||||
// news
|
||||
if(pPacket->m_DataSize == (int)(sizeof(VERSIONSRV_NEWS) + NEWS_SIZE) &&
|
||||
mem_comp(pPacket->m_pData, VERSIONSRV_NEWS, sizeof(VERSIONSRV_NEWS)) == 0)
|
||||
{
|
||||
if(mem_comp(m_aNews, (char*)pPacket->m_pData + sizeof(VERSIONSRV_NEWS), NEWS_SIZE))
|
||||
g_Config.m_UiPage = CMenus::PAGE_NEWS;
|
||||
|
||||
mem_copy(m_aNews, (char*)pPacket->m_pData + sizeof(VERSIONSRV_NEWS), NEWS_SIZE);
|
||||
|
||||
IOHANDLE NewsFile = m_pStorage->OpenFile("ddnet-news.txt", IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||
if(NewsFile)
|
||||
{
|
||||
io_write(NewsFile, m_aNews, sizeof(m_aNews));
|
||||
io_close(NewsFile);
|
||||
}
|
||||
}
|
||||
|
||||
// ddnet server list
|
||||
// Packet: VERSIONSRV_DDNETLIST + char[4] Token + int16 comp_length + int16 plain_length + char[comp_length]
|
||||
if(pPacket->m_DataSize >= (int)(sizeof(VERSIONSRV_DDNETLIST) + 8) &&
|
||||
mem_comp(pPacket->m_pData, VERSIONSRV_DDNETLIST, sizeof(VERSIONSRV_DDNETLIST)) == 0 &&
|
||||
mem_comp((char*)pPacket->m_pData+sizeof(VERSIONSRV_DDNETLIST), m_aDDNetSrvListToken, 4) == 0)
|
||||
{
|
||||
// reset random token
|
||||
m_DDNetSrvListTokenSet = false;
|
||||
int CompLength = *(short*)((char*)pPacket->m_pData+(sizeof(VERSIONSRV_DDNETLIST)+4));
|
||||
int PlainLength = *(short*)((char*)pPacket->m_pData+(sizeof(VERSIONSRV_DDNETLIST)+6));
|
||||
|
||||
if (pPacket->m_DataSize == (int)(sizeof(VERSIONSRV_DDNETLIST) + 8 + CompLength))
|
||||
{
|
||||
char aBuf[16384];
|
||||
uLongf DstLen = sizeof(aBuf);
|
||||
const char *pComp = (char*)pPacket->m_pData+sizeof(VERSIONSRV_DDNETLIST)+8;
|
||||
|
||||
// do decompression of serverlist
|
||||
if(uncompress((Bytef*)aBuf, &DstLen, (Bytef*)pComp, CompLength) == Z_OK && (int)DstLen == PlainLength)
|
||||
{
|
||||
aBuf[DstLen] = '\0';
|
||||
bool ListChanged = true;
|
||||
|
||||
IOHANDLE File = m_pStorage->OpenFile("ddnet-servers.json", IOFLAG_READ, IStorage::TYPE_SAVE);
|
||||
if(File)
|
||||
{
|
||||
char aBuf2[16384];
|
||||
io_read(File, aBuf2, sizeof(aBuf2));
|
||||
io_close(File);
|
||||
if (str_comp(aBuf, aBuf2) == 0)
|
||||
ListChanged = false;
|
||||
}
|
||||
|
||||
// decompression successful, write plain file
|
||||
if(ListChanged)
|
||||
{
|
||||
IOHANDLE File = m_pStorage->OpenFile("ddnet-servers.json", IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||
if(File)
|
||||
{
|
||||
io_write(File, aBuf, PlainLength);
|
||||
io_close(File);
|
||||
}
|
||||
if(g_Config.m_UiPage == CMenus::PAGE_DDNET)
|
||||
m_ServerBrowser.Refresh(IServerBrowser::TYPE_DDNET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// map version list
|
||||
if(pPacket->m_DataSize >= (int)sizeof(VERSIONSRV_MAPLIST) &&
|
||||
mem_comp(pPacket->m_pData, VERSIONSRV_MAPLIST, sizeof(VERSIONSRV_MAPLIST)) == 0)
|
||||
{
|
||||
int Size = pPacket->m_DataSize-sizeof(VERSIONSRV_MAPLIST);
|
||||
int Num = Size/sizeof(CMapVersion);
|
||||
m_MapChecker.AddMaplist((CMapVersion *)((char*)pPacket->m_pData+sizeof(VERSIONSRV_MAPLIST)), Num);
|
||||
}
|
||||
}
|
||||
|
||||
//server count from master server
|
||||
if(pPacket->m_DataSize == (int)sizeof(SERVERBROWSE_COUNT) + 2 && mem_comp(pPacket->m_pData, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT)) == 0)
|
||||
{
|
||||
|
@ -1584,10 +1461,6 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
|||
if(m_DummyConnected)
|
||||
DummyDisconnect(0);
|
||||
|
||||
// check for valid standard map
|
||||
if(!m_MapChecker.IsMapValid(pMap, MapCrc, MapSize))
|
||||
pError = "invalid standard map";
|
||||
|
||||
for(int i = 0; pMap[i]; i++) // protect the player from nasty map names
|
||||
{
|
||||
if(pMap[i] == '/' || pMap[i] == '\\')
|
||||
|
@ -2257,21 +2130,55 @@ void CClient::FinishMapDownload()
|
|||
}
|
||||
}
|
||||
|
||||
void CClient::ResetDDNetRanks()
|
||||
void CClient::ResetDDNetInfo()
|
||||
{
|
||||
if(m_pDDNetRanksTask)
|
||||
if(m_pDDNetInfoTask)
|
||||
{
|
||||
m_pDDNetRanksTask->Abort();
|
||||
delete m_pDDNetRanksTask;
|
||||
m_pDDNetRanksTask = NULL;
|
||||
m_pDDNetInfoTask->Abort();
|
||||
delete m_pDDNetInfoTask;
|
||||
m_pDDNetInfoTask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::FinishDDNetRanks()
|
||||
void CClient::FinishDDNetInfo()
|
||||
{
|
||||
ResetDDNetRanks();
|
||||
m_pStorage->RenameFile("ddnet-ranks.json.tmp", "ddnet-ranks.json", IStorage::TYPE_SAVE);
|
||||
m_ServerBrowser.LoadDDNetRanks();
|
||||
ResetDDNetInfo();
|
||||
m_pStorage->RenameFile("ddnet-info.json.tmp", "ddnet-info.json", IStorage::TYPE_SAVE);
|
||||
LoadDDNetInfo();
|
||||
}
|
||||
|
||||
void CClient::LoadDDNetInfo()
|
||||
{
|
||||
const json_value *pDDNetInfo = m_ServerBrowser.LoadDDNetInfo();
|
||||
|
||||
if(!pDDNetInfo)
|
||||
return;
|
||||
|
||||
const json_value *pVersion = json_object_get(pDDNetInfo, "version");
|
||||
if(pVersion && pVersion->type == json_string)
|
||||
{
|
||||
const char *pVersionString = json_string_get(pVersion);
|
||||
if(str_comp(pVersionString, GAME_RELEASE_VERSION))
|
||||
{
|
||||
str_copy(m_aVersionStr, pVersionString, sizeof(m_aVersionStr));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_aVersionStr[0] = '0';
|
||||
m_aVersionStr[1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
const json_value *pNews = json_object_get(pDDNetInfo, "news");
|
||||
if(pNews && pNews->type == json_string)
|
||||
{
|
||||
const char *pNewsString = json_string_get(pNews);
|
||||
|
||||
if(m_aNews[0] && str_comp(m_aNews, pNewsString))
|
||||
g_Config.m_UiPage = CMenus::PAGE_NEWS;
|
||||
|
||||
str_copy(m_aNews, pNewsString, sizeof(m_aNews));
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::PumpNetwork()
|
||||
|
@ -2584,19 +2491,19 @@ void CClient::Update()
|
|||
}
|
||||
}
|
||||
|
||||
if(m_pDDNetRanksTask)
|
||||
if(m_pDDNetInfoTask)
|
||||
{
|
||||
if(m_pDDNetRanksTask->State() == CFetchTask::STATE_DONE)
|
||||
FinishDDNetRanks();
|
||||
else if(m_pDDNetRanksTask->State() == CFetchTask::STATE_ERROR)
|
||||
if(m_pDDNetInfoTask->State() == CFetchTask::STATE_DONE)
|
||||
FinishDDNetInfo();
|
||||
else if(m_pDDNetInfoTask->State() == CFetchTask::STATE_ERROR)
|
||||
{
|
||||
dbg_msg("ddnet-ranks", "download failed");
|
||||
ResetDDNetRanks();
|
||||
dbg_msg("ddnet-info", "download failed");
|
||||
ResetDDNetInfo();
|
||||
}
|
||||
else if(m_pDDNetRanksTask->State() == CFetchTask::STATE_ABORTED)
|
||||
else if(m_pDDNetInfoTask->State() == CFetchTask::STATE_ABORTED)
|
||||
{
|
||||
delete m_pDDNetRanksTask;
|
||||
m_pDDNetRanksTask = NULL;
|
||||
delete m_pDDNetInfoTask;
|
||||
m_pDDNetInfoTask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2618,40 +2525,6 @@ void CClient::Update()
|
|||
}
|
||||
}
|
||||
|
||||
void CClient::VersionUpdate()
|
||||
{
|
||||
if(m_VersionInfo.m_State == CVersionInfo::STATE_INIT)
|
||||
{
|
||||
Engine()->HostLookup(&m_VersionInfo.m_VersionServeraddr, "version.ddnet.tw", m_NetClient[0].NetType());
|
||||
m_VersionInfo.m_State = CVersionInfo::STATE_START;
|
||||
}
|
||||
else if(m_VersionInfo.m_State == CVersionInfo::STATE_START)
|
||||
{
|
||||
if(m_VersionInfo.m_VersionServeraddr.m_Job.Status() == CJob::STATE_DONE)
|
||||
{
|
||||
CNetChunk Packet;
|
||||
|
||||
mem_zero(&Packet, sizeof(Packet));
|
||||
|
||||
m_VersionInfo.m_VersionServeraddr.m_Addr.port = VERSIONSRV_PORT;
|
||||
|
||||
Packet.m_ClientID = -1;
|
||||
Packet.m_Address = m_VersionInfo.m_VersionServeraddr.m_Addr;
|
||||
Packet.m_pData = VERSIONSRV_GETVERSION;
|
||||
Packet.m_DataSize = sizeof(VERSIONSRV_GETVERSION);
|
||||
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
||||
|
||||
m_NetClient[0].Send(&Packet);
|
||||
m_VersionInfo.m_State = CVersionInfo::STATE_READY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::CheckVersionUpdate()
|
||||
{
|
||||
m_VersionInfo.m_State = CVersionInfo::STATE_START;
|
||||
}
|
||||
|
||||
void CClient::RegisterInterfaces()
|
||||
{
|
||||
Kernel()->RegisterInterface(static_cast<IDemoRecorder*>(&m_DemoRecorder[RECORDER_MANUAL]), false);
|
||||
|
@ -2694,13 +2567,6 @@ void CClient::InitInterfaces()
|
|||
|
||||
m_Friends.Init();
|
||||
m_Foes.Init(true);
|
||||
|
||||
IOHANDLE newsFile = m_pStorage->OpenFile("ddnet-news.txt", IOFLAG_READ, IStorage::TYPE_SAVE);
|
||||
if (newsFile)
|
||||
{
|
||||
io_read(newsFile, m_aNews, NEWS_SIZE);
|
||||
io_close(newsFile);
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::Run()
|
||||
|
@ -2821,8 +2687,10 @@ void CClient::Run()
|
|||
m_Fifo.Init(m_pConsole, g_Config.m_ClInputFifo, CFGFLAG_CLIENT);
|
||||
#endif
|
||||
|
||||
RequestDDNetSrvList();
|
||||
RequestDDNetRanks();
|
||||
// loads the existing ddnet-info.json file if it exists
|
||||
LoadDDNetInfo();
|
||||
// but still request the new one from server
|
||||
RequestDDNetInfo();
|
||||
|
||||
bool LastD = false;
|
||||
bool LastQ = false;
|
||||
|
@ -2835,9 +2703,6 @@ void CClient::Run()
|
|||
{
|
||||
set_new_tick();
|
||||
|
||||
//
|
||||
VersionUpdate();
|
||||
|
||||
// handle pending connects
|
||||
if(m_aCmdConnect[0])
|
||||
{
|
||||
|
@ -3754,38 +3619,16 @@ bool CClient::RaceRecordIsRecording()
|
|||
return m_DemoRecorder[RECORDER_RACE].IsRecording();
|
||||
}
|
||||
|
||||
void CClient::RequestDDNetSrvList()
|
||||
{
|
||||
// request ddnet server list
|
||||
// generate new token
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_aDDNetSrvListToken[i] = rand()&0xff;
|
||||
m_DDNetSrvListTokenSet = true;
|
||||
|
||||
char aData[sizeof(VERSIONSRV_GETDDNETLIST)+4];
|
||||
mem_copy(aData, VERSIONSRV_GETDDNETLIST, sizeof(VERSIONSRV_GETDDNETLIST));
|
||||
mem_copy(aData+sizeof(VERSIONSRV_GETDDNETLIST), m_aDDNetSrvListToken, 4); // add token
|
||||
|
||||
CNetChunk Packet;
|
||||
mem_zero(&Packet, sizeof(Packet));
|
||||
Packet.m_ClientID = -1;
|
||||
Packet.m_Address = m_VersionInfo.m_VersionServeraddr.m_Addr;
|
||||
Packet.m_pData = aData;
|
||||
Packet.m_DataSize = sizeof(VERSIONSRV_GETDDNETLIST)+4;
|
||||
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
||||
m_NetClient[g_Config.m_ClDummy].Send(&Packet);
|
||||
}
|
||||
|
||||
void CClient::RequestDDNetRanks()
|
||||
void CClient::RequestDDNetInfo()
|
||||
{
|
||||
char aUrl[256];
|
||||
char aEscaped[128];
|
||||
|
||||
Fetcher()->Escape(aEscaped, sizeof(aEscaped), g_Config.m_PlayerName);
|
||||
str_format(aUrl, sizeof(aUrl), "https://ddnet.tw/players/?json=%s", aEscaped);
|
||||
str_format(aUrl, sizeof(aUrl), "https://info.ddnet.tw/info?name=%s", aEscaped);
|
||||
|
||||
m_pDDNetRanksTask = new CFetchTask(true, /*UseDDNetCA*/ true);
|
||||
Fetcher()->QueueAdd(m_pDDNetRanksTask, aUrl, "ddnet-ranks.json.tmp", IStorage::TYPE_SAVE);
|
||||
m_pDDNetInfoTask = new CFetchTask(true, /*UseDDNetCA*/ true);
|
||||
Fetcher()->QueueAdd(m_pDDNetInfoTask, aUrl, "ddnet-info.json.tmp", IStorage::TYPE_SAVE);
|
||||
}
|
||||
|
||||
int CClient::GetPredictionTime()
|
||||
|
|
|
@ -80,7 +80,6 @@ class CClient : public IClient, public CDemoPlayer::IListener
|
|||
class CUpdater m_Updater;
|
||||
class CFriends m_Friends;
|
||||
class CFriends m_Foes;
|
||||
class CMapChecker m_MapChecker;
|
||||
|
||||
char m_aServerAddressStr[256];
|
||||
|
||||
|
@ -135,7 +134,8 @@ class CClient : public IClient, public CDemoPlayer::IListener
|
|||
int m_MapdownloadCrc;
|
||||
int m_MapdownloadAmount;
|
||||
int m_MapdownloadTotalsize;
|
||||
CFetchTask *m_pDDNetRanksTask;
|
||||
|
||||
CFetchTask *m_pDDNetInfoTask;
|
||||
|
||||
// time
|
||||
CSmoothTime m_GameTime[2];
|
||||
|
@ -195,9 +195,6 @@ class CClient : public IClient, public CDemoPlayer::IListener
|
|||
void GraphicsThread();
|
||||
vec3 GetColorV3(int v);
|
||||
|
||||
char m_aDDNetSrvListToken[4];
|
||||
bool m_DDNetSrvListTokenSet;
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
CFifo m_Fifo;
|
||||
#endif
|
||||
|
@ -244,8 +241,6 @@ public:
|
|||
virtual bool InputExists(int Tick);
|
||||
|
||||
const char *LatestVersion();
|
||||
void VersionUpdate();
|
||||
void CheckVersionUpdate();
|
||||
|
||||
// ------ state handling -----
|
||||
void SetState(int s);
|
||||
|
@ -299,8 +294,11 @@ public:
|
|||
|
||||
void ResetMapDownload();
|
||||
void FinishMapDownload();
|
||||
void ResetDDNetRanks();
|
||||
void FinishDDNetRanks();
|
||||
|
||||
void RequestDDNetInfo();
|
||||
void ResetDDNetInfo();
|
||||
void FinishDDNetInfo();
|
||||
void LoadDDNetInfo();
|
||||
|
||||
virtual CFetchTask *MapDownloadTask() { return m_pMapdownloadTask; }
|
||||
virtual const char *MapDownloadName() { return m_aMapdownloadName; }
|
||||
|
@ -394,8 +392,6 @@ public:
|
|||
virtual void DemoSliceEnd();
|
||||
virtual void DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void *pUser);
|
||||
|
||||
void RequestDDNetSrvList();
|
||||
void RequestDDNetRanks();
|
||||
bool EditorHasUnsavedData() { return m_pEditor->HasUnsavedData(); }
|
||||
|
||||
virtual IFriends* Foes() {return &m_Foes; }
|
||||
|
|
|
@ -63,7 +63,13 @@ CServerBrowser::CServerBrowser()
|
|||
m_BroadcastTime = 0;
|
||||
m_BroadcastExtraToken = -1;
|
||||
|
||||
m_pDDNetRanks = 0;
|
||||
m_pDDNetInfo = 0;
|
||||
}
|
||||
|
||||
CServerBrowser::~CServerBrowser()
|
||||
{
|
||||
if(m_pDDNetInfo)
|
||||
json_value_free(m_pDDNetInfo);
|
||||
}
|
||||
|
||||
void CServerBrowser::SetBaseInfo(class CNetClient *pClient, const char *pNetVersion)
|
||||
|
@ -550,7 +556,6 @@ void CServerBrowser::Refresh(int Type)
|
|||
// next token
|
||||
m_CurrentToken = (m_CurrentToken+1)&0xff;
|
||||
|
||||
//
|
||||
m_ServerlistType = Type;
|
||||
|
||||
if(Type == IServerBrowser::TYPE_LAN)
|
||||
|
@ -593,9 +598,6 @@ void CServerBrowser::Refresh(int Type)
|
|||
}
|
||||
else if(Type == IServerBrowser::TYPE_DDNET)
|
||||
{
|
||||
LoadDDNetServers();
|
||||
LoadDDNetRanks();
|
||||
|
||||
// remove unknown elements of exclude list
|
||||
DDNetCountryFilterClean();
|
||||
DDNetTypeFilterClean();
|
||||
|
@ -926,31 +928,23 @@ void CServerBrowser::RemoveFavorite(const NETADDR &Addr)
|
|||
|
||||
void CServerBrowser::LoadDDNetServers()
|
||||
{
|
||||
if (!m_pDDNetInfo)
|
||||
return;
|
||||
|
||||
// parse JSON
|
||||
const json_value *pServers = json_object_get(m_pDDNetInfo, "servers");
|
||||
|
||||
if (!pServers || pServers->type != json_array)
|
||||
return;
|
||||
|
||||
// reset servers / countries
|
||||
m_NumDDNetCountries = 0;
|
||||
m_NumDDNetTypes = 0;
|
||||
|
||||
// load ddnet server list
|
||||
IStorage *pStorage = Kernel()->RequestInterface<IStorage>();
|
||||
IOHANDLE File = pStorage->OpenFile("ddnet-servers.json", IOFLAG_READ, IStorage::TYPE_ALL);
|
||||
|
||||
if(!File)
|
||||
return;
|
||||
|
||||
char aBuf[4096*4];
|
||||
mem_zero(aBuf, sizeof(aBuf));
|
||||
io_read(File, aBuf, sizeof(aBuf));
|
||||
io_close(File);
|
||||
|
||||
// parse JSON
|
||||
json_value *pCountries = json_parse(aBuf, sizeof(aBuf));
|
||||
|
||||
if (pCountries && pCountries->type == json_array)
|
||||
{
|
||||
for (int i = 0; i < json_array_length(pCountries) && m_NumDDNetCountries < MAX_DDNET_COUNTRIES; i++)
|
||||
for (int i = 0; i < json_array_length(pServers) && m_NumDDNetCountries < MAX_DDNET_COUNTRIES; i++)
|
||||
{
|
||||
// pSrv - { name, flagId, servers }
|
||||
const json_value *pSrv = json_array_get(pCountries, i);
|
||||
const json_value *pSrv = json_array_get(pServers, i);
|
||||
const json_value *pTypes = json_object_get(pSrv, "servers");
|
||||
const json_value *pName = json_object_get(pSrv, "name");
|
||||
const json_value *pFlagID = json_object_get(pSrv, "flagId");
|
||||
|
@ -975,6 +969,12 @@ void CServerBrowser::LoadDDNetServers()
|
|||
const char *pType = pTypes->u.object.values[t].name;
|
||||
const json_value *pAddrs = pTypes->u.object.values[t].value;
|
||||
|
||||
if (pAddrs->type != json_array)
|
||||
{
|
||||
dbg_msg("client_srvbrowse", "invalid attributes");
|
||||
continue;
|
||||
}
|
||||
|
||||
// add type
|
||||
if(json_array_length(pAddrs) > 0 && m_NumDDNetTypes < MAX_DDNET_TYPES)
|
||||
{
|
||||
|
@ -995,6 +995,11 @@ void CServerBrowser::LoadDDNetServers()
|
|||
for (int g = 0; g < json_array_length(pAddrs); g++, pCntr->m_NumServers++)
|
||||
{
|
||||
const json_value *pAddr = json_array_get(pAddrs, g);
|
||||
if (pAddr->type != json_string)
|
||||
{
|
||||
dbg_msg("client_srvbrowse", "invalid attributes");
|
||||
continue;
|
||||
}
|
||||
const char *pStr = json_string_get(pAddr);
|
||||
net_addr_from_str(&pCntr->m_aServers[pCntr->m_NumServers], pStr);
|
||||
str_copy(pCntr->m_aTypes[pCntr->m_NumServers], pType, sizeof(pCntr->m_aTypes[pCntr->m_NumServers]));
|
||||
|
@ -1003,17 +1008,46 @@ void CServerBrowser::LoadDDNetServers()
|
|||
|
||||
m_NumDDNetCountries++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCountries)
|
||||
json_value_free(pCountries);
|
||||
}
|
||||
|
||||
void CServerBrowser::LoadDDNetRanks()
|
||||
{
|
||||
// load ddnet ranks list
|
||||
for(int i = 0; i < m_NumServers; i++)
|
||||
{
|
||||
if(m_ppServerlist[i]->m_Info.m_aMap[0])
|
||||
m_ppServerlist[i]->m_Info.m_HasRank = HasRank(m_ppServerlist[i]->m_Info.m_aMap);
|
||||
}
|
||||
}
|
||||
|
||||
int CServerBrowser::HasRank(const char *pMap)
|
||||
{
|
||||
if(m_ServerlistType != IServerBrowser::TYPE_DDNET || !m_pDDNetInfo)
|
||||
return -1;
|
||||
|
||||
const json_value *pDDNetRanks = json_object_get(m_pDDNetInfo, "maps");
|
||||
|
||||
if(!pDDNetRanks || pDDNetRanks->type != json_array)
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < json_array_length(pDDNetRanks); i++)
|
||||
{
|
||||
const json_value *pJson = json_array_get(pDDNetRanks, i);
|
||||
if(!pJson || pJson->type != json_string)
|
||||
continue;
|
||||
|
||||
const char *pStr = json_string_get(pJson);
|
||||
|
||||
if(str_comp(pMap, pStr) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CServerBrowser::LoadDDNetInfoJson()
|
||||
{
|
||||
IStorage *pStorage = Kernel()->RequestInterface<IStorage>();
|
||||
IOHANDLE File = pStorage->OpenFile("ddnet-ranks.json", IOFLAG_READ, IStorage::TYPE_ALL);
|
||||
IOHANDLE File = pStorage->OpenFile("ddnet-info.json", IOFLAG_READ, IStorage::TYPE_ALL);
|
||||
|
||||
if(!File)
|
||||
return;
|
||||
|
@ -1031,34 +1065,31 @@ void CServerBrowser::LoadDDNetRanks()
|
|||
io_read(File, pBuf, Length);
|
||||
io_close(File);
|
||||
|
||||
m_pDDNetRanks = json_parse(pBuf, Length);
|
||||
if(m_pDDNetInfo)
|
||||
json_value_free(m_pDDNetInfo);
|
||||
|
||||
m_pDDNetInfo = json_parse(pBuf, Length);
|
||||
|
||||
mem_free(pBuf);
|
||||
|
||||
for(int i = 0; i < m_NumServers; i++)
|
||||
if(m_pDDNetInfo->type != json_object)
|
||||
{
|
||||
if(m_ppServerlist[i]->m_Info.m_aMap[0])
|
||||
m_ppServerlist[i]->m_Info.m_HasRank = HasRank(m_ppServerlist[i]->m_Info.m_aMap);
|
||||
json_value_free(m_pDDNetInfo);
|
||||
m_pDDNetInfo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int CServerBrowser::HasRank(const char *pMap)
|
||||
const json_value *CServerBrowser::LoadDDNetInfo()
|
||||
{
|
||||
if(m_ServerlistType != IServerBrowser::TYPE_DDNET)
|
||||
return -1;
|
||||
LoadDDNetInfoJson();
|
||||
LoadDDNetServers();
|
||||
|
||||
if(!m_pDDNetRanks)
|
||||
return -1;
|
||||
if(m_NumServers == 0)
|
||||
Refresh(m_ServerlistType);
|
||||
else
|
||||
LoadDDNetRanks();
|
||||
|
||||
for (int i = 0; i < json_array_length(m_pDDNetRanks); i++)
|
||||
{
|
||||
const json_value *pJson = json_array_get(m_pDDNetRanks, i);
|
||||
const char *pStr = json_string_get(pJson);
|
||||
if(str_comp(pMap, pStr) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return m_pDDNetInfo;
|
||||
}
|
||||
|
||||
bool CServerBrowser::IsRefreshing() const
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define ENGINE_CLIENT_SERVERBROWSER_H
|
||||
|
||||
#include <engine/serverbrowser.h>
|
||||
#include <engine/shared/memheap.h>
|
||||
#include <engine/external/json-parser/json.h>
|
||||
|
||||
class CServerBrowser : public IServerBrowser
|
||||
|
@ -58,6 +59,7 @@ public:
|
|||
};
|
||||
|
||||
CServerBrowser();
|
||||
virtual ~CServerBrowser();
|
||||
|
||||
// interface functions
|
||||
void Refresh(int Type);
|
||||
|
@ -74,8 +76,10 @@ public:
|
|||
void AddFavorite(const NETADDR &Addr);
|
||||
void RemoveFavorite(const NETADDR &Addr);
|
||||
|
||||
void LoadDDNetServers();
|
||||
void LoadDDNetRanks();
|
||||
void LoadDDNetServers();
|
||||
void LoadDDNetInfoJson();
|
||||
const json_value *LoadDDNetInfo();
|
||||
int HasRank(const char *pMap);
|
||||
int NumDDNetCountries() { return m_NumDDNetCountries; };
|
||||
int GetDDNetCountryFlag(int Index) { return m_aDDNetCountries[Index].m_FlagID; };
|
||||
|
@ -121,7 +125,8 @@ private:
|
|||
|
||||
char m_aDDNetTypes[MAX_DDNET_TYPES][32];
|
||||
int m_NumDDNetTypes;
|
||||
json_value *m_pDDNetRanks;
|
||||
|
||||
json_value *m_pDDNetInfo;
|
||||
|
||||
CServerEntry *m_aServerlistIp[256]; // ip hash list
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <engine/shared/demo.h>
|
||||
#include <engine/shared/econ.h>
|
||||
#include <engine/shared/filecollection.h>
|
||||
#include <engine/shared/mapchecker.h>
|
||||
#include <engine/shared/netban.h>
|
||||
#include <engine/shared/network.h>
|
||||
#include <engine/shared/packer.h>
|
||||
|
@ -1628,22 +1627,10 @@ char *CServer::GetMapName()
|
|||
|
||||
int CServer::LoadMap(const char *pMapName)
|
||||
{
|
||||
//DATAFILE *df;
|
||||
char aBuf[512];
|
||||
str_format(aBuf, sizeof(aBuf), "maps/%s.map", pMapName);
|
||||
GameServer()->OnMapChange(aBuf, sizeof(aBuf));
|
||||
|
||||
/*df = datafile_load(buf);
|
||||
if(!df)
|
||||
return 0;*/
|
||||
|
||||
// check for valid standard map
|
||||
if(!m_MapChecker.ReadAndValidateMap(Storage(), aBuf, IStorage::TYPE_ALL))
|
||||
{
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mapchecker", "invalid standard map");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!m_pMap->Load(aBuf))
|
||||
return 0;
|
||||
|
||||
|
@ -1671,7 +1658,6 @@ int CServer::LoadMap(const char *pMapName)
|
|||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBufMsg);
|
||||
|
||||
str_copy(m_aCurrentMap, pMapName, sizeof(m_aCurrentMap));
|
||||
//map_set(df);
|
||||
|
||||
// load complete map into memory for download
|
||||
{
|
||||
|
@ -1704,7 +1690,6 @@ int CServer::Run()
|
|||
g_UuidManager.DebugDump();
|
||||
}
|
||||
|
||||
//
|
||||
m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_ConsoleOutputLevel, SendRconLineAuthed, this);
|
||||
|
||||
// load map
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <engine/server/register.h>
|
||||
#include <engine/shared/console.h>
|
||||
#include <base/math.h>
|
||||
#include <engine/shared/mapchecker.h>
|
||||
#include <engine/shared/econ.h>
|
||||
#include <engine/shared/fifo.h>
|
||||
#include <engine/shared/netban.h>
|
||||
|
@ -202,7 +201,6 @@ public:
|
|||
|
||||
CDemoRecorder m_aDemoRecorder[MAX_CLIENTS+1];
|
||||
CRegister m_Register;
|
||||
CMapChecker m_MapChecker;
|
||||
CAuthManager m_AuthManager;
|
||||
|
||||
int m_RconRestrict;
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
/* (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 <base/math.h>
|
||||
#include <base/system.h>
|
||||
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include <versionsrv/versionsrv.h>
|
||||
#include <versionsrv/mapversions.h>
|
||||
|
||||
#include "datafile.h"
|
||||
#include "memheap.h"
|
||||
#include "mapchecker.h"
|
||||
|
||||
CMapChecker::CMapChecker()
|
||||
{
|
||||
Init();
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
void CMapChecker::Init()
|
||||
{
|
||||
m_Whitelist.Reset();
|
||||
m_pFirst = 0;
|
||||
m_RemoveDefaultList = false;
|
||||
}
|
||||
|
||||
void CMapChecker::SetDefaults()
|
||||
{
|
||||
AddMaplist(s_aMapVersionList, s_NumMapVersionItems);
|
||||
m_RemoveDefaultList = true;
|
||||
}
|
||||
|
||||
void CMapChecker::AddMaplist(CMapVersion *pMaplist, int Num)
|
||||
{
|
||||
if(m_RemoveDefaultList)
|
||||
Init();
|
||||
|
||||
for(int i = 0; i < Num; ++i)
|
||||
{
|
||||
CWhitelistEntry *pEntry = (CWhitelistEntry *)m_Whitelist.Allocate(sizeof(CWhitelistEntry));
|
||||
pEntry->m_pNext = m_pFirst;
|
||||
m_pFirst = pEntry;
|
||||
|
||||
str_copy(pEntry->m_aMapName, pMaplist[i].m_aName, sizeof(pEntry->m_aMapName));
|
||||
pEntry->m_MapCrc = (pMaplist[i].m_aCrc[0]<<24) | (pMaplist[i].m_aCrc[1]<<16) | (pMaplist[i].m_aCrc[2]<<8) | pMaplist[i].m_aCrc[3];
|
||||
pEntry->m_MapSize = (pMaplist[i].m_aSize[0]<<24) | (pMaplist[i].m_aSize[1]<<16) | (pMaplist[i].m_aSize[2]<<8) | pMaplist[i].m_aSize[3];
|
||||
}
|
||||
}
|
||||
|
||||
bool CMapChecker::IsMapValid(const char *pMapName, unsigned MapCrc, unsigned MapSize)
|
||||
{
|
||||
bool StandardMap = false;
|
||||
for(CWhitelistEntry *pCurrent = m_pFirst; pCurrent; pCurrent = pCurrent->m_pNext)
|
||||
{
|
||||
if(str_comp(pCurrent->m_aMapName, pMapName) == 0)
|
||||
{
|
||||
StandardMap = true;
|
||||
if(pCurrent->m_MapCrc == MapCrc && pCurrent->m_MapSize == MapSize)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return StandardMap?false:true;
|
||||
}
|
||||
|
||||
bool CMapChecker::ReadAndValidateMap(IStorage *pStorage, const char *pFilename, int StorageType)
|
||||
{
|
||||
bool LoadedMapInfo = false;
|
||||
bool StandardMap = false;
|
||||
unsigned MapCrc = 0;
|
||||
unsigned MapSize = 0;
|
||||
|
||||
// extract map name
|
||||
char aMapName[MAX_MAP_LENGTH];
|
||||
const char *pExtractedName = pFilename;
|
||||
const char *pEnd = 0;
|
||||
for(const char *pSrc = pFilename; *pSrc; ++pSrc)
|
||||
{
|
||||
if(*pSrc == '/' || *pSrc == '\\')
|
||||
pExtractedName = pSrc+1;
|
||||
else if(*pSrc == '.')
|
||||
pEnd = pSrc;
|
||||
}
|
||||
int Length = (int)(pEnd - pExtractedName);
|
||||
if(Length <= 0 || Length >= MAX_MAP_LENGTH)
|
||||
return true;
|
||||
str_copy(aMapName, pExtractedName, min((int)MAX_MAP_LENGTH, (int)(pEnd-pExtractedName+1)));
|
||||
|
||||
// check for valid map
|
||||
for(CWhitelistEntry *pCurrent = m_pFirst; pCurrent; pCurrent = pCurrent->m_pNext)
|
||||
{
|
||||
if(str_comp(pCurrent->m_aMapName, aMapName) == 0)
|
||||
{
|
||||
StandardMap = true;
|
||||
if(!LoadedMapInfo)
|
||||
{
|
||||
if(!CDataFileReader::GetCrcSize(pStorage, pFilename, StorageType, &MapCrc, &MapSize))
|
||||
return true;
|
||||
LoadedMapInfo = true;
|
||||
}
|
||||
|
||||
if(pCurrent->m_MapCrc == MapCrc && pCurrent->m_MapSize == MapSize)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return StandardMap?false:true;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/* (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. */
|
||||
#ifndef ENGINE_SHARED_MAPCHECKER_H
|
||||
#define ENGINE_SHARED_MAPCHECKER_H
|
||||
|
||||
#include "memheap.h"
|
||||
|
||||
class CMapChecker
|
||||
{
|
||||
enum
|
||||
{
|
||||
MAX_MAP_LENGTH=8,
|
||||
};
|
||||
|
||||
struct CWhitelistEntry
|
||||
{
|
||||
char m_aMapName[MAX_MAP_LENGTH];
|
||||
unsigned m_MapCrc;
|
||||
unsigned m_MapSize;
|
||||
CWhitelistEntry *m_pNext;
|
||||
};
|
||||
|
||||
class CHeap m_Whitelist;
|
||||
CWhitelistEntry *m_pFirst;
|
||||
|
||||
bool m_RemoveDefaultList;
|
||||
|
||||
void Init();
|
||||
void SetDefaults();
|
||||
|
||||
public:
|
||||
CMapChecker();
|
||||
void AddMaplist(struct CMapVersion *pMaplist, int Num);
|
||||
bool IsMapValid(const char *pMapName, unsigned MapCrc, unsigned MapSize);
|
||||
bool ReadAndValidateMap(class IStorage *pStorage, const char *pFilename, int StorageType);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -31,7 +31,6 @@
|
|||
#include <game/client/lineinput.h>
|
||||
#include <game/localization.h>
|
||||
#include <mastersrv/mastersrv.h>
|
||||
#include <versionsrv/versionsrv.h>
|
||||
|
||||
#include "countryflags.h"
|
||||
#include "menus.h"
|
||||
|
@ -696,7 +695,10 @@ int CMenus::RenderMenubar(CUIRect r)
|
|||
if(DoButton_MenuTab(&s_DDNetButton, Localize("DDNet"), m_ActivePage==PAGE_DDNET, &Button, CUI::CORNER_TR))
|
||||
{
|
||||
if(ServerBrowser()->GetCurrentType() != IServerBrowser::TYPE_DDNET)
|
||||
{
|
||||
Client()->RequestDDNetInfo();
|
||||
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
|
||||
}
|
||||
NewPage = PAGE_DDNET;
|
||||
m_DoubleClickIndex = -1;
|
||||
}
|
||||
|
|
|
@ -1397,8 +1397,7 @@ void CMenus::RenderServerbrowser(CUIRect MainView)
|
|||
else if(g_Config.m_UiPage == PAGE_DDNET)
|
||||
{
|
||||
// start a new serverlist request
|
||||
Client()->RequestDDNetSrvList();
|
||||
Client()->RequestDDNetRanks();
|
||||
Client()->RequestDDNetInfo();
|
||||
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
|
||||
}
|
||||
m_DoubleClickIndex = -1;
|
||||
|
|
|
@ -2155,7 +2155,7 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
|
|||
g_Config.m_ClHttpMapDownload ^= 1;
|
||||
}
|
||||
|
||||
//Updater
|
||||
// Updater
|
||||
#if defined(CONF_FAMILY_WINDOWS) || (defined(CONF_PLATFORM_LINUX) && !defined(__ANDROID__))
|
||||
{
|
||||
Left.HSplitTop(20.0f, &Label, &Left);
|
||||
|
@ -2163,7 +2163,7 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
|
|||
char aBuf[256];
|
||||
int State = Updater()->GetCurrentState();
|
||||
|
||||
//Update Button
|
||||
// Update Button
|
||||
if(NeedUpdate && State <= IUpdater::CLEAN)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), Localize("DDNet %s is available:"), Client()->LatestVersion());
|
||||
|
@ -2188,7 +2188,7 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
|
|||
static int s_ButtonUpdate = 0;
|
||||
if(DoButton_Menu(&s_ButtonUpdate, Localize("Check now"), 0, &Button))
|
||||
{
|
||||
Client()->CheckVersionUpdate();
|
||||
Client()->RequestDDNetInfo();
|
||||
}
|
||||
}
|
||||
UI()->DoLabelScaled(&Label, aBuf, 14.0f, -1);
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/* (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. */
|
||||
#ifndef VERSIONSRV_MAPVERSIONS_H
|
||||
#define VERSIONSRV_MAPVERSIONS_H
|
||||
|
||||
static CMapVersion s_aMapVersionList[] = {
|
||||
{"ctf1", {0x06, 0xb5, 0xf1, 0x17}, {0x00, 0x00, 0x12, 0x38}},
|
||||
{"ctf2", {0x27, 0xbc, 0x5e, 0xac}, {0x00, 0x00, 0x64, 0x1a}},
|
||||
{"ctf3", {0xa3, 0x73, 0x9d, 0x41}, {0x00, 0x00, 0x17, 0x0f}},
|
||||
{"ctf4", {0xbe, 0x7c, 0x4d, 0xb9}, {0x00, 0x00, 0x2e, 0xfe}},
|
||||
{"ctf5", {0xd9, 0x21, 0x29, 0xa0}, {0x00, 0x00, 0x2f, 0x4c}},
|
||||
{"ctf6", {0x28, 0xc8, 0x43, 0x51}, {0x00, 0x00, 0x69, 0x2f}},
|
||||
{"ctf7", {0x1d, 0x35, 0x98, 0x72}, {0x00, 0x00, 0x15, 0x87}},
|
||||
{"dm1", {0xf2, 0x15, 0x9e, 0x6e}, {0x00, 0x00, 0x16, 0xad}},
|
||||
{"dm2", {0x71, 0x83, 0x98, 0x78}, {0x00, 0x00, 0x21, 0xdf}},
|
||||
{"dm6", {0x47, 0x4d, 0xa2, 0x35}, {0x00, 0x00, 0x1e, 0x95}},
|
||||
{"dm7", {0x42, 0x6d, 0xa1, 0x67}, {0x00, 0x00, 0x27, 0x2a}},
|
||||
{"dm8", {0x85, 0xf1, 0x1e, 0xd6}, {0x00, 0x00, 0x9e, 0xbd}},
|
||||
{"dm9", {0x42, 0xd4, 0x77, 0x7e}, {0x00, 0x00, 0x20, 0x11}},
|
||||
};
|
||||
static const int s_NumMapVersionItems = sizeof(s_aMapVersionList)/sizeof(CMapVersion);
|
||||
#endif
|
|
@ -1,240 +0,0 @@
|
|||
/* (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 <base/system.h>
|
||||
|
||||
#include <engine/shared/network.h>
|
||||
|
||||
#include <game/version.h>
|
||||
|
||||
#include "versionsrv.h"
|
||||
#include "mapversions.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
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;
|
||||
unsigned char m_aNews[NEWS_SIZE];
|
||||
|
||||
unsigned char m_aServerList[DDNETLIST_SIZE];
|
||||
int m_ServerListPlainLength = 0;
|
||||
int m_ServerListCompLength = 0;
|
||||
bool m_ServerListLoaded = false;
|
||||
|
||||
static CNetClient g_NetOp; // main
|
||||
|
||||
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;
|
||||
|
||||
// copy header
|
||||
mem_copy(m_aPackets[m_NumPackets].m_Data.m_aHeader, VERSIONSRV_MAPLIST, sizeof(VERSIONSRV_MAPLIST));
|
||||
|
||||
// copy map versions
|
||||
for(int i = 0; i < Chunk; i++)
|
||||
{
|
||||
m_aPackets[m_NumPackets].m_Data.m_aMaplist[i] = *pCurrent;
|
||||
pCurrent++;
|
||||
}
|
||||
|
||||
m_aPackets[m_NumPackets].m_Size = sizeof(VERSIONSRV_MAPLIST) + sizeof(CMapVersion)*Chunk;
|
||||
|
||||
m_NumPackets++;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadNews()
|
||||
{
|
||||
IOHANDLE NewsFile = io_open("news", IOFLAG_READ);
|
||||
if (!NewsFile)
|
||||
return;
|
||||
|
||||
io_read(NewsFile, m_aNews, NEWS_SIZE);
|
||||
|
||||
io_close(NewsFile);
|
||||
}
|
||||
|
||||
void ReadServerList()
|
||||
{
|
||||
mem_zero(m_aServerList, sizeof(m_aServerList));
|
||||
|
||||
IOHANDLE File = io_open("serverlist.json", IOFLAG_READ);
|
||||
if (!File)
|
||||
return;
|
||||
|
||||
int PlainLength = io_length(File);
|
||||
char aPlain[16384];
|
||||
|
||||
io_read(File, aPlain, sizeof(aPlain));
|
||||
io_close(File);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
void SendVer(NETADDR *pAddr)
|
||||
{
|
||||
CNetChunk p;
|
||||
unsigned char aData[sizeof(VERSIONSRV_VERSION) + sizeof(GAME_RELEASE_VERSION)];
|
||||
|
||||
mem_copy(aData, VERSIONSRV_VERSION, sizeof(VERSIONSRV_VERSION));
|
||||
mem_copy(aData + sizeof(VERSIONSRV_VERSION), GAME_RELEASE_VERSION, sizeof(GAME_RELEASE_VERSION));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Packet: VERSIONSRV_DDNETLIST + char[4] Token + int16 comp_length + int16 plain_length + char[comp_length]
|
||||
void SendServerList(NETADDR *pAddr, const char *Token)
|
||||
{
|
||||
CNetChunk p;
|
||||
unsigned char aData[16384];
|
||||
short WordCompLength = m_ServerListCompLength;
|
||||
short WordPlainLength = m_ServerListPlainLength;
|
||||
|
||||
mem_copy(aData, VERSIONSRV_DDNETLIST, sizeof(VERSIONSRV_DDNETLIST));
|
||||
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
|
||||
mem_copy(aData + sizeof(VERSIONSRV_DDNETLIST)+8, m_aServerList, m_ServerListCompLength);
|
||||
|
||||
p.m_ClientID = -1;
|
||||
p.m_Address = *pAddr;
|
||||
p.m_Flags = NETSENDFLAG_CONNLESS;
|
||||
p.m_pData = aData;
|
||||
p.m_DataSize = sizeof(VERSIONSRV_DDNETLIST) + 4 + 2 + 2 + m_ServerListCompLength;
|
||||
|
||||
g_NetOp.Send(&p);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) // ignore_convention
|
||||
{
|
||||
NETADDR BindAddr;
|
||||
|
||||
dbg_logger_stdout();
|
||||
net_init();
|
||||
|
||||
mem_zero(&BindAddr, sizeof(BindAddr));
|
||||
BindAddr.type = NETTYPE_ALL;
|
||||
BindAddr.port = VERSIONSRV_PORT;
|
||||
if(!g_NetOp.Open(BindAddr, 0))
|
||||
{
|
||||
dbg_msg("mastersrv", "couldn't start network");
|
||||
return -1;
|
||||
}
|
||||
|
||||
BuildPackets();
|
||||
|
||||
ReadNews();
|
||||
ReadServerList();
|
||||
|
||||
dbg_msg("versionsrv", "started");
|
||||
|
||||
while(1)
|
||||
{
|
||||
g_NetOp.Update();
|
||||
|
||||
// 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);
|
||||
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(&Packet.m_Address, aAddrStr, sizeof(aAddrStr), false);
|
||||
dbg_msg("versionsrv", "version request by %s", aAddrStr);
|
||||
}
|
||||
|
||||
if(Packet.m_DataSize == sizeof(VERSIONSRV_GETNEWS) &&
|
||||
mem_comp(Packet.m_pData, VERSIONSRV_GETNEWS, sizeof(VERSIONSRV_GETNEWS)) == 0)
|
||||
{
|
||||
SendNews(&Packet.m_Address);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_ServerListLoaded &&
|
||||
Packet.m_DataSize == sizeof(VERSIONSRV_GETDDNETLIST) + 4 &&
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// wait for input
|
||||
net_socket_read_wait(g_NetOp.m_Socket, 1000000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/* (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. */
|
||||
#ifndef VERSIONSRV_VERSIONSRV_H
|
||||
#define VERSIONSRV_VERSIONSRV_H
|
||||
static const int VERSIONSRV_PORT = 8302;
|
||||
static const int NEWS_SIZE = 1380;
|
||||
static const int DDNETLIST_SIZE = 1380;
|
||||
|
||||
struct CMapVersion
|
||||
{
|
||||
char m_aName[8];
|
||||
unsigned char m_aCrc[4];
|
||||
unsigned char m_aSize[4];
|
||||
};
|
||||
|
||||
static const unsigned char VERSIONSRV_GETVERSION[] = {255, 255, 255, 255, 'v', 'e', 'r', 'g'};
|
||||
static const unsigned char VERSIONSRV_VERSION[] = {255, 255, 255, 255, 'v', 'e', 'r', 's'};
|
||||
|
||||
static const unsigned char VERSIONSRV_GETMAPLIST[] = {255, 255, 255, 255, 'v', 'm', 'l', 'g'};
|
||||
static const unsigned char VERSIONSRV_MAPLIST[] = {255, 255, 255, 255, 'v', 'm', 'l', 's'};
|
||||
|
||||
static const unsigned char VERSIONSRV_GETNEWS[] = {255, 255, 255, 255, 'n', 'e', 'w', 'g'};
|
||||
static const unsigned char VERSIONSRV_NEWS[] = {255, 255, 255, 255, 'n', 'e', 'w', 's'};
|
||||
|
||||
static const unsigned char VERSIONSRV_GETDDNETLIST[] = {255, 255, 255, 255, 'e', 'a', 's', 't'};
|
||||
static const unsigned char VERSIONSRV_DDNETLIST[] = {255, 255, 255, 255, 't', 's', 'a', 'e'};
|
||||
#endif
|
Loading…
Reference in a new issue