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/rpt | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/rpt')
| -rw-r--r-- | utils/rpt/rpt.cpp | 451 | ||||
| -rw-r--r-- | utils/rpt/rpt.vpc | 47 |
2 files changed, 498 insertions, 0 deletions
diff --git a/utils/rpt/rpt.cpp b/utils/rpt/rpt.cpp new file mode 100644 index 0000000..13144a2 --- /dev/null +++ b/utils/rpt/rpt.cpp @@ -0,0 +1,451 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +//============================================================================= + + +// NOTE: We specifically don't want to include *any* valve libraries +// because this is expected to be run on a customer's machine and we +// don't want to have to deal with any strange path stuff +#include <windows.h> +#include <stdio.h> + + +//----------------------------------------------------------------------------- +// Print help +//----------------------------------------------------------------------------- +void PrintHelp( ) +{ + printf( "Usage: rpt -i <in .csv file> -m <.mdl relative path> -o <output dir>\n" ); + printf( " [-f <fac output dir>] [-p] [-w] [-r <sample rate in hz>] [-s <sample filter size>]\n" ); + printf( " [-nop4] [-vproject <path to gameinfo.txt>]\n" ); + printf( "\t-h,-help,-?\t:Displays this help message.\n" ); + printf( "\t-m\t: Indicates the path of the .mdl file under game/mod/models/ to use in the sfm files.\n" ); + printf( "\t-o\t: Indicates output directory to place generated files in.\n" ); + printf( "\t-f\t: [Optional] Indicates that facial files should be created in the specified fac output dir.\n" ); + printf( "\t-p\t: [Optional] Indicates the extracted phonemes should be written into the wav file.\n" ); + printf( "\t-w\t: [Optional] Indicates the phonemes should be read from the wav file. Cannot also have -p specified.\n" ); + printf( "\t-r\t: [Optional] Specifies the phoneme extraction sample rate (default = 20)\n" ); + printf( "\t-s\t: [Optional] Specifies the phoneme extraction sample filter size (default = 0.08)\n" ); + printf( "\t-nop4\t: Disables auto perforce checkout/add.\n" ); + printf( "\t-vproject\t: Specifies path to a gameinfo.txt file (which mod to build for).\n" ); +} + + +//----------------------------------------------------------------------------- +// Used to parse the commandline +//----------------------------------------------------------------------------- +static int FindParm( const char *pParam, int argc, char **argv ) +{ + // Start at 1 so as to not search the exe name + for ( int i = 1; i < argc; ++i ) + { + if ( !strcmp( pParam, argv[i] ) ) + return i; + } + return 0; +} + + +//----------------------------------------------------------------------------- +// Strips the last file from a filename, returns int offset of string end +//----------------------------------------------------------------------------- +static size_t StripFileName( char *pFileName ) +{ + // In this case, we queried the key properly. Strip off the steamclient.dll name + // to make a good full path to steam.exe + char *pSlash = strrchr( pFileName, '\\' ); + char *pSlash2 = strrchr( pFileName, '/' ); + if ( pSlash2 > pSlash ) + { + pSlash = pSlash2; + } + if ( !pSlash ) + { + pSlash = pFileName; + } + else + { + ++pSlash; + } + *pSlash = 0; + size_t nLen = (size_t)pSlash - (size_t)pFileName; + return nLen; +} + + +//----------------------------------------------------------------------------- +// Used to detect where steam is running from +//----------------------------------------------------------------------------- +static DWORD GetActiveSteamPID( ) +{ + HKEY hKey; + LONG hResult = RegOpenKey( HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", &hKey ); + if ( hResult != ERROR_SUCCESS ) + return 0; + + DWORD nType; + char pTempBuf[256]; + DWORD nLen = sizeof(pTempBuf); + hResult = RegQueryValueEx( hKey, "pid", NULL, &nType, (unsigned char *)pTempBuf, &nLen ); + RegCloseKey( hKey ); + if ( hResult != ERROR_SUCCESS || nLen == 0 ) + return 0; + + switch( nType ) + { + case REG_DWORD: + return *(DWORD*)pTempBuf; + + case REG_QWORD: + return (DWORD)( *(__int64*)pTempBuf ); + + case REG_SZ: + case REG_EXPAND_SZ: + return atoi( pTempBuf ); + } + + return 0; +} + + +//----------------------------------------------------------------------------- +// Used to detect where steam is running from +//----------------------------------------------------------------------------- +static bool DetectSteamPath( char *pFileName, int nBufLen ) +{ + *pFileName = 0; + + DWORD nLen; + + // First check to see if there's an active process + HKEY hKey; + LONG hResult = RegOpenKey( HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", &hKey ); + if ( hResult == ERROR_SUCCESS ) + { + nLen = (DWORD)nBufLen; + hResult = RegQueryValueEx( hKey, "SteamClientDll", NULL, NULL, (LPBYTE)pFileName, &nLen ); + RegCloseKey( hKey ); + if ( hResult == ERROR_SUCCESS ) + { + // In this case, we queried the key properly. Strip off the steamclient.dll name + // to make a good full path to steam.exe + size_t nUsed = StripFileName( pFileName ); + strncpy( &pFileName[nUsed], "steam.exe", nBufLen - nUsed ); + return true; + } + } + + // If not, then get the default install location + hResult = RegOpenKey( HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey ); + if ( hResult != ERROR_SUCCESS ) + return false; + + nLen = (DWORD)nBufLen; + hResult = RegQueryValueEx( hKey, "SteamExe", NULL, NULL, (LPBYTE)pFileName, &nLen ); + RegCloseKey( hKey ); + return ( hResult == ERROR_SUCCESS && nLen != 0 ); +} + + +//----------------------------------------------------------------------------- +// Displays a windows error +//----------------------------------------------------------------------------- +static void DisplayWindowsError( const char *pMessage ) +{ + DWORD dw = GetLastError(); + char pErrorMessage[2048]; + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + pErrorMessage, sizeof(pErrorMessage), NULL ); + printf( "%s\n%s\n", pMessage, pErrorMessage ); +} + + +//----------------------------------------------------------------------------- +// Deletes steam.cfg +//----------------------------------------------------------------------------- +static void DeleteCfgFile( const char *pFullPath ) +{ + remove( pFullPath ); +} + + +//----------------------------------------------------------------------------- +// Launches steam.exe, returns process ID (0 if failed) +//----------------------------------------------------------------------------- +static DWORD LaunchSteam( const char *pFullPath, const char *pArgs ) +{ + // Try to launch steam, shutting down any existing instance. + STARTUPINFO si; + memset( &si, 0, sizeof si ); + si.cb = sizeof(si); + + PROCESS_INFORMATION pi; + if ( !CreateProcess( pFullPath, (char*)pArgs, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi ) ) + return 0; + + return pi.dwProcessId; +} + + +//----------------------------------------------------------------------------- +// Is process active? +//----------------------------------------------------------------------------- +static bool IsSteamProcessActive( DWORD nProcessID ) +{ + if ( nProcessID == 0 ) + return false; + + HANDLE hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, nProcessID ); + bool bProcessActive = ( hProcess != 0 ); + if ( bProcessActive ) + { + DWORD nExitCode; + BOOL bOk = GetExitCodeProcess( hProcess, &nExitCode ); + if ( !bOk || ( nExitCode != STILL_ACTIVE ) ) + { + bProcessActive = false; + } + } + + CloseHandle( hProcess ); + return bProcessActive; +} + + +static void TerminateSteamProcess( DWORD nProcessID ) +{ + if ( nProcessID == 0 ) + return; + + HANDLE hProcess = OpenProcess( PROCESS_TERMINATE, FALSE, nProcessID ); + if ( hProcess != 0 ) + { + TerminateProcess( hProcess, 0 ); + CloseHandle( hProcess ); + } +} + + +//----------------------------------------------------------------------------- +// Shuts down existing steam process +//----------------------------------------------------------------------------- +static bool ShutdownExistingSteamProcess( const char *pSteamPath ) +{ + DWORD nSteamPID = GetActiveSteamPID( ); + + // Ensure the process is actually running. + // The registry simply stores the last run steam process id + if ( !IsSteamProcessActive( nSteamPID ) ) + { + nSteamPID = 0; + } + + // Try to shut down existing instances of steam + if ( nSteamPID == 0 ) + return true; + + if ( !LaunchSteam( pSteamPath, "-shutdown" ) ) + { + DisplayWindowsError( "rpt: Unable to shutdown existing steam process!" ); + return false; + } + + // Wait for the old process to terminate + // Wait for at least 30 seconds. If it doesn't start by that time, + // then kill the existing process. + DWORD nStartTime = GetTickCount(); + DWORD nTestTime = 30; + while ( IsSteamProcessActive( nSteamPID ) ) + { + Sleep( 1000 ); + DWORD dt = ( GetTickCount() - nStartTime ) / 1000; + if ( dt <= nTestTime ) + continue; + + TerminateSteamProcess( nSteamPID ); + break; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Copies test files into position +//----------------------------------------------------------------------------- +bool CopyFilesRecursively( const char *pSrcPath, const char *pDestPath ) +{ + // Create a file that makes steam not delete different DLLs + char pSearchStr[MAX_PATH]; + _snprintf( pSearchStr, sizeof(pSearchStr), "%s*", pSrcPath ); + + WIN32_FIND_DATA find; + HANDLE hFind = FindFirstFile( pSearchStr, &find ); + if( INVALID_HANDLE_VALUE == hFind ) + return true; + + // Make sure the dest path exists + if ( ( GetFileAttributes( pDestPath ) & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) + { + if ( !CreateDirectory( pDestPath, NULL ) ) + { + printf( "Unable to create directory %s\n", pDestPath ); + return false; + } + } + + // Display each file and ask for the next. + do + { + // Skip . and .. + if ( !strcmp( find.cFileName, "." ) || !strcmp( find.cFileName, ".." ) ) + continue; + + char pSrcChildPath[MAX_PATH]; + char pDestChildPath[MAX_PATH]; + + // Deal with directories + if ( ( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && ( ( find.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) == 0 ) ) + { + _snprintf( pSrcChildPath, sizeof(pSrcChildPath), "%s%s\\", pSrcPath, find.cFileName ); + _snprintf( pDestChildPath, sizeof(pDestChildPath), "%s%s\\", pDestPath, find.cFileName ); + if ( !CopyFilesRecursively( pSrcChildPath, pDestChildPath ) ) + return false; + continue; + } + + _snprintf( pSrcChildPath, sizeof(pSrcChildPath), "%s%s", pSrcPath, find.cFileName ); + _snprintf( pDestChildPath, sizeof(pDestChildPath), "%s%s", pDestPath, find.cFileName ); + + // Copy everything else + // NOTE: This may fail if the file isn't already there + SetFileAttributes( pDestChildPath, FILE_ATTRIBUTE_NORMAL ); + + if ( CopyFile( pSrcChildPath, pDestChildPath, FALSE ) == 0 ) + { + printf( "Unable to copy file %s to %s\n", pSrcChildPath, pDestChildPath ); + return false; + } + + if ( !SetFileAttributes( pDestChildPath, FILE_ATTRIBUTE_READONLY ) ) + { + printf( "Unable to make file %s read only.\n", pDestChildPath ); + return false; + } + + } while( FindNextFile( hFind, &find ) ); + + // Close the find handle. + FindClose( hFind ); + return true; +} + + +//----------------------------------------------------------------------------- +// Copies test files into position +//----------------------------------------------------------------------------- +static bool CopyFilesIntoPosition( const char *pSteamPath ) +{ + // Create a file that makes steam not delete different DLLs + char pSteamRoot[MAX_PATH]; + strncpy( pSteamRoot, pSteamPath, sizeof(pSteamRoot) ); + StripFileName( pSteamRoot ); + + char pSrcRoot[MAX_PATH]; + if ( !::GetModuleFileName( ( HINSTANCE )GetModuleHandle( NULL ), pSrcRoot, sizeof(pSrcRoot) ) ) + { + printf( "Unable to find rpt launch path!\n" ); + return false; + } + StripFileName( pSrcRoot ); + + return CopyFilesRecursively( pSrcRoot, pSteamRoot ); +} + + +//----------------------------------------------------------------------------- +// Launches new steam process +//----------------------------------------------------------------------------- +static bool LaunchNewSteamProcess( const char *pSteamPath ) +{ + // Create a file that makes steam not delete different DLLs + char pCfgPath[MAX_PATH]; + strncpy( pCfgPath, pSteamPath, sizeof(pCfgPath) ); + size_t nUsed = StripFileName( pCfgPath ); + strncpy( &pCfgPath[nUsed], "steam.cfg", sizeof(pCfgPath) - nUsed ); + + FILE* fp = fopen( pCfgPath, "wt" ); + if ( !fp ) + { + printf( "rpt: Unable to relaunch steam! Aborting...\n" ); + return false; + } + + fprintf( fp, "MinFootprintAutoRefresh = disable\n" ); + fclose( fp ); + + // Launch a new instance of steam + DWORD nNewPID = LaunchSteam( pSteamPath, "" ); + + // Wait for the new process to start. + // Wait for at least 30 seconds. If it doesn't start by that time, + // stop what we're doing. + DWORD nStartTime = GetTickCount(); + DWORD nTestTime = 30; + while ( GetActiveSteamPID( ) != nNewPID ) + { + Sleep( 1000 ); + DWORD dt = ( GetTickCount() - nStartTime ) / 1000; + if ( dt <= nTestTime ) + continue; + + TerminateSteamProcess( nNewPID ); + DeleteCfgFile( pCfgPath ); + printf( "rpt: Unable to launch new steam process!" ); + return false; + } + + DeleteCfgFile( pCfgPath ); + + return true; +} + + +//----------------------------------------------------------------------------- +// The application object +//----------------------------------------------------------------------------- +int main( int argc, char **argv ) +{ + if ( FindParm( "-h", argc, argv ) || FindParm( "-help", argc, argv ) || FindParm( "-?", argc, argv ) ) + { + PrintHelp(); + return 0; + } + + // Detect the currently running version of steam + char pSteamPath[MAX_PATH]; + if ( !DetectSteamPath( pSteamPath, sizeof(pSteamPath) ) ) + { + printf( "rpt: Unable to detect steam installation path! Aborting...\n" ); + return 0; + } + + if ( !ShutdownExistingSteamProcess( pSteamPath ) ) + return 0; + + if ( !CopyFilesIntoPosition( pSteamPath ) ) + return 0; + + if ( !LaunchNewSteamProcess( pSteamPath ) ) + return 0; + + return -1; +}
\ No newline at end of file diff --git a/utils/rpt/rpt.vpc b/utils/rpt/rpt.vpc new file mode 100644 index 0000000..6050e05 --- /dev/null +++ b/utils/rpt/rpt.vpc @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// RPT.VPC [Remote Perf Testing] +// +// This project is used to copy files onto the customer machine to run +// specific tests. It also launches steam in a special way to make it +// not blow away those files. +// +// Project Script +//----------------------------------------------------------------------------- + +$MacroRequired "PLATSUBDIR" + +$Macro SRCDIR "..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" + +$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc" + +$Project +{ + $Folder "Source Files" + { + -$File "$SRCDIR\public\tier0\memoverride.cpp" + } + + $Folder "Link Libraries" + { + -$File "$SRCDIR\lib\public\tier0.lib" [!$WIN64] + -$File "$SRCDIR\lib\public\tier1.lib" [!$WIN64] + -$File "$SRCDIR\lib\public\vstdlib.lib" [!$WIN64] + + -$File "$SRCDIR\lib\public$PLATSUBDIR\tier0.lib" [$WIN64] + -$File "$SRCDIR\lib\public$PLATSUBDIR\tier1.lib" [$WIN64] + -$File "$SRCDIR\lib\public$PLATSUBDIR\vstdlib.lib" [$WIN64] + } +} + +$Project "rpt" +{ + $Folder "Source Files" + { + $File "rpt.cpp" + } + + $Folder "Link Libraries" + { + } +} |