*/
// net_master.c
-#include <malloc.h>
#include "quakedef.h"
+
cvar_t sv_masters [] =
{
{CVAR_SAVE, "sv_master1", ""},
{CVAR_SAVE, "sv_master4", ""}
};
+static qboolean masteravailable = false;
+static double nextheartbeattime = 0;
+static unsigned int nbtries = 6;
+
+
+/*
+====================
+Master_AllowHeartbeat
+
+Allow (or not) NET_Heartbeat to proceed depending on various factors
+====================
+*/
+qboolean Master_AllowHeartbeat (int priority)
+{
+ // We try "nbtries" times to contact a master server before giving up
+ if (! masteravailable)
+ {
+ if (!nbtries || realtime < nextheartbeattime)
+ return false;
+
+ nbtries--;
+ }
+ else
+ {
+ // if it's a state change, it can wait a little bit (30 sec max for now)
+ if (priority == 1 && nextheartbeattime - realtime > 30.0)
+ {
+ nextheartbeattime = realtime + 30.0;
+ return false;
+ }
+
+ if (priority <= 1 && realtime < nextheartbeattime)
+ return false;
+ }
+
+ // send an heartbeat every 3 minutes by default (every 5 sec if we haven't yet found a master server)
+ // TODO: some cvars would be better than hardcoded values
+ nextheartbeattime = realtime + (masteravailable ? (3.0 * 60.0) : 5.0);
+ return true;
+}
+
/*
====================
Build a getservers request for a master server
====================
*/
-char* Master_BuildGetServers (void)
+const char* Master_BuildGetServers (void)
{
static int nextmaster = 0;
cvar_t* sv_master;
Build an heartbeat for a master server
====================
*/
-char* Master_BuildHeartbeat (void)
+const char* Master_BuildHeartbeat (void)
{
static int nextmaster = 0;
cvar_t* sv_master;
char response [512];
size_t length;
+ masteravailable = true;
+
length = snprintf (response, sizeof (response), "infoResponse\x0A"
"\\gamename\\%s\\modname\\%s\\sv_maxclients\\%d"
"\\clients\\%d\\mapname\\%s\\hostname\\%s\\protocol\\%d",
{
int control;
qbyte* servers;
+ qbyte* crtserver;
int ipaddr;
struct qsockaddr svaddr;
char ipstring [32];
if (strncmp (net_message.data + 4, "getserversResponse\\", 19))
return;
- // Skip the next 18 bytes
+ // Skip the next 19 bytes
MSG_ReadLong(); MSG_ReadLong(); MSG_ReadLong(); MSG_ReadLong();
MSG_ReadShort(); MSG_ReadByte();
- servers = alloca (net_message.cursize - 23);
+ crtserver = servers = Z_Malloc (net_message.cursize - 23);
memcpy (servers , net_message.data + 23, net_message.cursize - 23);
// Extract the IP addresses
- while ((ipaddr = (servers[3] << 24) + (servers[2] << 16) + (servers[1] << 8) + servers[0]) != -1)
+ while ((ipaddr = (crtserver[3] << 24) | (crtserver[2] << 16) | (crtserver[1] << 8) | crtserver[0]) != -1)
{
- int port = (servers[5] << 8) + servers[4];
+ int port = (crtserver[5] << 8) | crtserver[4];
if (port == -1 || port == 0)
break;
dfunc->Write(dfunc->controlSock, net_message.data, net_message.cursize, &svaddr);
SZ_Clear(&net_message);
- if (servers[6] != '\\')
+ if (crtserver[6] != '\\')
break;
- servers += 7;
+ crtserver += 7;
}
+
+ Z_Free (servers);
}