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.

294 lines
7.0 KiB

  1. //====== Copyright c 1996-2008, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose: Exposing command console for scripting
  4. //
  5. //
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include "valve_ipc_win32.h"
  9. #include "tier0/dbg.h"
  10. #include "tier0/platform.h"
  11. #include "mathlib/mathlib.h"
  12. #include "tier1/convar.h"
  13. #include "UtlStringMap.h"
  14. #include "con_nprint.h"
  15. #include "cdll_int.h"
  16. #include "globalvars_base.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. extern IVEngineClient *engineClient;
  20. extern CGlobalVarsBase *gpGlobals;
  21. //////////////////////////////////////////////////////////////////////////
  22. //
  23. // Definition of CValveIpcServerUtl
  24. //
  25. class CValveIpcServerUtl : public CValveIpcServer
  26. {
  27. public:
  28. explicit CValveIpcServerUtl( char const *szServerName ) : CValveIpcServer( szServerName ) {}
  29. virtual BOOL ExecuteCommand( char *bufCommand, DWORD numCommandBytes, char *bufResult, DWORD &numResultBytes )
  30. {
  31. CUtlBuffer cmd( bufCommand, numCommandBytes, CUtlBuffer::READ_ONLY );
  32. CUtlBuffer res( bufResult, VALVE_IPC_CS_BUFFER, int( 0 ) );
  33. if ( !ExecuteCommand( cmd, res ) )
  34. return FALSE;
  35. numResultBytes = res.TellPut();
  36. return TRUE;
  37. }
  38. virtual BOOL ExecuteCommand( CUtlBuffer &cmd, CUtlBuffer &res ) = 0;
  39. };
  40. //////////////////////////////////////////////////////////////////////////
  41. //
  42. // Class encapsulating a single ipc console
  43. //
  44. class CIpcConsoleImpl : public CValveIpcServerUtl
  45. {
  46. public:
  47. explicit CIpcConsoleImpl( char const *szName );
  48. virtual BOOL ExecuteCommand( CUtlBuffer &cmd, CUtlBuffer &res );
  49. };
  50. CIpcConsoleImpl::CIpcConsoleImpl( char const *szName ) :
  51. CValveIpcServerUtl( szName )
  52. {
  53. }
  54. BOOL CIpcConsoleImpl::ExecuteCommand( CUtlBuffer &cmd, CUtlBuffer &res )
  55. {
  56. extern ConVar sv_cheats;
  57. if ( !sv_cheats.GetBool() )
  58. {
  59. res.PutString( "ERROR: Engine IPC communication requires sv_cheats 1!\n" );
  60. res.PutInt( 0 );
  61. return TRUE;
  62. }
  63. // NOTE: ExecuteCommand is called on a separate thread!
  64. engineClient->ClientCmd( ( char const * ) cmd.Base() );
  65. res.PutInt( 0 );
  66. return TRUE;
  67. }
  68. //////////////////////////////////////////////////////////////////////////
  69. //
  70. // Class encapsulating management of ipc consoles
  71. //
  72. class CIpcConsoleMgr
  73. {
  74. public:
  75. bool Enable( char const *szConsoleName );
  76. bool Disable( char const *szConsoleName );
  77. void DisableAll();
  78. void Show( char const *szConsoleName );
  79. void ShowAll();
  80. protected:
  81. CIpcConsoleImpl *FindConsole( char const *szConsoleName );
  82. CIpcConsoleImpl *CreateConsole( char const *szConsoleName );
  83. bool RemoveConsole( CIpcConsoleImpl *pConsole );
  84. protected:
  85. CUtlStringMap< CIpcConsoleImpl * > m_mapConsoles;
  86. };
  87. static CIpcConsoleMgr &IpcConsoleGetMgr()
  88. {
  89. static CIpcConsoleMgr s_mgr;
  90. return s_mgr;
  91. }
  92. static char const *IpcConsoleGetDefaultName()
  93. {
  94. return "ENGINE_IPC_SERVER";
  95. }
  96. bool CIpcConsoleMgr::Enable( char const *szConsoleName )
  97. {
  98. CIpcConsoleImpl *pConsole = FindConsole( szConsoleName );
  99. if ( !pConsole )
  100. pConsole = CreateConsole( szConsoleName );
  101. if ( pConsole->EnsureRegisteredAndRunning() )
  102. {
  103. Msg( "IPC: enabled console \"%s\"\n", szConsoleName );
  104. return true;
  105. }
  106. RemoveConsole( pConsole );
  107. Error( "IPC: Failed to enable console \"%s\"\n", szConsoleName );
  108. return false;
  109. }
  110. bool CIpcConsoleMgr::Disable( const char *szConsoleName )
  111. {
  112. CIpcConsoleImpl *pConsole = FindConsole( szConsoleName );
  113. if ( !pConsole )
  114. {
  115. Msg( "IPC: disabling unknown console \"%s\"\n", szConsoleName );
  116. return false;
  117. }
  118. pConsole->EnsureStoppedAndUnregistered();
  119. RemoveConsole( pConsole );
  120. Msg( "IPC: disabled console \"%s\"\n", szConsoleName );
  121. return true;
  122. }
  123. void CIpcConsoleMgr::DisableAll()
  124. {
  125. int numActiveConsoles = 0;
  126. for ( int idx = 0; idx < m_mapConsoles.GetNumStrings(); ++ idx )
  127. {
  128. char const *szConsoleName = m_mapConsoles.String( idx );
  129. CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
  130. if ( !pConsole )
  131. continue;
  132. pConsole->EnsureStoppedAndUnregistered();
  133. delete pConsole;
  134. pConsole = NULL;
  135. Msg( "IPC: disabled console \"%s\"\n", szConsoleName );
  136. ++ numActiveConsoles;
  137. }
  138. Msg( "IPC: disabled %d console(s).\n", numActiveConsoles );
  139. }
  140. void CIpcConsoleMgr::Show( const char *szConsoleName )
  141. {
  142. CIpcConsoleImpl *pConsole = FindConsole( szConsoleName );
  143. if ( pConsole )
  144. {
  145. Msg( "IPC: Active console \"%s\"\n", szConsoleName );
  146. }
  147. else
  148. {
  149. Msg( "IPC: Unknown console \"%s\"\n", szConsoleName );
  150. }
  151. }
  152. void CIpcConsoleMgr::ShowAll()
  153. {
  154. int numActiveConsoles = 0;
  155. for ( int idx = 0; idx < m_mapConsoles.GetNumStrings(); ++ idx )
  156. {
  157. char const *szConsoleName = m_mapConsoles.String( idx );
  158. CIpcConsoleImpl *pConsole = m_mapConsoles[ szConsoleName ];
  159. if ( !pConsole )
  160. continue;
  161. Msg( "IPC: Active console \"%s\"\n", szConsoleName );
  162. ++ numActiveConsoles;
  163. }
  164. Msg( "IPC: %d active console(s).\n", numActiveConsoles );
  165. }
  166. CIpcConsoleImpl * CIpcConsoleMgr::FindConsole( char const *szConsoleName )
  167. {
  168. if ( m_mapConsoles.Find( szConsoleName ) == m_mapConsoles.InvalidIndex() )
  169. return NULL;
  170. CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
  171. return pConsole;
  172. }
  173. CIpcConsoleImpl * CIpcConsoleMgr::CreateConsole( char const *szConsoleName )
  174. {
  175. CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
  176. pConsole = new CIpcConsoleImpl( szConsoleName );
  177. return pConsole;
  178. }
  179. bool CIpcConsoleMgr::RemoveConsole( CIpcConsoleImpl *pConsoleRemove )
  180. {
  181. if ( !pConsoleRemove )
  182. return false;
  183. for ( int idx = 0; idx < m_mapConsoles.GetNumStrings(); ++ idx )
  184. {
  185. char const *szConsoleName = m_mapConsoles.String( idx );
  186. CIpcConsoleImpl *&pConsole = m_mapConsoles[ szConsoleName ];
  187. if ( pConsole != pConsoleRemove )
  188. continue;
  189. delete pConsole;
  190. pConsole = NULL;
  191. return true;
  192. }
  193. return false;
  194. }
  195. //////////////////////////////////////////////////////////////////////////
  196. //
  197. // Console commands to enable, disable and show ipc console names
  198. //
  199. CON_COMMAND_F( ipc_console_enable, "Enable IPC console", FCVAR_CHEAT | FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
  200. {
  201. char const *szConsoleName = IpcConsoleGetDefaultName();
  202. if ( args.ArgC() <= 1 )
  203. {
  204. IpcConsoleGetMgr().Enable( szConsoleName );
  205. return;
  206. }
  207. else for ( int k = 1; k < args.ArgC(); ++ k )
  208. {
  209. szConsoleName = args.Arg( k );
  210. if ( IpcConsoleGetMgr().Enable( szConsoleName ) )
  211. return;
  212. }
  213. }
  214. CON_COMMAND_F( ipc_console_disable, "Disable IPC console(s)", FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
  215. {
  216. char const *szConsoleName = IpcConsoleGetDefaultName();
  217. if ( args.ArgC() <= 1 )
  218. {
  219. IpcConsoleGetMgr().Disable( szConsoleName );
  220. return;
  221. }
  222. else for ( int k = 1; k < args.ArgC(); ++ k )
  223. {
  224. szConsoleName = args.Arg( k );
  225. IpcConsoleGetMgr().Disable( szConsoleName );
  226. }
  227. }
  228. CON_COMMAND_F( ipc_console_disable_all, "Disable all IPC consoles", FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
  229. {
  230. IpcConsoleGetMgr().DisableAll();
  231. }
  232. CON_COMMAND_F( ipc_console_show, "Show status of IPC consoles", FCVAR_CLIENTCMD_CAN_EXECUTE | FCVAR_DONTRECORD )
  233. {
  234. if ( args.ArgC() <= 1 )
  235. {
  236. IpcConsoleGetMgr().ShowAll();
  237. return;
  238. }
  239. else for ( int k = 1; k < args.ArgC(); ++ k )
  240. {
  241. char const *szConsoleName = args.Arg( k );
  242. IpcConsoleGetMgr().Show( szConsoleName );
  243. }
  244. }