295 lines
7.0 KiB
C++
295 lines
7.0 KiB
C++
//====== 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 );
|
|
}
|
|
}
|
|
|