/* ================ Host_EndGame ================ */ void Host_EndGame( const char *message, ... ) { va_list argptr; static char string[MAX_SYSPATH]; va_start( argptr, message ); Q_vsprintf( string, message, argptr ); va_end( argptr ); MsgDev( D_INFO, "Host_EndGame: %s\n", string ); if( SV_Active()) { Q_snprintf( host.finalmsg, sizeof( host.finalmsg ), "Host_EndGame: %s", string ); SV_Shutdown( false ); return; } if( host.type == HOST_DEDICATED ) Sys_Break( "Host_EndGame: %s\n", string ); // dedicated servers exit SV_Shutdown( false ); CL_Disconnect(); // recreate world if needs CL_ClearEdicts (); // release all models Mod_ClearAll( true ); Host_AbortCurrentFrame (); }
/** * @sa SV_SpawnServer * @sa Com_ServerState */ void Com_SetServerState (int state) { Com_DPrintf(DEBUG_ENGINE, "Set server state to %i\n", state); if (state == ss_dead) SV_Shutdown("Server shutdown", false); else if (state == ss_restart) SV_Shutdown("Server map change", true); sv->state = (server_state_t)state; }
/* * Both client and server can use this, and it will * do the apropriate things. */ void Com_Error(int code, char *fmt, ...) { va_list argptr; static char msg[MAXPRINTMSG]; static qboolean recursive; if (recursive) { Sys_Error("recursive error after: %s", msg); } recursive = true; va_start(argptr, fmt); vsnprintf(msg, MAXPRINTMSG, fmt, argptr); va_end(argptr); if (code == ERR_DISCONNECT) { #ifndef DEDICATED_ONLY CL_Drop(); #endif recursive = false; longjmp(abortframe, -1); } else if (code == ERR_DROP) { Com_Printf("********************\nERROR: %s\n********************\n", msg); SV_Shutdown(va("Server crashed: %s\n", msg), false); #ifndef DEDICATED_ONLY CL_Drop(); #endif recursive = false; longjmp(abortframe, -1); } else { SV_Shutdown(va("Server fatal crashed: %s\n", msg), false); #ifndef DEDICATED_ONLY CL_Shutdown(); #endif } if (logfile) { fclose(logfile); logfile = NULL; } Sys_Error("%s", msg); recursive = false; }
void QDECL Com_Error( int code, const char *fmt, ... ) { va_list argptr; // when we are running automated scripts, make sure we // know if anything failed if ( com_buildScript && com_buildScript->integer ) { code = ERR_FATAL; } if ( com_errorEntered ) { Sys_Error( "recursive error after: %s", com_errorMessage ); } com_errorEntered = qtrue; //reset some game stuff here // SCR_UnprecacheScreenshot(); va_start (argptr,fmt); Q_vsnprintf (com_errorMessage, sizeof(com_errorMessage), fmt, argptr); va_end (argptr); if ( code != ERR_DISCONNECT ) { Cvar_Get("com_errorMessage", "", CVAR_ROM); //give com_errorMessage a default so it won't come back to life after a resetDefaults Cvar_Set("com_errorMessage", com_errorMessage); } SG_Shutdown(); // close any file pointers if ( code == ERR_DISCONNECT ) { SV_Shutdown("Disconnect", qtrue); CL_Disconnect(); CL_FlushMemory(); CL_StartHunkUsers(); com_errorEntered = qfalse; throw ("DISCONNECTED\n"); } else if ( code == ERR_DROP ) { // If loading/saving caused the crash/error - delete the temp file SG_WipeSavegame("current"); // delete file SV_Shutdown (va("Server crashed: %s\n", com_errorMessage), qtrue); CL_Disconnect(); CL_FlushMemory(); CL_StartHunkUsers(); Com_Printf (S_COLOR_RED"********************\n"S_COLOR_MAGENTA"ERROR: %s\n"S_COLOR_RED"********************\n", com_errorMessage); com_errorEntered = qfalse; throw ("DROPPED\n"); } else { CL_Shutdown (); SV_Shutdown (va(S_COLOR_RED"Server fatal crashed: %s\n", com_errorMessage), qtrue); } Com_Shutdown (); Sys_Error ("%s", com_errorMessage); }
/* ============= Com_Error Both client and server can use this, and it will do the apropriate things. ============= */ void Com_Error (int code, char *fmt, ...) { va_list argptr; static char msg[MAXPRINTMSG]; static qboolean recursive; // assert(Q_streq(fmt, "Disconnected from server")); // jitdebug if (recursive) Sys_Error("Recursive error after: %s", msg); recursive = true; va_start(argptr,fmt); _vsnprintf(msg, sizeof(msg), fmt, argptr); // jitsecurity -- prevent buffer overruns va_end(argptr); NULLTERMINATE(msg); // jitsecurity -- make sure string is null terminated. switch (code) // jiterror { case ERR_BENIGN: // jiterror - don't close the app. Just print the error to the console. Com_Printf("*** ERROR: %s\n", msg); recursive = false; return; case ERR_DISCONNECT: CL_Drop(); recursive = false; longjmp(abortframe, -1); break; case ERR_DROP: Com_Printf("********************\nERROR: %s\n********************\n", msg); SV_Shutdown(va("Server crashed: %s\n", msg), false); CL_Drop(); recursive = false; longjmp(abortframe, -1); break; case ERR_FATAL: default: SV_Shutdown(va("Server fatal crashed: %s\n", msg), false); CL_Shutdown(); } if (logfile) { fclose(logfile); logfile = NULL; } Sys_Error("%s", msg); }
//#include <sys/mman.h> void CL_Connect_f( void ) { char server[ sizeof( cls.servername ) ]; if( Cmd_Argc() != 2 ) { Msg( "Usage: connect <server>\n" ); return; } Q_strncpy( server, Cmd_Argv( 1 ), sizeof( cls.servername )); if( Host_ServerState()) { // if running a local server, kill it and reissue Q_strncpy( host.finalmsg, "Server quit", MAX_STRING ); SV_Shutdown( false ); } NET_Config( true ); // allow remote Msg( "server %s\n", server ); CL_Disconnect(); cls.state = ca_connecting; Q_strncpy( cls.servername, server, sizeof( cls.servername )); cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately }
/* ================= Sys_DoSignalAction ================= */ void Sys_DoSignalAction( int signal, const char* sigstring ) { static qboolean signalcaught = qfalse; char termmsg[MAX_STRING_CHARS]; Com_Printf( "Received signal: %s, exiting...\n", sigstring ); if( signalcaught ) { Com_Printf( "DOUBLE SIGNAL FAULT: Received signal: %s, exiting...\n", sigstring); } else { signalcaught = qtrue; Com_Printf("Server received signal: %s\nShutting down server...\n", sigstring); Com_sprintf(termmsg, sizeof(termmsg), "\nServer received signal: %s\nTerminating server...", sigstring); SV_Shutdown( termmsg ); Sys_EnterCriticalSection( 2 ); Com_CloseLogFiles(); //close all open logfiles FS_Shutdown(qtrue); } if( signal == SIGTERM || signal == SIGINT ) Sys_Exit( 1 ); else Sys_Exit( 2 ); }
/* ================= Sys_SigHandler ================= */ void Sys_SigHandler( int signal ) { static qboolean signalcaught = qfalse; //Com_Printf("signal: %d\n", signal); if( signalcaught ) { fprintf( stderr, "DOUBLE SIGNAL FAULT: Received signal %d, exiting...\n", signal ); } else { signalcaught = qtrue; VM_Forced_Unload_Start(); fprintf( stderr, "Received signal %d, exiting...\n", signal ); #ifndef DEDICATED CL_Shutdown(); #endif SV_Shutdown( "Signal caught" ); VM_Forced_Unload_Done(); } Sys_Exit( 0 ); // Exit with 0 to avoid recursive signals }
/* * Both client and server can use this, and it will * do the apropriate things. */ void Com_Quit(void) { Com_Printf("\n----------- shutting down ----------\n"); SV_Shutdown("Server quit\n", false); Sys_Quit(); }
/* ================ Sys_Error ================ */ void Sys_Error (const char *error, ...) { static qbool inerror = false; va_list argptr; char text[1024]; sv_error = true; if (inerror) Sys_Exit (1); inerror = true; va_start (argptr,error); vsnprintf (text, sizeof(text), error, argptr); va_end (argptr); if (!(int)sys_nostdout.value) Sys_Printf ("ERROR: %s\n", text); if (logs[ERROR_LOG].sv_logfile) { SV_Write_Log (ERROR_LOG, 1, va ("ERROR: %s\n", text)); // fclose (logs[ERROR_LOG].sv_logfile); } // FIXME: hack - checking SV_Shutdown with net_socket set in -1 NET_Shutdown if (svs.socketip != -1) SV_Shutdown (va("ERROR: %s\n", text)); if ((int)sys_restart_on_error.value) Sys_Quit (true); Sys_Exit (1); }
qboolean SV_NewGame( const char *mapName, qboolean loadGame ) { if( !loadGame ) { if( !SV_MapIsValid( mapName, GI->sp_entity, NULL )) { return false; } SV_ClearSaveDir (); SV_Shutdown( true ); } else { S_StopAllSounds (); SV_DeactivateServer (); } sv.loadgame = loadGame; sv.background = false; sv.changelevel = false; if( !SV_SpawnServer( mapName, NULL )) return false; SV_LevelInit( mapName, NULL, NULL, loadGame ); sv.loadgame = loadGame; SV_ActivateServer(); if( sv.state != ss_active ) return false; return true; }
void SV_Quit_f (void) { SV_FinalMessage ("server shutdown\n"); Con_Printf ("Shutting down.\n"); SV_Shutdown (); Sys_Quit (); }
//#include <sys/mman.h> void CL_Connect_f( void ) { string server; if( Cmd_Argc() != 2 ) { Msg( "Usage: connect <server>\n" ); return; } // default value 40000 ignored as we don't want to grow userinfo string if( ( cl_maxpacket->integer < 40000 ) && ( cl_maxpacket->integer > 99 ) ) { cl_maxpacket->flags |= CVAR_USERINFO; userinfo->modified = true; } Q_strncpy( server, Cmd_Argv( 1 ), MAX_STRING ); if( Host_ServerState()) { // if running a local server, kill it and reissue Q_strncpy( host.finalmsg, "Server quit", MAX_STRING ); SV_Shutdown( false ); } NET_Config( true ); // allow remote Msg( "server %s\n", server ); CL_Disconnect(); cls.state = ca_connecting; Q_strncpy( cls.servername, server, sizeof( cls.servername )); cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately }
static void SV_Restart_f (void) { client_t *client; int j; SZ_Clear (net_message->message); MSG_WriteByte (net_message->message, svc_print); MSG_WriteByte (net_message->message, PRINT_HIGH); MSG_WriteString (net_message->message, "\x9d\x9e\x9e\x9e\x9e\x9e\x9e\x9e" "\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x9e" "\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x9e" "\x9e\x9e\x9f\n" " Server \xf2\xe5\xf3\xf4\xe1\xf2\xf4 engaged\xae\xae\xae\n" "\x9d\x9e\x9e\x9e\x9e\x9e\x9e\x9e" "\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x9e" "\x9e\x9e\x9e\x9e\x9e\x9e\x9e\x9e" "\x9e\x9e\x9f\n\n"); MSG_WriteByte (net_message->message, svc_stufftext); MSG_WriteString (net_message->message, RESTART_CLSTUFF); MSG_WriteByte (net_message->message, svc_disconnect); for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) { if (client->state >= cs_spawned) Netchan_Transmit (&client->netchan, net_message->message->cursize, net_message->message->data); } Sys_Printf ("Shutting down: server restart, shell must relaunch server\n"); SV_Shutdown (); // Error code 2 on exit, indication shell must restart the server exit (2); }
static void signal_handler( int sig ) { static int try = 0; switch( try++ ) { case 0: if( sig == SIGINT || sig == SIGTERM ) { Com_Printf( "Received signal %d, exiting...\n", sig ); Com_Quit(); } else { Com_Error( ERR_FATAL, "Received signal %d\n", sig ); } break; case 1: #ifndef DEDICATED_ONLY printf( "Received signal %d, exiting...\n", sig ); SV_Shutdown( "Received signal, exiting...\n" ); CL_Shutdown(); _exit( 1 ); break; case 2: #endif printf( "Received signal %d, exiting...\n", sig ); _exit( 1 ); break; default: _exit( 1 ); break; } }
/* =============== SV_KillServer_f Kick everyone off, possibly in preparation for a new game =============== */ static void SV_KillServer_f (void) { if (!svs.initialized) return; SV_Shutdown ("Server was killed.\n", false); NET_Config ( NET_NONE ); // close network sockets }
/* ================ CL_Connect_f ================ */ void CL_Connect_f (void) { char *server; if (Cmd_Argc() != 2) { Com_Printf ("usage: connect <server>\n"); return; } if (Com_ServerState ()) { // if running a local server, kill it and reissue SV_Shutdown (va("Server quit\n", msg), false); } else { CL_Disconnect (); } server = Cmd_Argv (1); NET_Config (true); // allow remote CL_Disconnect (); cls.state = ca_connecting; strncpy (cls.servername, server, sizeof(cls.servername)-1); cls.connect_time = -99999; // CL_CheckForResend() will fire immediately }
/* ================= Sys_SigHandler ================= */ void Sys_SigHandler(int signal) { static qboolean signalcaught = qfalse; if (signalcaught) { fprintf(stderr, "DOUBLE SIGNAL FAULT: Received signal %d, exiting...\n", signal); } else { signalcaught = qtrue; #ifndef DEDICATED CL_Shutdown(); #endif SV_Shutdown(va("Received signal %d", signal)); } if (signal == SIGTERM || signal == SIGINT) { Sys_Exit(1); } else { Sys_Exit(2); } }
void CL_Connect_f(void) { char *server; if (Cmd_Argc() != 2) { Com_Printf("usage: connect <server>\n"); return; } if (Com_ServerState()) { /* if running a local server, kill it and reissue note: this is connect with the save game system */ SV_Shutdown("Server quit\n", false); } else { CL_Disconnect(); } server = Cmd_Argv(1); NET_Config(true); /* allow remote */ CL_Disconnect(); cls.state = ca_connecting; Q_strlcpy(cls.servername, server, sizeof(cls.servername)); cls.connect_time = -99999; /* HACK: CL_CheckForResend() will fire immediately */ }
/* * Com_Quit * * Both client and server can use this, and it will * do the apropriate things. */ void Com_Quit( void ) { if( dynvars_initialized ) { dynvar_t *quit = Dynvar_Lookup( "quit" ); if( quit ) { // wsw : aiwa : added "quit" event for pluggable clean-up (e.g. IRC shutdown) Dynvar_CallListeners( quit, NULL ); } Dynvar_Destroy( quit ); } SV_Shutdown( "Server quit\n" ); CL_Shutdown(); MM_Shutdown(); if( log_file ) { FS_FCloseFile( log_file ); log_file = 0; } Sys_Quit(); }
/* =============== SV_KillServer_f Kick everyone off, possibly in preparation for a new game =============== */ void SV_KillServer_f( void ) { if( !svs.initialized ) return; Q_strncpy( host.finalmsg, "Server was killed", MAX_STRING ); SV_Shutdown( false ); NET_Config ( false ); // close network sockets }
//FIXME: this is a callback from Sys_Quit and Sys_Error. It would be better //to run quit through here before the final handoff to the sys code. void Host_Shutdown (void) { static qbool isdown = false; if (isdown) { printf ("recursive shutdown\n"); return; } isdown = true; // on low-end systems quit process may last long time (was about 1 minute for me on old compo), // at the same time may repeats repeats repeats some sounds, trying preventing this S_StopAllSounds (true); S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin); SV_Shutdown ("Server quit\n"); #if (!defined WITH_PNG_STATIC && !defined WITH_JPEG_STATIC) QLib_Shutdown(); #endif CL_Shutdown (); NET_Shutdown (); Con_Shutdown(); #ifdef WITH_TCL TCL_Shutdown (); #endif }
//This shuts down both the client and server void Host_Error (char *error, ...) { va_list argptr; char string[1024]; static qbool inerror = false; if (inerror) Sys_Error ("Host_Error: recursively entered"); inerror = true; va_start (argptr,error); vsnprintf (string, sizeof(string), error, argptr); va_end (argptr); Com_Printf ("\n===========================\n"); Com_Printf ("Host_Error: %s\n",string); Com_Printf ("===========================\n\n"); SV_Shutdown (va("server crashed: %s\n", string)); CL_Disconnect (); if (!host_initialized) Sys_Error ("Host_Error: %s", string); inerror = false; Host_Abort (); }
void Host_EndGame (void) { SV_Shutdown ("Server was killed"); CL_Disconnect (); // clear disconnect messages from loopback NET_ClearLoopback (); }
/* ================= Sys_SigHandler ================= */ void Sys_SigHandler( int signal ) { static qboolean signalcaught = qfalse; fprintf( stderr, "Received signal: %s, exiting...\n", strsignal(signal) ); if( signalcaught ) { fprintf( stderr, "DOUBLE SIGNAL FAULT: Received signal: %s, exiting...\n", strsignal(signal)); } else { signalcaught = qtrue; Com_Printf("Server received signal: %s\nShutting down server...", strsignal(signal)); SV_Shutdown(va("\nServer received signal: %s\nTerminating server...", strsignal(signal)) ); Sys_EnterCriticalSection( 2 ); if(logfile) FS_FCloseFile(logfile); if(adminlogfile) FS_FCloseFile(adminlogfile); if(reliabledump) FS_FCloseFile(reliabledump); FS_Shutdown(qtrue); } if( signal == SIGTERM || signal == SIGINT ) Sys_Exit( 1 ); else Sys_Exit( 2 ); }
/** * @note Both client and server can use this, and it will * do the appropriate things. */ void Com_Error (int code, const char* fmt, ...) { va_list argptr; static char msg[MAXPRINTMSG]; static bool recursive = false; if (recursive) Sys_Error("recursive error after: %s", msg); recursive = true; va_start(argptr, fmt); Q_vsnprintf(msg, sizeof(msg), fmt, argptr); va_end(argptr); switch (code) { case ERR_DISCONNECT: Com_Printf("%s\n", msg); CL_Drop(); recursive = false; Com_Drop(); case ERR_DROP: Com_Printf("********************\n"); Com_Printf("ERROR: %s\n", msg); Com_Printf("********************\n"); Sys_Backtrace(); SV_Shutdown("Server crashed.", false); CL_Drop(); recursive = false; Com_Drop(); default: Com_Printf("%s\n", msg); SV_Shutdown("Server fatal crashed", false); /* send an receive net messages a last time */ NET_Wait(0); FS_CloseFile(&logfile); if (pipefile.f != nullptr) { FS_CloseFile(&pipefile); FS_RemoveFile(va("%s/%s", FS_Gamedir(), pipefile.name)); } CL_Shutdown(); Qcommon_Shutdown(); Sys_Error("Shutdown"); } }
/* ============= Com_Quit_f Both client and server can use this, and it will do the apropriate things. ============= */ void Com_Quit_f( void ) { // don't try to shutdown if we are in a recursive error if ( !com_errorEntered ) { SV_Shutdown ("Server quit\n"); CL_Shutdown (); Com_Shutdown (); } Sys_Quit (); }
/** * @sa Qcommon_Frame */ void SV_Frame (int now, void *data) { Com_ReadFromPipe(); /* change the gametype even if no server is running (e.g. the first time) */ if (sv_dedicated->integer && sv_gametype->modified) { Com_SetGameType(); sv_gametype->modified = false; } if (sv_dedicated->integer) { const char *s; do { s = Sys_ConsoleInput(); if (s) Cbuf_AddText(va("%s\n", s)); } while (s); } /* if server is not active, do nothing */ if (!svs.initialized) { #ifdef DEDICATED_ONLY Com_Printf("Starting next map from the mapcycle\n"); SV_NextMapcycle(); #endif return; } svs.realtime = now; /* keep the random time dependent */ rand(); SV_CheckSpawnSoldiers(); SV_CheckStartMatch(); SV_CheckTimeouts(); if (!sv_threads->integer) SV_RunGameFrame(); else /* signal the game frame thread to wake up */ SDL_CondSignal(svs.gameFrameCond); SV_LogHandleOutput(); /* next map in the cycle */ if (sv->endgame && sv_maxclients->integer > 1) SV_NextMapcycle(); /* send a heartbeat to the master if needed */ Master_Heartbeat(); SV_PingPlayers(); /* server is empty - so shutdown */ if (svs.abandon && svs.killserver) SV_Shutdown("Server disconnected.", false); }
void Host_ShutdownServer( void ) { if( !SV_Active()) return; Q_strncpy( host.finalmsg, "Server was killed", MAX_STRING ); Log_Printf( "Server shutdown\n" ); Log_Close(); SV_Shutdown( false ); }
static void Com_CatchError ( int code ) { if ( code == ERR_DISCONNECT ) { SV_Shutdown( "Server disconnected" ); CL_Disconnect( ); CL_FlushMemory( ); com_errorEntered = qfalse; } else if ( code == ERR_DROP ) { // If loading/saving caused the crash/error - delete the temp file SG_WipeSavegame("current"); // delete file Com_Printf ("********************\n" "ERROR: %s\n" "********************\n", com_errorMessage); SV_Shutdown (va("Server crashed: %s\n", com_errorMessage)); CL_Disconnect( ); CL_FlushMemory( ); com_errorEntered = qfalse; } }