mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-03 05:49:41 +03:00
1
This commit is contained in:
156
engine/cheatcodes.cpp
Normal file
156
engine/cheatcodes.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "cheatcodes.h"
|
||||
#include "cmd.h"
|
||||
#include "KeyValues.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "host.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Cheat Codes
|
||||
//=========================================================
|
||||
#define CHEAT_NAME_MAX_LEN 32
|
||||
#define CHEAT_CODE_MAX_LEN 10
|
||||
#define CHEAT_COMMAND_MAX_LEN 128
|
||||
static ButtonCode_t s_pKeyLog[CHEAT_CODE_MAX_LEN];
|
||||
static int s_nKeyLogIndex = 0;
|
||||
|
||||
|
||||
struct CheatCodeData_t
|
||||
{
|
||||
char szName[ CHEAT_NAME_MAX_LEN ];
|
||||
|
||||
bool bDevOnly;
|
||||
|
||||
int iCodeLength;
|
||||
ButtonCode_t pButtonCodes[ CHEAT_CODE_MAX_LEN ];
|
||||
|
||||
char szCommand[ CHEAT_COMMAND_MAX_LEN ];
|
||||
};
|
||||
|
||||
|
||||
static CUtlVector<CheatCodeData_t> s_CheatCodeCommands;
|
||||
|
||||
|
||||
void ClearCheatCommands( void )
|
||||
{
|
||||
s_CheatCodeCommands.RemoveAll();
|
||||
}
|
||||
|
||||
void ReadCheatCommandsFromFile( char *pchFileName )
|
||||
{
|
||||
KeyValues *pCheatCodeKeys = new KeyValues( "cheat_codes" );
|
||||
pCheatCodeKeys->LoadFromFile( g_pFullFileSystem, pchFileName, NULL );
|
||||
|
||||
KeyValues *pKey = NULL;
|
||||
for ( pKey = pCheatCodeKeys->GetFirstTrueSubKey(); pKey; pKey = pKey->GetNextTrueSubKey() )
|
||||
{
|
||||
int iCheat = s_CheatCodeCommands.AddToTail();
|
||||
CheatCodeData_t *pNewCheatCode = &(s_CheatCodeCommands[ iCheat ]);
|
||||
|
||||
Q_strncpy( pNewCheatCode->szName, pKey->GetName(), CHEAT_NAME_MAX_LEN ); // Get the name
|
||||
pNewCheatCode->bDevOnly = ( pKey->GetInt( "dev", 0 ) != 0 ); // Get developer only flag
|
||||
pNewCheatCode->iCodeLength = 0; // Start at zero code elements
|
||||
Q_strncpy( pNewCheatCode->szCommand, pKey->GetString( "command", "echo \"Cheat code has no command!\"" ), CHEAT_COMMAND_MAX_LEN );
|
||||
|
||||
KeyValues *pSubKey = NULL;
|
||||
for ( pSubKey = pKey->GetFirstSubKey(); pSubKey; pSubKey = pSubKey->GetNextKey() )
|
||||
{
|
||||
const char *pchType = pSubKey->GetName();
|
||||
if ( Q_strcmp( pchType, "code" ) == 0 )
|
||||
{
|
||||
AssertMsg( ( pNewCheatCode->iCodeLength < CHEAT_NAME_MAX_LEN ), "Cheat code elements exceeded max!" );
|
||||
|
||||
pNewCheatCode->pButtonCodes[ pNewCheatCode->iCodeLength ] = g_pInputSystem->StringToButtonCode( pSubKey->GetString() );
|
||||
++pNewCheatCode->iCodeLength;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pNewCheatCode->iCodeLength < CHEAT_NAME_MAX_LEN )
|
||||
{
|
||||
// If it's activation is a subsequence of another cheat, the longer cheat can't be activated!
|
||||
DevWarning( "Cheat code \"%s\" has less than %i code elements!", pKey->GetName(), CHEAT_NAME_MAX_LEN );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void ResetKeyLogging()
|
||||
{
|
||||
s_nKeyLogIndex = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void LogKeyPress( ButtonCode_t code )
|
||||
{
|
||||
if ( s_nKeyLogIndex < CHEAT_CODE_MAX_LEN )
|
||||
{
|
||||
// Log isn't full, so add it in the next spot
|
||||
s_pKeyLog[ s_nKeyLogIndex ] = code;
|
||||
++s_nKeyLogIndex;
|
||||
return;
|
||||
}
|
||||
|
||||
// Log is full so shift all data to the previous bucket
|
||||
int i;
|
||||
for ( i = 0; i < CHEAT_CODE_MAX_LEN - 1; ++i )
|
||||
{
|
||||
s_pKeyLog[ i ] = s_pKeyLog[ i + 1 ];
|
||||
}
|
||||
|
||||
// Log into the last bucket
|
||||
s_pKeyLog[ i ] = code;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void CheckCheatCodes()
|
||||
{
|
||||
// Loop through all cheat codes
|
||||
int iNumCheatCodes = s_CheatCodeCommands.Count();
|
||||
for ( int iCheatCode = 0; iCheatCode < iNumCheatCodes; ++iCheatCode )
|
||||
{
|
||||
CheatCodeData_t *pCheatCode = &(s_CheatCodeCommands[ iCheatCode ]);
|
||||
|
||||
if ( pCheatCode->bDevOnly && !developer.GetBool() )
|
||||
continue; // This cheat is only allowed in developer mode
|
||||
|
||||
int iLogIndex = s_nKeyLogIndex - pCheatCode->iCodeLength; // Check code against the back chunk of the log
|
||||
|
||||
if ( iLogIndex < 0 )
|
||||
continue; // There's less codes in the log than we need
|
||||
|
||||
int iCode = 0;
|
||||
|
||||
while ( iCode < pCheatCode->iCodeLength && pCheatCode->pButtonCodes[ iCode ] == s_pKeyLog[ iLogIndex ] )
|
||||
{
|
||||
++iCode;
|
||||
++iLogIndex;
|
||||
}
|
||||
|
||||
if ( iCode == pCheatCode->iCodeLength )
|
||||
{
|
||||
// Every part of the code was correct
|
||||
DevMsg( "Cheat code \"%s\" activated!", pCheatCode->szName );
|
||||
|
||||
Cbuf_AddText( "sv_cheats 1\n" );
|
||||
Cbuf_AddText( pCheatCode->szCommand );
|
||||
Cbuf_AddText( "\n" );
|
||||
|
||||
ResetKeyLogging();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user