summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2010-06-11 15:53:23 +0000
committerAndrey Nazarov <skuller@skuller.net>2010-06-11 15:53:23 +0000
commit698c7913e8e56649cb413b155bc9381e91f10bbe (patch)
treec5cb81a12a63c113d9c24c7a680f0154cbbf4888
parent47dead035e7bb52e9b360af6d9f13cdf5623b97f (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.c3
-rw-r--r--source/cl_parse.c13
-rw-r--r--source/files.c109
-rw-r--r--source/files.h4
-rw-r--r--source/mvd_parse.c3
-rw-r--r--source/sv_init.c9
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" );