diff options
Diffstat (limited to 'src/qcommon/files.c')
-rw-r--r-- | src/qcommon/files.c | 97 |
1 files changed, 65 insertions, 32 deletions
diff --git a/src/qcommon/files.c b/src/qcommon/files.c index 721536c4..87301441 100644 --- a/src/qcommon/files.c +++ b/src/qcommon/files.c @@ -203,6 +203,7 @@ static const unsigned pak_checksums[] = { typedef struct fileInPack_s { char *name; // name of the file unsigned long pos; // file info position in zip + unsigned long len; // uncompress file size struct fileInPack_s* next; // next file in the hash } fileInPack_t; @@ -991,7 +992,6 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF fileInPack_t *pakFile; directory_t *dir; long hash; - unz_s *zfi; FILE *temp; int l; char demoExt[16]; @@ -1112,26 +1112,17 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF if ( uniqueFILE ) { // open a new file on the pakfile - fsh[*file].handleFiles.file.z = unzReOpen (pak->pakFilename, pak->handle); + fsh[*file].handleFiles.file.z = unzOpen (pak->pakFilename); if (fsh[*file].handleFiles.file.z == NULL) { - Com_Error (ERR_FATAL, "Couldn't reopen %s", pak->pakFilename); + Com_Error (ERR_FATAL, "Couldn't open %s", pak->pakFilename); } } else { fsh[*file].handleFiles.file.z = pak->handle; } Q_strncpyz( fsh[*file].name, filename, sizeof( fsh[*file].name ) ); fsh[*file].zipFile = qtrue; - zfi = (unz_s *)fsh[*file].handleFiles.file.z; - // in case the file was new - temp = zfi->file; // set the file position in the zip file (also sets the current file info) - unzSetCurrentFileInfoPosition(pak->handle, pakFile->pos); - if ( zfi != pak->handle ) { - // copy the file info into the unzip structure - Com_Memcpy( zfi, pak->handle, sizeof(unz_s) ); - } - // we copy this back into the structure - zfi->file = temp; + unzSetOffset(fsh[*file].handleFiles.file.z, pakFile->pos); // open the file in the zip unzOpenCurrentFile( fsh[*file].handleFiles.file.z ); fsh[*file].zipFilePos = pakFile->pos; @@ -1140,7 +1131,7 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF Com_Printf( "FS_FOpenFileRead: %s (found in '%s')\n", filename, pak->pakFilename ); } - return zfi->cur_file_info.uncompressed_size; + return pakFile->len; } pakFile = pakFile->next; } while(pakFile != NULL); @@ -1367,7 +1358,7 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) { switch( origin ) { case FS_SEEK_SET: - unzSetCurrentFileInfoPosition(fsh[f].handleFiles.file.z, fsh[f].zipFilePos); + unzSetOffset(fsh[f].handleFiles.file.z, fsh[f].zipFilePos); unzOpenCurrentFile(fsh[f].handleFiles.file.z); //fallthrough @@ -1663,7 +1654,7 @@ Creates a new pak_t in the search chain for the contents of a zip file. ================= */ -static pack_t *FS_LoadZipFile( char *zipfile, const char *basename ) +static pack_t *FS_LoadZipFile(const char *zipfile, const char *basename) { fileInPack_t *buildBuffer; pack_t *pack; @@ -1686,8 +1677,6 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename ) if (err != UNZ_OK) return NULL; - fs_packFiles += gi.number_entry; - len = 0; unzGoToFirstFile(uf); for (i = 0; i < gi.number_entry; i++) @@ -1747,15 +1736,15 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename ) strcpy( buildBuffer[i].name, filename_inzip ); namePtr += strlen(filename_inzip) + 1; // store the file position in the zip - unzGetCurrentFileInfoPosition(uf, &buildBuffer[i].pos); - // + buildBuffer[i].pos = unzGetOffset(uf); + buildBuffer[i].len = file_info.uncompressed_size; buildBuffer[i].next = pack->hashTable[hash]; pack->hashTable[hash] = &buildBuffer[i]; unzGoToNextFile(uf); } - pack->checksum = Com_BlockChecksum( &fs_headerLongs[ 1 ], 4 * ( fs_numHeaderLongs - 1 ) ); - pack->pure_checksum = Com_BlockChecksum( fs_headerLongs, 4 * fs_numHeaderLongs ); + pack->checksum = Com_BlockChecksum( &fs_headerLongs[ 1 ], sizeof(*fs_headerLongs) * ( fs_numHeaderLongs - 1 ) ); + pack->pure_checksum = Com_BlockChecksum( fs_headerLongs, sizeof(*fs_headerLongs) * fs_numHeaderLongs ); pack->checksum = LittleLong( pack->checksum ); pack->pure_checksum = LittleLong( pack->pure_checksum ); @@ -1766,6 +1755,50 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename ) } /* +================= +FS_FreePak + +Frees a pak structure and releases all associated resources +================= +*/ + +static void FS_FreePak(pack_t *thepak) +{ + unzClose(thepak->handle); + Z_Free(thepak->buildBuffer); + Z_Free(thepak); +} + +/* +================= +FS_GetZipChecksum + +Compares whether the given pak file matches a referenced checksum +================= +*/ +qboolean FS_CompareZipChecksum(const char *zipfile) +{ + pack_t *thepak; + int index, checksum; + + thepak = FS_LoadZipFile(zipfile, ""); + + if(!thepak) + return qfalse; + + checksum = thepak->checksum; + FS_FreePak(thepak); + + for(index = 0; index < fs_numServerReferencedPaks; index++) + { + if(checksum == fs_serverReferencedPaks[index]) + return qtrue; + } + + return qfalse; +} + +/* ================================================================================= DIRECTORY SCANNING FUNCTIONS @@ -2537,6 +2570,8 @@ void FS_AddGameDirectory( const char *path, const char *dir ) { continue; // store the game name for downloading strcpy(pak->pakGamename, dir); + + fs_packFiles += pak->numfiles; search = Z_Malloc (sizeof(searchpath_t)); search->pack = pak; @@ -2726,18 +2761,16 @@ void FS_Shutdown( qboolean closemfp ) { } // free everything - for ( p = fs_searchpaths ; p ; p = next ) { + for(p = fs_searchpaths; p; p = next) + { next = p->next; - if ( p->pack ) { - unzClose(p->pack->handle); - Z_Free( p->pack->buildBuffer ); - Z_Free( p->pack ); - } - if ( p->dir ) { - Z_Free( p->dir ); - } - Z_Free( p ); + if(p->pack) + FS_FreePak(p->pack); + if (p->dir) + Z_Free(p->dir); + + Z_Free(p); } // any FS_ calls will now be an error until reinitialized |