Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.6 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "cheatcodes.h"
  7. #include "cmd.h"
  8. #include "keyvalues.h"
  9. #include "filesystem.h"
  10. #include "tier2/tier2.h"
  11. #include "inputsystem/iinputsystem.h"
  12. #include "host.h"
  13. #include "common.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. //=========================================================
  17. // Cheat Codes
  18. //=========================================================
  19. #define CHEAT_NAME_MAX_LEN 32
  20. #define CHEAT_CODE_MAX_LEN 10
  21. #define CHEAT_COMMAND_MAX_LEN 128
  22. static ButtonCode_t s_pKeyLog[CHEAT_CODE_MAX_LEN];
  23. static int s_nKeyLogIndex = 0;
  24. struct CheatCodeData_t
  25. {
  26. char szName[ CHEAT_NAME_MAX_LEN ];
  27. bool bDevOnly;
  28. int iCodeLength;
  29. ButtonCode_t pButtonCodes[ CHEAT_CODE_MAX_LEN ];
  30. char szCommand[ CHEAT_COMMAND_MAX_LEN ];
  31. };
  32. static CUtlVector<CheatCodeData_t> s_CheatCodeCommands;
  33. void ClearCheatCommands( void )
  34. {
  35. s_CheatCodeCommands.RemoveAll();
  36. }
  37. void ReadCheatCommandsFromFile( char *pchFileName )
  38. {
  39. #if defined( _CERT )
  40. return;
  41. #endif
  42. KeyValues *pCheatCodeKeys = new KeyValues( "cheat_codes" );
  43. if ( pCheatCodeKeys->LoadFromFile( g_pFullFileSystem, pchFileName, NULL ) )
  44. {
  45. KeyValues *pKey = NULL;
  46. for ( pKey = pCheatCodeKeys->GetFirstTrueSubKey(); pKey; pKey = pKey->GetNextTrueSubKey() )
  47. {
  48. int iCheat = s_CheatCodeCommands.AddToTail();
  49. CheatCodeData_t *pNewCheatCode = &(s_CheatCodeCommands[ iCheat ]);
  50. Q_strncpy( pNewCheatCode->szName, pKey->GetName(), CHEAT_NAME_MAX_LEN ); // Get the name
  51. pNewCheatCode->bDevOnly = ( pKey->GetInt( "dev", 0 ) != 0 ); // Get developer only flag
  52. pNewCheatCode->iCodeLength = 0; // Start at zero code elements
  53. Q_strncpy( pNewCheatCode->szCommand, pKey->GetString( "command", "echo \"Cheat code has no command!\"" ), CHEAT_COMMAND_MAX_LEN );
  54. KeyValues *pSubKey = NULL;
  55. for ( pSubKey = pKey->GetFirstSubKey(); pSubKey; pSubKey = pSubKey->GetNextKey() )
  56. {
  57. const char *pchType = pSubKey->GetName();
  58. if ( Q_strcmp( pchType, "code" ) == 0 )
  59. {
  60. AssertMsg( ( pNewCheatCode->iCodeLength < CHEAT_NAME_MAX_LEN ), "Cheat code elements exceeded max!" );
  61. pNewCheatCode->pButtonCodes[ pNewCheatCode->iCodeLength ] = g_pInputSystem->StringToButtonCode( pSubKey->GetString() );
  62. ++pNewCheatCode->iCodeLength;
  63. }
  64. }
  65. if ( pNewCheatCode->iCodeLength < CHEAT_NAME_MAX_LEN )
  66. {
  67. // If it's activation is a subsequence of another cheat, the longer cheat can't be activated!
  68. DevWarning( "Cheat code \"%s\" has less than %i code elements!", pKey->GetName(), CHEAT_NAME_MAX_LEN );
  69. }
  70. }
  71. }
  72. pCheatCodeKeys->deleteThis();
  73. }
  74. //---------------------------------------------------------
  75. //---------------------------------------------------------
  76. void ResetKeyLogging()
  77. {
  78. s_nKeyLogIndex = 0;
  79. }
  80. //---------------------------------------------------------
  81. //---------------------------------------------------------
  82. void LogKeyPress( ButtonCode_t code )
  83. {
  84. #if defined( _CERT )
  85. return;
  86. #endif
  87. if ( s_nKeyLogIndex < CHEAT_CODE_MAX_LEN )
  88. {
  89. // Log isn't full, so add it in the next spot
  90. s_pKeyLog[ s_nKeyLogIndex ] = code;
  91. ++s_nKeyLogIndex;
  92. return;
  93. }
  94. // Log is full so shift all data to the previous bucket
  95. int i;
  96. for ( i = 0; i < CHEAT_CODE_MAX_LEN - 1; ++i )
  97. {
  98. s_pKeyLog[ i ] = s_pKeyLog[ i + 1 ];
  99. }
  100. // Log into the last bucket
  101. s_pKeyLog[ i ] = code;
  102. }
  103. //---------------------------------------------------------
  104. //---------------------------------------------------------
  105. void CheckCheatCodes()
  106. {
  107. #if defined( _CERT )
  108. return;
  109. #endif
  110. // Loop through all cheat codes
  111. int iNumCheatCodes = s_CheatCodeCommands.Count();
  112. for ( int iCheatCode = 0; iCheatCode < iNumCheatCodes; ++iCheatCode )
  113. {
  114. CheatCodeData_t *pCheatCode = &(s_CheatCodeCommands[ iCheatCode ]);
  115. if ( pCheatCode->bDevOnly && !developer.GetBool() )
  116. continue; // This cheat is only allowed in developer mode
  117. int iLogIndex = s_nKeyLogIndex - pCheatCode->iCodeLength; // Check code against the back chunk of the log
  118. if ( iLogIndex < 0 )
  119. continue; // There's less codes in the log than we need
  120. int iCode = 0;
  121. while ( iCode < pCheatCode->iCodeLength && pCheatCode->pButtonCodes[ iCode ] == s_pKeyLog[ iLogIndex ] )
  122. {
  123. ++iCode;
  124. ++iLogIndex;
  125. }
  126. if ( iCode == pCheatCode->iCodeLength )
  127. {
  128. // Every part of the code was correct
  129. DevMsg( "Cheat code \"%s\" activated!", pCheatCode->szName );
  130. Cbuf_AddText( Cbuf_GetCurrentPlayer(), va( "sv_cheats 1\n%s\n", pCheatCode->szCommand ) );
  131. ResetKeyLogging();
  132. return;
  133. }
  134. }
  135. }