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.

847 lines
22 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include "server_pch.h"
  9. #include "sv_plugin.h"
  10. #include "filesystem.h"
  11. #include "filesystem_engine.h"
  12. #include "eiface.h"
  13. #include "sys.h"
  14. #include "sys_dll.h"
  15. #include "pr_edict.h"
  16. #include "networkstringtable.h"
  17. #include "networkstringtableserver.h"
  18. #include "matchmaking/imatchframework.h"
  19. // NOTE: This has to be the last file included!
  20. #include "tier0/memdbgon.h"
  21. extern IMatchFramework *g_pMatchFramework;
  22. extern CreateInterfaceFn g_AppSystemFactory;
  23. extern CSysModule *g_GameDLL;
  24. CServerPlugin s_ServerPlugin;
  25. CServerPlugin *g_pServerPluginHandler = &s_ServerPlugin;
  26. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerPlugin, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS, s_ServerPlugin );
  27. // Ascending value so they have a unique cookie to relate queries to the responses.
  28. static int g_iQueryCvarCookie = 1;
  29. QueryCvarCookie_t SendCvarValueQueryToClient( IClient *client, const char *pCvarName, bool bPluginQuery )
  30. {
  31. // Send a message to the client asking for the value.
  32. CSVCMsg_GetCvarValue_t msg;
  33. msg.set_cookie( g_iQueryCvarCookie++ );
  34. msg.set_cvar_name( pCvarName );
  35. // If the query came from the game DLL instead of from a plugin, then we negate the cookie
  36. // so it knows who to callback on when the value arrives back from the client.
  37. if ( !bPluginQuery )
  38. msg.set_cookie( -msg.cookie() );
  39. client->SendNetMsg( msg );
  40. return msg.cookie();
  41. }
  42. //---------------------------------------------------------------------------------
  43. // Purpose: constructor/destructor
  44. //---------------------------------------------------------------------------------
  45. CPlugin::CPlugin()
  46. {
  47. m_pPlugin = NULL;
  48. m_pPluginModule = NULL;
  49. m_bDisable = false;
  50. m_szName[0] = 0;
  51. }
  52. CPlugin::~CPlugin()
  53. {
  54. if ( m_pPlugin )
  55. {
  56. Unload();
  57. }
  58. m_pPlugin = NULL;
  59. if ( m_pPluginModule )
  60. {
  61. g_pFileSystem->UnloadModule( m_pPluginModule );
  62. }
  63. m_pPluginModule = NULL;
  64. }
  65. //---------------------------------------------------------------------------------
  66. // Purpose: loads and initializes a plugin
  67. //---------------------------------------------------------------------------------
  68. bool CPlugin::Load( const char *fileName )
  69. {
  70. if ( IsX360() )
  71. {
  72. return false;
  73. }
  74. char fixedFileName[ MAX_PATH ];
  75. Q_strncpy( fixedFileName, fileName, sizeof(fixedFileName) );
  76. Q_FixSlashes( fixedFileName );
  77. #if defined ( OSX ) || defined( LINUX )
  78. // Linux doesn't check signatures, so in that case disable plugins on the client completely unless -insecure is specified
  79. if ( !sv.IsDedicated() && Host_IsSecureServerAllowed() )
  80. return false;
  81. #else
  82. if ( !sv.IsDedicated() && Host_IsSecureServerAllowed() )
  83. {
  84. if ( CommandLine()->FindParm( "-LoadPluginsForClient" ) )
  85. Host_DisallowSecureServers();
  86. else
  87. return false;
  88. }
  89. #endif
  90. // Only allow unsigned plugins in -insecure mode
  91. if ( !Host_AllowLoadModule( fixedFileName, "GAME", false ) )
  92. return false;
  93. m_pPluginModule = g_pFileSystem->LoadModule( fixedFileName, "GAME", false );
  94. if ( m_pPluginModule )
  95. {
  96. CreateInterfaceFn pluginFactory = Sys_GetFactory( m_pPluginModule );
  97. if ( pluginFactory )
  98. {
  99. m_iPluginInterfaceVersion = 4;
  100. m_pPlugin = ( IServerPluginCallbacks * ) pluginFactory( INTERFACEVERSION_ISERVERPLUGINCALLBACKS, NULL );
  101. if ( !m_pPlugin )
  102. {
  103. m_iPluginInterfaceVersion = 3;
  104. m_pPlugin = ( IServerPluginCallbacks * ) pluginFactory( INTERFACEVERSION_ISERVERPLUGINCALLBACKS_VERSION_3, NULL );
  105. if ( !m_pPlugin )
  106. {
  107. m_iPluginInterfaceVersion = 2;
  108. m_pPlugin = ( IServerPluginCallbacks * ) pluginFactory( INTERFACEVERSION_ISERVERPLUGINCALLBACKS_VERSION_2, NULL );
  109. if ( !m_pPlugin )
  110. {
  111. m_iPluginInterfaceVersion = 1;
  112. m_pPlugin = ( IServerPluginCallbacks * ) pluginFactory( INTERFACEVERSION_ISERVERPLUGINCALLBACKS_VERSION_1, NULL );
  113. if ( !m_pPlugin )
  114. {
  115. Warning( "Could not get IServerPluginCallbacks interface from plugin \"%s\"", fileName );
  116. return false;
  117. }
  118. }
  119. }
  120. }
  121. CreateInterfaceFn gameServerFactory = Sys_GetFactory( g_GameDLL );
  122. if ( !m_pPlugin->Load( g_AppSystemFactory, gameServerFactory ) )
  123. {
  124. Warning( "Failed to load plugin \"%s\"\n", fileName );
  125. return false;
  126. }
  127. SetName( m_pPlugin->GetPluginDescription() );
  128. }
  129. }
  130. else
  131. {
  132. Warning( "Unable to load plugin \"%s\"\n", fileName );
  133. return false;
  134. }
  135. return true;
  136. }
  137. //---------------------------------------------------------------------------------
  138. // Purpose: unloads and cleans up a module
  139. //---------------------------------------------------------------------------------
  140. void CPlugin::Unload()
  141. {
  142. if ( m_pPlugin )
  143. {
  144. m_pPlugin->Unload();
  145. }
  146. m_pPlugin = NULL;
  147. g_pFileSystem->UnloadModule( m_pPluginModule );
  148. m_pPluginModule = NULL;
  149. }
  150. //---------------------------------------------------------------------------------
  151. // Purpose: sets the name of the plugin
  152. //---------------------------------------------------------------------------------
  153. void CPlugin::SetName( const char *name )
  154. {
  155. Q_strncpy( m_szName, name, sizeof(m_szName) );
  156. }
  157. //---------------------------------------------------------------------------------
  158. // Purpose: returns the name of the plugin
  159. //---------------------------------------------------------------------------------
  160. const char *CPlugin::GetName()
  161. {
  162. return m_szName;
  163. }
  164. //---------------------------------------------------------------------------------
  165. // Purpose: returns the callback interface of a module
  166. //---------------------------------------------------------------------------------
  167. IServerPluginCallbacks *CPlugin::GetCallback()
  168. {
  169. Assert( m_pPlugin );
  170. if ( m_pPlugin )
  171. {
  172. return m_pPlugin;
  173. }
  174. else
  175. {
  176. Assert( !"Unable to get plugin callback interface" );
  177. Warning( "Unable to get callback interface for \"%s\"\n", GetName() );
  178. return NULL;
  179. }
  180. }
  181. //---------------------------------------------------------------------------------
  182. // Purpose: enables or disabled a plugin (i.e stops it running)
  183. //---------------------------------------------------------------------------------
  184. void CPlugin::Disable( bool state )
  185. {
  186. Assert( m_pPlugin );
  187. if ( state )
  188. {
  189. m_pPlugin->Pause();
  190. }
  191. else
  192. {
  193. m_pPlugin->UnPause();
  194. }
  195. m_bDisable = state;
  196. }
  197. //---------------------------------------------------------------------------------
  198. // Purpose: constructor/destructor
  199. //---------------------------------------------------------------------------------
  200. CServerPlugin::CServerPlugin()
  201. {
  202. m_PluginHelperCheck = NULL;
  203. }
  204. CServerPlugin::~CServerPlugin()
  205. {
  206. }
  207. //---------------------------------------------------------------------------------
  208. // Purpose: loads all plugins
  209. //---------------------------------------------------------------------------------
  210. void CServerPlugin::LoadPlugins()
  211. {
  212. if ( IsX360() )
  213. {
  214. return;
  215. }
  216. m_Plugins.PurgeAndDeleteElements();
  217. char const *findfn = Sys_FindFirst( "addons/*.vdf", NULL, 0 );
  218. while ( findfn )
  219. {
  220. DevMsg( "Plugins: found file \"%s\"\n", findfn );
  221. if ( !g_pFileSystem->FileExists( va("addons/%s", findfn), "MOD" ) ) // verify its in the mods directory
  222. {
  223. findfn = Sys_FindNext( NULL, 0 );
  224. continue;
  225. }
  226. KeyValues *pluginsFile = new KeyValues("Plugins");
  227. pluginsFile->LoadFromFile( g_pFileSystem, va("addons/%s", findfn), "MOD" );
  228. if ( pluginsFile->GetString("file", NULL) )
  229. {
  230. LoadPlugin(pluginsFile->GetString("file"));
  231. }
  232. pluginsFile->deleteThis();
  233. // move to next item
  234. findfn = Sys_FindNext( NULL, 0 );
  235. }
  236. Sys_FindClose();
  237. CreateInterfaceFn gameServerFactory = Sys_GetFactory( g_GameDLL );
  238. m_PluginHelperCheck = (IPluginHelpersCheck *)gameServerFactory( INTERFACEVERSION_PLUGINHELPERSCHECK, NULL );
  239. }
  240. //---------------------------------------------------------------------------------
  241. // Purpose: unloads all plugins
  242. //---------------------------------------------------------------------------------
  243. void CServerPlugin::UnloadPlugins()
  244. {
  245. for ( int i = m_Plugins.Count() - 1; i >= 0; --i )
  246. {
  247. m_Plugins[i]->Unload();
  248. m_Plugins.Remove(i);
  249. }
  250. }
  251. //---------------------------------------------------------------------------------
  252. // Purpose: unload a single plugin
  253. //---------------------------------------------------------------------------------
  254. bool CServerPlugin::UnloadPlugin( int index )
  255. {
  256. if ( m_Plugins.IsValidIndex( index ) )
  257. {
  258. m_Plugins[index]->Unload();
  259. m_Plugins.Remove(index);
  260. return true;
  261. }
  262. return false;
  263. }
  264. //---------------------------------------------------------------------------------
  265. // Purpose: loads a particular dll
  266. //---------------------------------------------------------------------------------
  267. bool CServerPlugin::LoadPlugin( const char *fileName )
  268. {
  269. CPlugin *plugin = new CPlugin();
  270. if ( plugin->Load( fileName ) )
  271. {
  272. m_Plugins.AddToTail( plugin );
  273. return true;
  274. }
  275. else
  276. {
  277. delete plugin;
  278. return false;
  279. }
  280. }
  281. //---------------------------------------------------------------------------------
  282. // Purpose: stop all plugins from running
  283. //---------------------------------------------------------------------------------
  284. void CServerPlugin::DisablePlugins()
  285. {
  286. for ( int i = 0; i < m_Plugins.Count(); i++ )
  287. {
  288. m_Plugins[i]->Disable(true);
  289. }
  290. }
  291. //---------------------------------------------------------------------------------
  292. // Purpose: turns all plugins back on
  293. //---------------------------------------------------------------------------------
  294. void CServerPlugin::EnablePlugins()
  295. {
  296. for ( int i = 0; i < m_Plugins.Count(); i++ )
  297. {
  298. m_Plugins[i]->Disable(false);
  299. }
  300. }
  301. //---------------------------------------------------------------------------------
  302. // Purpose: stops a single plugin
  303. //---------------------------------------------------------------------------------
  304. void CServerPlugin::DisablePlugin( int index )
  305. {
  306. if ( m_Plugins.IsValidIndex( index ) )
  307. {
  308. m_Plugins[index]->Disable(true);
  309. }
  310. }
  311. //---------------------------------------------------------------------------------
  312. // Purpose: stops a single plugin
  313. //---------------------------------------------------------------------------------
  314. void CServerPlugin::EnablePlugin( int index )
  315. {
  316. if ( m_Plugins.IsValidIndex( index ) )
  317. {
  318. m_Plugins[index]->Disable(false);
  319. }
  320. }
  321. //---------------------------------------------------------------------------------
  322. // Purpose: prints info about loaded plugins and their state
  323. //---------------------------------------------------------------------------------
  324. void CServerPlugin::PrintDetails()
  325. {
  326. ConMsg( "Loaded plugins:\n");
  327. ConMsg( "---------------------\n" );
  328. for ( int i = 0; i < m_Plugins.Count(); i++ )
  329. {
  330. ConMsg( "%i:\t\"%s\"%s\n", i, m_Plugins[i]->GetName(), m_Plugins[i]->IsDisabled() ? " (disabled)": "" );
  331. }
  332. ConMsg( "---------------------\n" );
  333. }
  334. // helper macro to stop this being typed for every passthrough
  335. #define FORALL_PLUGINS for( int i = 0; i < m_Plugins.Count(); i++ )
  336. extern CNetworkStringTableContainer *networkStringTableContainerServer;
  337. //---------------------------------------------------------------------------------
  338. // Purpose: pass through functions for the 3rd party API
  339. //---------------------------------------------------------------------------------
  340. void CServerPlugin::LevelInit( char const *pMapName,
  341. char const *pMapEntities, char const *pOldLevel,
  342. char const *pLandmarkName, bool loadGame, bool background )
  343. {
  344. MDLCACHE_COARSE_LOCK_(g_pMDLCache);
  345. FORALL_PLUGINS
  346. {
  347. if ( ! m_Plugins[i]->IsDisabled() )
  348. {
  349. m_Plugins[i]->GetCallback()->LevelInit( pMapName );
  350. }
  351. }
  352. bool bPrevState = networkStringTableContainerServer->Lock( false );
  353. serverGameDLL->LevelInit( pMapName, pMapEntities, pOldLevel, pLandmarkName, loadGame, background );
  354. networkStringTableContainerServer->Lock( bPrevState );
  355. }
  356. void CServerPlugin::ServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
  357. {
  358. MDLCACHE_COARSE_LOCK_(g_pMDLCache);
  359. FORALL_PLUGINS
  360. {
  361. if ( ! m_Plugins[i]->IsDisabled() )
  362. {
  363. m_Plugins[i]->GetCallback()->ServerActivate( pEdictList, edictCount, clientMax );
  364. }
  365. }
  366. serverGameDLL->ServerActivate( pEdictList, edictCount, clientMax );
  367. }
  368. void CServerPlugin::GameFrame( bool simulating )
  369. {
  370. FORALL_PLUGINS
  371. {
  372. if ( ! m_Plugins[i]->IsDisabled() )
  373. {
  374. m_Plugins[i]->GetCallback()->GameFrame( simulating );
  375. }
  376. }
  377. serverGameDLL->GameFrame( simulating );
  378. }
  379. void CServerPlugin::LevelShutdown( void )
  380. {
  381. MDLCACHE_COARSE_LOCK_(g_pMDLCache);
  382. FORALL_PLUGINS
  383. {
  384. if ( ! m_Plugins[i]->IsDisabled() )
  385. {
  386. m_Plugins[i]->GetCallback()->LevelShutdown();
  387. }
  388. }
  389. serverGameDLL->LevelShutdown();
  390. }
  391. void CServerPlugin::ClientActive( edict_t *pEntity, bool bLoadGame )
  392. {
  393. FORALL_PLUGINS
  394. {
  395. if ( ! m_Plugins[i]->IsDisabled() )
  396. {
  397. m_Plugins[i]->GetCallback()->ClientActive( pEntity );
  398. }
  399. }
  400. serverGameClients->ClientActive( pEntity, bLoadGame );
  401. }
  402. void CServerPlugin::ClientFullyConnect( edict_t *pEntity )
  403. {
  404. FORALL_PLUGINS
  405. {
  406. if ( ! m_Plugins[i]->IsDisabled() )
  407. {
  408. m_Plugins[i]->GetCallback()->ClientFullyConnect( pEntity );
  409. }
  410. }
  411. serverGameClients->ClientFullyConnect( pEntity );
  412. }
  413. void CServerPlugin::ClientDisconnect( edict_t *pEntity )
  414. {
  415. FORALL_PLUGINS
  416. {
  417. if ( ! m_Plugins[i]->IsDisabled() )
  418. {
  419. m_Plugins[i]->GetCallback()->ClientDisconnect( pEntity );
  420. }
  421. }
  422. serverGameClients->ClientDisconnect( pEntity );
  423. }
  424. void CServerPlugin::ClientPutInServer( edict_t *pEntity, char const *playername )
  425. {
  426. FORALL_PLUGINS
  427. {
  428. if ( ! m_Plugins[i]->IsDisabled() )
  429. {
  430. m_Plugins[i]->GetCallback()->ClientPutInServer( pEntity, playername );
  431. }
  432. }
  433. serverGameClients->ClientPutInServer( pEntity, playername );
  434. }
  435. void CServerPlugin::SetCommandClient( int index )
  436. {
  437. FORALL_PLUGINS
  438. {
  439. if ( ! m_Plugins[i]->IsDisabled() )
  440. {
  441. m_Plugins[i]->GetCallback()->SetCommandClient( index );
  442. }
  443. }
  444. serverGameClients->SetCommandClient( index );
  445. }
  446. void CServerPlugin::ClientSettingsChanged( edict_t *pEdict )
  447. {
  448. FORALL_PLUGINS
  449. {
  450. if ( ! m_Plugins[i]->IsDisabled() )
  451. {
  452. m_Plugins[i]->GetCallback()->ClientSettingsChanged( pEdict );
  453. }
  454. }
  455. serverGameClients->ClientSettingsChanged( pEdict );
  456. }
  457. bool CServerPlugin::ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen )
  458. {
  459. PLUGIN_RESULT result = PLUGIN_CONTINUE;
  460. bool bAllowConnect = true, bSavedRetVal = true, bRetValOverridden = false;
  461. FORALL_PLUGINS
  462. {
  463. if ( ! m_Plugins[i]->IsDisabled() )
  464. {
  465. result = m_Plugins[i]->GetCallback()->ClientConnect( &bAllowConnect, pEntity, pszName, pszAddress, reject, maxrejectlen );
  466. if ( result == PLUGIN_STOP ) // stop executing right away
  467. {
  468. Assert( bAllowConnect == false );
  469. return bAllowConnect;
  470. }
  471. else if ( result == PLUGIN_OVERRIDE && bRetValOverridden == false ) // only the first PLUGIN_OVERRIDE return set the retval
  472. {
  473. bSavedRetVal = bAllowConnect;
  474. bRetValOverridden = true;
  475. }
  476. }
  477. }
  478. bAllowConnect = serverGameClients->ClientConnect( pEntity, pszName, pszAddress, reject, maxrejectlen );
  479. return bRetValOverridden ? bSavedRetVal : bAllowConnect;
  480. }
  481. void CServerPlugin::ClientCommand( edict_t *pEntity, const CCommand &args )
  482. {
  483. PLUGIN_RESULT result = PLUGIN_CONTINUE;
  484. FORALL_PLUGINS
  485. {
  486. if ( !m_Plugins[i]->IsDisabled() )
  487. {
  488. result = m_Plugins[i]->GetCallback()->ClientCommand( pEntity, args );
  489. if ( result == PLUGIN_STOP ) // stop executing right away
  490. return;
  491. }
  492. }
  493. serverGameClients->ClientCommand( pEntity, args );
  494. }
  495. QueryCvarCookie_t CServerPlugin::StartQueryCvarValue( edict_t *pEntity, const char *pCvarName )
  496. {
  497. // Figure out which client they're talking about.
  498. int clientnum = NUM_FOR_EDICT( pEntity );
  499. if (clientnum < 1 || clientnum > sv.GetClientCount() )
  500. {
  501. Warning( "StartQueryCvarValue: Invalid entity\n" );
  502. return InvalidQueryCvarCookie;
  503. }
  504. IClient *client = sv.Client( clientnum-1 );
  505. return SendCvarValueQueryToClient( client, pCvarName, true );
  506. }
  507. void CServerPlugin::NetworkIDValidated( const char *pszUserName, const char *pszNetworkID )
  508. {
  509. PLUGIN_RESULT result = PLUGIN_CONTINUE;
  510. FORALL_PLUGINS
  511. {
  512. if ( ! m_Plugins[i]->IsDisabled() )
  513. {
  514. result = m_Plugins[i]->GetCallback()->NetworkIDValidated( pszUserName, pszNetworkID );
  515. if ( result == PLUGIN_STOP ) // stop executing right away
  516. {
  517. return;
  518. }
  519. }
  520. }
  521. }
  522. void CServerPlugin::OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue )
  523. {
  524. FORALL_PLUGINS
  525. {
  526. CPlugin *p = m_Plugins[i];
  527. if ( !p->IsDisabled() )
  528. {
  529. // OnQueryCvarValueFinished was added in version 2 of this interface.
  530. if ( p->GetPluginInterfaceVersion() >= 2 )
  531. {
  532. p->GetCallback()->OnQueryCvarValueFinished( iCookie, pPlayerEntity, eStatus, pCvarName, pCvarValue );
  533. }
  534. }
  535. }
  536. }
  537. void CServerPlugin::OnEdictAllocated( edict_t *edict )
  538. {
  539. FORALL_PLUGINS
  540. {
  541. CPlugin *p = m_Plugins[i];
  542. if ( !p->IsDisabled() )
  543. {
  544. // OnEdictAllocated was added in version 3 of this interface.
  545. if ( p->GetPluginInterfaceVersion() >= 3 )
  546. {
  547. p->GetCallback()->OnEdictAllocated( edict );
  548. }
  549. }
  550. }
  551. }
  552. void CServerPlugin::OnEdictFreed( const edict_t *edict )
  553. {
  554. FORALL_PLUGINS
  555. {
  556. CPlugin *p = m_Plugins[i];
  557. if ( !p->IsDisabled() )
  558. {
  559. // OnEdictFreed was added in version 3 of this interface.
  560. if ( p->GetPluginInterfaceVersion() >= 3 )
  561. {
  562. p->GetCallback()->OnEdictFreed( edict );
  563. }
  564. }
  565. }
  566. }
  567. bool CServerPlugin::BNetworkCryptKeyCheckRequired( uint32 unFromIP, uint16 usFromPort, uint32 unAccountIdProvidedByClient,
  568. bool bClientWantsToUseCryptKey )
  569. {
  570. FORALL_PLUGINS
  571. {
  572. CPlugin *p = m_Plugins[ i ];
  573. if ( !p->IsDisabled() )
  574. {
  575. // BNetworkCryptKeyCheckRequired was added in version 4 of this interface.
  576. if ( p->GetPluginInterfaceVersion() >= 4 )
  577. {
  578. if ( p->GetCallback()->BNetworkCryptKeyCheckRequired( unFromIP, usFromPort, unAccountIdProvidedByClient,
  579. bClientWantsToUseCryptKey ) )
  580. return true;
  581. }
  582. }
  583. }
  584. // Default implementation will require a certificate only if client insists on using one
  585. return bClientWantsToUseCryptKey;
  586. }
  587. bool CServerPlugin::BNetworkCryptKeyValidate( uint32 unFromIP, uint16 usFromPort, uint32 unAccountIdProvidedByClient,
  588. int nEncryptionKeyIndexFromClient, int numEncryptedBytesFromClient, byte *pbEncryptedBufferFromClient,
  589. byte *pbPlainTextKeyForNetchan )
  590. {
  591. FORALL_PLUGINS
  592. {
  593. CPlugin *p = m_Plugins[ i ];
  594. if ( !p->IsDisabled() )
  595. {
  596. // BNetworkCryptKeyValidate was added in version 4 of this interface.
  597. if ( p->GetPluginInterfaceVersion() >= 4 )
  598. {
  599. if ( p->GetCallback()->BNetworkCryptKeyValidate( unFromIP, usFromPort, unAccountIdProvidedByClient,
  600. nEncryptionKeyIndexFromClient, numEncryptedBytesFromClient, pbEncryptedBufferFromClient,
  601. pbPlainTextKeyForNetchan ) )
  602. return true;
  603. }
  604. }
  605. }
  606. //
  607. // Example plugin implementation:
  608. //
  609. // byte arrPlainTextClientEncryptionKey[ 16 ] = {
  610. // 0x01, 0x02, 0x03, 0x04, 0x15, 0x16, 0x17, 0x00,
  611. // 0x10, 0x20, 0x30, 0x40, 0xA8, 0xB8, 0xC8, 0x00
  612. // };
  613. // V_memcpy( pbPlainTextKeyForNetchan, arrPlainTextClientEncryptionKey, 16 );
  614. // return true;
  615. return false;
  616. }
  617. //---------------------------------------------------------------------------------
  618. // Purpose: creates a VGUI menu on a clients screen
  619. //---------------------------------------------------------------------------------
  620. void CServerPlugin::CreateMessage( edict_t *pEntity, DIALOG_TYPE type, KeyValues *data, IServerPluginCallbacks *plugin )
  621. {
  622. if ( !pEntity )
  623. {
  624. ConMsg( "Invaid pEntity\n" );
  625. return;
  626. }
  627. if ( !data )
  628. {
  629. ConMsg( "No data keyvalues provided\n" );
  630. return;
  631. }
  632. if ( !plugin )
  633. {
  634. ConMsg( "No plugin provided\n" );
  635. return;
  636. }
  637. if ( m_PluginHelperCheck && !m_PluginHelperCheck->CreateMessage( plugin->GetPluginDescription(), pEntity, type, data ) )
  638. {
  639. ConMsg( "Disallowed by game dll\n" );
  640. return;
  641. }
  642. int clientnum = NUM_FOR_EDICT( pEntity );
  643. if (clientnum < 1 || clientnum > sv.GetClientCount() )
  644. {
  645. ConMsg( "Invalid entity\n" );
  646. return;
  647. }
  648. IClient *client = sv.Client(clientnum-1);
  649. CUtlBuffer buf;
  650. CSVCMsg_Menu_t menu;
  651. data->WriteAsBinary( buf );
  652. menu.set_dialog_type( type );
  653. menu.set_menu_key_values( buf.Base(), buf.TellPut() );
  654. client->SendNetMsg( menu );
  655. }
  656. void CServerPlugin::ClientCommand( edict_t *pEntity, const char *cmd )
  657. {
  658. int entnum = NUM_FOR_EDICT( pEntity );
  659. if ( ( entnum < 1 ) || ( entnum > sv.GetClientCount() ) )
  660. {
  661. Msg("\n!!!\nCServerPlugin::ClientCommand: Some entity tried to stuff '%s' to console buffer of entity %i when maxclients was set to %i, ignoring\n\n",
  662. cmd, entnum, sv.GetMaxClients() );
  663. return;
  664. }
  665. sv.GetClient(entnum-1)->ExecuteStringCommand( cmd );
  666. }
  667. //---------------------------------------------------------------------------------
  668. //
  669. //
  670. // Purpose: client commands for plugin functions
  671. //
  672. //
  673. //---------------------------------------------------------------------------------
  674. CON_COMMAND( plugin_print, "Prints details about loaded plugins" )
  675. {
  676. g_pServerPluginHandler->PrintDetails();
  677. }
  678. CON_COMMAND( plugin_pause, "plugin_pause <index> : pauses a loaded plugin" )
  679. {
  680. if ( args.ArgC() < 2 )
  681. {
  682. Warning( "Syntax: plugin_pause <index>\n" );
  683. }
  684. else
  685. {
  686. g_pServerPluginHandler->DisablePlugin( atoi(args[2]) );
  687. ConMsg( "Plugin disabled\n" );
  688. }
  689. }
  690. CON_COMMAND( plugin_unpause, "plugin_unpause <index> : unpauses a disabled plugin" )
  691. {
  692. if ( args.ArgC() < 2 )
  693. {
  694. Warning( "Syntax: plugin_unpause <index>\n" );
  695. }
  696. else
  697. {
  698. g_pServerPluginHandler->EnablePlugin( atoi(args[2]) );
  699. ConMsg( "Plugin enabled\n" );
  700. }
  701. }
  702. CON_COMMAND( plugin_pause_all, "pauses all loaded plugins" )
  703. {
  704. g_pServerPluginHandler->DisablePlugins();
  705. ConMsg( "Plugins disabled\n" );
  706. }
  707. CON_COMMAND( plugin_unpause_all, "unpauses all disabled plugins" )
  708. {
  709. g_pServerPluginHandler->EnablePlugins();
  710. ConMsg( "Plugins enabled\n" );
  711. }
  712. CON_COMMAND( plugin_load, "plugin_load <filename> : loads a plugin" )
  713. {
  714. if ( args.ArgC() < 2 )
  715. {
  716. Warning( "plugin_load <filename>\n" );
  717. }
  718. else
  719. {
  720. if ( !g_pServerPluginHandler->LoadPlugin( args[1] ) )
  721. {
  722. Warning( "Unable to load plugin \"%s\"\n", args[1] );
  723. return;
  724. }
  725. ConMsg( "Loaded plugin \"%s\"\n", args[1] );
  726. }
  727. }
  728. CON_COMMAND( plugin_unload, "plugin_unload <index> : unloads a plugin" )
  729. {
  730. if ( args.ArgC() < 2 )
  731. {
  732. Warning( "plugin_unload <index>\n" );
  733. }
  734. else
  735. {
  736. if ( !g_pServerPluginHandler->UnloadPlugin( atoi(args[1]) ) )
  737. {
  738. Warning( "Unable to unload plugin \"%s\", not found\n", args[1] );
  739. return;
  740. }
  741. ConMsg( "Unloaded plugin \"%s\"\n", args[1] );
  742. }
  743. }