cvar_t timelimit = {CVAR_SERVER | CVAR_NOTIFY, "timelimit","0", "ends level at this time (in minutes)"};
cvar_t sv_threaded = {CVAR_SERVER, "sv_threaded", "0", "enables a separate thread for server code, improving performance, especially when hosting a game while playing, EXPERIMENTAL, may be crashy"};
+cvar_t sv_rollspeed = {CVAR_CLIENT, "sv_rollspeed", "200", "how much strafing is necessary to tilt the view"};
+cvar_t sv_rollangle = {CVAR_CLIENT, "sv_rollangle", "2.0", "how much to tilt the view when strafing"};
+
cvar_t saved1 = {CVAR_SERVER | CVAR_SAVE, "saved1", "0", "unused cvar in quake that is saved to config.cfg on exit, can be used by mods"};
cvar_t saved2 = {CVAR_SERVER | CVAR_SAVE, "saved2", "0", "unused cvar in quake that is saved to config.cfg on exit, can be used by mods"};
cvar_t saved3 = {CVAR_SERVER | CVAR_SAVE, "saved3", "0", "unused cvar in quake that is saved to config.cfg on exit, can be used by mods"};
Cvar_RegisterVariable (&timelimit);
Cvar_RegisterVariable (&sv_threaded);
+ Cvar_RegisterVariable (&sv_rollangle);
+ Cvar_RegisterVariable (&sv_rollspeed);
+
Cvar_RegisterVariable (&saved1);
Cvar_RegisterVariable (&saved2);
Cvar_RegisterVariable (&saved3);
==================
*/
-void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int nvolume, float attenuation, qboolean reliable, float speed)
+void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int nvolume, float attenuation, qbool reliable, float speed)
{
prvm_prog_t *prog = SVVM_prog;
sizebuf_t *dest;
if (crash = true), don't bother sending signofs
=====================
*/
-void SV_DropClient(qboolean crash)
+void SV_DropClient(qbool crash)
{
prvm_prog_t *prog = SVVM_prog;
int i;
=============================================================================
*/
-static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, int enumber)
+static qbool SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, int enumber)
{
prvm_prog_t *prog = SVVM_prog;
int i;
#define MAX_LINEOFSIGHTTRACES 64
-qboolean SV_CanSeeBox(int numtraces, vec_t eyejitter, vec_t enlarge, vec_t entboxexpand, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
+qbool SV_CanSeeBox(int numtraces, vec_t eyejitter, vec_t enlarge, vec_t entboxexpand, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
{
prvm_prog_t *prog = SVVM_prog;
float pitchsign;
static void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t *msg, int maxsize)
{
prvm_prog_t *prog = SVVM_prog;
- qboolean need_empty = false;
+ qbool need_empty = false;
int i, numsendstates, numcsqcsendstates;
entity_state_t *s;
prvm_edict_t *camera;
- qboolean success;
+ qbool success;
vec3_t eye;
// if there isn't enough space to accomplish anything, skip it
//strlcpy (host_client->name, name, sizeof (host_client->name));
if (name != host_client->name) // prevent buffer overlap SIGABRT on Mac OSX
strlcpy (host_client->name, name, sizeof (host_client->name));
- PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(prog, host_client->name);
- if (strcmp(host_client->old_name, host_client->name))
- {
- if (host_client->begun)
- SV_BroadcastPrintf("%s ^7changed name to %s\n", host_client->old_name, host_client->name);
- strlcpy(host_client->old_name, host_client->name, sizeof(host_client->old_name));
- // send notification to all clients
- MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
- MSG_WriteByte (&sv.reliable_datagram, i);
- MSG_WriteString (&sv.reliable_datagram, host_client->name);
- SV_WriteNetnameIntoDemo(host_client);
- }
+ SV_Name(i);
// DP_SV_CLIENTCOLORS
host_client->colors = (int)PRVM_serveredictfloat(host_client->edict, clientcolors);
static void SV_Download_f(cmd_state_t *cmd)
{
const char *whichpack, *whichpack2, *extension;
- qboolean is_csqc; // so we need to check only once
+ qbool is_csqc; // so we need to check only once
if (Cmd_Argc(cmd) < 2)
{
dpsnprintf (modelname, sizeof(modelname), "maps/%s", map);
if (!FS_FileExists(modelname))
{
- Con_Printf("SpawnServer: no map file named maps/%s.bsp\n", map);
+ Con_Printf("SpawnServer: no map file named %s\n", modelname);
return;
}
}
Con_Printf("step :%3i\n", step);
}
-static qboolean SVVM_load_edict(prvm_prog_t *prog, prvm_edict_t *ent)
+static qbool SVVM_load_edict(prvm_prog_t *prog, prvm_edict_t *ent)
{
// remove things from different skill levels or deathmatch
if (gamemode != GAME_TRANSFUSION) //Transfusion does this in QC
{
static double sv_timer;
int i;
- qboolean playing;
char vabuf[1024];
-
- if((sv_timer += time) < 0)
- return sv_timer;
- // limit the frametime steps to no more than 100ms each
- if (sv_timer > 0.1)
- {
- if (!svs.threaded)
- svs.perf_acc_lost += (sv_timer - 0.1);
- sv_timer = 0.1;
- }
+ qbool playing = false;
if (!svs.threaded)
{
svs.perf_acc_realtime += time;
// Look for clients who have spawned
- playing = false;
- for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
- if(host_client->begun)
- if(host_client->netconnection)
- playing = true;
- if(sv.time < 10)
- {
- // don't accumulate time for the first 10 seconds of a match
- // so things can settle
- svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = host.sleeptime = 0;
- }
- else if(svs.perf_acc_realtime > 5)
+ for (i = 0, host_client = svs.clients; i < svs.maxclients; i++, host_client++)
+ if(host_client->begun && host_client->netconnection)
+ playing = true;
+
+ if(svs.perf_acc_realtime > 5)
{
svs.perf_cpuload = 1 - svs.perf_acc_sleeptime / svs.perf_acc_realtime;
svs.perf_lost = svs.perf_acc_lost / svs.perf_acc_realtime;
+
if(svs.perf_acc_offset_samples > 0)
{
svs.perf_offset_max = svs.perf_acc_offset_max;
svs.perf_offset_avg = svs.perf_acc_offset / svs.perf_acc_offset_samples;
svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
}
- if(svs.perf_lost > 0 && developer_extra.integer)
- if(playing) // only complain if anyone is looking
- Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
- svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = host.sleeptime = 0;
+
+ if(svs.perf_lost > 0 && developer_extra.integer && playing) // only complain if anyone is looking
+ Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
}
- if (sv.active && sv_timer > 0)
+ if(svs.perf_acc_realtime > 5 || sv.time < 10)
{
- // execute one or more server frames, with an upper limit on how much
- // execution time to spend on server frames to avoid freezing the game if
- // the server is overloaded, this execution time limit means the game will
- // slow down if the server is taking too long.
- int framecount, framelimit = 1;
- double advancetime, aborttime = 0;
- float offset;
- prvm_prog_t *prog = SVVM_prog;
- // receive packets on each main loop iteration, as the main loop may
- // be undersleeping due to select() detecting a new packet
- if (sv.active && !svs.threaded)
- NetConn_ServerFrame();
- // run the world state
- // don't allow simulation to run too fast or too slow or logic glitches can occur
-
- // stop running server frames if the wall time reaches this value
- if (sys_ticrate.value <= 0)
- advancetime = sv_timer;
- else
- {
- advancetime = sys_ticrate.value;
- // listen servers can run multiple server frames per client frame
- framelimit = cl_maxphysicsframesperserverframe.integer;
- aborttime = Sys_DirtyTime() + 0.1;
- }
- if(host_timescale.value > 0 && host_timescale.value < 1)
- advancetime = min(advancetime, 0.1 / host_timescale.value);
- else
- advancetime = min(advancetime, 0.1);
+ /*
+ * Don't accumulate time for the first 10 seconds of a match
+ * so things can settle
+ */
+ svs.perf_acc_realtime = svs.perf_acc_sleeptime =
+ svs.perf_acc_lost = svs.perf_acc_offset =
+ svs.perf_acc_offset_squared = svs.perf_acc_offset_max =
+ svs.perf_acc_offset_samples = host.sleeptime = 0;
+ }
- if(advancetime > 0)
- {
- offset = Sys_DirtyTime() - host.dirtytime;
- if (offset < 0 || offset >= 1800)
- offset = 0;
- offset += sv_timer;
- ++svs.perf_acc_offset_samples;
- svs.perf_acc_offset += offset;
- svs.perf_acc_offset_squared += offset * offset;
- if(svs.perf_acc_offset_max < offset)
- svs.perf_acc_offset_max = offset;
- }
+ /*
+ * Receive packets on each main loop iteration, as the main loop may
+ * be undersleeping due to select() detecting a new packet
+ */
+ if (sv.active)
+ NetConn_ServerFrame();
+ }
- // only advance time if not paused
- // the game also pauses in singleplayer when menu or console is used
- sv.frametime = advancetime * host_timescale.value;
- if (host_framerate.value)
- sv.frametime = host_framerate.value;
- if (sv.paused || host.paused)
- sv.frametime = 0;
+ /*
+ * If the accumulator hasn't become positive, don't
+ * run the frame. Everything that happens before this
+ * point will happen even if we're sleeping this frame.
+ */
+ if((sv_timer += time) < 0)
+ return sv_timer;
- for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
- {
- sv_timer -= advancetime;
+ // limit the frametime steps to no more than 100ms each
+ if (sv_timer > 0.1)
+ {
+ if (!svs.threaded)
+ svs.perf_acc_lost += (sv_timer - 0.1);
+ sv_timer = 0.1;
+ }
- // move things around and think unless paused
- if (sv.frametime)
- SV_Physics();
+ if (sv.active && sv_timer > 0 && !svs.threaded)
+ {
+ /*
+ * Execute one or more server frames, with an upper limit on how much
+ * execution time to spend on server frames to avoid freezing the game if
+ * the server is overloaded. This execution time limit means the game will
+ * slow down if the server is taking too long.
+ */
+ int framecount, framelimit = 1;
+ double advancetime, aborttime = 0;
+ float offset;
+ prvm_prog_t *prog = SVVM_prog;
+
+ // run the world state
+ // don't allow simulation to run too fast or too slow or logic glitches can occur
+
+ // stop running server frames if the wall time reaches this value
+ if (sys_ticrate.value <= 0)
+ advancetime = sv_timer;
+ else
+ {
+ advancetime = sys_ticrate.value;
+ // listen servers can run multiple server frames per client frame
+ framelimit = cl_maxphysicsframesperserverframe.integer;
+ aborttime = Sys_DirtyTime() + 0.1;
+ }
- // if this server frame took too long, break out of the loop
- if (framelimit > 1 && Sys_DirtyTime() >= aborttime)
- break;
- }
- R_TimeReport("serverphysics");
+ if(host_timescale.value > 0 && host_timescale.value < 1)
+ advancetime = min(advancetime, 0.1 / host_timescale.value);
+ else
+ advancetime = min(advancetime, 0.1);
- // send all messages to the clients
- SV_SendClientMessages();
+ if(advancetime > 0)
+ {
+ offset = Sys_DirtyTime() - host.dirtytime;
+ if (offset < 0 || offset >= 1800)
+ offset = 0;
+
+ offset += sv_timer;
+ ++svs.perf_acc_offset_samples;
+ svs.perf_acc_offset += offset;
+ svs.perf_acc_offset_squared += offset * offset;
+
+ if(svs.perf_acc_offset_max < offset)
+ svs.perf_acc_offset_max = offset;
+ }
- if (sv.paused == 1 && host.realtime > sv.pausedstart && sv.pausedstart > 0) {
- prog->globals.fp[OFS_PARM0] = host.realtime - sv.pausedstart;
- PRVM_serverglobalfloat(time) = sv.time;
- prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
- }
+ // only advance time if not paused
+ // the game also pauses in singleplayer when menu or console is used
+ sv.frametime = advancetime * host_timescale.value;
+ if (host_framerate.value)
+ sv.frametime = host_framerate.value;
+ if (sv.paused || host.paused)
+ sv.frametime = 0;
- // send an heartbeat if enough time has passed since the last one
- NetConn_Heartbeat(0);
- R_TimeReport("servernetwork");
- }
- else
+ for (framecount = 0; framecount < framelimit && sv_timer > 0; framecount++)
{
- // don't let r_speeds display jump around
- R_TimeReport("serverphysics");
- R_TimeReport("servernetwork");
+ sv_timer -= advancetime;
+
+ // move things around and think unless paused
+ if (sv.frametime)
+ SV_Physics();
+
+ // if this server frame took too long, break out of the loop
+ if (framelimit > 1 && Sys_DirtyTime() >= aborttime)
+ break;
+ }
+
+ R_TimeReport("serverphysics");
+
+ // send all messages to the clients
+ SV_SendClientMessages();
+
+ if (sv.paused == 1 && host.realtime > sv.pausedstart && sv.pausedstart > 0) {
+ prog->globals.fp[OFS_PARM0] = host.realtime - sv.pausedstart;
+ PRVM_serverglobalfloat(time) = sv.time;
+ prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
}
+
+ // send an heartbeat if enough time has passed since the last one
+ NetConn_Heartbeat(0);
+ R_TimeReport("servernetwork");
+ }
+ else
+ {
+ // don't let r_speeds display jump around
+ R_TimeReport("serverphysics");
+ R_TimeReport("servernetwork");
}
+
// if there is some time remaining from this frame, reset the timer
if (sv_timer >= 0)
{
svs.perf_acc_lost += sv_timer;
sv_timer = 0;
}
+
return sv_timer;
}
static int SV_ThreadFunc(void *voiddata)
{
prvm_prog_t *prog = SVVM_prog;
- qboolean playing = false;
+ qbool playing = false;
double sv_timer = 0;
double sv_deltarealtime, sv_oldrealtime, sv_realtime;
double wait;