Fix writing/loading configs when changing game/mod

When connecting to a multiplayer game that runs a different mod
("game" cvar) than you are, it didn't load the corresponging configs
from the mod, but saved your changes to the config to the mod's config.
Which is doubly useless.
Now when the "game" cvar is changed, the configs are reloaded (from
the right directories for the mod), and when disconnecting the configs
are written, so the changes you did for a mod while playing MP are saved
before game is reset to the game you started with.
This commit is contained in:
Daniel Gibson 2018-02-24 21:00:35 +01:00
parent d6f9cf64a4
commit f0e21e2ab4
6 changed files with 76 additions and 21 deletions

View file

@ -285,6 +285,8 @@ CL_Rcon_f(void)
NET_SendPacket(NS_CLIENT, strlen(message) + 1, message, to);
}
void CL_WriteConfiguration(void);
/*
* Goes from a connected state to full screen
* console state Sends a disconnect message to
@ -357,6 +359,13 @@ CL_Disconnect(void)
cls.state = ca_disconnected;
snd_is_underwater = false;
// save config for old game/mod
CL_WriteConfiguration();
// we disconnected, so revert to default game/mod (might have been different mod on MP server)
const char* game = Qcommon_GetInitialGame();
Cvar_Set("game", (char*)game);
}
void

View file

@ -243,7 +243,6 @@ Com_Error(int code, char *fmt, ...)
recursive = false;
longjmp(abortframe, -1);
}
else if (code == ERR_DROP)
{
Com_Printf("********************\nERROR: %s\n********************\n",
@ -255,7 +254,6 @@ Com_Error(int code, char *fmt, ...)
recursive = false;
longjmp(abortframe, -1);
}
else
{
SV_Shutdown(va("Server fatal crashed: %s\n", msg), false);

View file

@ -205,6 +205,13 @@ Cvar_Get(char *var_name, char *var_value, int flags)
}
}
// if $game is the default one ("baseq2"), then use "" instead because
// other code assumes this behavior (e.g. FS_BuildGameSpecificSearchPath())
if(strcmp(var_name, "game") == 0 && strcmp(var_value, BASEDIRNAME) == 0)
{
var_value = "";
}
var = Z_Malloc(sizeof(*var));
var->name = CopyString(var_name);
var->string = CopyString(var_value);
@ -246,6 +253,13 @@ Cvar_Set2(char *var_name, char *value, qboolean force)
}
}
// if $game is the default one ("baseq2"), then use "" instead because
// other code assumes this behavior (e.g. FS_BuildGameSpecificSearchPath())
if(strcmp(var_name, "game") == 0 && strcmp(value, BASEDIRNAME) == 0)
{
value = "";
}
if (!force)
{
if (var->flags & CVAR_NOSET)
@ -264,8 +278,8 @@ Cvar_Set2(char *var_name, char *value, qboolean force)
}
Z_Free(var->latched_string);
var->latched_string = NULL;
}
else
{
if (strcmp(value, var->string) == 0)
@ -279,7 +293,6 @@ Cvar_Set2(char *var_name, char *value, qboolean force)
Com_Printf("%s will be changed for next game.\n", var_name);
var->latched_string = CopyString(value);
}
else
{
var->string = CopyString(value);
@ -294,7 +307,6 @@ Cvar_Set2(char *var_name, char *value, qboolean force)
return var;
}
}
else
{
if (var->latched_string)
@ -355,6 +367,13 @@ Cvar_FullSet(char *var_name, char *value, int flags)
userinfo_modified = true;
}
// if $game is the default one ("baseq2"), then use "" instead because
// other code assumes this behavior (e.g. FS_BuildGameSpecificSearchPath())
if(strcmp(var_name, "game") == 0 && strcmp(value, BASEDIRNAME) == 0)
{
value = "";
}
Z_Free(var->string);
var->string = CopyString(value);

View file

@ -1462,20 +1462,17 @@ FS_BuildGameSpecificSearchPath(char *dir)
fsRawPath_t *search;
fsSearchPath_t *next;
// This is against PEBCAK. The user may give us paths like
// xatrix/ or even /home/stupid/quake2/xatrix.
if (!*dir || !strcmp(dir, ".") || strstr(dir, "..") || strstr(dir, "/") || strstr(dir, "\\"))
// empty string means baseq2
if(dir[0] == '\0')
{
Com_Printf("Gamedir should be a single filename, not a path.\n");
return;
dir = BASEDIRNAME;
}
// BASEDIR is already added as a generic directory. Adding it
// again as a specialised directory breaks the logic in other
// parts of the code. This may happen if the user does something
// like ./quake2 +set game baseq2
if(!Q_stricmp(dir, BASEDIRNAME))
// This is against PEBCAK. The user may give us paths like
// xatrix/ or even /home/stupid/quake2/xatrix.
if (!strcmp(dir, ".") || strstr(dir, "..") || strstr(dir, "/") || strstr(dir, "\\"))
{
Com_Printf("Gamedir should be a single filename, not a path.\n");
return;
}
@ -1556,6 +1553,9 @@ FS_BuildGameSpecificSearchPath(char *dir)
// render dll doesn't link the filesystem stuff.
Com_sprintf(path, sizeof(path), "%s/scrnshot", fs_gamedir);
Sys_Mkdir(path);
// the gamedir has changed, so read in the corresponding configs
Qcommon_ExecConfigs(false);
}
// --------

View file

@ -178,6 +178,27 @@ Qcommon_Mainloop(void)
}
}
void Qcommon_ExecConfigs(qboolean gameStartUp)
{
Cbuf_AddText("exec default.cfg\n");
Cbuf_AddText("exec yq2.cfg\n");
Cbuf_AddText("exec config.cfg\n");
if(gameStartUp)
{
// only when the game is first started we execute autoexec.cfg and set the cvars from commandline
Cbuf_AddText("exec autoexec.cfg\n");
Cbuf_AddEarlyCommands(true);
}
Cbuf_Execute();
}
static char initialGame[MAX_QPATH];
const char* Qcommon_GetInitialGame(void)
{
return initialGame;
}
void
Qcommon_Init(int argc, char **argv)
{
@ -214,16 +235,22 @@ Qcommon_Init(int argc, char **argv)
Cbuf_AddEarlyCommands(false);
Cbuf_Execute();
// remember the initial game name that might have been set on commandline
{
cvar_t* gameCvar = Cvar_Get("game", "", CVAR_LATCH | CVAR_SERVERINFO);
const char* game = "";
if(gameCvar->string && gameCvar->string[0])
{
game = gameCvar->string;
}
Q_strlcpy(initialGame, game, sizeof(initialGame));
}
// The filesystems needs to be initialized after the cvars.
FS_InitFilesystem();
// Add and execute configuration files.
Cbuf_AddText("exec default.cfg\n");
Cbuf_AddText("exec yq2.cfg\n");
Cbuf_AddText("exec config.cfg\n");
Cbuf_AddText("exec autoexec.cfg\n");
Cbuf_AddEarlyCommands(true);
Cbuf_Execute();
Qcommon_ExecConfigs(true);
// Zone malloc statistics.
Cmd_AddCommand("z_stats", Z_Stats_f);

View file

@ -749,6 +749,8 @@ void *Z_TagMalloc(int size, int tag);
void Z_FreeTags(int tag);
void Qcommon_Init(int argc, char **argv);
void Qcommon_ExecConfigs(qboolean addEarlyCmds);
const char* Qcommon_GetInitialGame(void);
void Qcommon_Frame(int msec);
void Qcommon_Shutdown(void);