Cache serverinfo responses

This commit is contained in:
Learath2 2019-11-03 00:33:30 +01:00
parent 516bc98436
commit 7f0589bff7
2 changed files with 147 additions and 35 deletions

View file

@ -1502,7 +1502,49 @@ void CServer::SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type)
SendServerInfo(pAddr, Token, Type, SendClients); SendServerInfo(pAddr, Token, Type, SendClients);
} }
void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients) void CServer::CCache::AddChunk(const void *pData, int Size)
{
SCacheChunk *pNew = new SCacheChunk;
if(!pNew)
return;
pNew->m_pData = malloc(Size);
if(!pNew->m_pData) {
delete pNew;
return;
}
mem_copy(pNew->m_pData, pData, Size);
pNew->m_DataSize = Size;
if(!m_pRoot)
m_pRoot = m_pTail = pNew;
else
{
m_pTail->m_pNext = pNew;
m_pTail = pNew;
}
}
void CServer::CCache::Clear()
{
if(!m_pRoot)
return;
SCacheChunk *pChunk = m_pRoot, *pTmp = 0;
while(pChunk)
{
pTmp = pChunk;
pChunk = pChunk->m_pNext;
free(pTmp->m_pData);
delete pTmp;
}
m_pRoot = 0;
m_pTail = 0;
}
void CServer::CacheServerInfo(CCache *pCache, int Type, bool SendClients)
{ {
// One chance to improve the protocol! // One chance to improve the protocol!
CPacker p; CPacker p;
@ -1526,17 +1568,6 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
#define ADD_RAW(p, x) (p).AddRaw(x, sizeof(x)) #define ADD_RAW(p, x) (p).AddRaw(x, sizeof(x))
#define ADD_INT(p, x) do { str_format(aBuf, sizeof(aBuf), "%d", x); (p).AddString(aBuf, 0); } while(0) #define ADD_INT(p, x) do { str_format(aBuf, sizeof(aBuf), "%d", x); (p).AddString(aBuf, 0); } while(0)
switch(Type)
{
case SERVERINFO_EXTENDED: ADD_RAW(p, SERVERBROWSE_INFO_EXTENDED); break;
case SERVERINFO_64_LEGACY: ADD_RAW(p, SERVERBROWSE_INFO_64_LEGACY); break;
case SERVERINFO_VANILLA: ADD_RAW(p, SERVERBROWSE_INFO); break;
case SERVERINFO_INGAME: ADD_RAW(p, SERVERBROWSE_INFO); break;
default: dbg_assert(false, "unknown serverinfo type");
}
ADD_INT(p, Token);
p.AddString(GameServer()->Version(), 32); p.AddString(GameServer()->Version(), 32);
if(Type != SERVERINFO_VANILLA) if(Type != SERVERINFO_VANILLA)
{ {
@ -1596,20 +1627,14 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
int PrefixSize = p.Size(); int PrefixSize = p.Size();
CPacker pp; CPacker pp;
CNetChunk Packet; int ChunksSaved = 0;
int PacketsSent = 0; int PlayersSaved = 0;
int PlayersSent = 0;
Packet.m_ClientID = -1;
Packet.m_Address = *pAddr;
Packet.m_Flags = NETSENDFLAG_CONNLESS;
#define SEND(size) \ #define SAVE(size) \
do \ do \
{ \ { \
Packet.m_pData = pp.Data(); \ pCache->AddChunk(pp.Data(), size); \
Packet.m_DataSize = size; \ ChunksSaved++; \
m_NetServer.Send(&Packet); \
PacketsSent++; \
} while(0) } while(0)
#define RESET() \ #define RESET() \
@ -1622,18 +1647,18 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
RESET(); RESET();
if(Type == SERVERINFO_64_LEGACY) if(Type == SERVERINFO_64_LEGACY)
pp.AddInt(PlayersSent); // offset pp.AddInt(PlayersSaved); // offset
if(!SendClients) if(!SendClients)
{ {
SEND(pp.Size()); SAVE(pp.Size());
return; return;
} }
if(Type == SERVERINFO_EXTENDED) if(Type == SERVERINFO_EXTENDED)
{ {
pPrefix = SERVERBROWSE_INFO_EXTENDED_MORE; pPrefix = "";
PrefixSize = sizeof(SERVERBROWSE_INFO_EXTENDED_MORE); PrefixSize = 0;
} }
int Remaining; int Remaining;
@ -1661,9 +1686,9 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
break; break;
// Otherwise we're SERVERINFO_64_LEGACY. // Otherwise we're SERVERINFO_64_LEGACY.
SEND(pp.Size()); SAVE(pp.Size());
RESET(); RESET();
pp.AddInt(PlayersSent); // offset pp.AddInt(PlayersSaved); // offset
Remaining = 24; Remaining = 24;
} }
if(Remaining > 0) if(Remaining > 0)
@ -1688,25 +1713,79 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
{ {
// Retry current player. // Retry current player.
i--; i--;
SEND(PreviousSize); SAVE(PreviousSize);
RESET(); RESET();
ADD_INT(pp, Token); ADD_INT(pp, ChunksSaved);
ADD_INT(pp, PacketsSent);
pp.AddString("", 0); // extra info, reserved pp.AddString("", 0); // extra info, reserved
continue; continue;
} }
} }
PlayersSent++; PlayersSaved++;
} }
} }
SEND(pp.Size()); SAVE(pp.Size());
#undef SEND #undef SAVE
#undef RESET #undef RESET
#undef ADD_RAW #undef ADD_RAW
#undef ADD_INT #undef ADD_INT
} }
void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients)
{
CPacker p;
char aBuf[128];
p.Reset();
CCache::SCacheChunk *pFirstChunk = m_ServerInfoCache[Type * 2 + SendClients].GetFirst();
#define ADD_RAW(p, x) (p).AddRaw(x, sizeof(x))
#define ADD_INT(p, x) do { str_format(aBuf, sizeof(aBuf), "%d", x); (p).AddString(aBuf, 0); } while(0)
switch(Type)
{
case SERVERINFO_EXTENDED: ADD_RAW(p, SERVERBROWSE_INFO_EXTENDED); break;
case SERVERINFO_64_LEGACY: ADD_RAW(p, SERVERBROWSE_INFO_64_LEGACY); break;
case SERVERINFO_VANILLA: ADD_RAW(p, SERVERBROWSE_INFO); break;
case SERVERINFO_INGAME: ADD_RAW(p, SERVERBROWSE_INFO); break;
default: dbg_assert(false, "unknown serverinfo type");
}
ADD_INT(p, Token);
p.AddRaw(pFirstChunk->m_pData, pFirstChunk->m_DataSize);
CNetChunk Packet;
Packet.m_ClientID = -1;
Packet.m_Address = *pAddr;
Packet.m_Flags = NETSENDFLAG_CONNLESS;
Packet.m_pData = p.Data();
Packet.m_DataSize = p.Size();
m_NetServer.Send(&Packet);
if(Type == SERVERINFO_INGAME || Type == SERVERINFO_VANILLA)
return;
for(CCache::SCacheChunk *pChunk = pFirstChunk->m_pNext; pChunk; pChunk = pChunk->m_pNext)
{
p.Reset();
if(Type == SERVERINFO_EXTENDED)
{
p.AddRaw(SERVERBROWSE_INFO_EXTENDED_MORE, sizeof(SERVERBROWSE_INFO_EXTENDED_MORE));
ADD_INT(p, Token);
}
else if(Type == SERVERINFO_64_LEGACY)
{
p.AddRaw(pFirstChunk->m_pData, pFirstChunk->m_DataSize);
}
p.AddRaw(pChunk->m_pData, pChunk->m_DataSize);
Packet.m_pData = p.Data();
Packet.m_DataSize = p.Size();
m_NetServer.Send(&Packet);
}
}
void CServer::UpdateServerInfo() void CServer::UpdateServerInfo()
{ {
for(int i = 0; i < MAX_CLIENTS; ++i) for(int i = 0; i < MAX_CLIENTS; ++i)
@ -2066,6 +2145,15 @@ int CServer::Run()
// master server stuff // master server stuff
m_Register.RegisterUpdate(m_NetServer.NetType()); m_Register.RegisterUpdate(m_NetServer.NetType());
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 2; j++)
{
m_ServerInfoCache[i * 2 + j].Clear();
CacheServerInfo(&m_ServerInfoCache[i * 2 + j], i, j);
}
}
if(!NonActive) if(!NonActive)
PumpNetwork(); PumpNetwork();
@ -2121,6 +2209,10 @@ int CServer::Run()
m_NetServer.Drop(i, pDisconnectReason); m_NetServer.Drop(i, pDisconnectReason);
} }
for(int i = 0; i < 3; i++)
for(int j = 0; j < 2; j++)
m_ServerInfoCache[i * 2 + j].Clear();
m_Econ.Shutdown(); m_Econ.Shutdown();
#if defined(CONF_FAMILY_UNIX) #if defined(CONF_FAMILY_UNIX)

View file

@ -291,6 +291,26 @@ public:
void ProcessClientPacket(CNetChunk *pPacket); void ProcessClientPacket(CNetChunk *pPacket);
class CCache {
public:
struct SCacheChunk {
int m_DataSize;
void *m_pData;
SCacheChunk *m_pNext;
};
private:
SCacheChunk *m_pRoot, *m_pTail;
public:
void AddChunk(const void *pData, int Size);
SCacheChunk *GetFirst() { return m_pRoot; };
void Clear();
};
CCache m_ServerInfoCache[3 * 2];
void CacheServerInfo(CCache *pCache, int Type, bool SendClients);
void SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients); void SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients);
void SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type); void SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type);
void UpdateServerInfo(); void UpdateServerInfo();