X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=net_master.c;h=1f63d17f614b7800ab82b3cb686f601dae54b724;hb=0896ffc41ce8fdf985d5659b2b572763c527fdf9;hp=8fd7ed8c46bd6e5c4f6915802bf0cfdc8559df35;hpb=04826446c325116c03990a9faf04d6439816a6e2;p=xonotic%2Fdarkplaces.git diff --git a/net_master.c b/net_master.c index 8fd7ed8c..1f63d17f 100644 --- a/net_master.c +++ b/net_master.c @@ -19,17 +19,58 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // net_master.c -#include #include "quakedef.h" + +cvar_t sv_public = {0, "sv_public", "0"}; +cvar_t sv_heartbeatperiod = {CVAR_SAVE, "sv_heartbeatperiod", "180"}; + cvar_t sv_masters [] = { + {0, "sv_masterextra1", "68.102.242.12"}, {CVAR_SAVE, "sv_master1", ""}, {CVAR_SAVE, "sv_master2", ""}, {CVAR_SAVE, "sv_master3", ""}, {CVAR_SAVE, "sv_master4", ""} }; +static double nextheartbeattime = 0; + + +/* +==================== +Master_AllowHeartbeat + +Allow (or not) NET_Heartbeat to proceed depending on various factors +==================== +*/ +qboolean Master_AllowHeartbeat (int priority) +{ + // LordHavoc: make advertising optional + if (!sv_public.integer) + return false; + // LordHavoc: don't advertise singleplayer games + if (svs.maxclients < 2) + return false; + // if it's a state change (client connected), limit next heartbeat to no + // more than 30 sec in the future + if (priority == 1 && nextheartbeattime > realtime + 30.0) + nextheartbeattime = realtime + 30.0; + if (priority <= 1 && realtime < nextheartbeattime) + return false; + // limit heartbeatperiod to 30 to 270 second range, + // lower limit is to avoid abusing master servers with excess traffic, + // upper limit is to avoid timing out on the master server (which uses + // 300 sec timeout) + if (sv_heartbeatperiod.value < 30) + Cvar_SetValueQuick(&sv_heartbeatperiod, 30); + if (sv_heartbeatperiod.value > 270) + Cvar_SetValueQuick(&sv_heartbeatperiod, 270); + // send a heartbeat as often as the admin wants + nextheartbeattime = realtime + sv_heartbeatperiod.value; + return true; +} + /* ==================== @@ -38,13 +79,13 @@ Master_BuildGetServers 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; char request [256]; - - if (nextmaster >= sizeof (sv_masters) / sizeof (sv_masters[0])) + + if (nextmaster >= (int)(sizeof (sv_masters) / sizeof (sv_masters[0]))) { nextmaster = 0; return NULL; @@ -58,7 +99,7 @@ char* Master_BuildGetServers (void) nextmaster = 0; return NULL; } - + // Build the heartbeat snprintf (request, sizeof (request), "getservers %s %u empty full\x0A", gamename, NET_PROTOCOL_VERSION); SZ_Clear (&net_message); @@ -78,12 +119,12 @@ Master_BuildHeartbeat Build an heartbeat for a master server ==================== */ -char* Master_BuildHeartbeat (void) +const char* Master_BuildHeartbeat (void) { static int nextmaster = 0; cvar_t* sv_master; - - if (nextmaster >= sizeof (sv_masters) / sizeof (sv_masters[0])) + + if (nextmaster >= (int)(sizeof (sv_masters) / sizeof (sv_masters[0]))) { nextmaster = 0; return NULL; @@ -97,7 +138,7 @@ char* Master_BuildHeartbeat (void) nextmaster = 0; return NULL; } - + // Build the heartbeat SZ_Clear (&net_message); MSG_WriteLong (&net_message, -1); @@ -169,6 +210,8 @@ Initialize the code that handles master server requests and reponses void Master_Init (void) { unsigned int ind; + Cvar_RegisterVariable (&sv_public); + Cvar_RegisterVariable (&sv_heartbeatperiod); for (ind = 0; ind < sizeof (sv_masters) / sizeof (sv_masters[0]); ind++) Cvar_RegisterVariable (&sv_masters[ind]); } @@ -185,11 +228,12 @@ void Master_ParseServerList (net_landriver_t* dfunc) { int control; qbyte* servers; + qbyte* crtserver; int ipaddr; struct qsockaddr svaddr; char ipstring [32]; - if (net_message.cursize < sizeof(int)) + if (net_message.cursize < (int)sizeof(int)) return; // is the cache full? @@ -205,17 +249,17 @@ void Master_ParseServerList (net_landriver_t* dfunc) 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; @@ -238,8 +282,10 @@ void Master_ParseServerList (net_landriver_t* dfunc) 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); }