//========= 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; istrCommand, 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; istrCommand; 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