diff --git a/Quake/common.c b/Quake/common.c index 33578f1b..bceb133d 100644 --- a/Quake/common.c +++ b/Quake/common.c @@ -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; } diff --git a/Quake/common.h b/Quake/common.h index 88c7e75e..2e84095b 100644 --- a/Quake/common.h +++ b/Quake/common.h @@ -239,6 +239,7 @@ typedef struct searchpath_s // Note that /game1 and // /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); diff --git a/Quake/pr_ext.c b/Quake/pr_ext.c index 6019f835..72bd7f8d 100644 --- a/Quake/pr_ext.c +++ b/Quake/pr_ext.c @@ -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,17 +7201,17 @@ 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.")}, - {"sprintf", PF_sprintf, PF_sprintf, 627, PF_sprintf,627, "string(string fmt, ...)"}, + {"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."}, - {"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."}, + {"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, ...)"}, }; -static const char *extnames[] = +static const char *extnames[] = { "DP_CON_SET", "DP_CON_SETA",