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.

324 lines
6.7 KiB

  1. //========== Copyright � 2008, Valve Corporation, All rights reserved. ========
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "vscript_shared.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. IScriptVM * g_pScriptVM;
  16. extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
  17. DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_VScript, "VScript", LCF_CONSOLE_ONLY, LS_WARNING );
  18. // #define VMPROFILE 1
  19. #ifdef VMPROFILE
  20. #define VMPROF_START double debugStartTime = Plat_FloatTime();
  21. #define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 );
  22. #else // !VMPROFILE
  23. #define VMPROF_START
  24. #define VMPROF_SHOW
  25. #endif // VMPROFILE
  26. HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
  27. {
  28. if ( !g_pScriptVM )
  29. {
  30. return NULL;
  31. }
  32. static const char *pszExtensions[] =
  33. {
  34. "", // SL_NONE
  35. ".gm", // SL_GAMEMONKEY
  36. ".nut", // SL_SQUIRREL
  37. ".lua", // SL_LUA
  38. ".py", // SL_PYTHON
  39. };
  40. const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()];
  41. const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' );
  42. if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 )
  43. {
  44. Log_Warning( LOG_VScript, "Script file type does not match VM type\n" );
  45. return NULL;
  46. }
  47. CFmtStr scriptPath;
  48. if ( pszIncomingExtension )
  49. {
  50. scriptPath.sprintf( "scripts/vscripts/%s", pszScriptName );
  51. }
  52. else
  53. {
  54. scriptPath.sprintf( "scripts/vscripts/%s%s", pszScriptName, pszVMExtension );
  55. }
  56. const char *pBase;
  57. CUtlBuffer bufferScript;
  58. if ( g_pScriptVM->GetLanguage() == SL_PYTHON )
  59. {
  60. // python auto-loads raw or precompiled modules - don't load data here
  61. pBase = NULL;
  62. }
  63. else
  64. {
  65. bool bResult = filesystem->ReadFile( scriptPath, "GAME", bufferScript );
  66. if( !bResult )
  67. {
  68. Log_Warning( LOG_VScript, "Script not found (%s) \n", scriptPath.operator const char *() );
  69. Assert( "Error running script" );
  70. }
  71. pBase = (const char *) bufferScript.Base();
  72. if ( !pBase || !*pBase )
  73. {
  74. return NULL;
  75. }
  76. }
  77. const char *pszFilename = V_strrchr( scriptPath, '/' );
  78. pszFilename++;
  79. HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, pszFilename );
  80. if ( !hScript )
  81. {
  82. Log_Warning( LOG_VScript, "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() );
  83. Assert( "Error running script" );
  84. }
  85. return hScript;
  86. }
  87. static int g_ScriptServerRunScriptDepth;
  88. bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing )
  89. {
  90. if ( !g_pScriptVM )
  91. {
  92. return false;
  93. }
  94. if ( !pszScriptName || !*pszScriptName )
  95. {
  96. Log_Warning( LOG_VScript, "Cannot run script: NULL script name\n" );
  97. return false;
  98. }
  99. // Prevent infinite recursion in VM
  100. if ( g_ScriptServerRunScriptDepth > 16 )
  101. {
  102. Log_Warning( LOG_VScript, "IncludeScript stack overflow\n" );
  103. return false;
  104. }
  105. g_ScriptServerRunScriptDepth++;
  106. HSCRIPT hScript = VScriptCompileScript( pszScriptName, bWarnMissing );
  107. bool bSuccess = false;
  108. if ( hScript )
  109. {
  110. #ifdef GAME_DLL
  111. if ( gpGlobals->maxClients == 1 )
  112. {
  113. CBaseEntity *pPlayer = UTIL_GetLocalPlayer();
  114. if ( pPlayer )
  115. {
  116. g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
  117. }
  118. }
  119. #endif
  120. bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR );
  121. if ( !bSuccess )
  122. {
  123. Log_Warning( LOG_VScript, "Error running script named %s\n", pszScriptName );
  124. Assert( "Error running script" );
  125. }
  126. }
  127. g_ScriptServerRunScriptDepth--;
  128. return bSuccess;
  129. }
  130. #ifdef CLIENT_DLL
  131. CON_COMMAND( script_client, "Run the text as a script" )
  132. #else
  133. CON_COMMAND( script, "Run the text as a script" )
  134. #endif
  135. {
  136. #ifdef CLIENT_DLL
  137. if ( !engine->IsClientLocalToActiveServer() )
  138. return;
  139. #else
  140. if ( !UTIL_IsCommandIssuedByServerAdmin() )
  141. return;
  142. #endif
  143. if ( !*args[1] )
  144. {
  145. Log_Warning( LOG_VScript, "No function name specified\n" );
  146. return;
  147. }
  148. if ( !g_pScriptVM )
  149. {
  150. Log_Warning( LOG_VScript, "Scripting disabled or no server running\n" );
  151. return;
  152. }
  153. const char *pszScript = args.GetCommandString();
  154. #ifdef CLIENT_DLL
  155. pszScript += 13;
  156. #else
  157. pszScript += 6;
  158. #endif
  159. while ( *pszScript == ' ' )
  160. {
  161. pszScript++;
  162. }
  163. if ( !*pszScript )
  164. {
  165. return;
  166. }
  167. if ( *pszScript != '\"' )
  168. {
  169. g_pScriptVM->Run( pszScript );
  170. }
  171. else
  172. {
  173. pszScript++;
  174. const char *pszEndQuote = pszScript;
  175. while ( *pszEndQuote != '\"' )
  176. {
  177. pszEndQuote++;
  178. }
  179. if ( !*pszEndQuote )
  180. {
  181. return;
  182. }
  183. *((char *)pszEndQuote) = 0;
  184. g_pScriptVM->Run( pszScript );
  185. *((char *)pszEndQuote) = '\"';
  186. }
  187. }
  188. #ifdef CLIENT_DLL
  189. CON_COMMAND( script_execute_client, "Run a vscript file" )
  190. #else
  191. CON_COMMAND( script_execute, "Run a vscript file" )
  192. #endif
  193. {
  194. #ifdef CLIENT_DLL
  195. if ( !engine->IsClientLocalToActiveServer() )
  196. return;
  197. #else
  198. if ( !UTIL_IsCommandIssuedByServerAdmin() )
  199. return;
  200. #endif
  201. if ( !*args[1] )
  202. {
  203. Log_Warning( LOG_VScript, "No script specified\n" );
  204. return;
  205. }
  206. if ( !g_pScriptVM )
  207. {
  208. Log_Warning( LOG_VScript, "Scripting disabled or no server running\n" );
  209. return;
  210. }
  211. VScriptRunScript( args[1], true );
  212. }
  213. #ifdef CLIENT_DLL
  214. CON_COMMAND( script_debug_client, "Connect the vscript VM to the script debugger" )
  215. #else
  216. CON_COMMAND( script_debug, "Connect the vscript VM to the script debugger" )
  217. #endif
  218. {
  219. #ifdef CLIENT_DLL
  220. if ( !engine->IsClientLocalToActiveServer() )
  221. return;
  222. #else
  223. if ( !UTIL_IsCommandIssuedByServerAdmin() )
  224. return;
  225. #endif
  226. if ( !g_pScriptVM )
  227. {
  228. Log_Warning( LOG_VScript, "Scripting disabled or no server running\n" );
  229. return;
  230. }
  231. g_pScriptVM->ConnectDebugger();
  232. }
  233. #ifdef CLIENT_DLL
  234. CON_COMMAND( script_help_client, "Output help for script functions, optionally with a search string" )
  235. #else
  236. CON_COMMAND( script_help, "Output help for script functions, optionally with a search string" )
  237. #endif
  238. {
  239. #ifdef CLIENT_DLL
  240. if ( !engine->IsClientLocalToActiveServer() )
  241. return;
  242. #else
  243. if ( !UTIL_IsCommandIssuedByServerAdmin() )
  244. return;
  245. #endif
  246. if ( !g_pScriptVM )
  247. {
  248. Log_Warning( LOG_VScript, "Scripting disabled or no server running\n" );
  249. return;
  250. }
  251. const char *pszArg1 = "*";
  252. if ( *args[1] )
  253. {
  254. pszArg1 = args[1];
  255. }
  256. g_pScriptVM->Run( CFmtStr( "PrintHelp( \"%s\" );", pszArg1 ) );
  257. }
  258. #ifdef CLIENT_DLL
  259. CON_COMMAND( script_dump_all_client, "Dump the state of the VM to the console" )
  260. #else
  261. CON_COMMAND( script_dump_all, "Dump the state of the VM to the console" )
  262. #endif
  263. {
  264. #ifdef CLIENT_DLL
  265. if ( !engine->IsClientLocalToActiveServer() )
  266. return;
  267. #else
  268. if ( !UTIL_IsCommandIssuedByServerAdmin() )
  269. return;
  270. #endif
  271. if ( !g_pScriptVM )
  272. {
  273. Log_Warning( LOG_VScript, "Scripting disabled or no server running\n" );
  274. return;
  275. }
  276. g_pScriptVM->DumpState();
  277. }