Allow search_begin to filter by package names.

This commit is contained in:
Shpoike 2020-09-04 13:17:28 +01:00
parent 8915c41e0c
commit f232be4f77
3 changed files with 62 additions and 39 deletions

View File

@ -2516,9 +2516,11 @@ static void COM_ListFiles(void *ctx, searchpath_t *spath, const char *pattern, q
}
#endif
}
void COM_ListAllFiles(void *ctx, const char *pattern, qboolean (*cb)(void *ctx, const char *fname, time_t mtime, size_t fsize, searchpath_t *spath))
void COM_ListAllFiles(void *ctx, const char *pattern, qboolean (*cb)(void *ctx, const char *fname, time_t mtime, size_t fsize, searchpath_t *spath), unsigned int flags, const char *pkgfilter)
{
searchpath_t *search;
const char *sp;
qboolean foundpackage = false;
if (*pattern == '/' || strchr(pattern, ':') //block absolute paths
|| strchr(pattern, '\\') //block unportable paths (also ones that mess up other checks)
@ -2531,6 +2533,23 @@ void COM_ListAllFiles(void *ctx, const char *pattern, qboolean (*cb)(void *ctx,
//don't add the same pak twice.
for (search = com_searchpaths; search; search = search->next)
{
if (pkgfilter)
{
if (flags & (1u<<1))
sp = search->purename;
else
{
sp = strchr(search->purename, '/');
if (sp && !strchr(++sp, '/'))
;
else
continue; //ignore packages inside other packages. they're just too weird.
}
if (strcmp(pkgfilter, sp))
continue; //ignore this package
}
foundpackage = true;
if (search->pack)
{
pack_t *pak = search->pack;
@ -2546,9 +2565,16 @@ void COM_ListAllFiles(void *ctx, const char *pattern, qboolean (*cb)(void *ctx,
COM_ListFiles(ctx, search, pattern, cb);
}
}
if (flags & (1u<<1) && (flags & (1u<<2)) && pkgfilter && foundpackage)
{ //if we're using full package paths, and we're trying to force the search, then be prepared to search gamedirs which are not currently active too if we didn't already search it.
// searchpath_t dummy;
// dummy.filename =
Con_Printf("search_begin: SB_FORCESEARCH not supported\n");
}
}
static qboolean COM_AddPackage(searchpath_t *basepath, const char *pakfile)
static qboolean COM_AddPackage(searchpath_t *basepath, const char *pakfile, const char *purename)
{
searchpath_t *search;
pack_t *pak;
@ -2583,6 +2609,8 @@ static qboolean COM_AddPackage(searchpath_t *basepath, const char *pakfile)
}
search = (searchpath_t *) Z_Malloc(sizeof(searchpath_t));
q_strlcpy(search->filename, pakfile, sizeof(search->filename));
q_strlcpy(search->purename, purename, sizeof(search->purename));
search->path_id = basepath->path_id;
search->pack = pak;
search->next = com_searchpaths;
@ -2595,8 +2623,10 @@ static qboolean COM_AddEnumeratedPackage(void *ctx, const char *pakfile)
{
searchpath_t *basepath = ctx;
char fullpakfile[MAX_OSPATH];
char purepakfile[MAX_OSPATH];
q_snprintf (fullpakfile, sizeof(fullpakfile), "%s/%s", basepath->filename, pakfile);
return COM_AddPackage(basepath, fullpakfile);
q_snprintf (purepakfile, sizeof(purepakfile), "%s/%s", basepath->purename, pakfile);
return COM_AddPackage(basepath, fullpakfile, purepakfile);
}
const char *COM_GetGameNames(qboolean full)
@ -2662,6 +2692,7 @@ static void COM_AddGameDirectory (const char *dir)
unsigned int path_id;
searchpath_t *searchdir;
char pakfile[MAX_OSPATH];
char purename[MAX_OSPATH];
qboolean been_here = false;
FILE *listing;
qboolean found;
@ -2699,6 +2730,7 @@ _add_path:
searchdir = (searchpath_t *) Z_Malloc(sizeof(searchpath_t));
searchdir->path_id = path_id;
q_strlcpy (searchdir->filename, com_gamedir, sizeof(searchdir->filename));
q_strlcpy (searchdir->purename, dir, sizeof(searchdir->purename));
q_snprintf (pakfile, sizeof(pakfile), "%s/pak.lst", com_gamedir);
listing = fopen(pakfile, "rb");
@ -2724,14 +2756,16 @@ _add_path:
if (strchr(com_token, '/') || strchr(com_token, '\\') || strchr(com_token, ':'))
continue;
q_snprintf (pakfile, sizeof(pakfile), "%s/%s", com_gamedir, com_token);
COM_AddPackage(searchdir, pakfile);
q_snprintf (purename, sizeof(purename), "%s/%s", dir, com_token);
COM_AddPackage(searchdir, pakfile, purename);
if (path_id == 1 && !fitzmode && !q_strncasecmp(com_token, "pak0.", 5))
{ //add this now, to try to retain correct ordering.
qboolean old = com_modified;
if (been_here) base = host_parms->userdir;
q_snprintf (pakfile, sizeof(pakfile), "%s/%s.%s", base, enginepackname, COM_FileGetExtension(com_token));
COM_AddPackage(searchdir, pakfile);
q_snprintf (purename, sizeof(purename), "%s.%s", enginepackname, COM_FileGetExtension(com_token));
COM_AddPackage(searchdir, pakfile, purename);
com_modified = old;
}
}
@ -2743,9 +2777,11 @@ _add_path:
found = false;
q_snprintf (pakfile, sizeof(pakfile), "%s/pak%i.pak", com_gamedir, i);
found |= COM_AddPackage(searchdir, pakfile);
q_snprintf (purename, sizeof(purename), "%s/pak%i.pak", dir, i);
found |= COM_AddPackage(searchdir, pakfile, purename);
q_snprintf (pakfile, sizeof(pakfile), "%s/pak%i.pk3", com_gamedir, i);
found |= COM_AddPackage(searchdir, pakfile);
q_snprintf (purename, sizeof(purename), "%s/pak%i.pk3", dir, i);
found |= COM_AddPackage(searchdir, pakfile, purename);
if (i == 0 && path_id == 1 && !fitzmode)
{
@ -2753,9 +2789,11 @@ _add_path:
if (been_here) base = host_parms->userdir;
q_snprintf (pakfile, sizeof(pakfile), "%s/%s.pak", base, enginepackname);
COM_AddPackage(searchdir, pakfile);
q_snprintf (purename, sizeof(purename), "%s.pak", enginepackname);
COM_AddPackage(searchdir, pakfile, purename);
q_snprintf (pakfile, sizeof(pakfile), "%s/%s.pk3", base, enginepackname);
COM_AddPackage(searchdir, pakfile);
q_snprintf (purename, sizeof(purename), "%s.pk3", enginepackname);
COM_AddPackage(searchdir, pakfile, purename);
com_modified = old;
}

View File

@ -239,6 +239,7 @@ typedef struct searchpath_s
// Note that <install_dir>/game1 and
// <userdir>/game1 have the same id.
char filename[MAX_OSPATH];
char purename[MAX_OSPATH]; // 'gamedir[/foo.pak]'
pack_t *pack; // only one of filename / pack will be used
struct searchpath_s *next;
} searchpath_t;
@ -253,7 +254,7 @@ extern char com_basedir[MAX_OSPATH];
extern char com_gamedir[MAX_OSPATH];
extern int file_from_pak; // global indicating that file came from a pak
void COM_ListAllFiles(void *ctx, const char *pattern, qboolean (*cb)(void *ctx, const char *fname, time_t mtime, size_t fsize, searchpath_t *spath));
void COM_ListAllFiles(void *ctx, const char *pattern, qboolean (*cb)(void *ctx, const char *fname, time_t mtime, size_t fsize, searchpath_t *spath), unsigned int flags, const char *pkgfilter);
const char *COM_GetGameNames(qboolean full);
qboolean COM_GameDirMatches(const char *tdirs);

View File

@ -3146,14 +3146,14 @@ static void PF_search_begin(void)
const char *pattern = G_STRING(OFS_PARM0);
unsigned int flags = G_FLOAT(OFS_PARM1);
// qboolaen quiet = !!G_FLOAT(OFS_PARM2);
// const char *pkgfilter = G_STRING(OFS_PARM3);
const char *pkgfilter = (qcvm->argc>3)?G_STRING(OFS_PARM3):NULL;
for (i = 0; i < countof(searches); i++)
{
if (!searches[i].owner)
{
searches[i].flags = flags;
COM_ListAllFiles(&searches[i], pattern, PR_Search_AddFile);
COM_ListAllFiles(&searches[i], pattern, PR_Search_AddFile, flags, pkgfilter);
if (!searches[i].numfiles)
break;
searches[i].owner = qcvm;
@ -3241,28 +3241,12 @@ static void PF_search_getpackagename(void)
{
if (searches[handle].flags & 2)
{ //gamedir/packagename. not necessarily fopenable.
if (spath->pack)
{
const char *pathname = spath->pack->filename;
const char *last = pathname, *last2 = "";
while (*pathname)
{
if (*pathname == '/')
{
last2 = last;
last = pathname + 1;
}
pathname++;
}
G_INT(OFS_RETURN) = PR_MakeTempString(last2);
}
else
G_INT(OFS_RETURN) = PR_MakeTempString(COM_SkipPath(spath->filename));
G_INT(OFS_RETURN) = PR_MakeTempString(spath->purename);
}
else
{ //like whichpack thus like frik_file. which sucks.
if (spath->pack)
G_INT(OFS_RETURN) = PR_MakeTempString(COM_SkipPath(spath->pack->filename));
G_INT(OFS_RETURN) = PR_MakeTempString(COM_SkipPath(spath->purename));
else
G_INT(OFS_RETURN) = 0;
}
@ -7116,7 +7100,7 @@ static struct
{"argv", PF_ArgV, PF_ArgV, 442, PF_ArgV,59, "string(float n)"},// (KRIMZON_SV_PARSECLIENTCOMMAND
{"argc", PF_ArgC, PF_ArgC, 0, PF_ArgC,0, "float()"},
{"setattachment", PF_setattachment, PF_setattachment, 443, PF_NoMenu, "void(entity e, entity tagentity, string tagname)", ""},// (DP_GFX_QUAKE3MODELTAGS)
{"search_begin", PF_search_begin, PF_search_begin, 444, PF_search_begin,74, "searchhandle(string pattern, optional float caseinsensitive, optional float quiet)", "initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle."},
{"search_begin", PF_search_begin, PF_search_begin, 444, PF_search_begin,74, "searchhandle(string pattern, float flags, float quiet, optional string filterpackage)", "initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle."},
{"search_end", PF_search_end, PF_search_end, 445, PF_search_end,75, "void(searchhandle handle)", ""},
{"search_getsize", PF_search_getsize, PF_search_getsize, 446, PF_search_getsize,76, "float(searchhandle handle)", " Retrieves the number of files that were found."},
{"search_getfilename",PF_search_getfilename,PF_search_getfilename,447,PF_search_getfilename,77, "string(searchhandle handle, float num)", "Retrieves name of one of the files that was found by the initial search."},
@ -7217,14 +7201,14 @@ static struct
// {"generateentitydata",PF_generateentitydata,NULL, 0, PF_NoMenu, D("string(entity e)", "Dumps the entities fields into a string which can later be parsed with parseentitydata."}),
{"getgamedirinfo", PF_NoSSQC, PF_NoCSQC, 626, PF_getgamedirinfo,626, D("string(float n, float prop)", "Provides a way to enumerate available mod directories.")},
{"getgamedirinfo", PF_NoSSQC, PF_getgamedirinfo, 626, PF_getgamedirinfo,626, D("string(float n, float prop)", "Provides a way to enumerate available mod directories.")},
{"sprintf", PF_sprintf, PF_sprintf, 627, PF_sprintf,627, "string(string fmt, ...)"},
{"getsurfacenumtriangles",PF_getsurfacenumtriangles,PF_getsurfacenumtriangles,628,PF_NoMenu, "float(entity e, float s)"},
{"getsurfacetriangle",PF_getsurfacetriangle,PF_getsurfacetriangle,629,PF_NoMenu, "vector(entity e, float s, float n)"},
{"setkeybind", PF_NoSSQC, PF_cl_setkeybind, 630, PF_cl_setkeybind,630, "float(float key, string bind, optional float bindmap)", "Changes a key binding."},
{"getsurfacetriangle",PF_getsurfacetriangle,PF_getsurfacetriangle, 629, PF_NoMenu, "vector(entity e, float s, float n)"},
{"setkeybind", PF_NoSSQC, PF_cl_setkeybind, 630, PF_cl_setkeybind,630, "float(float key, string bind, optional float bindmap, optional float modifier)", "Changes a key binding."},
{"getbindmaps", PF_NoSSQC, PF_cl_getbindmaps, 631, PF_cl_getbindmaps,631, "vector()", "stub."},
{"setbindmaps", PF_NoSSQC, PF_cl_setbindmaps, 632, PF_cl_setbindmaps,632, "float(vector bm)", "stub."},
{"digest_hex", PF_digest_hex, PF_digest_hex, 639, PF_digest_hex, 639, "string(string digest, string data, ...)", "stub."},
{"digest_hex", PF_digest_hex, PF_digest_hex, 639, PF_digest_hex, 639, "string(string digest, string data, ...)"},
};
static const char *extnames[] =