mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-24 21:02:26 +00:00
Add file uri support, requires a '-allowfileurl' commandline argument.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6318 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
cdcb3c3950
commit
503162aefe
12 changed files with 250 additions and 67 deletions
|
@ -6174,12 +6174,15 @@ done:
|
|||
qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file)
|
||||
{
|
||||
hrf_t *f;
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
|
||||
//win32 file urls are basically fucked, so defer to the windows api.
|
||||
#if defined(FTE_TARGET_WEB)
|
||||
if (nlen >= 8 && !strncmp(fname, "file:///", 8))
|
||||
{ //just here so we don't get confused by the arbitrary scheme check below.
|
||||
}
|
||||
#else
|
||||
//file urls need special handling, if only for percent-encoding.
|
||||
char utf8[MAX_OSPATH*3];
|
||||
if (nlen >= 7 && !strncmp(fname, "file://", 7))
|
||||
if (nlen >= 5 && !strncmp(fname, "file:", 5))
|
||||
{
|
||||
qboolean Sys_ResolveFileURL(const char *inurl, int inlen, char *out, int outlen);
|
||||
if (!Sys_ResolveFileURL(fname, nlen, utf8, sizeof(utf8)))
|
||||
{
|
||||
Con_Printf("Cannot resolve file url\n");
|
||||
|
@ -6188,17 +6191,6 @@ qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file)
|
|||
fname = utf8;
|
||||
nlen = strlen(fname);
|
||||
}
|
||||
#elif defined(FTE_TARGET_WEB)
|
||||
if (nlen >= 8 && !strncmp(fname, "file:///", 8))
|
||||
{ //just here so we don't get confused by the arbitrary scheme check below.
|
||||
}
|
||||
#else
|
||||
//unix file urls are fairly consistant - must be an absolute path.
|
||||
if (nlen >= 8 && !strncmp(fname, "file:///", 8))
|
||||
{
|
||||
fname += 7;
|
||||
nlen -= 7;
|
||||
}
|
||||
#endif
|
||||
else if((nlen >= 7 && !strncmp(fname, "http://", 7)) ||
|
||||
(nlen >= 8 && !strncmp(fname, "https://", 8)))
|
||||
|
|
|
@ -1313,7 +1313,7 @@ void VARGS Con_ThrottlePrintf (float *timer, int developerlevel, const char *fmt
|
|||
|
||||
if (*timer > now)
|
||||
; //in the future? zomg
|
||||
else if (*timer > now-1)
|
||||
else if (*timer >= now-1)
|
||||
return; //within the last second
|
||||
*timer = now; //in the future? zomg
|
||||
|
||||
|
|
|
@ -13706,6 +13706,7 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
|
|||
char *altname;
|
||||
char *nextalt;
|
||||
qboolean exactext = !!(tex->flags & IF_EXACTEXTENSION);
|
||||
qboolean exactpath = false;
|
||||
|
||||
int locflags = FSLF_DEPTH_INEXPLICIT|FSLF_DEEPONFAILURE;
|
||||
int bestdepth = 0x7fffffff, depth;
|
||||
|
@ -13716,7 +13717,13 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
|
|||
if (strncmp(tex->ident, "http:", 5) && strncmp(tex->ident, "https:", 6))
|
||||
for(altname = tex->ident;altname;altname = nextalt)
|
||||
{
|
||||
nextalt = strchr(altname, ':');
|
||||
if (!strncmp(altname, "file:", 5))
|
||||
{
|
||||
nextalt = strchr(altname+5, ':');
|
||||
exactpath = true;
|
||||
}
|
||||
else
|
||||
nextalt = strchr(altname, ':');
|
||||
if (nextalt)
|
||||
{
|
||||
nextalt++;
|
||||
|
@ -13754,18 +13761,21 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
|
|||
if (!tex->fallbackdata || (gl_load24bit.ival && !(tex->flags & IF_NOREPLACE)))
|
||||
{
|
||||
#ifdef IMAGEFMT_DDS
|
||||
Q_snprintfz(fname, sizeof(fname), "dds/%s.dds", nicename);
|
||||
depth = FS_FLocateFile(fname, locflags, &loc);
|
||||
if (depth < bestdepth)
|
||||
if (!exactpath)
|
||||
{
|
||||
Q_strncpyz(bestname, fname, bestnamesize);
|
||||
bestdepth = depth;
|
||||
*bestloc = loc;
|
||||
*bestflags = 0;
|
||||
Q_snprintfz(fname, sizeof(fname), "dds/%s.dds", nicename);
|
||||
depth = FS_FLocateFile(fname, locflags, &loc);
|
||||
if (depth < bestdepth)
|
||||
{
|
||||
Q_strncpyz(bestname, fname, bestnamesize);
|
||||
bestdepth = depth;
|
||||
*bestloc = loc;
|
||||
*bestflags = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strchr(nicename, '/') || strchr(nicename, '\\')) //never look in a root dir for the pic
|
||||
if (exactpath || strchr(nicename, '/') || strchr(nicename, '\\')) //never look in a root dir for the pic
|
||||
i = 0;
|
||||
else
|
||||
i = 1;
|
||||
|
@ -13774,6 +13784,8 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
|
|||
{
|
||||
if (!tex_path[i].enabled)
|
||||
continue;
|
||||
if (exactpath && i)
|
||||
break;
|
||||
if (tex_path[i].args >= 3)
|
||||
{ //this is a path that needs subpaths
|
||||
char subpath[MAX_QPATH];
|
||||
|
|
|
@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define FTEENGINE
|
||||
#include "../plugins/plugin.h"
|
||||
#endif
|
||||
#include "fs.h"
|
||||
|
||||
#undef malloc
|
||||
|
||||
|
@ -1077,7 +1078,7 @@ static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext)
|
|||
#endif
|
||||
backtrace_symbols_fd(array+firstframe, size-firstframe, 2);
|
||||
|
||||
if (sig == SIGINT)
|
||||
if (sig == SIGINT || fs_readonly)
|
||||
fd = -1; //don't write out crash logs on ctrl+c
|
||||
else
|
||||
fd = open("crash.log", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
|
@ -1181,7 +1182,6 @@ char *Sys_ConsoleInput(void)
|
|||
}
|
||||
|
||||
//begin meta generation helper
|
||||
#include "fs.h"
|
||||
static int Crypto_GenerateSignature(qbyte *hashdata, size_t hashsize, qbyte *signdata, size_t signsizemax)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -1474,6 +1474,12 @@ qboolean Sys_ResolveFileURL(const char *inurl, int inlen, char *out, int outlen)
|
|||
if (FAILED(pPathCreateFromUrlW(wurl, local, &grr, 0)))
|
||||
return false;
|
||||
narrowen(out, outlen, local);
|
||||
while(*out)
|
||||
{
|
||||
if (*out == '\\')
|
||||
*out = '/';
|
||||
out++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -1046,7 +1046,8 @@ void Con_TextEditor_f(void)
|
|||
{
|
||||
char *fname = Cmd_Argv(1);
|
||||
char *line = strrchr(fname, ':');
|
||||
if (line)
|
||||
char *lineend = NULL;
|
||||
if (line && strtol(line+1, &lineend, 0) && !lineend)
|
||||
*line++ = 0;
|
||||
if (!*fname)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@ hashtable_t filesystemhash;
|
|||
static qboolean com_fschanged = true, com_fsneedreload;
|
||||
qboolean com_installer = false;
|
||||
qboolean fs_readonly;
|
||||
static searchpath_t *fs_allowfileuri;
|
||||
int waitingformanifest;
|
||||
static unsigned int fs_restarts;
|
||||
void *fs_thread_mutex;
|
||||
|
@ -170,6 +171,85 @@ void VARGS VFS_PRINTF(vfsfile_t *vf, const char *format, ...)
|
|||
|
||||
|
||||
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
|
||||
//windows has a special helper function to handle legacy URIs.
|
||||
#else
|
||||
qboolean Sys_ResolveFileURL(const char *inurl, int inlen, char *out, int outlen)
|
||||
{
|
||||
const unsigned char *i = inurl, *inend = inurl+inlen;
|
||||
unsigned char *o = out, *outend = out+outlen;
|
||||
unsigned char hex;
|
||||
|
||||
//make sure its a file url...
|
||||
if (inlen < 5 || strncmp(inurl, "file:", 5))
|
||||
return false;
|
||||
i += 5;
|
||||
|
||||
if (i+1 < inend && i[0] == '/' && i[1] == '/')
|
||||
{ //has an authority field...
|
||||
i+=2;
|
||||
//except we don't support authorities other than ourself...
|
||||
if (i < inend || *i != '/')
|
||||
return false; //must be an absolute path...
|
||||
#ifdef _WIN32
|
||||
i++; //on windows, (full)absolute paths start with a drive name...
|
||||
#endif
|
||||
}
|
||||
else if (i < inend && i[0] == '/')
|
||||
; // file:/foo (no authority)
|
||||
else
|
||||
return false;
|
||||
|
||||
//everything else must be percent-encoded
|
||||
while (i < inend)
|
||||
{
|
||||
if (!*i || o == outend)
|
||||
return false; //don't allow nulls...
|
||||
else if (*i == '/' && i+1<inend && i[1] == '/')
|
||||
return false; //two slashes is invalid (can be parent directory on some systems, or just buggy or weird)
|
||||
else if (*i == '\\')
|
||||
return false; //don't allow backslashes. they're meant to be percent-encoded anyway.
|
||||
else if (*i == '%' && i+2<inend)
|
||||
{
|
||||
hex = 0;
|
||||
if (i[1] >= 'A' && i[1] <= 'F')
|
||||
hex += i[1]-'A'+10;
|
||||
else if (i[1] >= 'a' && i[1] <= 'f')
|
||||
hex += i[1]-'a'+10;
|
||||
else if (i[1] >= '0' && i[1] <= '9')
|
||||
hex += i[1]-'0';
|
||||
else
|
||||
{
|
||||
*o++ = *i++;
|
||||
continue;
|
||||
}
|
||||
hex <<= 4;
|
||||
if (i[2] >= 'A' && i[2] <= 'F')
|
||||
hex += i[2]-'A'+10;
|
||||
else if (i[2] >= 'a' && i[2] <= 'f')
|
||||
hex += i[2]-'a'+10;
|
||||
else if (i[2] >= '0' && i[2] <= '9')
|
||||
hex += i[2]-'0';
|
||||
else
|
||||
{
|
||||
*o++ = *i++;
|
||||
continue;
|
||||
}
|
||||
*o++ = hex;
|
||||
i += 3;
|
||||
}
|
||||
else
|
||||
*o++ = *i++;
|
||||
}
|
||||
|
||||
if (o == outend)
|
||||
return false;
|
||||
*o = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1104,7 +1184,7 @@ static int QDECL COM_Dir_List(const char *name, qofs_t size, time_t mtime, void
|
|||
colour = "^1"; //superseeded
|
||||
Q_snprintfz(link, sizeof(link), "\\tip\\flocate error");
|
||||
}
|
||||
else if (loc.search->handle == spath)
|
||||
else if (loc.search->handle == spath || (fs_allowfileuri&&loc.search == fs_allowfileuri))
|
||||
{
|
||||
colour = "^2";
|
||||
|
||||
|
@ -1657,6 +1737,19 @@ int FS_FLocateFile(const char *filename, unsigned int lflags, flocation_t *loc)
|
|||
loc->search = NULL;
|
||||
loc->len = -1;
|
||||
|
||||
if (!strncmp(filename, "file:", 5))
|
||||
{
|
||||
if (fs_allowfileuri && Sys_ResolveFileURL(filename, strlen(filename), cleanpath, sizeof(cleanpath)))
|
||||
{
|
||||
fs_finds++;
|
||||
found = fs_allowfileuri->handle->FindFile(fs_allowfileuri->handle, loc, cleanpath, NULL);
|
||||
if (found)
|
||||
loc->search = fs_allowfileuri;
|
||||
}
|
||||
pf = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
filename = FS_GetCleanPath(filename, (lflags&FSLF_QUIET), cleanpath, sizeof(cleanpath));
|
||||
if (!filename)
|
||||
{
|
||||
|
@ -1864,7 +1957,7 @@ qboolean FS_GetLocationForPackageHandle(flocation_t *loc, searchpathfuncs_t *spa
|
|||
if (search->handle == spath)
|
||||
{
|
||||
loc->search = search;
|
||||
return spath->FindFile(spath, loc, fname, NULL);
|
||||
return spath->FindFile(spath, loc, fname, NULL) == FF_FOUND;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -2033,27 +2126,28 @@ static const char *FS_GetCleanPath(const char *pattern, qboolean silent, char *o
|
|||
char *o;
|
||||
char *seg;
|
||||
char *end = outbuf + outlen;
|
||||
static float throttletimer;
|
||||
|
||||
s = pattern;
|
||||
seg = o = outbuf;
|
||||
if (!pattern || !*pattern)
|
||||
{
|
||||
Con_Printf("Error: Empty filename\n");
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: Empty filename\n");
|
||||
return NULL;
|
||||
}
|
||||
for(;;)
|
||||
{
|
||||
if (o == end)
|
||||
{
|
||||
Con_Printf("Error: filename too long\n");
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: filename too long\n");
|
||||
return NULL;
|
||||
}
|
||||
if (*s == ':')
|
||||
{
|
||||
if (s == pattern+1 && (s[1] == '/' || s[1] == '\\'))
|
||||
Con_Printf("Error: absolute path in filename %s\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: absolute path in filename %s\n", pattern);
|
||||
else
|
||||
Con_Printf("Error: alternative data stream in filename %s\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: alternative data stream in filename %s\n", pattern);
|
||||
return NULL;
|
||||
}
|
||||
else if (*s == '\\' || *s == '/' || !*s)
|
||||
|
@ -2062,7 +2156,7 @@ static const char *FS_GetCleanPath(const char *pattern, qboolean silent, char *o
|
|||
{
|
||||
if (o == outbuf)
|
||||
{
|
||||
Con_Printf("Error: absolute path in filename %s\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: absolute path in filename %s\n", pattern);
|
||||
return NULL;
|
||||
}
|
||||
if (!*s)
|
||||
|
@ -2070,7 +2164,7 @@ static const char *FS_GetCleanPath(const char *pattern, qboolean silent, char *o
|
|||
*o++ = '\0';
|
||||
break;
|
||||
}
|
||||
Con_Printf("Error: empty directory name (%s)\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: empty directory name (%s)\n", pattern);
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
|
@ -2080,17 +2174,17 @@ static const char *FS_GetCleanPath(const char *pattern, qboolean silent, char *o
|
|||
seg++;
|
||||
if (!seg[0])
|
||||
{
|
||||
Con_Printf("Error: No filename (%s)\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: No filename (%s)\n", pattern);
|
||||
return NULL;
|
||||
}
|
||||
if (seg[0] == '.')
|
||||
{
|
||||
if (o == seg+1)
|
||||
Con_Printf("Error: source directory (%s)\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: source directory (%s)\n", pattern);
|
||||
else if (seg[1] == '.')
|
||||
Con_Printf("Error: parent directory (%s)\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: parent directory (%s)\n", pattern);
|
||||
else
|
||||
Con_Printf("Error: hidden name (%s)\n", pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: hidden name (%s)\n", pattern);
|
||||
return NULL;
|
||||
}
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
|
@ -2108,7 +2202,7 @@ static const char *FS_GetCleanPath(const char *pattern, qboolean silent, char *o
|
|||
{
|
||||
if (o == seg+4 || seg[4] == ' '|| seg[4] == '\t' || seg[4] == '.')
|
||||
{
|
||||
Con_Printf("Error: reserved name in path (%c%c%c%c in %s)\n", seg[0], seg[1], seg[2], seg[3], pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: reserved name in path (%c%c%c%c in %s)\n", seg[0], seg[1], seg[2], seg[3], pattern);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2125,7 +2219,7 @@ static const char *FS_GetCleanPath(const char *pattern, qboolean silent, char *o
|
|||
{
|
||||
if (o == seg+3 || seg[3] == ' '|| seg[3] == '\t' || seg[3] == '.')
|
||||
{
|
||||
Con_Printf("Error: reserved name in path (%c%c%c in %s)\n", seg[0], seg[1], seg[2], pattern);
|
||||
Con_ThrottlePrintf(&throttletimer, 0, "Error: reserved name in path (%c%c%c in %s)\n", seg[0], seg[1], seg[2], pattern);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2401,6 +2495,16 @@ vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_rela
|
|||
if (fs_readonly && *mode == 'w')
|
||||
return NULL;
|
||||
|
||||
if (!strncmp(filename, "file:", 5))
|
||||
{
|
||||
if (fs_allowfileuri || relativeto == FS_SYSTEM)
|
||||
{
|
||||
if (Sys_ResolveFileURL(filename, strlen(filename), fullname, sizeof(fullname)))
|
||||
return VFSOS_Open(fullname, mode);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (relativeto == FS_SYSTEM)
|
||||
return VFSOS_Open(filename, mode);
|
||||
|
||||
|
@ -2869,6 +2973,11 @@ static qboolean FS_EnumerateFilesEach(searchpathfuncs_t *handle, char *matches,
|
|||
char *sep;
|
||||
for (; matches; matches = sep)
|
||||
{
|
||||
if (!strncmp(matches, "file:", 5))
|
||||
{
|
||||
sep = strchr(matches+5, ':');
|
||||
continue;
|
||||
}
|
||||
sep = strchr(matches, ':');
|
||||
if (sep)
|
||||
{
|
||||
|
@ -2892,6 +3001,11 @@ static int FS_EnumerateFilesEachSys (const char *syspath, char *matches, int (*f
|
|||
char *sep;
|
||||
for (; matches; matches = sep)
|
||||
{
|
||||
if (!strncmp(matches, "file:", 5))
|
||||
{
|
||||
sep = strchr(matches+5, ':');
|
||||
continue;
|
||||
}
|
||||
sep = strchr(matches, ':');
|
||||
if (sep)
|
||||
{
|
||||
|
@ -2989,9 +3103,42 @@ searchpathfuncs_t *COM_EnumerateFilesPackage (char *matches, const char *package
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct fs_enumerate_fileuri_s
|
||||
{
|
||||
int (QDECL *func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t*);
|
||||
void *parm;
|
||||
};
|
||||
static int QDECL COM_EnumerateFiles_FileURI (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
||||
{
|
||||
char syspath[MAX_OSPATH];
|
||||
struct fs_enumerate_fileuri_s *e = parm;
|
||||
size_t nlen = strlen(name)+1;
|
||||
if (7+nlen > sizeof(syspath))
|
||||
return true;
|
||||
memcpy(syspath, "file://", 7);
|
||||
memcpy(syspath+7, name, nlen);
|
||||
return e->func(syspath, flags, mtime, e->parm, spath);
|
||||
}
|
||||
|
||||
void COM_EnumerateFiles (const char *match, int (QDECL *func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t*), void *parm)
|
||||
{
|
||||
searchpath_t *search;
|
||||
|
||||
if (!strncmp(match, "file:", 5))
|
||||
{
|
||||
if (fs_allowfileuri)
|
||||
{
|
||||
char syspath[MAX_OSPATH];
|
||||
struct fs_enumerate_fileuri_s e;
|
||||
e.func = func;
|
||||
e.parm = parm;
|
||||
if (Sys_ResolveFileURL(match, strlen(match), syspath, sizeof(syspath)))
|
||||
Sys_EnumerateFiles(NULL, syspath, COM_EnumerateFiles_FileURI, &e, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (search = com_searchpaths; search ; search = search->next)
|
||||
{
|
||||
// is the element a pak file?
|
||||
|
@ -7502,6 +7649,11 @@ void COM_InitFilesystem (void)
|
|||
COM_InitHomedir(NULL);
|
||||
|
||||
fs_readonly = COM_CheckParm("-readonly");
|
||||
if (COM_CheckParm("-allowfileuri") || COM_CheckParm("-allowfileurl"))
|
||||
{
|
||||
fs_allowfileuri = (searchpath_t*)Z_Malloc (sizeof(searchpath_t));
|
||||
fs_allowfileuri->handle = VFSOS_OpenPath(NULL, NULL, "", "", "");
|
||||
}
|
||||
|
||||
fs_thread_mutex = Sys_CreateMutex();
|
||||
}
|
||||
|
@ -7520,7 +7672,10 @@ extern searchpathfuncs_t *(QDECL FSPAK_LoadArchive) (vfsfile_t *packhandle, sear
|
|||
extern searchpathfuncs_t *(QDECL FSDWD_LoadArchive) (vfsfile_t *packhandle, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix);
|
||||
#endif*/
|
||||
void FS_RegisterDefaultFileSystems(void)
|
||||
{
|
||||
{ //packages listed last will be scanned for last (and thus be favoured when searching for game files)
|
||||
#ifdef PACKAGE_DOOMWAD
|
||||
FS_RegisterFileSystemType(NULL, "wad", FSDWD_LoadArchive, true);
|
||||
#endif
|
||||
#ifdef PACKAGE_DZIP
|
||||
FS_RegisterFileSystemType(NULL, "dz", FSDZ_LoadArchive, false);
|
||||
#endif
|
||||
|
@ -7531,7 +7686,6 @@ void FS_RegisterDefaultFileSystems(void)
|
|||
FS_RegisterFileSystemType(NULL, "PAK", FSPAK_LoadArchive, true);
|
||||
#endif
|
||||
#endif
|
||||
FS_RegisterFileSystemType(NULL, "pk3dir", VFSOS_OpenPath, true); //used for git repos or whatever, to make packaging easier
|
||||
#ifdef PACKAGE_PK3
|
||||
FS_RegisterFileSystemType(NULL, "pk3", FSZIP_LoadArchive, true); //quake3's extension for zips
|
||||
FS_RegisterFileSystemType(NULL, "pk4", FSZIP_LoadArchive, true); //quake4's extension for zips...
|
||||
|
@ -7545,7 +7699,5 @@ void FS_RegisterDefaultFileSystems(void)
|
|||
FS_RegisterFileSystemType(NULL, "dll", FSZIP_LoadArchive, false); //for plugin metas / self-extracting zips.
|
||||
FS_RegisterFileSystemType(NULL, "so", FSZIP_LoadArchive, false); //for plugin metas / self-extracting zips.
|
||||
#endif
|
||||
#ifdef PACKAGE_DOOMWAD
|
||||
FS_RegisterFileSystemType(NULL, "wad", FSDWD_LoadArchive, true);
|
||||
#endif
|
||||
FS_RegisterFileSystemType(NULL, "pk3dir", VFSOS_OpenPath, true); //used for git repos or whatever, to make packaging easier
|
||||
}
|
||||
|
|
|
@ -601,7 +601,7 @@ static qboolean QDECL VFSW32_CreateLoc(searchpathfuncs_t *handle, flocation_t *l
|
|||
loc->offset = 0;
|
||||
loc->fhandle = handle;
|
||||
loc->rawname[sizeof(loc->rawname)-1] = 0;
|
||||
if (Q_snprintfz (loc->rawname, sizeof(loc->rawname), "%s/%s", wp->rootpath, filename))
|
||||
if (Q_snprintfz (loc->rawname, sizeof(loc->rawname), "%s%s", wp->rootpath, filename))
|
||||
return FF_NOTFOUND;
|
||||
for (ofs = loc->rawname+1 ; *ofs ; ofs++)
|
||||
{
|
||||
|
@ -639,7 +639,7 @@ static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t
|
|||
*/
|
||||
|
||||
// check a file in the directory tree
|
||||
if (Q_snprintfz (netpath, sizeof(netpath), "%s/%s", wp->rootpath, filename))
|
||||
if (Q_snprintfz (netpath, sizeof(netpath), "%s%s", wp->rootpath, filename))
|
||||
return FF_NOTFOUND;
|
||||
|
||||
if (!WinNT)
|
||||
|
@ -716,8 +716,8 @@ static qboolean QDECL VFSW32_RenameFile(searchpathfuncs_t *handle, const char *o
|
|||
char newsyspath[MAX_OSPATH];
|
||||
if (fs_readonly)
|
||||
return false;
|
||||
snprintf (oldsyspath, sizeof(oldsyspath)-1, "%s/%s", wp->rootpath, oldfname);
|
||||
snprintf (newsyspath, sizeof(newsyspath)-1, "%s/%s", wp->rootpath, newfname);
|
||||
snprintf (oldsyspath, sizeof(oldsyspath)-1, "%s%s", wp->rootpath, oldfname);
|
||||
snprintf (newsyspath, sizeof(newsyspath)-1, "%s%s", wp->rootpath, newfname);
|
||||
return Sys_Rename(oldsyspath, newsyspath);
|
||||
}
|
||||
static qboolean QDECL VFSW32_RemoveFile(searchpathfuncs_t *handle, const char *filename)
|
||||
|
@ -726,7 +726,7 @@ static qboolean QDECL VFSW32_RemoveFile(searchpathfuncs_t *handle, const char *f
|
|||
char syspath[MAX_OSPATH];
|
||||
if (fs_readonly)
|
||||
return false;
|
||||
snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename);
|
||||
snprintf (syspath, sizeof(syspath)-1, "%s%s", wp->rootpath, filename);
|
||||
if (*filename && filename[strlen(filename)-1] == '/')
|
||||
return Sys_rmdir(syspath);
|
||||
return Sys_remove(syspath);
|
||||
|
@ -745,6 +745,8 @@ searchpathfuncs_t *QDECL VFSW32_OpenPath(vfsfile_t *mustbenull, searchpathfuncs_
|
|||
{
|
||||
wchar_t wide[MAX_OSPATH];
|
||||
memcpy(np->rootpath, desc, dlen+1);
|
||||
if (*np->rootpath)
|
||||
Q_strncpy(np->rootpath+dlen, "/", 2);
|
||||
if (!WinNT)
|
||||
np->changenotification = FindFirstChangeNotificationA(np->rootpath, true, FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_CREATION);
|
||||
else
|
||||
|
|
|
@ -75,6 +75,8 @@ unsigned int Sys_Milliseconds (void);
|
|||
double Sys_DoubleTime (void);
|
||||
qboolean Sys_RandomBytes(qbyte *string, int len);
|
||||
|
||||
qboolean Sys_ResolveFileURL(const char *inurl, int inlen, char *out, int outlen);
|
||||
|
||||
char *Sys_ConsoleInput (void);
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -2220,8 +2220,8 @@ void Q_InitProgs(enum initprogs_e flags)
|
|||
oldprnum=prnum;
|
||||
}
|
||||
|
||||
//progs depended on by maps.
|
||||
a = as = COM_LoadStackFile(va("maps/%s.inf", svs.name), addons, sizeof(addons), NULL);
|
||||
/* //progs depended on by maps.
|
||||
a = as = COM_LoadStackFile(va("%s.inf", sv.modelname), addons, sizeof(addons), NULL);
|
||||
if (a)
|
||||
{
|
||||
if (progstype == PROG_QW)
|
||||
|
@ -2284,7 +2284,7 @@ void Q_InitProgs(enum initprogs_e flags)
|
|||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
//add any addons specified
|
||||
for (i2 = 0; i2 < MAXADDONS; i2++)
|
||||
{
|
||||
|
|
|
@ -698,7 +698,7 @@ void SV_Map_f (void)
|
|||
{
|
||||
char *mangled = Cmd_Argv(1);
|
||||
char *sep = strchr(mangled, ':');
|
||||
if (sep)
|
||||
if (sep && strncmp(mangled, "file:", 5) && strncmp(mangled, "http:", 5) && strncmp(mangled, "https:", 5))
|
||||
{
|
||||
*sep++ = 0;
|
||||
if (Cmd_FromGamecode())
|
||||
|
@ -737,7 +737,7 @@ void SV_Map_f (void)
|
|||
else
|
||||
{
|
||||
snprintf (expanded, sizeof(expanded), "maps/%s.bsp", level); // this function and the if statement below, is a quake bugfix which stopped a map called "dm6++.bsp" from loading because of the + sign, quake2 map syntax interprets + character as "intro.cin+base1.bsp", to play a cinematic then load a map after
|
||||
if (!COM_FCheckExists (expanded))
|
||||
if (!COM_FCheckExists (level) && !COM_FCheckExists (expanded))
|
||||
{
|
||||
nextserver = strchr(level, '+');
|
||||
if (nextserver)
|
||||
|
@ -841,7 +841,7 @@ void SV_Map_f (void)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.bsp.gz", "maps/%s.bsp.xz", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ /*"maps/%s.ent",*/ NULL};
|
||||
char *exts[] = {"%s", "maps/%s", "maps/%s.bsp", "maps/%s.bsp.gz", "maps/%s.bsp.xz", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ /*"maps/%s.ent",*/ NULL};
|
||||
int i, j;
|
||||
|
||||
for (i = 0; exts[i]; i++)
|
||||
|
|
|
@ -1016,22 +1016,38 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
|||
{
|
||||
//.map is commented out because quite frankly, they're a bit annoying when the engine loads the gpled start.map when really you wanted to just play the damn game intead of take it apart.
|
||||
//if you want to load a .map, just use 'map foo.map' instead.
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ "maps/%s.bsp.gz", "maps/%s.bsp.xz", NULL};
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ "maps/%s.bsp.gz", "maps/%s.bsp.xz", NULL}, *e;
|
||||
int depth, bestdepth;
|
||||
flocation_t loc;
|
||||
time_t filetime;
|
||||
Q_strncpyz (svs.name, server, sizeof(svs.name));
|
||||
Q_snprintfz (sv.modelname, sizeof(sv.modelname), exts[0], server);
|
||||
Q_snprintfz (sv.modelname, sizeof(sv.modelname), "%s", server);
|
||||
bestdepth = COM_FDepthFile(sv.modelname, false);
|
||||
for (i = 1; exts[i]; i++)
|
||||
{
|
||||
depth = COM_FDepthFile(va(exts[i], server), false);
|
||||
if (depth < bestdepth)
|
||||
if (bestdepth == FDEPTH_MISSING)
|
||||
{ //not an exact name, scan the maps subdir.
|
||||
for (i = 0; exts[i]; i++)
|
||||
{
|
||||
bestdepth = depth;
|
||||
Q_snprintfz (sv.modelname, sizeof(sv.modelname), exts[i], server);
|
||||
depth = COM_FDepthFile(va(exts[i], server), false);
|
||||
if (depth < bestdepth)
|
||||
{
|
||||
bestdepth = depth;
|
||||
Q_snprintfz (sv.modelname, sizeof(sv.modelname), exts[i], server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(sv.modelname, "maps/", 5))
|
||||
Q_strncpyz (svs.name, sv.modelname+5, sizeof(svs.name));
|
||||
else
|
||||
Q_strncpyz (svs.name, sv.modelname, sizeof(svs.name));
|
||||
e = (char*)COM_GetFileExtension(svs.name, NULL);
|
||||
if (!strcmp(e, ".gz") || !strcmp(e, ".xz"))
|
||||
{
|
||||
*e = 0;
|
||||
e = (char*)COM_GetFileExtension(svs.name, NULL);
|
||||
}
|
||||
if (!strcmp(e, ".bsp"))
|
||||
*e = 0;
|
||||
|
||||
sv.world.worldmodel = Mod_ForName (sv.modelname, MLV_ERROR);
|
||||
|
||||
if (FS_FLocateFile(sv.modelname,FSLF_IFFOUND, &loc) && FS_GetLocMTime(&loc, &filetime))
|
||||
|
|
Loading…
Reference in a new issue