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/xbox/vxconsole/remote_cmds.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/xbox/vxconsole/remote_cmds.cpp')
| -rw-r--r-- | utils/xbox/vxconsole/remote_cmds.cpp | 484 |
1 files changed, 484 insertions, 0 deletions
diff --git a/utils/xbox/vxconsole/remote_cmds.cpp b/utils/xbox/vxconsole/remote_cmds.cpp new file mode 100644 index 0000000..f74bda0 --- /dev/null +++ b/utils/xbox/vxconsole/remote_cmds.cpp @@ -0,0 +1,484 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// REMOTE_CMDS.CPP +// +// Remote commands received by an external application and dispatched. +//=====================================================================================// +#include "vxconsole.h" + +remoteCommand_t *g_remoteCommands[MAX_RCMDS]; +int g_numRemoteCommands; + +//----------------------------------------------------------------------------- +// MatchRemoteCommands +// +//----------------------------------------------------------------------------- +int MatchRemoteCommands( char *pCmdStr, const char *cmdList[], int maxCmds ) +{ + int numCommands = 0; + + // look in local + int matchLen = strlen( pCmdStr ); + for ( int i=0; i<g_numRemoteCommands; i++ ) + { + if ( !strnicmp( pCmdStr, g_remoteCommands[i]->strCommand, matchLen ) ) + { + cmdList[numCommands++] = g_remoteCommands[i]->strCommand; + if ( numCommands >= maxCmds ) + break; + } + } + + return ( numCommands ); +} + +//----------------------------------------------------------------------------- +// GetToken +// +//----------------------------------------------------------------------------- +char *GetToken( char **ppTokenStream ) +{ + static char token[MAX_TOKENCHARS]; + int len; + char c; + char *pData; + + len = 0; + token[0] = 0; + + if ( !ppTokenStream ) + return NULL; + + pData = *ppTokenStream; + + // skip whitespace +skipwhite: + while ( ( c = *pData ) <= ' ' ) + { + if ( !c ) + goto cleanup; + pData++; + } + + // skip // comments + if ( c=='/' && pData[1] == '/' ) + { + while ( *pData && *pData != '\n' ) + pData++; + goto skipwhite; + } + + // handle quoted strings specially + if ( c == '\"' ) + { + pData++; + while ( 1 ) + { + c = *pData++; + if ( c=='\"' || !c ) + goto cleanup; + + token[len] = c; + len++; + if ( len > MAX_TOKENCHARS-1 ) + goto cleanup; + } + } + + // parse a regular word + do + { + token[len] = c; + pData++; + len++; + if ( len > MAX_TOKENCHARS-1 ) + break; + c = *pData; + } + while ( c > ' ' && c <= '~' ); + +cleanup: + token[len] = 0; + *ppTokenStream = pData; + return ( token ); +} + +//----------------------------------------------------------------------------- +// CommandCompleted +// +//----------------------------------------------------------------------------- +void CommandCompleted( int errCode ) +{ + char cmdString[MAX_PATH]; + + // send command complete + sprintf( cmdString, "%s!__complete__%d", VXCONSOLE_COMMAND_PREFIX, errCode ); + DmAPI_SendCommand( cmdString, true ); +} + +//----------------------------------------------------------------------------- +// DebugCommand +//----------------------------------------------------------------------------- +void DebugCommand( const char *pStrFormat, ... ) +{ + char buffer[MAX_QUEUEDSTRINGLEN]; + va_list arglist; + + if ( !g_debugCommands ) + return; + + va_start( arglist, pStrFormat ); + _vsnprintf( buffer, MAX_QUEUEDSTRINGLEN, pStrFormat, arglist ); + va_end( arglist ); + + PrintToQueue( RGB( 0,128,0 ), "[CMD]: %s", buffer ); +} + +//----------------------------------------------------------------------------- +// Remote_NotifyPrintFunc +// +//----------------------------------------------------------------------------- +DWORD __stdcall Remote_NotifyPrintFunc( const CHAR *pStrNotification ) +{ + int color; + + if ( !strnicmp( pStrNotification, VXCONSOLE_PRINT_PREFIX, strlen( VXCONSOLE_PRINT_PREFIX ) ) ) + { + // skip past prefix! + pStrNotification += strlen( VXCONSOLE_PRINT_PREFIX )+1; + } + + color = XBX_CLR_DEFAULT; + + if ( !strnicmp( pStrNotification, VXCONSOLE_COLOR_PREFIX, strlen( VXCONSOLE_COLOR_PREFIX ) ) ) + { + // skip past prefix[12345678] + char buff[16]; + pStrNotification += strlen( VXCONSOLE_COLOR_PREFIX ); + memcpy( buff, pStrNotification, 10 ); + if ( buff[0] == '[' && buff[9] == ']' ) + { + buff[0] = ' '; + buff[9] = ' '; + buff[10] = '\0'; + + sscanf( buff, "%x", &color ); + pStrNotification += 10; + } + } + + PrintToQueue( color, "%s\n", pStrNotification ); + return S_OK; +} + +//----------------------------------------------------------------------------- +// Remote_NotifyDebugString +// +// Print as [DBG]:xxxx +//----------------------------------------------------------------------------- +DWORD __stdcall Remote_NotifyDebugString( ULONG dwNotification, DWORD dwParam ) +{ + if ( g_captureDebugSpew ) + { + PDMN_DEBUGSTR p = ( PDMN_DEBUGSTR )dwParam; + int len; + + // strip all terminating cr + len = p->Length-1; + while ( len > 0 ) + { + if ( p->String[len] != '\n' ) + { + len++; + break; + } + len--; + } + + // for safety, terminate + CHAR* strTemp = new CHAR[len+1]; + memcpy( strTemp, p->String, len*sizeof( CHAR ) ); + strTemp[len] = '\0'; + + PrintToQueue( RGB( 0,0,255 ), "[DBG]: %s\n", strTemp ); + + delete[] strTemp; + } + + // Don't let the compiler complain about unused parameters + ( VOID )dwNotification; + + return 0; +} + +//----------------------------------------------------------------------------- +// Remote_CompareCommands +// +//----------------------------------------------------------------------------- +int Remote_CompareCommands( const void *pElem1, const void *pElem2 ) +{ + remoteCommand_t *pCmd1; + remoteCommand_t *pCmd2; + + pCmd1 = *( remoteCommand_t** )( pElem1 ); + pCmd2 = *( remoteCommand_t** )( pElem2 ); + + return ( strcmp( pCmd1->strCommand, pCmd2->strCommand ) ); +} + +//----------------------------------------------------------------------------- +// Remote_DeleteCommands +// +//----------------------------------------------------------------------------- +void Remote_DeleteCommands() +{ + if ( !g_numRemoteCommands ) + return; + + for ( int i=0; i<g_numRemoteCommands; i++ ) + { + delete [] g_remoteCommands[i]->strCommand; + delete [] g_remoteCommands[i]->strHelp; + delete g_remoteCommands[i]; + + g_remoteCommands[i] = NULL; + } + + g_numRemoteCommands = 0; +} + +//----------------------------------------------------------------------------- +// Remote_AddCommand +// +//----------------------------------------------------------------------------- +bool Remote_AddCommand( char *command, char *helptext ) +{ + if ( g_numRemoteCommands == MAX_RCMDS ) + { + // full + return false; + } + + // look for duplicate + int i; + for ( i = 0; i < g_numRemoteCommands; i++ ) + { + if ( !stricmp( command, g_remoteCommands[i]->strCommand ) ) + break; + } + if ( i < g_numRemoteCommands ) + { + // already in list, skip - not an error + return true; + } + + // add new command to list + g_remoteCommands[g_numRemoteCommands] = new remoteCommand_t; + g_remoteCommands[g_numRemoteCommands]->strCommand = new char[strlen( command )+1]; + strcpy( g_remoteCommands[g_numRemoteCommands]->strCommand, command ); + + g_remoteCommands[g_numRemoteCommands]->strHelp = new char[strlen( helptext )+1]; + strcpy( g_remoteCommands[g_numRemoteCommands]->strHelp, helptext ); + + g_numRemoteCommands++; + + // success + return true; +} + +//----------------------------------------------------------------------------- +// rc_AddCommands +// +// Exposes an app's list of remote commands +//----------------------------------------------------------------------------- +int rc_AddCommands( char *commandPtr ) +{ + char* cmdToken; + int numCommands; + int cmdList; + int retAddr; + int retVal; + int errCode; + xrCommand_t* locallist; + + errCode = -1; + + // pacifier for lengthy operation + ConsoleWindowPrintf( RGB( 0, 0, 0 ), "Receiving Console Commands From Game..." ); + + // get number of commands + cmdToken = GetToken( &commandPtr ); + if ( !cmdToken[0] ) + goto cleanUp; + sscanf( cmdToken, "%x", &numCommands ); + + // get command list + cmdToken = GetToken( &commandPtr ); + if ( !cmdToken[0] ) + goto cleanUp; + sscanf( cmdToken, "%x", &cmdList ); + + // get retAddr + cmdToken = GetToken( &commandPtr ); + if ( !cmdToken[0] ) + goto cleanUp; + sscanf( cmdToken, "%x", &retAddr ); + + locallist = new xrCommand_t[numCommands]; + memset( locallist, 0, numCommands*sizeof( xrCommand_t ) ); + + // get the caller's command list + DmGetMemory( ( void* )cmdList, numCommands*sizeof( xrCommand_t ), locallist, NULL ); + + int numAdded = 0; + for ( int i=0; i<numCommands; i++ ) + { + if ( Remote_AddCommand( locallist[i].nameString, locallist[i].helpString ) ) + numAdded++; + } + + // sort the list + qsort( g_remoteCommands, g_numRemoteCommands, sizeof( remoteCommand_t* ), Remote_CompareCommands ); + + ConsoleWindowPrintf( RGB( 0, 0, 0 ), "Completed.\n" ); + + // return the result + retVal = numAdded; + int xboxRetVal = BigDWord( retVal ); + DmSetMemory( ( void* )retAddr, sizeof( int ), &xboxRetVal, NULL ); + + DebugCommand( "0x%8.8x = AddCommands( 0x%8.8x, 0x%8.8x )\n", retVal, numCommands, cmdList ); + + delete [] locallist; + + // success + errCode = 0; + + if ( g_bPlayTestMode ) + { + if ( g_connectedToApp ) + { + // send the developer command + ProcessCommand( "developer 1" ); + } + } + +cleanUp: + return ( errCode ); +} + +//----------------------------------------------------------------------------- +// Remote_NotifyCommandFunc +// +//----------------------------------------------------------------------------- +DWORD __stdcall Remote_NotifyCommandFunc( const CHAR *strNotification ) +{ + CHAR* commandPtr; + CHAR* cmdToken; + int errCode; + bool async; + + // skip over the command prefix and the exclamation mark + strNotification += strlen( VXCONSOLE_COMMAND_PREFIX ) + 1; + commandPtr = ( CHAR* )strNotification; + + // failure until otherwise + errCode = -1; + + // default synchronous + async = false; + + cmdToken = GetToken( &commandPtr ); + + if ( cmdToken && !stricmp( cmdToken, "AddCommands()" ) ) + { + errCode = rc_AddCommands( commandPtr ); + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "SetProfile()" ) ) + { + // first arg dictates routing + cmdToken = GetToken( &commandPtr ); + if ( cmdToken && !stricmp( cmdToken, "cpu" ) ) + errCode = rc_SetCpuProfile( commandPtr ); + else if ( cmdToken && !stricmp( cmdToken, "texture" ) ) + errCode = rc_SetTexProfile( commandPtr ); + + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "SetProfileData()" ) ) + { + // first arg dictates routing + cmdToken = GetToken( &commandPtr ); + if ( cmdToken && !stricmp( cmdToken, "cpu" ) ) + errCode = rc_SetCpuProfileData( commandPtr ); + else if ( cmdToken && !stricmp( cmdToken, "texture" ) ) + errCode = rc_SetTexProfileData( commandPtr ); + + async = true; + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "TextureList()" ) ) + { + errCode = rc_TextureList( commandPtr ); + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "MaterialList()" ) ) + { + errCode = rc_MaterialList( commandPtr ); + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "SoundList()" ) ) + { + errCode = rc_SoundList( commandPtr ); + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "TimeStampLog()" ) ) + { + errCode = rc_TimeStampLog( commandPtr ); + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "MemDump()" ) ) + { + errCode = rc_MemDump( commandPtr ); + async = true; + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "MapInfo()" ) ) + { + errCode = rc_MapInfo( commandPtr ); + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "Assert()" ) ) + { + errCode = rc_Assert( commandPtr ); + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "FreeMemory()" ) ) + { + errCode = rc_FreeMemory( commandPtr ); + async = true; + goto cleanUp; + } + else if ( cmdToken && !stricmp( cmdToken, "Disconnect()" ) ) + { + // disconnect requires specialized processing + // send command status first while connection valid, then do actual disconnect + // disconnect is always assumed to be valid, can't be denied + CommandCompleted( 0 ); + DoDisconnect( TRUE ); + return S_OK; + } + else + { + // unknown command + PrintToQueue( RGB( 255,0,0 ), "Unknown Command: %s\n", strNotification ); + goto cleanUp; + } + +cleanUp: + if ( !async ) + CommandCompleted( errCode ); + + return ( S_OK ); +} |