Skip to content

Commit 987d8cc

Browse files
committed
Exirmirai's server hibernation mode
JACoders#826
1 parent 5975ed5 commit 987d8cc

5 files changed

Lines changed: 53 additions & 1 deletion

File tree

codemp/qcommon/common.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ int Com_ModifyMsec( int msec ) {
14261426
// dedicated servers don't want to clamp for a much longer
14271427
// period, because it would mess up all the client's views
14281428
// of time.
1429-
if ( com_sv_running->integer && msec > 500 ) {
1429+
if ( !svs.hibernation.enabled && com_sv_running->integer && msec > 500 ) {
14301430
Com_Printf( "Hitch warning: %i msec frame time\n", msec );
14311431
}
14321432
clampTime = 5000;

codemp/server/server.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
2323

2424
#pragma once
2525

26+
#include <chrono>
27+
#include <string>
28+
2629
#include "qcommon/q_shared.h"
2730
#include "qcommon/qcommon.h"
2831
#include "game/g_public.h"
@@ -217,6 +220,13 @@ typedef struct serverStatic_s {
217220
netadr_t authorizeAddress; // for rcon return messages
218221

219222
qboolean gameStarted; // gvm is loaded
223+
224+
struct {
225+
qboolean enabled;
226+
int lastTimeDisconnected;
227+
float sv_fps;
228+
} hibernation;
229+
220230
} serverStatic_t;
221231

222232
#define SERVER_MAXBANS 1024
@@ -278,6 +288,7 @@ extern cvar_t *sv_legacyFixes;
278288
extern cvar_t *sv_banFile;
279289

280290
extern cvar_t *sv_snapShotDuelCull;
291+
extern cvar_t *sv_hibernateTime;
281292

282293
extern serverBan_t serverBans[SERVER_MAXBANS];
283294
extern int serverBansCount;

codemp/server/sv_client.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ void SV_DirectConnect( netadr_t from ) {
337337
return;
338338
}
339339

340+
Cvar_SetValue("sv_fps", svs.hibernation.sv_fps);
341+
svs.hibernation.enabled = qfalse;
342+
Com_Printf("Server restored from hibernation\n");
343+
340344
SV_UserinfoChanged( newcl );
341345

342346
// send the connect packet to the client
@@ -424,6 +428,14 @@ void SV_DropClient( client_t *drop, const char *reason ) {
424428
// to the master so it is known the server is empty
425429
// send a heartbeat now so the master will get up to date info
426430
// if there is already a slot for this ip, reuse it
431+
432+
int players = 0;
433+
for (i = 0; i < sv_maxclients->integer; i++) {
434+
if (svs.clients[i].state >= CS_CONNECTED && svs.clients[i].netchan.remoteAddress.type != NA_BOT) {
435+
players++;
436+
}
437+
}
438+
427439
for (i=0 ; i < sv_maxclients->integer ; i++ ) {
428440
if ( svs.clients[i].state >= CS_CONNECTED ) {
429441
break;
@@ -432,6 +444,11 @@ void SV_DropClient( client_t *drop, const char *reason ) {
432444
if ( i == sv_maxclients->integer ) {
433445
SV_Heartbeat_f();
434446
}
447+
448+
if (players == 0) {
449+
svs.hibernation.lastTimeDisconnected = Sys_Milliseconds();
450+
}
451+
435452
}
436453

437454
void SV_CreateClientGameStateMessage( client_t *client, msg_t *msg ) {

codemp/server/sv_init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,8 @@ void SV_Init (void) {
10111011
sv_banFile = Cvar_Get( "sv_banFile", "serverbans.dat", CVAR_ARCHIVE, "File to use to store bans and exceptions" );
10121012

10131013
sv_snapShotDuelCull = Cvar_Get("sv_snapShotDuelCull", "1", CVAR_NONE, "Snapshot-based duel isolation");
1014+
sv_hibernateTime = Cvar_Get("sv_hibernateTime", "0", CVAR_ARCHIVE_ND, "Time after which server will enter hibernation mode");
1015+
svs.hibernation.sv_fps = sv_fps->value;
10141016

10151017
// initialize bot cvars so they are listed and can be set before loading the botlib
10161018
SV_BotInitCvars();

codemp/server/sv_main.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ cvar_t *sv_legacyFixes;
7171
cvar_t *sv_banFile;
7272

7373
cvar_t *sv_snapShotDuelCull;
74+
cvar_t *sv_hibernateTime;
7475

7576
serverBan_t serverBans[SERVER_MAXBANS];
7677
int serverBansCount = 0;
@@ -1151,6 +1152,27 @@ void SV_Frame( int msec ) {
11511152
return;
11521153
}
11531154

1155+
if (svs.initialized && svs.gameStarted) {
1156+
int i = 0;
1157+
int players = 0;
1158+
for (i = 0; i < sv_maxclients->integer; i++) {
1159+
if (svs.clients[i].state >= CS_CONNECTED && svs.clients[i].netchan.remoteAddress.type != NA_BOT) {
1160+
players++;
1161+
}
1162+
}
1163+
1164+
//Check for hibernation mode
1165+
if (sv_hibernateTime->integer && !svs.hibernation.enabled && !players) {
1166+
int elapsed_time = Sys_Milliseconds() - svs.hibernation.lastTimeDisconnected;
1167+
if (elapsed_time >= sv_hibernateTime->integer) {
1168+
Cvar_Set("sv_fps", "1");
1169+
sv_fps->value = svs.hibernation.sv_fps;
1170+
svs.hibernation.enabled = qtrue;
1171+
Com_Printf("Server entered hibernation mode\n");
1172+
}
1173+
}
1174+
}
1175+
11541176
if ( !com_sv_running->integer ) {
11551177
return;
11561178
}

0 commit comments

Comments
 (0)