{
float time;
static double nextmsg = -1;
+#if 0
+ static double lasttime = -1;
+#endif
int oldreadcount;
qboolean oldbadread;
sizebuf_t old;
// no need if server is local and definitely not if this is a demo
- if (!cls.netcon || cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (!cls.netcon || cls.protocol == PROTOCOL_QUAKEWORLD || cls.signon >= SIGNONS)
return;
if (readmessages)
memcpy(net_message.data, olddata, net_message.cursize);
}
+#if 0
+ if((time = Sys_DoubleTime()) >= lasttime + 1)
+ {
+ Con_Printf("long delta: %f\n", time - lasttime);
+ }
+ lasttime = Sys_DoubleTime();
+#endif
+
if (cls.netcon && (time = Sys_DoubleTime()) >= nextmsg)
{
sizebuf_t msg;
// load or reload .loc file for team chat messages
CL_Locs_Reload_f();
+ // make sure we send enough keepalives
+ CL_KeepaliveMessage(false);
+
// reset particles and other per-level things
R_Modules_NewMap();
+ // make sure we send enough keepalives
+ CL_KeepaliveMessage(false);
+
// load the team chat beep if possible
cl.foundtalk2wav = FS_FileExists("sound/misc/talk2.wav");
{
if (cl.model_precache[cl.loadmodel_current] && cl.model_precache[cl.loadmodel_current]->Draw)
continue;
- if (cls.signon < SIGNONS)
- CL_KeepaliveMessage(true);
+ CL_KeepaliveMessage(true);
cl.model_precache[cl.loadmodel_current] = Mod_ForName(cl.model_name[cl.loadmodel_current], false, false, cl.loadmodel_current == 1);
if (cl.model_precache[cl.loadmodel_current] && cl.model_precache[cl.loadmodel_current]->Draw && cl.loadmodel_current == 1)
{
{
if (cl.sound_precache[cl.loadsound_current] && S_IsSoundPrecached(cl.sound_precache[cl.loadsound_current]))
continue;
- if (cls.signon < SIGNONS)
- CL_KeepaliveMessage(true);
+ CL_KeepaliveMessage(true);
// Don't lock the sfx here, S_ServerSounds already did that
cl.sound_precache[cl.loadsound_current] = S_PrecacheSound(cl.sound_name[cl.loadsound_current], false, false);
}
}
if (cl.model_precache[cl.downloadmodel_current] && cl.model_precache[cl.downloadmodel_current]->Draw)
continue;
- if (cls.signon < SIGNONS)
- CL_KeepaliveMessage(true);
+ CL_KeepaliveMessage(true);
if (strcmp(cl.model_name[cl.downloadmodel_current], "null") && !FS_FileExists(cl.model_name[cl.downloadmodel_current]))
{
if (cl.downloadmodel_current == 1)
}
if (cl.sound_precache[cl.downloadsound_current] && S_IsSoundPrecached(cl.sound_precache[cl.downloadsound_current]))
continue;
- if (cls.signon < SIGNONS)
- CL_KeepaliveMessage(true);
+ CL_KeepaliveMessage(true);
dpsnprintf(soundname, sizeof(soundname), "sound/%s", cl.sound_name[cl.downloadsound_current]);
if (!FS_FileExists(soundname) && !FS_FileExists(cl.sound_name[cl.downloadsound_current]))
{
cl.last_received_message = realtime;
- if (cls.netcon && cls.signon < SIGNONS)
- CL_KeepaliveMessage(false);
+ CL_KeepaliveMessage(false);
//
// if recording demos, copy the message out
void CL_Parse_ErrorCleanUp(void);
void QW_CL_StartUpload(unsigned char *data, int size);
extern cvar_t qport;
+void CL_KeepaliveMessage(qboolean readmessages); // call this during loading of large content
//
// view
GL_Texture_CalcImageSize(glt->texturetype, glt->flags, glt->inputwidth, glt->inputheight, glt->inputdepth, &glt->tilewidth, &glt->tileheight, &glt->tiledepth);
R_PrecacheTexture(glt);
+ // texture converting and uploading can take a while, so make sure we're sending keepalives
+ CL_KeepaliveMessage(false);
+
return (rtexture_t *)glt;
}
Con_Printf(format == firstformat ? "\"%s\"" : (format[1].formatstring ? ", \"%s\"" : " or \"%s\".\n"), format->formatstring);
}
}
+
+ // texture loading can take a while, so make sure we're sending keepalives
+ CL_KeepaliveMessage(false);
+
if (developer_memorydebug.integer)
Mem_CheckSentinelsGlobal();
return NULL;
}
Mod_ShadowMesh_AddTriangle(mempool, mesh, map_diffuse, map_specular, map_normal, vbuf);
}
+
+ // the triangle calculation can take a while, so let's do a keepalive here
+ CL_KeepaliveMessage(false);
}
shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int neighbors, int expandable)
{
+ // the preparation before shadow mesh initialization can take a while, so let's do a keepalive here
+ CL_KeepaliveMessage(false);
+
return Mod_ShadowMesh_Alloc(mempool, maxverts, maxtriangles, map_diffuse, map_specular, map_normal, light, neighbors, expandable);
}
}
Mem_Free(mesh);
}
+
+ // this can take a while, so let's do a keepalive here
+ CL_KeepaliveMessage(false);
+
return firstmesh;
}
static unsigned char net_message_buf[NET_MAXMESSAGE];
cvar_t net_messagetimeout = {0, "net_messagetimeout","300", "drops players who have not sent any packets for this many seconds"};
-cvar_t net_connecttimeout = {0, "net_connecttimeout","10", "after requesting a connection, the client must reply within this many seconds or be dropped (cuts down on connect floods)"};
+cvar_t net_connecttimeout = {0, "net_connecttimeout","15", "after requesting a connection, the client must reply within this many seconds or be dropped (cuts down on connect floods). Must be above 10 seconds."};
cvar_t net_connectfloodblockingtimeout = {0, "net_connectfloodblockingtimeout", "5", "when a connection packet is received, it will block all future connect packets from that IP address for this many seconds (cuts down on connect floods)"};
cvar_t hostname = {CVAR_SAVE, "hostname", "UNNAMED", "server message to show in server browser"};
cvar_t developer_networking = {0, "developer_networking", "0", "prints all received and sent packets (recommended only for debugging)"};
static void SV_StartDownload_f(void);
static void SV_Download_f(void);
static void SV_VM_Setup();
+extern cvar_t net_connecttimeout;
void VM_CustomStats_Clear (void);
void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
client->num_pings = 0;
#endif
client->ping = 0;
+
+ // allow the client some time to send his keepalives, even if map loading took ages
+ client->netconnection->timeout = realtime + net_connecttimeout.value;
}
/*
/*
================
-SV_SpawnServer
+SV_/pawnServer
This is called at the start of each level
================
// create a baseline for more efficient communications
if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
SV_CreateBaseline ();
-
+
+ // to prevent network timeouts
+ realtime = Sys_DoubleTime();
+
// send serverinfo to all connected clients, and set up botclients coming back from a level change
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
{