summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2012-12-19 18:29:09 +0400
committerAndrey Nazarov <skuller@skuller.net>2012-12-19 18:37:55 +0400
commit941dbcd016b3daeb49d3b88d6625e6257118f5e2 (patch)
treed79556e25859c54aeef13d6d8f5e3526da8ac084
parent203191b12124aba55938668ae315fcbaa4217f2a (diff)
Check MVD spectators activity before suspending.
Idling spectators or bots could prevent MVD/GTV server from suspending. Work around that by tracking last activity time.
-rw-r--r--doc/server.txt2
-rw-r--r--src/server/mvd/client.c48
-rw-r--r--src/server/mvd/client.h3
-rw-r--r--src/server/mvd/game.c48
4 files changed, 75 insertions, 26 deletions
diff --git a/doc/server.txt b/doc/server.txt
index 022a88c..cc8d4b6 100644
--- a/doc/server.txt
+++ b/doc/server.txt
@@ -365,7 +365,7 @@ mvd_timeout::
mvd_suspend_time::
GTV connections are suspended after this period of time, in minutes,
- counted from the moment last MVD spectator disconnects. Setting this to
+ counted from the last moment of MVD spectator(s) activity. Setting this to
zero disables client side suspending entirely. Default value is 5.
mvd_wait_delay::
diff --git a/src/server/mvd/client.c b/src/server/mvd/client.c
index 626e108..e3c3642 100644
--- a/src/server/mvd/client.c
+++ b/src/server/mvd/client.c
@@ -103,14 +103,15 @@ mvd_t mvd_waitingRoom;
qboolean mvd_dirty;
int mvd_chanid;
+qboolean mvd_active;
+unsigned mvd_last_activity;
+
jmp_buf mvd_jmpbuf;
#ifdef _DEBUG
cvar_t *mvd_shownet;
#endif
-static qboolean mvd_active;
-
static cvar_t *mvd_timeout;
static cvar_t *mvd_suspend_time;
static cvar_t *mvd_wait_delay;
@@ -373,6 +374,29 @@ static gtv_t *gtv_set_conn(int arg)
return NULL;
}
+static void set_mvd_active(void)
+{
+ unsigned delta = mvd_suspend_time->value * 60 * 1000;
+
+ // zero timeout = always active
+ if (delta == 0)
+ mvd_last_activity = svs.realtime;
+
+ if (svs.realtime - mvd_last_activity > delta) {
+ if (mvd_active) {
+ Com_DPrintf("Suspending MVD streams.\n");
+ mvd_active = qfalse;
+ mvd_dirty = qtrue;
+ }
+ } else {
+ if (!mvd_active) {
+ Com_DPrintf("Resuming MVD streams.\n");
+ mvd_active = qtrue;
+ mvd_dirty = qtrue;
+ }
+ }
+}
+
/*
==============
MVD_Frame
@@ -382,25 +406,11 @@ Called from main server loop.
*/
int MVD_Frame(void)
{
- static unsigned prevtime;
gtv_t *gtv, *next;
int connections = 0;
if (sv.state == ss_broadcast) {
- unsigned delta = mvd_suspend_time->value * 60 * 1000;
-
- if (!delta || !LIST_EMPTY(&sv_clientlist)) {
- prevtime = svs.realtime;
- if (!mvd_active) {
- Com_DPrintf("Resuming MVD streams.\n");
- mvd_active = qtrue;
- }
- } else if (mvd_active) {
- if (svs.realtime - prevtime > delta) {
- Com_DPrintf("Suspending MVD streams.\n");
- mvd_active = qfalse;
- }
- }
+ set_mvd_active();
}
// run all GTV connections (but not demos)
@@ -1667,6 +1677,10 @@ void MVD_Spawn(void)
Q_strlcpy(sv.name, mvd_waitingRoom.mapname, sizeof(sv.name));
sv.state = ss_broadcast;
+
+ // start as inactive
+ mvd_last_activity = INT_MIN;
+ set_mvd_active();
}
static void MVD_Spawn_f(void)
diff --git a/src/server/mvd/client.h b/src/server/mvd/client.h
index 63db9d4..8d1f511 100644
--- a/src/server/mvd/client.h
+++ b/src/server/mvd/client.h
@@ -179,6 +179,9 @@ extern list_t mvd_channel_list;
extern mvd_t mvd_waitingRoom;
extern qboolean mvd_dirty;
+extern qboolean mvd_active;
+extern unsigned mvd_last_activity;
+
#ifdef _DEBUG
extern cvar_t *mvd_shownet;
#endif
diff --git a/src/server/mvd/game.c b/src/server/mvd/game.c
index 7e1a326..569617d 100644
--- a/src/server/mvd/game.c
+++ b/src/server/mvd/game.c
@@ -161,6 +161,11 @@ static void MVD_LayoutChannels(mvd_client_t *client)
"yv 80 string \" Please wait until players\""
"yv 88 string \" connect.\""
;
+ static const char inactive[] =
+ "yv 72 string \" Traffic saving mode.\""
+ "yv 80 string \" Press any key to wake\""
+ "yv 88 string \" this server up.\""
+ ;
char layout[MAX_STRING_CHARS];
char buffer[MAX_QPATH];
mvd_t *mvd;
@@ -205,8 +210,13 @@ static void MVD_LayoutChannels(mvd_client_t *client)
}
} else {
client->layout_cursor = 0;
- memcpy(layout + total, nochans, sizeof(nochans) - 1);
- total += sizeof(nochans) - 1;
+ if (mvd_active) {
+ memcpy(layout + total, nochans, sizeof(nochans) - 1);
+ total += sizeof(nochans) - 1;
+ } else {
+ memcpy(layout + total, inactive, sizeof(inactive) - 1);
+ total += sizeof(inactive) - 1;
+ }
}
layout[total] = 0;
@@ -639,14 +649,19 @@ copy:
client->ps.pmove.pm_type = PM_FREEZE;
client->clientNum = target - mvd->players;
- if (mvd_stats_hack->integer && target != mvd->dummy) {
- // copy stats of the dummy MVD observer
- target = mvd->dummy;
- for (i = 0; i < MAX_STATS; i++) {
- if (mvd_stats_hack->integer & (1 << i)) {
- client->ps.stats[i] = target->ps.stats[i];
+ if (target != mvd->dummy) {
+ if (mvd_stats_hack->integer) {
+ // copy stats of the dummy MVD observer
+ target = mvd->dummy;
+ for (i = 0; i < MAX_STATS; i++) {
+ if (mvd_stats_hack->integer & (1 << i)) {
+ client->ps.stats[i] = target->ps.stats[i];
+ }
}
}
+
+ // chasing someone counts as activity
+ mvd_last_activity = svs.realtime;
}
}
@@ -1195,6 +1210,12 @@ static void MVD_GameClientCommand(edict_t *ent)
}
cmd = Cmd_Argv(0);
+ if (!*cmd) {
+ return;
+ }
+
+ // don't timeout
+ mvd_last_activity = svs.realtime;
if (!strcmp(cmd, "!mvdadmin")) {
MVD_Admin_f(client);
@@ -1583,6 +1604,9 @@ static qboolean MVD_GameClientConnect(edict_t *ent, char *userinfo)
// override server state
MVD_SetServerState(client->cl, mvd);
+ // don't timeout
+ mvd_last_activity = svs.realtime;
+
return qtrue;
}
@@ -1730,6 +1754,14 @@ static void MVD_GameClientThink(edict_t *ent, usercmd_t *cmd)
usercmd_t *old = &client->lastcmd;
pmove_t pm;
+ if (cmd->buttons != old->buttons
+ || cmd->forwardmove != old->forwardmove
+ || cmd->sidemove != old->sidemove
+ || cmd->upmove != old->upmove) {
+ // don't timeout
+ mvd_last_activity = svs.realtime;
+ }
+
if ((cmd->buttons & ~old->buttons) & BUTTON_ATTACK) {
MVD_Observe_f(client);
}