csgo-2018-source/engine/ipc_console.cpp

295 lines
7.0 KiB
C++
Raw Normal View History

2021-07-25 12:11:47 +08:00
//====== Copyright c 1996-2008, Valve Corporation, All rights reserved. =======//
//
// Purpose: Exposing command console for scripting
//
//
#include <windows.h>
#include <stdio.h>
#include "valve_ipc_win32.h"
#include "tier0/dbg.h"
#include "tier0/platform.h"
#include "mathlib/mathlib.h"
#include "tier1/convar.h"
#include "UtlStringMap.h"
#include "con_nprint.h"
#include "cdll_int.h"
#include "globalvars_base.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern IVEngineClient *engineClient;
extern CGlobalVarsBase *gpGlobals;
//////////////////////////////////////////////////////////////////////////
//
// Definition of CValveIpcServerUtl
//
class CValveIpcServerUtl : public CValveIpcServer
{
public:
explicit CValveIpcServerUtl( char const *szServerName ) : CValveIpcServer( szServerName ) {}
virtual BOOL ExecuteCommand( char *bufCommand, DWORD numCommandBytes, char *bufResult, DWORD &numResultBytes )
{
CUtlBuffer cmd( bufCommand, numCommandBytes, CUtlBuffer::READ_ONLY );
CUtlBuffer res( bufResult, VALVE_IPC_CS_BUFFER, int( 0 ) );
if ( !ExecuteCommand( cmd, res ) )
return FALSE;
numResultBytes = res.TellPut();
return TRUE;
}
virtual BOOL ExecuteCommand( CUtlBuffer &cmd, CUtlBuffer &res ) = 0;
};
//////////////////////////////////////////////////////////////////////////
//
// Class encapsulating a single ipc console
//
class CIpcConsoleImpl : public CValveIpcServerUtl
{
public:
explicit CIpcConsoleImpl( char const *szName );
virtual BOOL ExecuteCommand( CUtlBuffer &cmd, CUtlBuffer &res );
};
CIpcConsoleImpl::CIpcConsoleImpl( char const *szName ) :
CValveIpcServerUtl( szName )
{
}
BOOL CIpcConsoleImpl::ExecuteCommand( CUtlBuffer &cmd, CUtlBuffer &res )
{
extern ConVar sv_cheats;
if ( !sv_cheats.GetBool() )
{
res.PutString( "ERROR: Engine IPC communication requires sv_cheats 1!\n" );
res.PutInt( 0 );
return TRUE;
}
// NOTE: ExecuteCommand is called on a separate thread!
engineClient->ClientCmd( ( char const * ) cmd.Base() );
res.PutInt( 0 );
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//
// Class encapsulating management of ipc consoles
//
class CIpcConsoleMgr
{
public:
bool Enable( char const *szConsoleName );
bool Disable( char const *szConsoleName );
void DisableAll();
void Show( char const *szConsoleName );
void ShowAll();
protected:
CIpcConsoleImpl *FindConsole( char const *szConsoleName );
CIpcConsoleImpl *CreateConsole( char const *szConsoleName );
bool RemoveConsole( CIpcConsoleImpl *pConsole );
protected:
CUtlStringMap< CIpcConsoleImpl * > m_mapConsoles;
};
static CIpcConsoleMgr &IpcConsoleGetMgr()
{
static CIpcConsoleMgr s_mgr;
return s_mgr;
}
static char const *IpcConsoleGetDefaultName()
{
return "ENGINE_IPC_SERVER";
}
bool CIpcConsoleMgr::Enable( char const *szConsoleName )
{
CIpcConsoleImpl *pConsole = FindConsole( szConsoleName );
if ( !pConsole )
pConsole = CreateConsole( szConsoleName );
if ( pConsole->EnsureRegisteredAndRunning() )
{
Msg( "IPC: enabled console \"%s\"\n", szConsoleName );
return true;
}
RemoveConsole( pConsole );
Error( "IPC: Failed to enable console \"%s\"\n", szConsoleName );
return false;
}
bool CIpcConsoleMgr::Disable( const char *szConsoleName )
{
CIpcConsoleImpl *pConsole = FindConsole( szConsoleName );
if ( !pConsole )
{
Msg( "IPC: disabling unknown console \"%s\"\n", szConsoleName );
return false;
}
pConsole->EnsureStoppedAndUnregistered();
RemoveConsole( pConsole );
Msg( "IPC: disabled console \"%s\"\n", szConsoleName );
return true;
}
void CIpcConsoleMgr::DisableAll()
{
int numActiveConsoles = 0;
for ( int idx = 0; idx < m_mapConsoles.GetNumStrings(); ++ idx )
{
char const *szConsoleName = m_mapConsoles.String( idx );
CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
if ( !pConsole )
continue;
pConsole->EnsureStoppedAndUnregistered();
delete pConsole;
pConsole = NULL;
Msg( "IPC: disabled console \"%s\"\n", szConsoleName );
++ numActiveConsoles;
}
Msg( "IPC: disabled %d console(s).\n", numActiveConsoles );
}
void CIpcConsoleMgr::Show( const char *szConsoleName )
{
CIpcConsoleImpl *pConsole = FindConsole( szConsoleName );
if ( pConsole )
{
Msg( "IPC: Active console \"%s\"\n", szConsoleName );
}
else
{
Msg( "IPC: Unknown console \"%s\"\n", szConsoleName );
}
}
void CIpcConsoleMgr::ShowAll()
{
int numActiveConsoles = 0;
for ( int idx = 0; idx < m_mapConsoles.GetNumStrings(); ++ idx )
{
char const *szConsoleName = m_mapConsoles.String( idx );
CIpcConsoleImpl *pConsole = m_mapConsoles[ szConsoleName ];
if ( !pConsole )
continue;
Msg( "IPC: Active console \"%s\"\n", szConsoleName );
++ numActiveConsoles;
}
Msg( "IPC: %d active console(s).\n", numActiveConsoles );
}
CIpcConsoleImpl * CIpcConsoleMgr::FindConsole( char const *szConsoleName )
{
if ( m_mapConsoles.Find( szConsoleName ) == m_mapConsoles.InvalidIndex() )
return NULL;
CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
return pConsole;
}
CIpcConsoleImpl * CIpcConsoleMgr::CreateConsole( char const *szConsoleName )
{
CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
pConsole = new CIpcConsoleImpl( szConsoleName );
return pConsole;
}
bool CIpcConsoleMgr::RemoveConsole( CIpcConsoleImpl *pConsoleRemove )
{
if ( !pConsoleRemove )
return false;
for ( int idx = 0; idx < m_mapConsoles.GetNumStrings(); ++ idx )
{
char const *szConsoleName = m_mapConsoles.String( idx );
CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
if ( pConsole != pConsoleRemove )
continue;
delete pConsole;
pConsole = NULL;
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
//
// Console commands to enable, disable and show ipc console names
//
CON_COMMAND_F( ipc_console_enable, "Enable IPC console", FCVAR_CHEAT | FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
{
char const *szConsoleName = IpcConsoleGetDefaultName();
if ( args.ArgC() <= 1 )
{
IpcConsoleGetMgr().Enable( szConsoleName );
return;
}
else for ( int k = 1; k < args.ArgC(); ++ k )
{
szConsoleName = args.Arg( k );
if ( IpcConsoleGetMgr().Enable( szConsoleName ) )
return;
}
}
CON_COMMAND_F( ipc_console_disable, "Disable IPC console(s)", FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
{
char const *szConsoleName = IpcConsoleGetDefaultName();
if ( args.ArgC() <= 1 )
{
IpcConsoleGetMgr().Disable( szConsoleName );
return;
}
else for ( int k = 1; k < args.ArgC(); ++ k )
{
szConsoleName = args.Arg( k );
IpcConsoleGetMgr().Disable( szConsoleName );
}
}
CON_COMMAND_F( ipc_console_disable_all, "Disable all IPC consoles", FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
{
IpcConsoleGetMgr().DisableAll();
}
CON_COMMAND_F( ipc_console_show, "Show status of IPC consoles", FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
{
if ( args.ArgC() <= 1 )
{
IpcConsoleGetMgr().ShowAll();
return;
}
else for ( int k = 1; k < args.ArgC(); ++ k )
{
char const *szConsoleName = args.Arg( k );
IpcConsoleGetMgr().Show( szConsoleName );
}
}