diff --git a/engine/client/cl_gameui.c b/engine/client/cl_gameui.c index f4cdf9473d..b39ee040cf 100644 --- a/engine/client/cl_gameui.c +++ b/engine/client/cl_gameui.c @@ -1114,7 +1114,7 @@ static void GAME_EXPORT UI_ShellExecute( const char *path, const char *parms, in Platform_ShellExecute( path, parms ); if( shouldExit ) - Sys_Quit(); + Sys_Quit( __func__ ); } /* diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index d59ec32310..5c556eefd0 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -965,7 +965,7 @@ CL_Quit_f void CL_Quit_f( void ) { CL_Disconnect(); - Sys_Quit(); + Sys_Quit( "command" ); } /* diff --git a/engine/common/common.h b/engine/common/common.h index cae534ec19..6b08e02c8a 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -547,7 +547,7 @@ qboolean Sound_SupportedFileFormat( const char *fileext ); typedef void( *pfnChangeGame )( const char *progname ); qboolean Host_IsQuakeCompatible( void ); -void EXPORT Host_Shutdown( void ); +void Host_ShutdownWithReason( const char *reason ); int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func ); void Host_EndGame( qboolean abort, const char *message, ... ) FORMAT_CHECK( 2 ); void Host_AbortCurrentFrame( void ) NORETURN; diff --git a/engine/common/host.c b/engine/common/host.c index d708dfd0be..e24d12980b 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -209,7 +209,7 @@ static void Sys_PrintUsage( const char *exename ) fprintf( stderr, usage_str, exename ); #endif - Sys_Quit(); + Sys_Quit( NULL ); } static void Sys_PrintBugcompUsage( const char *exename ) @@ -234,7 +234,7 @@ static void Sys_PrintBugcompUsage( const char *exename ) fprintf( stderr, usage_str, exename ); #endif - Sys_Quit(); + Sys_Quit( NULL ); } /* @@ -915,7 +915,7 @@ static void Host_RunTests( int stage ) #endif Msg( "Done! %d passed, %d failed\n", tests_stats.passed, tests_stats.failed ); error_on_exit = tests_stats.failed > 0 ? EXIT_FAILURE : EXIT_SUCCESS; - Sys_Quit(); + Sys_Quit( NULL ); } } #endif @@ -1162,6 +1162,11 @@ static void Host_FreeCommon( void ) FS_Shutdown(); } +static void Sys_Quit_f( void ) +{ + Sys_Quit( "command" ); +} + /* ================= Host_Main @@ -1236,8 +1241,8 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa // disable texture replacements for dedicated Cvar_FullSet( "host_allow_materials", "0", FCVAR_READ_ONLY ); - Cmd_AddRestrictedCommand( "quit", Sys_Quit, "quit the game" ); - Cmd_AddRestrictedCommand( "exit", Sys_Quit, "quit the game" ); + Cmd_AddRestrictedCommand( "quit", Sys_Quit_f, "quit the game" ); + Cmd_AddRestrictedCommand( "exit", Sys_Quit_f, "quit the game" ); } else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" ); @@ -1320,20 +1325,34 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa return 0; } +void EXPORT Host_Shutdown( void ); +void EXPORT Host_Shutdown( void ) +{ + Host_ShutdownWithReason( "launcher shutdown" ); +} + /* ================= Host_Shutdown ================= */ -void EXPORT Host_Shutdown( void ) +void Host_ShutdownWithReason( const char *reason ) { qboolean error = host.status == HOST_ERR_FATAL; - if( host.shutdown_issued ) return; + if( host.shutdown_issued ) + return; + host.shutdown_issued = true; - if( host.status != HOST_ERR_FATAL ) host.status = HOST_SHUTDOWN; // prepare host to normal shutdown - if( !host.change_game ) Q_strncpy( host.finalmsg, "Server shutdown", sizeof( host.finalmsg )); + if( reason != NULL ) + Con_Printf( S_NOTE "Issuing host shutdown due to reason \"%s\"\n", reason ); + + if( host.status != HOST_ERR_FATAL ) + host.status = HOST_SHUTDOWN; // prepare host to normal shutdown + + if( !host.change_game ) + Q_strncpy( host.finalmsg, "Server shutdown", sizeof( host.finalmsg )); #if !XASH_DEDICATED if( host.type == HOST_NORMAL && !error ) diff --git a/engine/common/masterlist.c b/engine/common/masterlist.c index fb94406a52..d3b2bf225c 100644 --- a/engine/common/masterlist.c +++ b/engine/common/masterlist.c @@ -385,10 +385,7 @@ void NET_SaveMasters( void ) master_t *m; if( !ml.modified ) - { - Con_Reportf( "Master server list not changed\n" ); return; - } f = FS_Open( "xashcomm.lst", "w", true ); diff --git a/engine/common/system.c b/engine/common/system.c index f42a61edd8..ca781f3572 100644 --- a/engine/common/system.c +++ b/engine/common/system.c @@ -412,7 +412,7 @@ void Sys_Error( const char *error, ... ) Sys_WaitForQuit(); } - Sys_Quit(); + Sys_Quit( "caught an error" ); } #if XASH_EMSCRIPTEN @@ -435,9 +435,9 @@ void my_exit(int ret) Sys_Quit ================ */ -void Sys_Quit( void ) +void Sys_Quit( const char *reason ) { - Host_Shutdown(); + Host_ShutdownWithReason( reason ); exit( error_on_exit ); } @@ -540,7 +540,7 @@ qboolean Sys_NewInstance( const char *gamedir ) // just restart the entire thing printf( "envSetNextLoad exe: `%s`\n", exe ); printf( "envSetNextLoad argv:\n`%s`\n", newargs ); - Host_Shutdown( ); + Host_ShutdownWithReason( "changing game" ); envSetNextLoad( exe, newargs ); exit( 0 ); #else @@ -578,7 +578,7 @@ qboolean Sys_NewInstance( const char *gamedir ) #if XASH_PSVITA // under normal circumstances it's always going to be the same path exe = strdup( "app0:/eboot.bin" ); - Host_Shutdown( ); + Host_ShutdownWithReason( "changing game" ); sceAppMgrLoadExec( exe, newargs, NULL ); #else exelen = wai_getExecutablePath( NULL, 0, NULL ); @@ -586,7 +586,7 @@ qboolean Sys_NewInstance( const char *gamedir ) wai_getExecutablePath( exe, exelen, NULL ); exe[exelen] = 0; - Host_Shutdown(); + Host_ShutdownWithReason( "changing game" ); execv( exe, newargs ); #endif diff --git a/engine/common/system.h b/engine/common/system.h index 617d636c5b..ac18890178 100644 --- a/engine/common/system.h +++ b/engine/common/system.h @@ -59,7 +59,7 @@ void Sys_Print( const char *pMsg ); void Sys_PrintLog( const char *pMsg ); void Sys_InitLog( void ); void Sys_CloseLog( void ); -void Sys_Quit( void ) NORETURN; +void Sys_Quit( const char *reason ) NORETURN; qboolean Sys_NewInstance( const char *gamedir ); void *Sys_GetNativeObject( const char *obj ); diff --git a/engine/platform/posix/crash_posix.c b/engine/platform/posix/crash_posix.c index f36a826a6e..b49897bcb5 100644 --- a/engine/platform/posix/crash_posix.c +++ b/engine/platform/posix/crash_posix.c @@ -197,8 +197,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context) CL_Crashed(); host.status = HOST_CRASHED; - - Sys_Quit(); + Sys_Quit( "crashed" ); } void Sys_SetupCrashHandler( void ) diff --git a/engine/platform/posix/sys_posix.c b/engine/platform/posix/sys_posix.c index c0436d4b66..1244b27caf 100644 --- a/engine/platform/posix/sys_posix.c +++ b/engine/platform/posix/sys_posix.c @@ -148,7 +148,9 @@ void Posix_Daemonize( void ) static void Posix_SigtermCallback( int signal ) { - Sys_Quit(); + string reason; + Con_Printf( reason, sizeof( reason ), "caught signal %d", signal ); + Sys_Quit( reason ); } void Posix_SetupSigtermHandling( void ) diff --git a/engine/platform/sdl/events.c b/engine/platform/sdl/events.c index 472e34a842..f3b1448bfa 100644 --- a/engine/platform/sdl/events.c +++ b/engine/platform/sdl/events.c @@ -498,7 +498,7 @@ static void SDLash_EventHandler( SDL_Event *event ) break; case SDL_QUIT: - Sys_Quit(); + Sys_Quit( "caught SDL_QUIT" ); break; #if SDL_VERSION_ATLEAST( 2, 0, 0 ) case SDL_MOUSEWHEEL: diff --git a/engine/platform/win32/crash_win.c b/engine/platform/win32/crash_win.c index 563f6285cd..55ab7e434f 100644 --- a/engine/platform/win32/crash_win.c +++ b/engine/platform/win32/crash_win.c @@ -305,7 +305,7 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo ) if( host_developer.value <= 0 ) { // no reason to call debugger in release build - just exit - Sys_Quit(); + Sys_Quit( "crashed" ); return EXCEPTION_CONTINUE_EXECUTION; }