diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/bspzip | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/bspzip')
| -rw-r--r-- | utils/bspzip/bspzip.cpp | 552 | ||||
| -rw-r--r-- | utils/bspzip/bspzip.vpc | 56 |
2 files changed, 608 insertions, 0 deletions
diff --git a/utils/bspzip/bspzip.cpp b/utils/bspzip/bspzip.cpp new file mode 100644 index 0000000..e01bcce --- /dev/null +++ b/utils/bspzip/bspzip.cpp @@ -0,0 +1,552 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include <stdio.h> +#include "bsplib.h" +#include "cmdlib.h" +#include "tier0/icommandline.h" +#include "utlbuffer.h" + +int CopyVariableLump( int lump, void **dest, int size ); + +void StripPath( const char* pPath, char* pBuf, int nBufLen ) +{ + const char *pSrc; + + // want filename only + pSrc = pPath + Q_strlen( pPath ) - 1; + while ((pSrc != pPath) && (*(pSrc-1) != '\\') && (*(pSrc-1) != '/') && (*(pSrc-1) != ':')) + pSrc--; + + Q_strncpy( pBuf, pSrc, nBufLen ); +} + +bool RepackBSP( const char *pszMapFile, bool bCompress ) +{ + Msg( "Repacking %s\n", pszMapFile ); + + if ( !g_pFullFileSystem->FileExists( pszMapFile ) ) + { + Warning( "Couldn't open input file %s - BSP recompress failed\n", pszMapFile ); + return false; + } + + CUtlBuffer inputBuffer; + if ( !g_pFullFileSystem->ReadFile( pszMapFile, NULL, inputBuffer ) ) + { + Warning( "Couldn't read file %s - BSP compression failed\n", pszMapFile ); + return false; + } + + CUtlBuffer outputBuffer; + + if ( !RepackBSP( inputBuffer, outputBuffer, + bCompress ? RepackBSPCallback_LZMA : NULL, + bCompress ? IZip::eCompressionType_LZMA : IZip::eCompressionType_None ) ) + { + Warning( "Internal error compressing BSP\n" ); + return false; + } + + g_pFullFileSystem->WriteFile( pszMapFile, NULL, outputBuffer ); + + Msg( "Successfully repacked %s -- %u -> %u bytes\n", + pszMapFile, inputBuffer.TellPut(), outputBuffer.TellPut() ); + + return true; +} + +void Usage( void ) +{ + fprintf( stderr, "usage: \n" ); + fprintf( stderr, "bspzip -extract <bspfile> <blah.zip>\n"); + fprintf( stderr, "bspzip -extractfiles <bspfile> <targetpath>\n"); + fprintf( stderr, "bspzip -dir <bspfile>\n"); + fprintf( stderr, "bspzip -addfile <bspfile> <relativepathname> <fullpathname> <newbspfile>\n"); + fprintf( stderr, "bspzip -addlist <bspfile> <listfile> <newbspfile>\n"); + fprintf( stderr, "bspzip -addorupdatelist <bspfile> <listfile> <newbspfile>\n"); + fprintf( stderr, "bspzip -extractcubemaps <bspfile> <targetPath>\n"); + fprintf( stderr, " Extracts the cubemaps to <targetPath>.\n"); + fprintf( stderr, "bspzip -deletecubemaps <bspfile>\n"); + fprintf( stderr, " Deletes the cubemaps from <bspFile>.\n"); + fprintf( stderr, "bspzip -addfiles <bspfile> <relativePathPrefix> <listfile> <newbspfile>\n"); + fprintf( stderr, " Adds files to <newbspfile>.\n"); + fprintf( stderr, "bspzip -repack [ -compress ] <bspfile>\n"); + fprintf( stderr, " Optimally repacks a BSP file, optionally using compressed BSP format.\n"); + fprintf( stderr, " Using on a compressed BSP without -compress will effectively decompress\n"); + fprintf( stderr, " a compressed BSP.\n"); + + exit( -1 ); +} + +char* xzpFilename = NULL; + +int main( int argc, char **argv ) +{ + ::SetHDRMode( false ); + + Msg( "\nValve Software - bspzip.exe (%s)\n", __DATE__ ); + + int curArg = 1; + + // Options parsing assumes + // [ -game foo ] -<action> <action specific args> + + // Skip -game foo + if ( argc >= curArg + 2 && stricmp( argv[curArg], "-game" ) == 0 ) + { + // Handled by filesystem code + curArg += 2; + } + + // Should have at least action + if ( curArg >= argc ) + { + // End of args + Usage(); + return 0; + } + + // Pointers to the action, the file, and any action args so I can remove all the messy argc pointer math this was + // using. + char *pAction = argv[curArg]; + curArg++; + char **pActionArgs = &argv[curArg]; + int nActionArgs = argc - curArg; + + CommandLine()->CreateCmdLine( argc, argv ); + + MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); + if( ( stricmp( pAction, "-extract" ) == 0 ) && nActionArgs == 2 ) + { + // bspzip -extract <bspfile> <blah.zip> + CmdLib_InitFileSystem( pActionArgs[0] ); + + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); + + char zipName[MAX_PATH] = { 0 }; + V_strncpy( zipName, pActionArgs[1], sizeof( zipName ) ); + Q_DefaultExtension(zipName, ".zip", sizeof( zipName ) ); + + ExtractZipFileFromBSP( bspName, zipName ); + } + else if( ( stricmp( pAction, "-extractfiles" ) == 0 ) && nActionArgs == 2 ) + { + // bsipzip -extractfiles <bspfile> <targetpath> + CmdLib_InitFileSystem( pActionArgs[0] ); + + // necessary for xbox process + // only the .vtf are extracted as necessary for streaming and not the .vmt + // the .vmt are non-streamed and therefore remain, referenced normally as part of the bsp search path + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); + + char targetPathName[MAX_PATH] = { 0 }; + V_strncpy( targetPathName, pActionArgs[1], sizeof( targetPathName ) ); + Q_AppendSlash( targetPathName, sizeof( targetPathName ) ); + + printf( "\n" ); + printf( "Opening bsp file: %s\n", bspName ); + LoadBSPFile( bspName ); + + CUtlBuffer buf; + char relativeName[MAX_PATH] = { 0 }; + char targetName[MAX_PATH] = { 0 }; + int fileSize = 0; + int id = -1; + int numFilesExtracted = 0; + while(true) + { + id = GetNextFilename( GetPakFile(), id, relativeName, sizeof(relativeName), fileSize ); + if ( id == -1) + break; + + { + buf.EnsureCapacity( fileSize ); + buf.SeekPut( CUtlBuffer::SEEK_HEAD, 0 ); + ReadFileFromPak( GetPakFile(), relativeName, false, buf ); + + V_strncpy( targetName, targetPathName, sizeof(targetName) ); + V_strncat( targetName, relativeName, sizeof(targetName) ); + Q_FixSlashes( targetName, '\\' ); + + SafeCreatePath( targetName ); + + printf( "Writing file: %s\n", targetName ); + FILE *fp = fopen( targetName, "wb" ); + if ( !fp ) + { + printf( "Error: Could not write %s\n", targetName); + exit( -1 ); + } + + fwrite( buf.Base(), fileSize, 1, fp ); + fclose( fp ); + + numFilesExtracted++; + } + } + printf( "%d files extracted.\n", numFilesExtracted ); + } + else if( ( stricmp( pAction, "-extractcubemaps" ) == 0 ) && nActionArgs == 2 ) + { + // bspzip -extractcubemaps <bspfile> <targetPath> + CmdLib_InitFileSystem( pActionArgs[0] ); + // necessary for xbox process + // only the .vtf are extracted as necessary for streaming and not the .vmt + // the .vmt are non-streamed and therefore remain, referenced normally as part of the bsp search path + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); + + char targetPathName[MAX_PATH] = { 0 }; + V_strncpy( targetPathName, pActionArgs[1], sizeof(targetPathName) ); + Q_AppendSlash( targetPathName, sizeof( targetPathName ) ); + + printf( "\n" ); + printf( "Opening bsp file: %s\n", bspName ); + LoadBSPFile( bspName ); + + CUtlBuffer buf; + char relativeName[MAX_PATH] = { 0 }; + char targetName[MAX_PATH] = { 0 }; + int fileSize = 0; + int id = -1; + int numFilesExtracted = 0; + while (1) + { + id = GetNextFilename( GetPakFile(), id, relativeName, sizeof(relativeName), fileSize ); + if ( id == -1) + break; + + if ( Q_stristr( relativeName, ".vtf" ) ) + { + buf.EnsureCapacity( fileSize ); + buf.SeekPut( CUtlBuffer::SEEK_HEAD, 0 ); + ReadFileFromPak( GetPakFile(), relativeName, false, buf ); + + V_strncpy( targetName, targetPathName, sizeof( targetName ) ); + V_strncat( targetName, relativeName, sizeof( targetName ) ); + Q_FixSlashes( targetName, '\\' ); + + SafeCreatePath( targetName ); + + printf( "Writing vtf file: %s\n", targetName ); + FILE *fp = fopen( targetName, "wb" ); + if ( !fp ) + { + printf( "Error: Could not write %s\n", targetName); + exit( -1 ); + } + + fwrite( buf.Base(), fileSize, 1, fp ); + fclose( fp ); + + numFilesExtracted++; + } + } + printf( "%d cubemaps extracted.\n", numFilesExtracted ); + } + else if( ( stricmp( pAction, "-deletecubemaps" ) == 0 ) && nActionArgs == 1 ) + { + // bspzip -deletecubemaps <bspfile> + CmdLib_InitFileSystem( pActionArgs[0] ); + // necessary for xbox process + // the cubemaps are deleted as they cannot yet be streamed out of the bsp + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); + + printf( "\n" ); + printf( "Opening bsp file: %s\n", bspName ); + LoadBSPFile( bspName ); + + CUtlBuffer buf; + char relativeName[MAX_PATH] = { 0 }; + int fileSize = 0; + int id = -1; + int numFilesDeleted = 0; + while (1) + { + id = GetNextFilename( GetPakFile(), id, relativeName, sizeof(relativeName), fileSize ); + if ( id == -1) + break; + + if ( Q_stristr( relativeName, ".vtf" ) ) + { + RemoveFileFromPak( GetPakFile(), relativeName ); + + numFilesDeleted++; + + // start over + id = -1; + } + } + + printf( "%d cubemaps deleted.\n", numFilesDeleted ); + if ( numFilesDeleted ) + { + // save out bsp file + printf( "Updating bsp file: %s\n", bspName ); + WriteBSPFile( bspName ); + } + } + else if( ( stricmp( pAction, "-addfiles" ) == 0 ) && nActionArgs == 4 ) + { + // bspzip -addfiles <bspfile> <relativePathPrefix> <listfile> <newbspfile> + CmdLib_InitFileSystem( pActionArgs[0] ); + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension( bspName, ".bsp", sizeof( bspName ) ); + + char relativePrefixName[MAX_PATH] = { 0 }; + V_strncpy( relativePrefixName, pActionArgs[1], sizeof( relativePrefixName ) ); + + char filelistName[MAX_PATH] = { 0 }; + V_strncpy( filelistName, pActionArgs[2], sizeof( filelistName ) ); + + char newbspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[3] ); + Q_DefaultExtension( newbspName, ".bsp", sizeof( newbspName) ); + + char fullpathName[MAX_PATH] = { 0 }; + FILE *fp = fopen(filelistName, "r"); + if ( fp ) + { + printf("Opening bsp file: %s\n", bspName); + LoadBSPFile(bspName); + + while ( !feof(fp) ) + { + if ( ( fgets( fullpathName, sizeof( fullpathName ), fp ) != NULL ) ) + { + if ( *fullpathName && fullpathName[strlen(fullpathName) - 1] == '\n' ) + { + fullpathName[strlen(fullpathName) - 1] = '\0'; + } + + // strip the path and add relative prefix + char fileName[MAX_PATH] = { 0 }; + char relativeName[MAX_PATH] = { 0 }; + StripPath( fullpathName, fileName, sizeof( fileName ) ); + V_strncpy( relativeName, relativePrefixName, sizeof( relativeName ) ); + V_strncat( relativeName, fileName, sizeof( relativeName ) ); + + printf( "Adding file: %s as %s\n", fullpathName, relativeName ); + + AddFileToPak( GetPakFile(), relativeName, fullpathName ); + } + else if ( !feof( fp ) ) + { + printf( "Error: Missing full path names\n"); + fclose( fp ); + return( -1 ); + } + } + printf("Writing new bsp file: %s\n", newbspName); + WriteBSPFile(newbspName); + fclose( fp ); + } + } + else if( ( stricmp( pAction, "-dir" ) == 0 ) && nActionArgs == 1 ) + { + // bspzip -dir <bspfile> + CmdLib_InitFileSystem( pActionArgs[0] ); + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); + LoadBSPFile (bspName); + PrintBSPPackDirectory(); + } + else if( ( stricmp( pAction, "-addfile" ) == 0 ) && nActionArgs == 4 ) + { + // bspzip -addfile <bspfile> <relativepathname> <fullpathname> <newbspfile> + CmdLib_InitFileSystem( pActionArgs[0] ); + + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); + + char relativeName[MAX_PATH] = { 0 }; + V_strncpy( relativeName, pActionArgs[1], sizeof( relativeName ) ); + + char fullpathName[MAX_PATH] = { 0 }; + V_strncpy( fullpathName, pActionArgs[2], sizeof( fullpathName ) ); + + char newbspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[3] ); + Q_DefaultExtension (newbspName, ".bsp", sizeof( newbspName ) ); + + // read it in, add pack file, write it back out + LoadBSPFile (bspName); + AddFileToPak( GetPakFile(), relativeName, fullpathName ); + WriteBSPFile(newbspName); + } + else if( ( stricmp( pAction, "-addlist" ) == 0 ) && nActionArgs == 3 ) + { + // bspzip -addlist <bspfile> <listfile> <newbspfile> + CmdLib_InitFileSystem( pActionArgs[0] ); + + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); + + char filelistName[MAX_PATH] = { 0 }; + V_strncpy( filelistName, pActionArgs[1], sizeof( filelistName ) ); + + char newbspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[2] ); + Q_DefaultExtension (newbspName, ".bsp", sizeof( newbspName) ); + + // read it in, add pack file, write it back out + + char relativeName[MAX_PATH] = { 0 }; + char fullpathName[MAX_PATH] = { 0 }; + FILE *fp = fopen(filelistName, "r"); + if ( fp ) + { + printf("Opening bsp file: %s\n", bspName); + LoadBSPFile (bspName); + + while ( !feof(fp) ) + { + relativeName[ 0 ] = 0; + fullpathName[ 0 ] = 0; + if ( ( fgets( relativeName, sizeof( relativeName ), fp ) != NULL ) && + ( fgets( fullpathName, sizeof( fullpathName ), fp ) != NULL ) ) + { + int l1 = strlen(relativeName); + int l2 = strlen(fullpathName); + if ( l1 > 0 ) + { + if ( relativeName[ l1 - 1 ] == '\n' ) + { + relativeName[ l1 - 1 ] = 0; + } + } + if ( l2 > 0 ) + { + if ( fullpathName[ l2 - 1 ] == '\n' ) + { + fullpathName[ l2 - 1 ] = 0; + } + } + printf("Adding file: %s\n", fullpathName); + AddFileToPak( GetPakFile(), relativeName, fullpathName ); + } + else if ( !feof( fp ) || ( relativeName[0] && !fullpathName[0] ) ) + { + printf( "Error: Missing paired relative/full path names\n"); + fclose( fp ); + return( -1 ); + } + } + printf("Writing new bsp file: %s\n", newbspName); + WriteBSPFile(newbspName); + fclose( fp ); + } + } + else if( ( stricmp( pAction, "-addorupdatelist" ) == 0 ) && nActionArgs == 3 ) + { + // bspzip -addorupdatelist <bspfile> <listfile> <newbspfile> + CmdLib_InitFileSystem( pActionArgs[0] ); + char bspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( bspName, sizeof( bspName ), pActionArgs[0] ); + Q_DefaultExtension (bspName, ".bsp", sizeof( bspName ) ); + + char filelistName[MAX_PATH] = { 0 }; + V_strncpy( filelistName, pActionArgs[1], sizeof( filelistName ) ); + + char newbspName[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( newbspName, sizeof( newbspName ), pActionArgs[2] ); + Q_DefaultExtension (newbspName, ".bsp", sizeof( newbspName) ); + + // read it in, add pack file, write it back out + + char relativeName[MAX_PATH] = { 0 }; + char fullpathName[MAX_PATH] = { 0 }; + FILE *fp = fopen(filelistName, "r"); + if ( fp ) + { + printf("Opening bsp file: %s\n", bspName); + LoadBSPFile (bspName); + + while ( !feof(fp) ) + { + relativeName[ 0 ] = 0; + fullpathName[ 0 ] = 0; + if ( ( fgets( relativeName, sizeof( relativeName ), fp ) != NULL ) && + ( fgets( fullpathName, sizeof( fullpathName ), fp ) != NULL ) ) + { + int l1 = strlen(relativeName); + int l2 = strlen(fullpathName); + if ( l1 > 0 ) + { + if ( relativeName[ l1 - 1 ] == '\n' ) + { + relativeName[ l1 - 1 ] = 0; + } + } + if ( l2 > 0 ) + { + if ( fullpathName[ l2 - 1 ] == '\n' ) + { + fullpathName[ l2 - 1 ] = 0; + } + } + + bool bUpdating = FileExistsInPak( GetPakFile(), relativeName ); + printf("%s file: %s\n", bUpdating ? "Updating" : "Adding", fullpathName); + if ( bUpdating ) + { + RemoveFileFromPak( GetPakFile(), relativeName ); + } + AddFileToPak( GetPakFile(), relativeName, fullpathName ); + } + else if ( !feof( fp ) || ( relativeName[0] && !fullpathName[0] ) ) + { + printf( "Error: Missing paired relative/full path names\n"); + fclose( fp ); + return( -1 ); + } + } + printf("Writing new bsp file: %s\n", newbspName); + WriteBSPFile(newbspName); + fclose( fp ); + } + } + else if( ( stricmp( pAction, "-repack" ) == 0 ) && ( nActionArgs == 1 || nActionArgs == 2 ) ) + { + // bspzip -repack [ -compress ] <bspfile> + bool bCompress = false; + const char *pFile = pActionArgs[0]; + if ( nActionArgs == 2 && stricmp( pActionArgs[0], "-compress" ) == 0 ) + { + pFile = pActionArgs[1]; + bCompress = true; + } + else if ( nActionArgs == 2 ) + { + Usage(); + return 0; + } + + CmdLib_InitFileSystem( pFile ); + char szAbsBSPPath[MAX_PATH] = { 0 }; + Q_MakeAbsolutePath( szAbsBSPPath, sizeof( szAbsBSPPath ), pFile ); + Q_DefaultExtension( szAbsBSPPath, ".bsp", sizeof( szAbsBSPPath ) ); + return RepackBSP( szAbsBSPPath, bCompress ) ? 0 : -1; + } + else + { + Usage(); + } + return 0; +} diff --git a/utils/bspzip/bspzip.vpc b/utils/bspzip/bspzip.vpc new file mode 100644 index 0000000..649b0b4 --- /dev/null +++ b/utils/bspzip/bspzip.vpc @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// BSPZIP.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" + +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\common" + $PreprocessorDefinitions "$BASE;ZIP_SUPPORT_LZMA_ENCODE" + } + + $Linker [$WIN32] + { + $EnableLargeAddresses "Support Addresses Larger Than 2 Gigabytes (/LARGEADDRESSAWARE)" + } +} + +$Project "Bspzip" +{ + $Folder "Source Files" + { + $File "..\common\bsplib.cpp" + $File "bspzip.cpp" + $File "..\common\cmdlib.cpp" + $File "$SRCDIR\public\filesystem_helpers.cpp" + $File "$SRCDIR\public\filesystem_init.cpp" + $File "..\common\filesystem_tools.cpp" + $File "$SRCDIR\public\lumpfiles.cpp" + $File "..\common\scriplib.cpp" + $File "$SRCDIR\public\zip_utils.cpp" + } + + $Folder "Header Files" + { + $File "$SRCDIR\public\bspfile.h" + $File "$SRCDIR\public\tier1\characterset.h" + $File "$SRCDIR\public\filesystem_helpers.h" + $File "..\common\filesystem_tools.h" + $File "$SRCDIR\public\zip_utils.h" + } + + $Folder "Link Libraries" + { + $Lib mathlib + $Lib tier2 + $Lib "$LIBCOMMON/lzma" + } +} |