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/vmtcheck | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/vmtcheck')
| -rw-r--r-- | utils/vmtcheck/stdafx.cpp | 15 | ||||
| -rw-r--r-- | utils/vmtcheck/stdafx.h | 26 | ||||
| -rw-r--r-- | utils/vmtcheck/vmtcheck.cpp | 279 | ||||
| -rw-r--r-- | utils/vmtcheck/vmtcheck.vpc | 89 | ||||
| -rw-r--r-- | utils/vmtcheck/vmtcheck_util.cpp | 115 | ||||
| -rw-r--r-- | utils/vmtcheck/vmtcheck_util.h | 20 |
6 files changed, 544 insertions, 0 deletions
diff --git a/utils/vmtcheck/stdafx.cpp b/utils/vmtcheck/stdafx.cpp new file mode 100644 index 0000000..1fdf9da --- /dev/null +++ b/utils/vmtcheck/stdafx.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.cpp : source file that includes just the standard includes +// classcheck.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/utils/vmtcheck/stdafx.h b/utils/vmtcheck/stdafx.h new file mode 100644 index 0000000..e0ae61a --- /dev/null +++ b/utils/vmtcheck/stdafx.h @@ -0,0 +1,26 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__50E4147E_A508_4D85_BF0A_BA26676063F0__INCLUDED_) +#define AFX_STDAFX_H__50E4147E_A508_4D85_BF0A_BA26676063F0__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__50E4147E_A508_4D85_BF0A_BA26676063F0__INCLUDED_) diff --git a/utils/vmtcheck/vmtcheck.cpp b/utils/vmtcheck/vmtcheck.cpp new file mode 100644 index 0000000..241a1d0 --- /dev/null +++ b/utils/vmtcheck/vmtcheck.cpp @@ -0,0 +1,279 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "stdafx.h" +#include <stdio.h> +#include <windows.h> +#include "vmtcheck_util.h" +#include "tier0/dbg.h" +#include "utldict.h" +#include "filesystem.h" +#include "FileSystem_Tools.h" +#include "KeyValues.h" +#include "cmdlib.h" + +bool uselogfile = false; + +struct AnalysisData +{ + CUtlSymbolTable symbols; +}; + +static AnalysisData g_Analysis; + + +static bool spewed = false; + +SpewRetval_t SpewFunc( SpewType_t type, char const *pMsg ) +{ + spewed = true; + + printf( "%s", pMsg ); + OutputDebugString( pMsg ); + + if ( type == SPEW_ERROR ) + { + printf( "\n" ); + OutputDebugString( "\n" ); + } + + return SPEW_CONTINUE; +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void printusage( void ) +{ + vprint( 0, "usage: vmtcheck <materials/.vmt root directory>\n\ + \t-v = verbose output\n\ + \t-l = log to file log.txt\n\ + \ne.g.: vmtcheck -l u:/hl2/hl2/materials\n" ); + + // Exit app + exit( 1 ); +} + +void BuildFileList_R( CUtlVector< CUtlSymbol >& files, char const *dir, char const *extension ) +{ + WIN32_FIND_DATA wfd; + + char directory[ 256 ]; + char filename[ 256 ]; + HANDLE ff; + + sprintf( directory, "%s\\*.*", dir ); + + if ( ( ff = FindFirstFile( directory, &wfd ) ) == INVALID_HANDLE_VALUE ) + return; + + int extlen = strlen( extension ); + + do + { + if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { + + if ( wfd.cFileName[ 0 ] == '.' ) + continue; + + // Recurse down directory + sprintf( filename, "%s\\%s", dir, wfd.cFileName ); + BuildFileList_R( files, filename, extension ); + } + else + { + int len = strlen( wfd.cFileName ); + if ( len > extlen ) + { + if ( !stricmp( &wfd.cFileName[ len - extlen ], extension ) ) + { + char filename[ MAX_PATH ]; + Q_snprintf( filename, sizeof( filename ), "%s\\%s", dir, wfd.cFileName ); + _strlwr( filename ); + + Q_FixSlashes( filename ); + + CUtlSymbol sym = g_Analysis.symbols.AddString( filename ); + files.AddToTail( sym ); + + if ( !( files.Count() % 3000 ) ) + { + vprint( 0, "...found %i .vmt files\n", files.Count() ); + } + } + } + } + } while ( FindNextFile( ff, &wfd ) ); +} + +void BuildFileList( CUtlVector< CUtlSymbol >& files, char const *rootdir, char const *extension ) +{ + files.RemoveAll(); + BuildFileList_R( files, rootdir, extension ); +} + +bool ValidateVMTFile( char const *vmtname, int offset ) +{ + bool valid = true; + + KeyValues *kv = new KeyValues( "Test" ); + if ( kv->LoadFromFile( g_pFileSystem, &vmtname[offset] ) ) + { + // Do any custom checking here... + } + else + { + valid = false; + } + kv->deleteThis(); + + return valid; +} + +void ProcessMaterialsDirectory( char const *basedir ) +{ + vprint( 0, "building .vmt list\n" ); + + CUtlVector< CUtlSymbol > vmts; + + BuildFileList( vmts, basedir, ".vmt" ); + + vprint( 0, "found %i .vmt files\n\n", vmts.Count() ); + + int offset = strlen( basedir ) + 1; + offset -= strlen( "materials/" ); + if ( offset < 0 ) + { + Error( "Bogus offset\n" ); + } + + // Now iterate vmts and load into memory, etc. + + int c = vmts.Count(); + int valid = 0; + for ( int i = 0; i < c; i++ ) + { + CUtlSymbol& sym = vmts[ i ]; + + char const *vmtfile = g_Analysis.symbols.String( sym ); + + if ( verbose ) + { + vprint( 0, "checking %i .vmt %s\n", i, vmtfile ); + } + + spewed = false; + if ( ValidateVMTFile( vmtfile, offset ) ) + { + if ( !spewed ) + { + valid++; + } + } + + if ( i > 0 && !( i % 1000 ) ) + { + vprint( 0, "Analyzed %i .vmt files (%.2f %%%%)\n", i, 100.0f * (float)i/(float)c ); + } + } + + int ecount = c - valid; + vprint( 0, "\nSummary: found %i/%i (%.2f percent) .vmt errors\n", ecount, c, 100.0 * ecount / max( c, 1 ) ); + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CheckLogFile( void ) +{ + if ( uselogfile ) + { + _unlink( "log.txt" ); + vprint( 0, " Outputting to log.txt\n" ); + } +} + +void PrintHeader() +{ + vprint( 0, "Valve Software - vmtcheck.exe (%s)\n", __DATE__ ); + vprint( 0, "--- VMT File Consistency Checker ---\n" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : argc - +// argv[] - +// Output : int +//----------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + SpewOutputFunc( SpewFunc ); + SpewActivate( "vmtcheck", 2 ); + + int i=1; + for ( i ; i<argc ; i++) + { + if ( argv[ i ][ 0 ] == '-' ) + { + switch( argv[ i ][ 1 ] ) + { + case 'l': + uselogfile = true; + break; + case 'v': + verbose = true; + break; + default: + printusage(); + break; + } + } + } + + if ( argc < 2 || ( i != argc ) ) + { + PrintHeader(); + printusage(); + } + + CheckLogFile(); + + PrintHeader(); + + vprint( 0, " Looking for messed up .vmt files...\n" ); + + char vmtdir[ 256 ]; + strcpy( vmtdir, argv[ i - 1 ] ); + + if ( !strstr( vmtdir, "materials" ) ) + { + vprint( 0, "Materials dir %s looks invalid (format: u:/tf2/hl2/materials)\n", vmtdir ); + + return 0; + } + + char workingdir[ 256 ]; + workingdir[0] = 0; + Q_getwd( workingdir, sizeof( workingdir ) ); + + // If they didn't specify -game on the command line, use VPROJECT. + CmdLib_InitFileSystem( workingdir ); + + vprint( 0, "game dir %s\nmaterials dir %s\n\n", + gamedir, + vmtdir ); + + Q_StripTrailingSlash( vmtdir ); + ProcessMaterialsDirectory( vmtdir ); + + FileSystem_Term(); + + return 0; +} diff --git a/utils/vmtcheck/vmtcheck.vpc b/utils/vmtcheck/vmtcheck.vpc new file mode 100644 index 0000000..8788d86 --- /dev/null +++ b/utils/vmtcheck/vmtcheck.vpc @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// VMTCHECK.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" + +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\common" + $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)" + $Create/UsePCHThroughFile "stdafx.h" + $PrecompiledHeaderFile "Debug/vmtcheck.pch" + } +} + +$Project "Vmtcheck" +{ + $Folder "Source Files" + { + -$File "$SRCDIR\public\tier0\memoverride.cpp" + + $File "vmtcheck.cpp" + $File "vmtcheck_util.cpp" + + $File "..\common\cmdlib.cpp" \ + "$SRCDIR\public\filesystem_helpers.cpp" \ + "$SRCDIR\public\filesystem_init.cpp" \ + "..\common\filesystem_tools.cpp" + { + $Configuration + { + $Compiler + { + $Create/UsePrecompiledHeader "Not Using Precompiled Headers" + } + } + } + + $File "StdAfx.cpp" + { + $Configuration + { + $Compiler + { + $Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)" + } + } + } + } + + $Folder "Header Files" + { + $File "$SRCDIR\public\tier0\basetypes.h" + $File "..\common\cmdlib.h" + $File "$SRCDIR\public\tier0\commonmacros.h" + $File "$SRCDIR\public\tier0\dbg.h" + $File "$SRCDIR\public\tier0\fasttimer.h" + $File "$SRCDIR\public\mathlib\mathlib.h" + $File "$SRCDIR\public\tier0\memdbgon.h" + $File "$SRCDIR\public\tier0\platform.h" + $File "$SRCDIR\public\tier0\protected_things.h" + $File "StdAfx.h" + $File "$SRCDIR\public\string_t.h" + $File "$SRCDIR\public\tier1\strtools.h" + $File "$SRCDIR\public\studio.h" + $File "$SRCDIR\public\tier1\utldict.h" + $File "$SRCDIR\public\tier1\utlmemory.h" + $File "$SRCDIR\public\tier1\utlrbtree.h" + $File "$SRCDIR\public\tier1\utlsymbol.h" + $File "$SRCDIR\public\tier1\utlvector.h" + $File "$SRCDIR\public\mathlib\vector.h" + $File "$SRCDIR\public\mathlib\vector2d.h" + $File "$SRCDIR\public\mathlib\vector4d.h" + $File "vmtcheck_util.h" + $File "$SRCDIR\public\vstdlib\vstdlib.h" + } + + $Folder "Link Libraries" + { + $Lib tier2 + } +} diff --git a/utils/vmtcheck/vmtcheck_util.cpp b/utils/vmtcheck/vmtcheck_util.cpp new file mode 100644 index 0000000..afbffec --- /dev/null +++ b/utils/vmtcheck/vmtcheck_util.cpp @@ -0,0 +1,115 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "stdafx.h" +#include <io.h> +#include <stdio.h> +#include <windows.h> +#include "vmtcheck_util.h" +#include "tier0/dbg.h" + +extern bool uselogfile; + +//----------------------------------------------------------------------------- +// Purpose: +// Input : depth - +// *fmt - +// ... - +//----------------------------------------------------------------------------- +void vprint( int depth, const char *fmt, ... ) +{ + char string[ 8192 ]; + va_list va; + va_start( va, fmt ); + vsprintf( string, fmt, va ); + va_end( va ); + + FILE *fp = NULL; + + if ( uselogfile ) + { + fp = fopen( "log.txt", "ab" ); + } + + while ( depth-- > 0 ) + { + printf( " " ); + OutputDebugString( " " ); + if ( fp ) + { + fprintf( fp, " " ); + } + } + + ::printf( "%s", string ); + OutputDebugString( string ); + + if ( fp ) + { + char *p = string; + while ( *p ) + { + if ( *p == '\n' ) + { + fputc( '\r', fp ); + } + fputc( *p, fp ); + p++; + } + fclose( fp ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +// *len - +// Output : unsigned char +//----------------------------------------------------------------------------- +unsigned char *COM_LoadFile( const char *name, int *len) +{ + FILE *fp; + fp = fopen( name, "rb" ); + if ( !fp ) + { + *len = 0; + return NULL; + } + + fseek( fp, 0, SEEK_END ); + *len = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + + unsigned char *buffer = new unsigned char[ *len + 1 ]; + fread( buffer, *len, 1, fp ); + fclose( fp ); + buffer[ *len ] = 0; + + return buffer; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *buffer - +//----------------------------------------------------------------------------- +void COM_FreeFile( unsigned char *buffer ) +{ + delete[] buffer; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *dir - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool COM_DirectoryExists( const char *dir ) +{ + if ( !_access( dir, 0 ) ) + return true; + + return false; +} diff --git a/utils/vmtcheck/vmtcheck_util.h b/utils/vmtcheck/vmtcheck_util.h new file mode 100644 index 0000000..4c3c701 --- /dev/null +++ b/utils/vmtcheck/vmtcheck_util.h @@ -0,0 +1,20 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#ifndef CLASSCHECK_UTIL_H +#define CLASSCHECK_UTIL_H +#ifdef _WIN32 +#pragma once +#endif + + +void vprint( int depth, const char *fmt, ... ); + +unsigned char *COM_LoadFile( const char *name, int *len); +void COM_FreeFile( unsigned char *buffer ); +bool COM_DirectoryExists( const char *dir ); + +#endif // CLASSCHECK_UTIL_H |