Improve FS_GetModList

- Paths to search for mods are now specified in an array

- Mods can now consist solely of ".pk3dir" folders and still be
considered valid

- The function now has a consistent style
This commit is contained in:
Max Crofts 2017-04-12 17:49:50 +10:00
parent 7ea46532d5
commit af69d1148f

View file

@ -2510,38 +2510,33 @@ void FS_GetModDescription( const char *modDir, char *description, int descriptio
FS_GetModList FS_GetModList
Returns a list of mod directory names Returns a list of mod directory names
A mod directory is a peer to baseq3 with a pk3 in it A mod directory is a peer to baseq3 with a pk3 or pk3dir in it
The directories are searched in base path, cd path and home path
================ ================
*/ */
int FS_GetModList( char *listbuf, int bufsize ) { int FS_GetModList( char *listbuf, int bufsize ) {
int nMods, i, j, nTotal, nLen, nPaks, nPotential, nDescLen; int nMods, i, j, k, nTotal, nLen, nPaks, nDirs, nPakDirs, nPotential, nDescLen;
char **pFiles = NULL; char **pFiles = NULL;
char **pPaks = NULL; char **pPaks = NULL;
char **pDirs = NULL;
char *name, *path; char *name, *path;
char description[MAX_OSPATH]; char description[MAX_OSPATH];
int dummy; int dummy;
char **pFiles0 = NULL; char **pFiles0 = NULL;
char **pFiles1 = NULL;
char **pFiles2 = NULL;
char **pFiles3 = NULL;
char **pFiles4 = NULL;
char **pFiles5 = NULL;
qboolean bDrop = qfalse; qboolean bDrop = qfalse;
// paths to search for mods
const char * const paths[] = { fs_basepath->string, fs_homepath->string, fs_steampath->string, fs_gogpath->string };
*listbuf = 0; *listbuf = 0;
nMods = nTotal = 0; nMods = nTotal = 0;
pFiles0 = Sys_ListFiles( fs_homepath->string, NULL, NULL, &dummy, qtrue ); // iterate through paths and get list of potential mods
pFiles1 = Sys_ListFiles( fs_basepath->string, NULL, NULL, &dummy, qtrue ); for (i = 0; i < ARRAY_LEN(paths); i++) {
pFiles2 = Sys_ListFiles( fs_steampath->string, NULL, NULL, &dummy, qtrue ); pFiles0 = Sys_ListFiles(paths[i], NULL, NULL, &dummy, qtrue);
pFiles3 = Sys_ListFiles( fs_gogpath->string, NULL, NULL, &dummy, qtrue ); // Sys_ConcatenateFileLists frees the lists so Sys_FreeFileList isn't required
// we searched for mods in the four paths pFiles = Sys_ConcatenateFileLists(pFiles, pFiles0);
// it is likely that we have duplicate names now, which we will cleanup below }
pFiles4 = Sys_ConcatenateFileLists( pFiles0, pFiles1 );
pFiles5 = Sys_ConcatenateFileLists( pFiles2, pFiles3 );
pFiles = Sys_ConcatenateFileLists( pFiles4, pFiles5 );
nPotential = Sys_CountFileList(pFiles); nPotential = Sys_CountFileList(pFiles);
@ -2551,8 +2546,7 @@ int FS_GetModList( char *listbuf, int bufsize ) {
// ignore duplicate mod directories // ignore duplicate mod directories
if (i != 0) { if (i != 0) {
bDrop = qfalse; bDrop = qfalse;
for(j=0; j<i; j++) for (j = 0; j < i; j++) {
{
if (Q_stricmp(pFiles[j], name) == 0) { if (Q_stricmp(pFiles[j], name) == 0) {
// this one can be dropped // this one can be dropped
bDrop = qtrue; bDrop = qtrue;
@ -2560,49 +2554,35 @@ int FS_GetModList( char *listbuf, int bufsize ) {
} }
} }
} }
if (bDrop) { // we also drop "baseq3" "." and ".."
if (bDrop || Q_stricmp(name, com_basegame->string) == 0 || Q_stricmpn(name, ".", 1) == 0) {
continue; continue;
} }
// we drop "baseq3" "." and ".."
if (Q_stricmp(name, com_basegame->string) && Q_stricmpn(name, ".", 1)) { // in order to be a valid mod the directory must contain at least one .pk3 or .pk3dir
// now we need to find some .pk3 files to validate the mod
// NOTE TTimo: (actually I'm not sure why .. what if it's a mod under developement with no .pk3?)
// we didn't keep the information when we merged the directory names, as to what OS Path it was found under // we didn't keep the information when we merged the directory names, as to what OS Path it was found under
// so it could be in base path, cd path or home path // so we will try each of them here
// we will try each three of them here (yes, it's a bit messy) for (j = 0; j < ARRAY_LEN(paths); j++) {
path = FS_BuildOSPath( fs_basepath->string, name, "" ); path = FS_BuildOSPath(paths[j], name, "");
nPaks = 0; nPaks = nDirs = nPakDirs = 0;
pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse);
Sys_FreeFileList( pPaks ); // we only use Sys_ListFiles to check wether .pk3 files are present
/* try on home path */
if ( nPaks <= 0 )
{
path = FS_BuildOSPath( fs_homepath->string, name, "" );
nPaks = 0;
pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse); pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse);
pDirs = Sys_ListFiles(path, "/", NULL, &nDirs, qfalse);
for (k = 0; k < nDirs; k++) {
// we only want to count directories ending with ".pk3dir"
if (FS_IsExt(pDirs[k], ".pk3dir", strlen(pDirs[k]))) {
nPakDirs++;
}
}
// we only use Sys_ListFiles to check whether files are present
Sys_FreeFileList(pPaks); Sys_FreeFileList(pPaks);
Sys_FreeFileList(pDirs);
if (nPaks > 0 || nPakDirs > 0) {
break;
}
} }
/* try on steam path */ if (nPaks > 0 || nPakDirs > 0) {
if ( nPaks <= 0 )
{
path = FS_BuildOSPath( fs_steampath->string, name, "" );
nPaks = 0;
pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
Sys_FreeFileList( pPaks );
}
/* try on gog path */
if ( nPaks <= 0 )
{
path = FS_BuildOSPath( fs_gogpath->string, name, "" );
nPaks = 0;
pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
Sys_FreeFileList( pPaks );
}
if (nPaks > 0) {
nLen = strlen(name) + 1; nLen = strlen(name) + 1;
// nLen is the length of the mod path // nLen is the length of the mod path
// we need to see if there is a description available // we need to see if there is a description available
@ -2616,13 +2596,11 @@ int FS_GetModList( char *listbuf, int bufsize ) {
listbuf += nDescLen; listbuf += nDescLen;
nTotal += nLen + nDescLen; nTotal += nLen + nDescLen;
nMods++; nMods++;
} } else {
else {
break; break;
} }
} }
} }
}
Sys_FreeFileList( pFiles ); Sys_FreeFileList( pFiles );
return nMods; return nMods;