diff options
author | Thilo Schulz <arny@ats.s.bawue.de> | 2011-09-27 22:16:07 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-10 23:38:29 +0000 |
commit | 8f53d0826c3bc1742fd37db56c9f3499d3060a9a (patch) | |
tree | b8b9f9ba73d083bf102238564032e4c2ed3da9c9 /src | |
parent | e9d0af975a62f645d0ff3b29d49670f176b57918 (diff) |
Allow VM_Restart to load unpure qagame.qvm so that local server won't crash after map_restart if server operator has qagame.qvm residing outside pak file (#5196) Thanks to "rg3" for providing a shell account
Diffstat (limited to 'src')
-rw-r--r-- | src/qcommon/files.c | 20 | ||||
-rw-r--r-- | src/qcommon/qcommon.h | 4 | ||||
-rw-r--r-- | src/qcommon/vm.c | 22 | ||||
-rw-r--r-- | src/server/sv_game.c | 2 |
4 files changed, 27 insertions, 21 deletions
diff --git a/src/qcommon/files.c b/src/qcommon/files.c index 94779b90..7fc209e9 100644 --- a/src/qcommon/files.c +++ b/src/qcommon/files.c @@ -1054,7 +1054,7 @@ Returns filesize and an open FILE pointer. */ extern qboolean com_fullyInitialized; -long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_t *file, qboolean uniqueFILE) +long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_t *file, qboolean uniqueFILE, qboolean unpure) { long hash; pack_t *pak; @@ -1152,7 +1152,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_ if(search->pack->hashTable[hash]) { // disregard if it doesn't match one of the allowed pure pak files - if(!FS_PakIsPure(search->pack)) + if(!unpure && !FS_PakIsPure(search->pack)) { *file = 0; return -1; @@ -1243,7 +1243,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_ // this test can make the search fail although the file is in the directory // I had the problem on https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=8 // turned out I used FS_FileExists instead - if(fs_numServerPaks) + if(!unpure && fs_numServerPaks) { if(!FS_IsExt(filename, ".cfg", len) && // for config files !FS_IsExt(filename, ".menu", len) && // menu files @@ -1303,7 +1303,7 @@ long FS_FOpenFileRead(const char *filename, fileHandle_t *file, qboolean uniqueF for(search = fs_searchpaths; search; search = search->next) { - len = FS_FOpenFileReadDir(filename, search, file, uniqueFILE); + len = FS_FOpenFileReadDir(filename, search, file, uniqueFILE, qfalse); if(file == NULL) { @@ -1387,7 +1387,7 @@ vmInterpret_t FS_FindVM(void **startSearch, char *found, int foundlen, const cha } } - if(FS_FOpenFileReadDir(qvmName, search, NULL, qfalse) > 0) + if(FS_FOpenFileReadDir(qvmName, search, NULL, qfalse, qfalse) > 0) { *startSearch = search; return VMI_COMPILED; @@ -1409,7 +1409,7 @@ vmInterpret_t FS_FindVM(void **startSearch, char *found, int foundlen, const cha } } - if(FS_FOpenFileReadDir(qvmName, search, NULL, qfalse) > 0) + if(FS_FOpenFileReadDir(qvmName, search, NULL, qfalse, qfalse) > 0) { *startSearch = search; @@ -1714,7 +1714,7 @@ a null buffer will just return the file length without loading If searchPath is non-NULL search only in that specific search path ============ */ -long FS_ReadFileDir(const char *qpath, void *searchPath, void **buffer) +long FS_ReadFileDir(const char *qpath, void *searchPath, qboolean unpure, void **buffer) { fileHandle_t h; searchpath_t *search; @@ -1787,7 +1787,7 @@ long FS_ReadFileDir(const char *qpath, void *searchPath, void **buffer) else { // look for it in a specific search path only - len = FS_FOpenFileReadDir(qpath, search, &h, qfalse); + len = FS_FOpenFileReadDir(qpath, search, &h, qfalse, unpure); } if ( h == 0 ) { @@ -1846,7 +1846,7 @@ a null buffer will just return the file length without loading */ long FS_ReadFile(const char *qpath, void **buffer) { - return FS_ReadFileDir(qpath, NULL, buffer); + return FS_ReadFileDir(qpath, NULL, qfalse, buffer); } /* @@ -2713,7 +2713,7 @@ qboolean FS_Which(const char *filename, void *searchPath) { searchpath_t *search = searchPath; - if(FS_FOpenFileReadDir(filename, search, NULL, qfalse) > 0) + if(FS_FOpenFileReadDir(filename, search, NULL, qfalse, qfalse) > 0) { if(search->pack) { diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h index caabf7f4..746376fb 100644 --- a/src/qcommon/qcommon.h +++ b/src/qcommon/qcommon.h @@ -342,7 +342,7 @@ void VM_Free( vm_t *vm ); void VM_Clear(void); void VM_Forced_Unload_Start(void); void VM_Forced_Unload_Done(void); -vm_t *VM_Restart( vm_t *vm ); +vm_t *VM_Restart(vm_t *vm, qboolean unpure); intptr_t QDECL VM_Call( vm_t *vm, int callNum, ... ); @@ -644,7 +644,7 @@ int FS_Read( void *buffer, int len, fileHandle_t f ); void FS_FCloseFile( fileHandle_t f ); // note: you can't just fclose from another DLL, due to MS libc issues -long FS_ReadFileDir(const char *qpath, void *searchPath, void **buffer); +long FS_ReadFileDir(const char *qpath, void *searchPath, qboolean unpure, void **buffer); long FS_ReadFile(const char *qpath, void **buffer); // returns the length of the file // a null buffer will just return the file length without loading diff --git a/src/qcommon/vm.c b/src/qcommon/vm.c index 90af748f..6113901d 100644 --- a/src/qcommon/vm.c +++ b/src/qcommon/vm.c @@ -364,7 +364,8 @@ VM_LoadQVM Load a .qvm file ================= */ -vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) { +vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc, qboolean unpure) +{ int dataLength; int i; char filename[MAX_QPATH]; @@ -377,7 +378,7 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) { Com_sprintf( filename, sizeof(filename), "vm/%s.qvm", vm->name ); Com_Printf( "Loading vm file %s...\n", filename ); - FS_ReadFileDir(filename, vm->searchPath, &header.v); + FS_ReadFileDir(filename, vm->searchPath, unpure, &header.v); if ( !header.h ) { Com_Printf( "Failed.\n" ); @@ -523,9 +524,13 @@ VM_Restart Reload the data, but leave everything else in place This allows a server to do a map_restart without changing memory allocation + +We need to make sure that servers can access unpure QVMs (not contained in any pak) +even if the client is pure, so take "unpure" as argument. ================= */ -vm_t *VM_Restart( vm_t *vm ) { +vm_t *VM_Restart(vm_t *vm, qboolean unpure) +{ vmHeader_t *header; // DLL's can't be restarted in place @@ -543,15 +548,16 @@ vm_t *VM_Restart( vm_t *vm ) { } // load the image - Com_Printf( "VM_Restart()\n" ); + Com_Printf("VM_Restart()\n"); - if( !( header = VM_LoadQVM( vm, qfalse ) ) ) { - Com_Error( ERR_DROP, "VM_Restart failed" ); + if(!(header = VM_LoadQVM(vm, qfalse, unpure))) + { + Com_Error(ERR_DROP, "VM_Restart failed"); return NULL; } // free the original file - FS_FreeFile( header ); + FS_FreeFile(header); return vm; } @@ -622,7 +628,7 @@ vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), else if(retval == VMI_COMPILED) { vm->searchPath = startSearch; - if((header = VM_LoadQVM(vm, qtrue))) + if((header = VM_LoadQVM(vm, qtrue, qfalse))) break; // VM_Free overwrites the name on failed load diff --git a/src/server/sv_game.c b/src/server/sv_game.c index 4948a9c8..099bc9f5 100644 --- a/src/server/sv_game.c +++ b/src/server/sv_game.c @@ -549,7 +549,7 @@ void SV_RestartGameProgs( void ) { VM_Call( gvm, GAME_SHUTDOWN, qtrue ); // do a restart instead of a free - gvm = VM_Restart( gvm ); + gvm = VM_Restart(gvm, qtrue); if ( !gvm ) { Com_Error( ERR_FATAL, "VM_Restart on game failed" ); } |