mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 12:01:25 +00:00
140 lines
8.7 KiB
C
140 lines
8.7 KiB
C
#include "hash.h"
|
|
|
|
/*
|
|
Threading:
|
|
When the main thread will harm the filesystem tree/hash, it will first lock fs_thread_mutex (FIXME: make a proper rwlock).
|
|
Worker threads must thus lock that mutex for any opens (to avoid it changing underneath it), but can unlock it as soon as the open call returns.
|
|
Files may be shared between threads, but not simultaneously.
|
|
The filesystem driver is responsible for closing the pak/pk3 once all files are closed, and must ensure that opens+reads+closes as well as archive closure are thread safe.
|
|
*/
|
|
|
|
#define FSVER 3
|
|
|
|
|
|
#define FF_NOTFOUND (0u) //file wasn't found
|
|
#define FF_FOUND (1u<<0u) //file was found
|
|
#define FF_SYMLINK (1u<<1u) //file contents are the name of a different file (symlink). do a recursive lookup on the name
|
|
#define FF_DIRECTORY (1u<<2u)
|
|
|
|
typedef struct
|
|
{
|
|
bucket_t buck;
|
|
int depth; /*shallower files will remove deeper files*/
|
|
} fsbucket_t;
|
|
extern hashtable_t filesystemhash; //this table is the one to build your hash references into
|
|
extern int fs_hash_dups; //for tracking efficiency. no functional use.
|
|
extern int fs_hash_files; //for tracking efficiency. no functional use.
|
|
extern qboolean fs_readonly; //if true, fopen(, "w") should always fail.
|
|
extern void *fs_thread_mutex;
|
|
extern float fs_accessed_time;
|
|
extern cvar_t fs_dlURL;
|
|
|
|
struct searchpath_s;
|
|
struct searchpathfuncs_s
|
|
{
|
|
int fsver;
|
|
void (QDECL *ClosePath)(searchpathfuncs_t *handle); //removes a reference, kills it when it reaches 0. the package can only actually be killed once all contained files are closed.
|
|
void (QDECL *AddReference)(searchpathfuncs_t *handle); //adds an extra reference, so we survive closes better.
|
|
|
|
void (QDECL *GetPathDetails)(searchpathfuncs_t *handle, char *outdetails, size_t sizeofdetails);
|
|
void (QDECL *BuildHash)(searchpathfuncs_t *handle, int depth, void (QDECL *FS_AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle));
|
|
unsigned int (QDECL *FindFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL)
|
|
//note that if rawfile and offset are set, many Com_FileOpens will read the raw file
|
|
//otherwise ReadFile will be called instead.
|
|
void (QDECL *ReadFile)(searchpathfuncs_t *handle, flocation_t *loc, char *buffer); //reads the entire file in one go (size comes from loc, so make sure the loc is valid, this is for performance with compressed archives)
|
|
int (QDECL *EnumerateFiles)(searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath), void *parm);
|
|
|
|
int (QDECL *GeneratePureCRC) (searchpathfuncs_t *handle, int seed, int usepure);
|
|
|
|
vfsfile_t * (QDECL *OpenVFS)(searchpathfuncs_t *handle, flocation_t *loc, const char *mode);
|
|
|
|
qboolean (QDECL *PollChanges)(searchpathfuncs_t *handle); //returns true if there were changes
|
|
|
|
qboolean (QDECL *FileStat)(searchpathfuncs_t *handle, flocation_t *loc, time_t *mtime);
|
|
qboolean (QDECL *CreateFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *filename); //like FindFile, but returns a usable loc even if the file does not exist yet (may also create requisite directories too)
|
|
qboolean (QDECL *RenameFile)(searchpathfuncs_t *handle, const char *oldname, const char *newname); //returns true on success, false if source doesn't exist, or if dest does (cached locs may refer to either new or old name).
|
|
qboolean (QDECL *RemoveFile)(searchpathfuncs_t *handle, const char *filename); //returns true on success, false if it wasn't found or is readonly.
|
|
};
|
|
//searchpathfuncs_t *(QDECL *OpenNew)(vfsfile_t *file, const char *desc); //returns a handle to a new pak/path
|
|
|
|
//the stdio filesystem is special as that's the starting point of the entire filesystem
|
|
//warning: the handle is known to be a string pointer to the dir name
|
|
extern searchpathfuncs_t *(QDECL VFSOS_OpenPath) (vfsfile_t *file, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix);
|
|
extern searchpathfuncs_t *(QDECL FSZIP_LoadArchive) (vfsfile_t *file, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix);
|
|
extern searchpathfuncs_t *(QDECL FSPAK_LoadArchive) (vfsfile_t *file, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix);
|
|
extern searchpathfuncs_t *(QDECL FSDWD_LoadArchive) (vfsfile_t *file, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix);
|
|
extern searchpathfuncs_t *(QDECL FSDZ_LoadArchive) (vfsfile_t *file, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix);
|
|
vfsfile_t *QDECL VFSOS_Open(const char *osname, const char *mode);
|
|
vfsfile_t *FS_DecompressGZip(vfsfile_t *infile, vfsfile_t *outfile);
|
|
|
|
int FS_RegisterFileSystemType(void *module, const char *extension, searchpathfuncs_t *(QDECL *OpenNew)(vfsfile_t *file, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix), qboolean loadscan);
|
|
void FS_UnRegisterFileSystemType(int idx);
|
|
void FS_UnRegisterFileSystemModule(void *module);
|
|
|
|
void FS_AddHashedPackage(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, const char *pakpath, const char *qhash, const char *pakprefix, unsigned int packageflags);
|
|
void PM_LoadPackages(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, int minpri, int maxpri);
|
|
void PM_ManifestChanged(ftemanifest_t *man);
|
|
void *PM_GeneratePackageFromMeta(vfsfile_t *file, char *fname, size_t fnamesize, enum fs_relative *fsroot);
|
|
void PM_FileInstalled(const char *filename, enum fs_relative fsroot, void *metainfo, qboolean enable); //we finished installing a file via some other mechanism (drag+drop or from server. insert it into the updates menu.
|
|
void PM_EnumeratePlugins(void (*callback)(const char *name, qboolean blocked));
|
|
struct xcommandargcompletioncb_s;
|
|
void PM_EnumerateMaps(const char *partial, struct xcommandargcompletioncb_s *ctx);
|
|
void PM_LoadMap(const char *package, const char *map);
|
|
unsigned int PM_IsApplying(void);
|
|
unsigned int PM_MarkUpdates (void); //mark new/updated packages as needing install.
|
|
void PM_ApplyChanges(void); //for -install/-doinstall args
|
|
qboolean PM_AreSourcesNew(qboolean doprompt);
|
|
qboolean PM_FindUpdatedEngine(char *syspath, size_t syspathsize); //names the engine we should be running
|
|
void PM_AddManifestPackages(ftemanifest_t *man);
|
|
void Menu_Download_Update(void);
|
|
|
|
typedef struct
|
|
{
|
|
char *description;
|
|
void (*Update) (const char *url, vfsfile_t *out, qboolean favourcache);
|
|
#define plugupdatesourcefuncs_name "UpdateSource"
|
|
} plugupdatesourcefuncs_t;
|
|
qboolean PM_RegisterUpdateSource(void *module, plugupdatesourcefuncs_t *funcs);
|
|
|
|
enum modsourcetype_e
|
|
{
|
|
MST_SYSTEM, //found via an fmf installed at system level (eg part of a flatpak app)
|
|
MST_DEFAULT, //the default.fmf in the working directory
|
|
MST_BASEDIR, //other fmf files in the basedir
|
|
MST_HOMEDIR, //other fmf files in the homedir
|
|
MST_GAMEDIR, //mod found from just looking for gamedirs.
|
|
MST_INTRINSIC, //knowledge of the mod came one of the games we're hardcoded with.
|
|
|
|
MST_UNKNOWN, //forgot where it came from...
|
|
};
|
|
int FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man, enum modsourcetype_e sourcetype), void *usr);
|
|
|
|
struct modlist_s
|
|
{
|
|
ftemanifest_t *manifest;
|
|
enum modsourcetype_e sourcetype;
|
|
char *gamedir;
|
|
char *description;
|
|
};
|
|
struct modlist_s *Mods_GetMod(size_t diridx);
|
|
|
|
#define SPF_REFERENCED 1 //something has been loaded from this path. should filter out client references...
|
|
#define SPF_COPYPROTECTED 2 //downloads are not allowed fom here.
|
|
#define SPF_TEMPORARY 4 //a map-specific path, purged at map change.
|
|
#define SPF_EXPLICIT 8 //a root gamedir (bumps depth on gamedir depth checks).
|
|
#define SPF_UNTRUSTED 16 //has been downloaded from somewhere. configs inside it should never be execed with local access rights.
|
|
#define SPF_PRIVATE 32 //private to the client. ie: the fte dir. name is not networked.
|
|
#define SPF_WRITABLE 64 //safe to write here. lots of weird rules etc.
|
|
#define SPF_BASEPATH 128 //part of the basegames, and not the mod gamedir(s).
|
|
#define SPF_QSHACK 256 //a bit of a hack, allows scanning for $rootdir/quakespasm.pak
|
|
#define SPF_SERVER 512 //a package that was loaded to match the server's packages
|
|
#define SPF_ISDIR 1024 //is an actual directory (not itself a package).
|
|
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, unsigned int flags);
|
|
|
|
#ifdef AVAIL_XZDEC
|
|
vfsfile_t *FS_XZ_DecompressWriteFilter(vfsfile_t *infile);
|
|
vfsfile_t *FS_XZ_DecompressReadFilter(vfsfile_t *srcfile);
|
|
#endif
|
|
#ifdef AVAIL_GZDEC
|
|
vfsfile_t *FS_GZ_WriteFilter(vfsfile_t *outfile, qboolean autoclosefile, qboolean compress);
|
|
#endif
|