cvar_t sv_checkforpacketsduringsleep = {0, "sv_checkforpacketsduringsleep", "0", "uses select() function to wait between frames which can be interrupted by packets being received, instead of Sleep()/usleep()/SDL_Sleep() functions which do not check for packets"};
cvar_t sv_clmovement_enable = {0, "sv_clmovement_enable", "1", "whether to allow clients to use cl_movement prediction, which can cause choppy movement on the server which may annoy other players"};
cvar_t sv_clmovement_minping = {0, "sv_clmovement_minping", "0", "if client ping is below this time in milliseconds, then their ability to use cl_movement prediction is disabled for a while (as they don't need it)"};
+cvar_t sv_clmovement_maxnetfps = {0, "sv_clmovement_maxnetfps", "80", "max amount of movement packets to accept per second"};
cvar_t sv_clmovement_minping_disabletime = {0, "sv_clmovement_minping_disabletime", "1000", "when client falls below minping, disable their prediction for this many milliseconds (should be at least 1000 or else their prediction may turn on/off frequently)"};
cvar_t sv_clmovement_inputtimeout = {0, "sv_clmovement_inputtimeout", "0.2", "when a client does not send input for this many seconds, force them to move anyway (unlike QuakeWorld)"};
cvar_t sv_cullentities_nevercullbmodels = {0, "sv_cullentities_nevercullbmodels", "0", "if enabled the clients are always notified of moving doors and lifts and other submodels of world (warning: eats a lot of network bandwidth on some levels!)"};
cvar_t sv_autodemo_perclient = {CVAR_SAVE, "sv_autodemo_perclient", "0", "set to 1 to enable autorecorded per-client demos (they'll start to record at the beginning of a match); set it to 2 to also record client->server packets (for debugging)"};
cvar_t sv_autodemo_perclient_nameformat = {CVAR_SAVE, "sv_autodemo_perclient_nameformat", "sv_autodemos/%Y-%m-%d_%H-%M", "The format of the sv_autodemo_perclient filename, followed by the map name, the client number and the IP address + port number, separated by underscores (the date is encoded using strftime escapes)" };
+cvar_t halflifebsp = {0, "halflifebsp", "0", "indicates the current map is hlbsp format (useful to know because of different bounding box sizes)"};
server_t sv;
server_static_t svs;
Cvar_RegisterVariable (&sv_areagrid_mingridsize);
Cvar_RegisterVariable (&sv_checkforpacketsduringsleep);
Cvar_RegisterVariable (&sv_clmovement_enable);
+ Cvar_RegisterVariable (&sv_clmovement_maxnetfps);
Cvar_RegisterVariable (&sv_clmovement_minping);
Cvar_RegisterVariable (&sv_clmovement_minping_disabletime);
Cvar_RegisterVariable (&sv_clmovement_inputtimeout);
Cvar_RegisterVariable (&sv_autodemo_perclient);
Cvar_RegisterVariable (&sv_autodemo_perclient_nameformat);
+ Cvar_RegisterVariable (&halflifebsp);
+
// any special defaults for gamemodes go here
if (gamemode == GAME_HIPNOTIC)
{
sb.data = (unsigned char *) buf;
sb.maxsize = sizeof(buf);
i = 0;
- while(MakeDownloadPacket(sv.csqc_progname, sv.csqc_progdata, sv.csqc_progsize, sv.csqc_progcrc, i++, &sb, sv.protocol))
+ while(MakeDownloadPacket(sv.csqc_progname, svs.csqc_progdata, sv.csqc_progsize, sv.csqc_progcrc, i++, &sb, sv.protocol))
SV_WriteDemoMessage(client, &sb, false);
}
Con_DPrintf("Downloading %s to %s\n", host_client->download_name, host_client->name);
if(host_client->download_deflate)
- host_client->download_file = FS_FileFromData(sv.csqc_progdata_deflated, sv.csqc_progsize_deflated, true);
+ host_client->download_file = FS_FileFromData(svs.csqc_progdata_deflated, svs.csqc_progsize_deflated, true);
else
- host_client->download_file = FS_FileFromData(sv.csqc_progdata, sv.csqc_progsize, true);
+ host_client->download_file = FS_FileFromData(svs.csqc_progdata, sv.csqc_progsize, true);
// no, no space is needed between %s and %s :P
Host_ClientCommands("\ncl_downloadbegin %i %s%s\n", (int)FS_FileSize(host_client->download_file), host_client->download_name, extensions);
if (precachemode == 1)
Con_Printf("SV_ModelIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename);
strlcpy(sv.model_precache[i], filename, sizeof(sv.model_precache[i]));
- sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, false);
+ sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, s[0] == '*' ? sv.modelname : NULL);
if (sv.state != ss_loading)
{
MSG_WriteByte(&sv.reliable_datagram, svc_precache);
{
fs_offset_t progsize;
- if(sv.csqc_progdata)
+ if(svs.csqc_progdata)
{
Con_DPrintf("Unloading old CSQC data.\n");
- Mem_Free(sv.csqc_progdata);
- if(sv.csqc_progdata_deflated)
- Mem_Free(sv.csqc_progdata_deflated);
+ Mem_Free(svs.csqc_progdata);
+ if(svs.csqc_progdata_deflated)
+ Mem_Free(svs.csqc_progdata_deflated);
}
- sv.csqc_progdata = NULL;
- sv.csqc_progdata_deflated = NULL;
+ svs.csqc_progdata = NULL;
+ svs.csqc_progdata_deflated = NULL;
Con_Print("Loading csprogs.dat\n");
sv.csqc_progname[0] = 0;
- sv.csqc_progdata = FS_LoadFile(csqc_progname.string, sv_mempool, false, &progsize);
+ svs.csqc_progdata = FS_LoadFile(csqc_progname.string, sv_mempool, false, &progsize);
if(progsize > 0)
{
size_t deflated_size;
sv.csqc_progsize = (int)progsize;
- sv.csqc_progcrc = CRC_Block(sv.csqc_progdata, progsize);
+ sv.csqc_progcrc = CRC_Block(svs.csqc_progdata, progsize);
strlcpy(sv.csqc_progname, csqc_progname.string, sizeof(sv.csqc_progname));
Con_Printf("server detected csqc progs file \"%s\" with size %i and crc %i\n", sv.csqc_progname, sv.csqc_progsize, sv.csqc_progcrc);
Con_Print("Compressing csprogs.dat\n");
//unsigned char *FS_Deflate(const unsigned char *data, size_t size, size_t *deflated_size, int level, mempool_t *mempool);
- sv.csqc_progdata_deflated = FS_Deflate(sv.csqc_progdata, progsize, &deflated_size, -1, sv_mempool);
- sv.csqc_progsize_deflated = (int)deflated_size;
+ svs.csqc_progdata_deflated = FS_Deflate(svs.csqc_progdata, progsize, &deflated_size, -1, sv_mempool);
+ svs.csqc_progsize_deflated = (int)deflated_size;
Con_Printf("Deflated: %g%%\n", 100.0 - 100.0 * (deflated_size / (float)progsize));
- Con_DPrintf("Uncompressed: %u\nCompressed: %u\n", (unsigned)sv.csqc_progsize, (unsigned)sv.csqc_progsize_deflated);
+ Con_DPrintf("Uncompressed: %u\nCompressed: %u\n", (unsigned)sv.csqc_progsize, (unsigned)svs.csqc_progsize_deflated);
}
}
/*
================
-SV_/pawnServer
+SV_SpawnServer
This is called at the start of each level
================
SV_VM_End();
}
- worldmodel = Mod_ForName(modelname, false, true, true);
+ // free q3 shaders so that any newly downloaded shaders will be active
+ Mod_FreeQ3Shaders();
+
+ worldmodel = Mod_ForName(modelname, false, true, NULL);
if (!worldmodel || !worldmodel->TraceBox)
{
Con_Printf("Couldn't load map %s\n", modelname);
// level's data which is no longer valiud
cls.signon = 0;
+ Cvar_SetValue("halflifebsp", worldmodel->brush.ishlbsp);
+
if(*sv_random_seed.string)
{
srand(sv_random_seed.integer);
for (i = 1;i < sv.worldmodel->brush.numsubmodels;i++)
{
dpsnprintf(sv.model_precache[i+1], sizeof(sv.model_precache[i+1]), "*%i", i);
- sv.models[i+1] = Mod_ForName (sv.model_precache[i+1], false, false, false);
+ sv.models[i+1] = Mod_ForName (sv.model_precache[i+1], false, false, sv.modelname);
}
//
VectorClear(prog->edicts->fields.server->angles);
// all setup is completed, any further precache statements are errors
- sv.state = ss_active;
+// sv.state = ss_active; // LordHavoc: workaround for svc_precache bug
prog->allowworldwrites = false;
// run two frames to allow everything to settle
+ prog->globals.server->time = sv.time = 1.0001;
for (i = 0;i < 2;i++)
{
sv.frametime = 0.1;
SV_Physics ();
}
- Mod_PurgeUnused();
+ if (cls.state == ca_dedicated)
+ Mod_PurgeUnused();
// 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 ();
-
+
+ sv.state = ss_active; // LordHavoc: workaround for svc_precache bug
+
// to prevent network timeouts
realtime = Sys_DoubleTime();