diff options
author | Andrey Nazarov <skuller@skuller.net> | 2012-12-19 18:29:09 +0400 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2012-12-19 18:37:55 +0400 |
commit | 941dbcd016b3daeb49d3b88d6625e6257118f5e2 (patch) | |
tree | d79556e25859c54aeef13d6d8f5e3526da8ac084 | |
parent | 203191b12124aba55938668ae315fcbaa4217f2a (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.txt | 2 | ||||
-rw-r--r-- | src/server/mvd/client.c | 48 | ||||
-rw-r--r-- | src/server/mvd/client.h | 3 | ||||
-rw-r--r-- | src/server/mvd/game.c | 48 |
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); } |