summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThilo Schulz <arny@ats.s.bawue.de>2011-09-27 22:16:07 +0000
committerTim Angus <tim@ngus.net>2013-01-10 23:38:29 +0000
commit8f53d0826c3bc1742fd37db56c9f3499d3060a9a (patch)
treeb8b9f9ba73d083bf102238564032e4c2ed3da9c9 /src
parente9d0af975a62f645d0ff3b29d49670f176b57918 (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.c20
-rw-r--r--src/qcommon/qcommon.h4
-rw-r--r--src/qcommon/vm.c22
-rw-r--r--src/server/sv_game.c2
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" );
}