diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 94a1c7f6b..246a802bc 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -3042,6 +3042,7 @@ enum QCSEARCH_ALLOWDUPES = 1u<<2, //don't filter out dupes, allowing entries hidden by later packages to be shown. QCSEARCH_FORCESEARCH = 1u<<3, //force the search to succeed even if the gamedir/package is not active. QCSEARCH_MULTISEARCH = 1u<<4, //to avoid possible string manipulation exploits? + QCSEARCH_NAMESORT = 1u<<5, //sort results by filename, instead of by filesystem priority/randomness }; searchpathfuncs_t *COM_EnumerateFilesPackage (char *matches, const char *package, unsigned int flags, int (QDECL *func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t*), void *parm); typedef struct prvmsearch_s { @@ -3050,7 +3051,7 @@ typedef struct prvmsearch_s { searchpath_t searchinfo; int entries; - struct + struct prvmsearchentry_s { char *name; qofs_t size; @@ -3118,6 +3119,14 @@ void search_close_progs(pubprogfuncs_t *prinst, qboolean complain) } } +static int QDECL search_name_sort(const void *av, const void *bv) +{ + const struct prvmsearchentry_s *a = av, *b = bv; + int ret = strcmp(a->name, b->name); + //FIXME: if equal sort by original order! + return ret; +} + static int QDECL search_enumerate(const char *name, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath) { prvmsearch_t *s = parm; @@ -3186,6 +3195,9 @@ void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_ Q_strncpyz(s->searchinfo.purepath, package?package:"", sizeof(s->searchinfo.purepath)); s->searchinfo.handle = COM_EnumerateFilesPackage(s->pattern, package?s->searchinfo.purepath:NULL, s->fsflags, search_enumerate, s); + if (flags&QCSEARCH_NAMESORT) + qsort(s->entry, s->entries, sizeof(*s->entry), search_name_sort); + G_FLOAT(OFS_RETURN) = j; } //void search_end(float handle) = #75; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 7c1a981b8..12bc625c6 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -10632,8 +10632,9 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs "SB_CASEINSENSITIVE=1<<0," "SB_FULLPACKAGEPATH=1<<1," "SB_ALLOWDUPES=1<<2," - "SB_FORCESEARCH=1<<3" - "SB_MULTISEARCH=1<<4" + "SB_FORCESEARCH=1<<3," + "SB_MULTISEARCH=1<<4," + "SB_NAMESORT=1<<5" "} flags, float quiet, optional string package)"}, {"search_end", PF_Fixme, 0, 0, 0, 75, "void(searchhandle handle)"}, {"search_getsize", PF_Fixme, 0, 0, 0, 76, "float(searchhandle handle)"},