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.

240 lines
5.8 KiB

  1. //========== Copyright (c) 2008, Valve Corporation, All rights reserved. ========
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "vscript_client.h"
  8. #include "icommandline.h"
  9. #include "tier1/utlbuffer.h"
  10. #include "tier1/fmtstr.h"
  11. #include "filesystem.h"
  12. #include "characterset.h"
  13. #include "isaverestore.h"
  14. #include "gamerules.h"
  15. #include "vscript_client_nut.h"
  16. #if defined ( PORTAL2 )
  17. #include "usermessages.h"
  18. #include "hud_macros.h"
  19. #endif
  20. extern IScriptManager *scriptmanager;
  21. extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
  22. // #define VMPROFILE 1
  23. #ifdef VMPROFILE
  24. #define VMPROF_START double debugStartTime = Plat_FloatTime();
  25. #define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 );
  26. #else // !VMPROFILE
  27. #define VMPROF_START
  28. #define VMPROF_SHOW
  29. #endif // VMPROFILE
  30. //-----------------------------------------------------------------------------
  31. //
  32. //-----------------------------------------------------------------------------
  33. static float Time()
  34. {
  35. return gpGlobals->curtime;
  36. }
  37. static const char *GetMapName()
  38. {
  39. return engine->GetLevelName();
  40. }
  41. static const char *DoUniqueString( const char *pszBase )
  42. {
  43. static char szBuf[512];
  44. g_pScriptVM->GenerateUniqueKey( pszBase, szBuf, ARRAYSIZE(szBuf) );
  45. return szBuf;
  46. }
  47. bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
  48. {
  49. if ( !VScriptRunScript( pszScript, hScope, true ) )
  50. {
  51. g_pScriptVM->RaiseException( CFmtStr( "Failed to include script \"%s\"", ( pszScript ) ? pszScript : "unknown" ) );
  52. return false;
  53. }
  54. return true;
  55. }
  56. int GetDeveloperLevel()
  57. {
  58. return developer.GetInt();
  59. }
  60. bool VScriptClientInit()
  61. {
  62. VMPROF_START
  63. if( scriptmanager != NULL )
  64. {
  65. ScriptLanguage_t scriptLanguage = SL_DEFAULT;
  66. char const *pszScriptLanguage;
  67. if ( CommandLine()->CheckParm( "-scriptlang", &pszScriptLanguage ) )
  68. {
  69. if( !Q_stricmp(pszScriptLanguage, "gamemonkey") )
  70. {
  71. scriptLanguage = SL_GAMEMONKEY;
  72. }
  73. else if( !Q_stricmp(pszScriptLanguage, "squirrel") )
  74. {
  75. scriptLanguage = SL_SQUIRREL;
  76. }
  77. else if( !Q_stricmp(pszScriptLanguage, "python") )
  78. {
  79. scriptLanguage = SL_PYTHON;
  80. }
  81. else
  82. {
  83. DevWarning("-scriptlang does not recognize a language named '%s'. virtual machine did NOT start.\n", pszScriptLanguage );
  84. scriptLanguage = SL_NONE;
  85. }
  86. }
  87. if( scriptLanguage != SL_NONE )
  88. {
  89. if ( g_pScriptVM == NULL )
  90. g_pScriptVM = scriptmanager->CreateVM( scriptLanguage );
  91. if( g_pScriptVM )
  92. {
  93. Log_Msg( LOG_VScript, "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
  94. ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map.");
  95. ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" );
  96. ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
  97. ScriptRegisterFunction( g_pScriptVM, GetDeveloperLevel, "Gets the level of 'develoer'" );
  98. if ( GameRules() )
  99. {
  100. GameRules()->RegisterScriptFunctions();
  101. }
  102. //g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
  103. if ( scriptLanguage == SL_SQUIRREL )
  104. {
  105. g_pScriptVM->Run( g_Script_vscript_client );
  106. }
  107. VScriptRunScript( "mapspawn", false );
  108. VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
  109. return true;
  110. }
  111. else
  112. {
  113. DevWarning("VM Did not start!\n");
  114. }
  115. }
  116. }
  117. else
  118. {
  119. Log_Msg( LOG_VScript, "\nVSCRIPT: Scripting is disabled.\n" );
  120. }
  121. g_pScriptVM = NULL;
  122. return false;
  123. }
  124. void VScriptClientTerm()
  125. {
  126. if( g_pScriptVM != NULL )
  127. {
  128. if( g_pScriptVM )
  129. {
  130. scriptmanager->DestroyVM( g_pScriptVM );
  131. g_pScriptVM = NULL;
  132. }
  133. }
  134. }
  135. class CVScriptGameSystem : public CAutoGameSystemPerFrame
  136. {
  137. public:
  138. // Inherited from IAutoServerSystem
  139. virtual void LevelInitPreEntity( void )
  140. {
  141. // <sergiy> Note: we may need script VM garbage collection at this point in the future. Currently, VM does not persist
  142. // across level boundaries. GC is not necessary because our scripts are supposed to never create circular references
  143. // and everything else is handled with ref counting. For the case of bugs creating circular references, the plan is to add
  144. // diagnostics that detects such loops and warns the developer.
  145. m_bAllowEntityCreationInScripts = true;
  146. VScriptClientInit();
  147. }
  148. virtual void LevelInitPostEntity( void )
  149. {
  150. m_bAllowEntityCreationInScripts = false;
  151. }
  152. virtual void LevelShutdownPostEntity( void )
  153. {
  154. VScriptClientTerm();
  155. }
  156. virtual void FrameUpdatePostEntityThink()
  157. {
  158. if ( g_pScriptVM )
  159. g_pScriptVM->Frame( gpGlobals->frametime );
  160. }
  161. bool m_bAllowEntityCreationInScripts;
  162. };
  163. CVScriptGameSystem g_VScriptGameSystem;
  164. bool IsEntityCreationAllowedInScripts( void )
  165. {
  166. return g_VScriptGameSystem.m_bAllowEntityCreationInScripts;
  167. }
  168. #if defined ( PORTAL2 )
  169. void __MsgFunc_SetMixLayerTriggerFactor( bf_read &msg )
  170. {
  171. char buf[MAX_PATH];
  172. msg.ReadString( buf, ARRAYSIZE( buf ), false );
  173. int iLayerID = engine->GetMixLayerIndex( buf );
  174. if ( iLayerID < 0 )
  175. {
  176. Warning( "Invalid mix layer passed to SetMixLayerTriggerFactor: '%s'\n", buf );
  177. return;
  178. }
  179. msg.ReadString( buf, ARRAYSIZE( buf ), false );
  180. int iGroupID = engine->GetMixGroupIndex( buf );
  181. if ( iGroupID < 0 )
  182. {
  183. Warning( "Invalid mix group passed to SetMixLayerTriggerFactor: '%s'\n", buf );
  184. return;
  185. }
  186. engine->SetMixLayerTriggerFactor( iLayerID, iGroupID, msg.ReadFloat() );
  187. }
  188. class CSetMixLayerTriggerHelper : public CAutoGameSystem
  189. {
  190. virtual bool Init()
  191. {
  192. for( int i = 0; i < MAX_SPLITSCREEN_PLAYERS; ++i )
  193. {
  194. ACTIVE_SPLITSCREEN_PLAYER_GUARD( i );
  195. HOOK_MESSAGE( SetMixLayerTriggerFactor );
  196. }
  197. return true;
  198. }
  199. };
  200. static CSetMixLayerTriggerHelper g_SetMixLayerTriggerHelper;
  201. #endif