mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-26 06:20:48 +00:00
Do not display baseq2 savegames in mods / addons
The savegame list is generated by calling FS_FOpenFile() for each possible savegame name. When a file handle is returned the savegame exists, otherwise the savegame slot is empty. But FS_FOpenFile() searches in every directory known to the VFS. If a savegame file isn't found in $moddir but in baseq2, the file in baseq2 is opened and a baseq2 savegame is displayed in the mods / addons savegame menu. The fix is compromise between a clean solution and invasiveness: - Refactor FS_FOpenFile() to include FS_FOpenFileRead(). FS_FOpenFile() was used only to open read only files, limit its's possibilities to do exactly that. - Introduce a new flag "gamedir_only" to FS_FOpenFile(). When true only the gamedir directories are searched and not other directories like baseq2. - Change all callers to FS_FOpenFile()s new signature. - Use the new gamedir_only flag to limit the searchpath for savegames to the gamedir.
This commit is contained in:
parent
2e82fe85fd
commit
7456daf65f
6 changed files with 130 additions and 160 deletions
|
@ -612,7 +612,7 @@ SCR_PlayCinematic(char *arg)
|
|||
}
|
||||
|
||||
Com_sprintf(name, sizeof(name), "video/%s", arg);
|
||||
FS_FOpenFile(name, &cl.cinematic_file, FS_READ);
|
||||
FS_FOpenFile(name, &cl.cinematic_file, false);
|
||||
|
||||
if (!cl.cinematic_file)
|
||||
{
|
||||
|
|
|
@ -2226,7 +2226,7 @@ Create_Savestrings(void)
|
|||
for (i = 0; i < MAX_SAVESLOTS; i++)
|
||||
{
|
||||
Com_sprintf(name, sizeof(name), "save/save%i/server.ssv", m_loadsave_page * MAX_SAVESLOTS + i);
|
||||
FS_FOpenFile(name, &f, FS_READ);
|
||||
FS_FOpenFile(name, &f, true);
|
||||
|
||||
if (!f)
|
||||
{
|
||||
|
|
|
@ -367,134 +367,6 @@ FS_FOpenFileWrite(fsHandle_t *handle)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns file size or -1 if not found. Can open separate files as well as
|
||||
* files inside pack files (both PAK and PK3).
|
||||
*/
|
||||
int
|
||||
FS_FOpenFileRead(fsHandle_t *handle)
|
||||
{
|
||||
char path[MAX_OSPATH];
|
||||
int i;
|
||||
fsSearchPath_t *search;
|
||||
fsPack_t *pack;
|
||||
|
||||
file_from_pak = 0;
|
||||
#ifdef ZIP
|
||||
file_from_pk3 = 0;
|
||||
#endif
|
||||
|
||||
/* Search through the path, one element at a time. */
|
||||
for (search = fs_searchPaths; search; search = search->next)
|
||||
{
|
||||
/* Search inside a pack file. */
|
||||
if (search->pack)
|
||||
{
|
||||
pack = search->pack;
|
||||
|
||||
for (i = 0; i < pack->numFiles; i++)
|
||||
{
|
||||
if (Q_stricmp(pack->files[i].name, handle->name) == 0)
|
||||
{
|
||||
/* Found it! */
|
||||
Com_FilePath(pack->name, fs_fileInPath,
|
||||
sizeof(fs_fileInPath));
|
||||
fs_fileInPack = true;
|
||||
|
||||
if (fs_debug->value)
|
||||
{
|
||||
Com_Printf("FS_FOpenFileRead: '%s' (found in '%s').\n",
|
||||
handle->name, pack->name);
|
||||
}
|
||||
|
||||
if (pack->pak)
|
||||
{
|
||||
/* PAK */
|
||||
file_from_pak = 1;
|
||||
handle->file = fopen(pack->name, "rb");
|
||||
|
||||
if (handle->file)
|
||||
{
|
||||
fseek(handle->file, pack->files[i].offset, SEEK_SET);
|
||||
return pack->files[i].size;
|
||||
}
|
||||
}
|
||||
#ifdef ZIP
|
||||
else if (pack->pk3)
|
||||
{
|
||||
/* PK3 */
|
||||
file_from_pk3 = 1;
|
||||
Q_strlcpy(file_from_pk3_name, strrchr(pack->name,
|
||||
'/') + 1, sizeof(file_from_pk3_name));
|
||||
handle->zip = unzOpen(pack->name);
|
||||
|
||||
if (handle->zip)
|
||||
{
|
||||
if (unzLocateFile(handle->zip, handle->name,
|
||||
2) == UNZ_OK)
|
||||
{
|
||||
if (unzOpenCurrentFile(handle->zip) == UNZ_OK)
|
||||
{
|
||||
return pack->files[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
unzClose(handle->zip);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Com_Error(ERR_FATAL, "Couldn't reopen '%s'", pack->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search in a directory tree. */
|
||||
Com_sprintf(path, sizeof(path), "%s/%s", search->path, handle->name);
|
||||
|
||||
handle->file = fopen(path, "rb");
|
||||
|
||||
if (!handle->file)
|
||||
{
|
||||
Q_strlwr(path);
|
||||
handle->file = fopen(path, "rb");
|
||||
}
|
||||
|
||||
if (!handle->file)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handle->file)
|
||||
{
|
||||
/* Found it! */
|
||||
Q_strlcpy(fs_fileInPath, search->path, sizeof(fs_fileInPath));
|
||||
fs_fileInPack = false;
|
||||
|
||||
if (fs_debug->value)
|
||||
{
|
||||
Com_Printf("FS_FOpenFileRead: '%s' (found in '%s').\n",
|
||||
handle->name, search->path);
|
||||
}
|
||||
|
||||
return FS_FileLength(handle->file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found! */
|
||||
fs_fileInPath[0] = 0;
|
||||
fs_fileInPack = false;
|
||||
|
||||
if (fs_debug->value)
|
||||
{
|
||||
Com_Printf("FS_FOpenFileRead: couldn't find '%s'.\n", handle->name);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Other dll's can't just call fclose() on files returned by FS_FOpenFile.
|
||||
*/
|
||||
|
@ -546,41 +418,139 @@ Developer_searchpath(int who)
|
|||
* for streaming data out of either a pak file or a seperate file.
|
||||
*/
|
||||
int
|
||||
FS_FOpenFile(const char *name, fileHandle_t *f, fsMode_t mode)
|
||||
FS_FOpenFile(const char *name, fileHandle_t *f, qboolean gamedir_only)
|
||||
{
|
||||
int size = 0;
|
||||
char path[MAX_OSPATH];
|
||||
fsHandle_t *handle;
|
||||
fsPack_t *pack;
|
||||
fsSearchPath_t *search;
|
||||
int i;
|
||||
|
||||
file_from_pak = 0;
|
||||
#ifdef ZIP
|
||||
file_from_pk3 = 0;
|
||||
#endif
|
||||
|
||||
handle = FS_HandleForFile(name, f);
|
||||
|
||||
Q_strlcpy(handle->name, name, sizeof(handle->name));
|
||||
handle->mode = mode;
|
||||
handle->mode = FS_READ;
|
||||
|
||||
switch (mode)
|
||||
/* Search through the path, one element at a time. */
|
||||
for (search = fs_searchPaths; search; search = search->next)
|
||||
{
|
||||
case FS_READ:
|
||||
size = FS_FOpenFileRead(handle);
|
||||
break;
|
||||
case FS_WRITE:
|
||||
size = FS_FOpenFileWrite(handle);
|
||||
break;
|
||||
case FS_APPEND:
|
||||
size = FS_FOpenFileAppend(handle);
|
||||
break;
|
||||
default:
|
||||
Com_Error(ERR_FATAL, "FS_FOpenFile: bad mode (%i)", mode);
|
||||
break;
|
||||
if (gamedir_only)
|
||||
{
|
||||
if (strstr(search->path, FS_Gamedir()) == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search inside a pack file. */
|
||||
if (search->pack)
|
||||
{
|
||||
pack = search->pack;
|
||||
|
||||
for (i = 0; i < pack->numFiles; i++)
|
||||
{
|
||||
if (Q_stricmp(pack->files[i].name, handle->name) == 0)
|
||||
{
|
||||
/* Found it! */
|
||||
Com_FilePath(pack->name, fs_fileInPath, sizeof(fs_fileInPath));
|
||||
fs_fileInPack = true;
|
||||
|
||||
if (fs_debug->value)
|
||||
{
|
||||
Com_Printf("FS_FOpenFile: '%s' (found in '%s').\n",
|
||||
handle->name, pack->name);
|
||||
}
|
||||
|
||||
if (pack->pak)
|
||||
{
|
||||
/* PAK */
|
||||
file_from_pak = 1;
|
||||
handle->file = fopen(pack->name, "rb");
|
||||
|
||||
if (handle->file)
|
||||
{
|
||||
fseek(handle->file, pack->files[i].offset, SEEK_SET);
|
||||
return pack->files[i].size;
|
||||
}
|
||||
}
|
||||
#ifdef ZIP
|
||||
else if (pack->pk3)
|
||||
{
|
||||
/* PK3 */
|
||||
file_from_pk3 = 1;
|
||||
Q_strlcpy(file_from_pk3_name, strrchr(pack->name, '/') + 1, sizeof(file_from_pk3_name));
|
||||
handle->zip = unzOpen(pack->name);
|
||||
|
||||
if (handle->zip)
|
||||
{
|
||||
if (unzLocateFile(handle->zip, handle->name, 2) == UNZ_OK)
|
||||
{
|
||||
if (unzOpenCurrentFile(handle->zip) == UNZ_OK)
|
||||
{
|
||||
return pack->files[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
unzClose(handle->zip);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Com_Error(ERR_FATAL, "Couldn't reopen '%s'", pack->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search in a directory tree. */
|
||||
Com_sprintf(path, sizeof(path), "%s/%s", search->path, handle->name);
|
||||
|
||||
handle->file = fopen(path, "rb");
|
||||
|
||||
if (!handle->file)
|
||||
{
|
||||
Q_strlwr(path);
|
||||
handle->file = fopen(path, "rb");
|
||||
}
|
||||
|
||||
if (!handle->file)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handle->file)
|
||||
{
|
||||
/* Found it! */
|
||||
Q_strlcpy(fs_fileInPath, search->path, sizeof(fs_fileInPath));
|
||||
fs_fileInPack = false;
|
||||
|
||||
if (fs_debug->value)
|
||||
{
|
||||
Com_Printf("FS_FOpenFile: '%s' (found in '%s').\n",
|
||||
handle->name, search->path);
|
||||
}
|
||||
|
||||
return FS_FileLength(handle->file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size != -1)
|
||||
/* Not found! */
|
||||
fs_fileInPath[0] = 0;
|
||||
fs_fileInPack = false;
|
||||
|
||||
if (fs_debug->value)
|
||||
{
|
||||
return size;
|
||||
Com_Printf("FS_FOpenFile: couldn't find '%s'.\n", handle->name);
|
||||
}
|
||||
|
||||
/* Couldn't open, so free the handle. */
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
*f = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -732,7 +702,7 @@ FS_LoadFile(char *path, void **buffer)
|
|||
fileHandle_t f; /* File handle. */
|
||||
|
||||
buf = NULL;
|
||||
size = FS_FOpenFile(path, &f, FS_READ);
|
||||
size = FS_FOpenFile(path, &f, false);
|
||||
|
||||
if (size <= 0)
|
||||
{
|
||||
|
|
|
@ -686,7 +686,7 @@ typedef enum
|
|||
} fsSearchType_t;
|
||||
|
||||
void FS_DPrintf(const char *format, ...);
|
||||
int FS_FOpenFile(const char *name, fileHandle_t *f, fsMode_t mode);
|
||||
int FS_FOpenFile(const char *name, fileHandle_t *f, qboolean gamedir_only);
|
||||
void FS_FCloseFile(fileHandle_t f);
|
||||
int FS_Read(void *buffer, int size, fileHandle_t f);
|
||||
int FS_FRead(void *buffer, int size, int count, fileHandle_t f);
|
||||
|
|
|
@ -41,12 +41,12 @@ SV_WipeSavegame(char *savename)
|
|||
|
||||
Com_sprintf(name, sizeof(name), "%s/save/%s/server.ssv",
|
||||
FS_Gamedir(), savename);
|
||||
|
||||
|
||||
remove(name);
|
||||
|
||||
Com_sprintf(name, sizeof(name), "%s/save/%s/game.ssv",
|
||||
FS_Gamedir(), savename);
|
||||
|
||||
|
||||
remove(name);
|
||||
|
||||
Com_sprintf(name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir(), savename);
|
||||
|
@ -194,7 +194,7 @@ SV_ReadLevelFile(void)
|
|||
Com_DPrintf("SV_ReadLevelFile()\n");
|
||||
|
||||
Com_sprintf(name, sizeof(name), "save/current/%s.sv2", sv.name);
|
||||
FS_FOpenFile(name, &f, FS_READ);
|
||||
FS_FOpenFile(name, &f, true);
|
||||
|
||||
if (!f)
|
||||
{
|
||||
|
@ -300,7 +300,7 @@ SV_ReadServerFile(void)
|
|||
Com_DPrintf("SV_ReadServerFile()\n");
|
||||
|
||||
Com_sprintf(name, sizeof(name), "save/current/server.ssv");
|
||||
FS_FOpenFile(name, &f, FS_READ);
|
||||
FS_FOpenFile(name, &f, true);
|
||||
|
||||
if (!f)
|
||||
{
|
||||
|
@ -315,7 +315,7 @@ SV_ReadServerFile(void)
|
|||
FS_Read(mapcmd, sizeof(mapcmd), f);
|
||||
|
||||
/* read all CVAR_LATCH cvars
|
||||
these will be things like
|
||||
these will be things like
|
||||
coop, skill, deathmatch, etc */
|
||||
while (1)
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ SV_BeginDemoserver(void)
|
|||
char name[MAX_OSPATH];
|
||||
|
||||
Com_sprintf(name, sizeof(name), "demos/%s", sv.name);
|
||||
FS_FOpenFile(name, &sv.demofile, FS_READ);
|
||||
FS_FOpenFile(name, &sv.demofile, false);
|
||||
|
||||
if (!sv.demofile)
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ SV_Configstrings_f(void)
|
|||
start = (int)strtol(Cmd_Argv(2), (char **)NULL, 10);
|
||||
|
||||
/* write a packet full of data */
|
||||
while (sv_client->netchan.message.cursize < MAX_MSGLEN / 2 &&
|
||||
while (sv_client->netchan.message.cursize < MAX_MSGLEN / 2 &&
|
||||
start < MAX_CONFIGSTRINGS)
|
||||
{
|
||||
if (sv.configstrings[start][0])
|
||||
|
@ -387,7 +387,7 @@ SV_Nextserver(void)
|
|||
const char *v;
|
||||
|
||||
if ((sv.state == ss_game) ||
|
||||
((sv.state == ss_pic) &&
|
||||
((sv.state == ss_pic) &&
|
||||
!Cvar_VariableValue("coop")))
|
||||
{
|
||||
return; /* can't nextserver while playing a normal game */
|
||||
|
|
Loading…
Reference in a new issue