diff options
author | Andrey Nazarov <skuller@skuller.net> | 2010-06-11 15:53:23 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2010-06-11 15:53:23 +0000 |
commit | 698c7913e8e56649cb413b155bc9381e91f10bbe (patch) | |
tree | c5cb81a12a63c113d9c24c7a680f0154cbbf4888 | |
parent | 47dead035e7bb52e9b360af6d9f13cdf5623b97f (diff) |
Fixed gamedir not being changed properly when connecting to a server.
Forbid changing gamedir at all while connected to a server.
Automatically restart filesystem when user changes gamedir while disconnected.
Killed FS_NeedRestart and FS_SafeToRestart.
-rw-r--r-- | source/cl_main.c | 3 | ||||
-rw-r--r-- | source/cl_parse.c | 13 | ||||
-rw-r--r-- | source/files.c | 109 | ||||
-rw-r--r-- | source/files.h | 4 | ||||
-rw-r--r-- | source/mvd_parse.c | 3 | ||||
-rw-r--r-- | source/sv_init.c | 9 |
6 files changed, 59 insertions, 82 deletions
diff --git a/source/cl_main.c b/source/cl_main.c index cdd3b5d..306c604 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -591,6 +591,9 @@ void CL_ClearState( void ) { if( cls.state > ca_connected ) { cls.state = ca_connected; } + + // unprotect game cvar + fs_game->flags &= ~CVAR_ROM; } /* diff --git a/source/cl_parse.c b/source/cl_parse.c index aa1340d..2a988cf 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -766,13 +766,16 @@ static void CL_ParseServerData( void ) { } // never allow demos to change gamedir - // do not set gamedir if connected to local sever, - // since it was already done by SV_InitGame + // do not change gamedir if connected to local sever either, + // as it was already done by SV_InitGame, and changing it + // here will not work since server is now running if( !cls.demo.playback && !sv_running->integer ) { + // pretend it has been set by user, so that 'changed' hook + // gets called and filesystem is restarted Cvar_UserSet( "game", cl.gamedir ); - if( FS_NeedRestart() ) { - CL_RestartFilesystem( qfalse ); - } + + // protect it from modifications while we are connected + fs_game->flags |= CVAR_ROM; } // parse player entity number diff --git a/source/files.c b/source/files.c index 6257dea..d238cb2 100644 --- a/source/files.c +++ b/source/files.c @@ -433,7 +433,7 @@ Creates any directories needed to store the given filename. Expects a fully qualified quake path (i.e. with / separators). ============ */ -static void FS_CreatePath( char *path ) { +void FS_CreatePath( char *path ) { char *ofs; if( !*path ) { @@ -1540,7 +1540,7 @@ then loads and adds pak*.pak, then anything else in alphabethical order. */ static void q_printf( 2, 3 ) FS_AddGameDirectory( int mode, const char *fmt, ... ) { va_list argptr; - searchpath_t *search; + searchpath_t *search; size_t len; va_start( argptr, fmt ); @@ -1585,8 +1585,8 @@ FS_CopyInfo ================= */ file_info_t *FS_CopyInfo( const char *name, size_t size, time_t ctime, time_t mtime ) { - file_info_t *out; - size_t len; + file_info_t *out; + size_t len; if( !name ) { return NULL; @@ -2385,45 +2385,9 @@ static void setup_basedir( void ) { fs_base_searchpaths = fs_searchpaths; } -// returns true if 'game' value is set and valid -static qboolean check_gamedir( void ) { - size_t len; - - if( !fs_game->string[0] ) { - return qfalse; // not set - } - - if( !FS_strcmp( fs_game->string, BASEGAME ) ) { - goto reset; // normalize it - } - - if( strchr( fs_game->string, '/' ) ) { - Com_WPrintf( "'%s' should be a single directory name, not a path.\n", fs_game->name ); - goto reset; - } - - // since gamedir is exported to server info, validate it - len = Info_SubValidate( fs_game->string ); - if( len == SIZE_MAX ) { - Com_WPrintf( "'%s' should not contain '\\', ';' or '\"' characters.\n", fs_game->name ); - goto reset; - } - - if( len >= MAX_QPATH ) { - Com_WPrintf( "'%s' should be less than 64 characters long.\n", fs_game->name ); - goto reset; - } - - return qtrue; - -reset: - Cvar_Reset( fs_game ); - return qfalse; -} - // Sets the gamedir and path to a different directory. static void setup_gamedir( void ) { - if( check_gamedir() ) { + if( fs_game->string[0] ) { // add system path first FS_AddGameDirectory( FS_PATH_GAME, "%s/%s", sys_basedir->string, fs_game->string ); @@ -2448,7 +2412,7 @@ static void setup_gamedir( void ) { Cvar_FullSet( "fs_gamedir", fs_gamedir, CVAR_ROM, FROM_CODE ); } -qboolean FS_SafeToRestart( void ) { +static qboolean safe_to_restart( void ) { file_t *file; int i; @@ -2467,18 +2431,6 @@ qboolean FS_SafeToRestart( void ) { /* ================ -FS_NeedRestart -================ -*/ -qboolean FS_NeedRestart( void ) { - if( fs_game->latched_string ) { - return qtrue; - } - return qfalse; -} - -/* -================ FS_Restart Unless total is true, reloads paks only up to base dir @@ -2536,7 +2488,7 @@ Console command to fully re-start the file system. ============ */ static void FS_Restart_f( void ) { - if( !FS_SafeToRestart() ) { + if( !safe_to_restart() ) { Com_Printf( "Can't \"%s\", there are some open file handles.\n", Cmd_Argv( 0 ) ); return; } @@ -2593,6 +2545,42 @@ void FS_Shutdown( void ) { Cmd_Deregister( c_fs ); } +// this is called when local server starts up and gets it's latched variables, +// client receives a serverdata packet, or user changes the game by hand while +// disconnected +static void fs_game_changed( cvar_t *self ) { + char *s = self->string; + + // validate it + if( *s ) { + if( !FS_strcmp( s, BASEGAME ) ) { + Cvar_Reset( self ); + } else if( strchr( s, '/' ) ) { + Com_Printf( "'%s' should be a single directory name, not a path.\n", self->name ); + Cvar_Reset( self ); + } + } + + // check for the first time startup + if( !fs_base_searchpaths ) { + // start up with baseq2 by default + setup_basedir(); + + // check for game override + setup_gamedir(); + + FS_Path_f(); + return; + } + + // otherwise, restart the filesystem +#if USE_CLIENT + CL_RestartFilesystem( qfalse ); +#else + FS_Restart( qfalse ); +#endif +} + /* ================ FS_Init @@ -2607,15 +2595,10 @@ void FS_Init( void ) { fs_debug = Cvar_Get( "fs_debug", "0", 0 ); #endif + // get the game cvar and start the filesystem fs_game = Cvar_Get( "game", "", CVAR_LATCH|CVAR_SERVERINFO ); - - // start up with baseq2 by default - setup_basedir(); - - // check for game override - setup_gamedir(); - - FS_Path_f(); + fs_game->changed = fs_game_changed; + fs_game_changed( fs_game ); Com_Printf( "-----------------------------\n" ); } diff --git a/source/files.h b/source/files.h index b0a9d29..e352bec 100644 --- a/source/files.h +++ b/source/files.h @@ -77,14 +77,14 @@ typedef struct file_info_s { void FS_Init( void ); void FS_Shutdown( void ); -qboolean FS_NeedRestart( void ); void FS_Restart( qboolean total ); -qboolean FS_SafeToRestart( void ); #if USE_CLIENT qboolean FS_RenameFile( const char *from, const char *to ); #endif +void FS_CreatePath( char *path ); + char *FS_CopyExtraInfo( const char *name, const file_info_t *info ); size_t FS_FOpenFile( const char *filename, fileHandle_t *f, int mode ); diff --git a/source/mvd_parse.c b/source/mvd_parse.c index 70a9439..a74a63a 100644 --- a/source/mvd_parse.c +++ b/source/mvd_parse.c @@ -1007,9 +1007,6 @@ static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { #if 0 // change gamedir unless playing a demo Cvar_UserSet( "game", mvd->gamedir ); - if( FS_NeedRestart() ) { - FS_Restart(); - } #endif // parse configstrings diff --git a/source/sv_init.c b/source/sv_init.c index 339ac4b..1c0d90f 100644 --- a/source/sv_init.c +++ b/source/sv_init.c @@ -188,15 +188,6 @@ void SV_InitGame( qboolean ismvd ) { Cvar_Reset( sv_recycle ); #endif - // restart filesystem now - if( FS_NeedRestart() ) { -#if USE_CLIENT - CL_RestartFilesystem( qfalse ); -#else - FS_Restart( qfalse ); -#endif - } - if( ismvd ) { Cvar_Set( "deathmatch", "1" ); Cvar_Set( "coop", "0" ); |