Added support for "mapspawn_addon" scripts in addon paths (inspired by L4D2)

This commit is contained in:
Blixibon 2022-08-28 13:10:23 -05:00
parent 1426eccc68
commit daf55037fe
4 changed files with 192 additions and 9 deletions

View File

@ -707,6 +707,10 @@ bool VScriptClientInit()
VScriptRunScript( "vscript_client", true );
VScriptRunScript( "mapspawn", false );
#ifdef MAPBASE_VSCRIPT
RunAddonScripts();
#endif
VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
return true;

View File

@ -672,6 +672,8 @@ bool VScriptServerInit()
VScriptRunScript( "mapspawn", false );
#ifdef MAPBASE_VSCRIPT
RunAddonScripts();
// Since the world entity spawns before VScript is initted, RunVScripts() is called before the VM has started, so no scripts are run.
// This gets around that by calling the same function right after the VM is initted.
GetWorldEntity()->RunVScripts();

View File

@ -40,15 +40,6 @@ extern int vscript_token;
int vscript_token_hack = vscript_token;
#endif
HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
{
if ( !g_pScriptVM )
{
return NULL;
}
static const char *pszExtensions[] =
{
"", // SL_NONE
@ -58,6 +49,15 @@ HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
".py", // SL_PYTHON
};
HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
{
if ( !g_pScriptVM )
{
return NULL;
}
const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()];
const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' );
if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 )
@ -171,6 +171,113 @@ bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMiss
}
#ifdef MAPBASE_VSCRIPT
//
// These functions are currently only used for "mapspawn_addon" scripts.
//
HSCRIPT VScriptCompileScriptAbsolute( const char *pszScriptName, bool bWarnMissing, const char *pszRootFolderName )
{
if ( !g_pScriptVM )
{
return NULL;
}
const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()];
const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' );
if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 )
{
CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type does not match VM type\n" );
return NULL;
}
CFmtStr scriptPath;
if ( pszIncomingExtension )
{
scriptPath = pszScriptName;
}
else
{
scriptPath.sprintf( "%s%s", pszScriptName, pszVMExtension );
}
const char *pBase;
CUtlBuffer bufferScript;
if ( g_pScriptVM->GetLanguage() == SL_PYTHON )
{
// python auto-loads raw or precompiled modules - don't load data here
pBase = NULL;
}
else
{
bool bResult = filesystem->ReadFile( scriptPath, NULL, bufferScript );
if ( !bResult && bWarnMissing )
{
CGWarning( 0, CON_GROUP_VSCRIPT, "Script not found (%s) \n", scriptPath.operator const char *() );
Assert( "Error running script" );
}
pBase = (const char *) bufferScript.Base();
if ( !pBase || !*pBase )
{
return NULL;
}
}
// Attach the folder to the script ID
const char *pszFilename = V_strrchr( scriptPath, '/' );
scriptPath.sprintf( "%s%s", pszRootFolderName, pszFilename );
HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, scriptPath );
if ( !hScript )
{
CGWarning( 0, CON_GROUP_VSCRIPT, "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() );
Assert( "Error running script" );
}
return hScript;
}
bool VScriptRunScriptAbsolute( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing, const char *pszRootFolderName )
{
if ( !g_pScriptVM )
{
return false;
}
if ( !pszScriptName || !*pszScriptName )
{
CGWarning( 0, CON_GROUP_VSCRIPT, "Cannot run script: NULL script name\n" );
return false;
}
// Prevent infinite recursion in VM
if ( g_ScriptServerRunScriptDepth > 16 )
{
CGWarning( 0, CON_GROUP_VSCRIPT, "IncludeScript stack overflow\n" );
return false;
}
g_ScriptServerRunScriptDepth++;
HSCRIPT hScript = VScriptCompileScriptAbsolute( pszScriptName, bWarnMissing, pszRootFolderName );
bool bSuccess = false;
if ( hScript )
{
bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR );
if ( !bSuccess )
{
Warning( "Error running script named %s\n", pszScriptName );
Assert( "Error running script" );
}
}
g_ScriptServerRunScriptDepth--;
return bSuccess;
}
#endif
#ifdef GAME_DLL
#define IsCommandIssuedByServerAdmin() UTIL_IsCommandIssuedByServerAdmin()
#else
@ -321,6 +428,74 @@ CON_COMMAND_F( script_dump_all, "Dump the state of the VM to the console", FCVAR
//-----------------------------------------------------------------------------
#ifdef MAPBASE_VSCRIPT
void RunAddonScripts()
{
char searchPaths[4096];
filesystem->GetSearchPath( "ADDON", true, searchPaths, sizeof( searchPaths ) );
for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) )
{
char folderName[MAX_PATH];
Q_FileBase( path, folderName, sizeof( folderName ) );
// mapspawn_addon
char fullpath[MAX_PATH];
Q_snprintf( fullpath, sizeof( fullpath ), "%sscripts/vscripts/mapspawn_addon", path );
Q_FixSlashes( fullpath );
VScriptRunScriptAbsolute( fullpath, NULL, false, folderName );
}
}
// UNDONE: "autorun" folder
/*
void RunAutorunScripts()
{
FileFindHandle_t fileHandle;
char szDirectory[MAX_PATH];
char szFileName[MAX_PATH];
char szPartialScriptPath[MAX_PATH];
// TODO: Scanning for VM extension would make this more efficient
Q_strncpy( szDirectory, "scripts/vscripts/autorun/*", sizeof( szDirectory ) );
const char *pszScriptFile = filesystem->FindFirst( szDirectory, &fileHandle );
while (pszScriptFile && fileHandle != FILESYSTEM_INVALID_FIND_HANDLE)
{
Q_FileBase( pszScriptFile, szFileName, sizeof( szFileName ) );
Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/%s", szFileName );
VScriptRunScript( szPartialScriptPath );
pszScriptFile = filesystem->FindNext( fileHandle );
}
// Non-shared scripts
#ifdef CLIENT_DLL
Q_strncpy( szDirectory, "scripts/vscripts/autorun/client/*", sizeof( szDirectory ) );
#else
Q_strncpy( szDirectory, "scripts/vscripts/autorun/server/*", sizeof( szDirectory ) );
#endif
pszScriptFile = filesystem->FindFirst( szDirectory, &fileHandle );
while (pszScriptFile && fileHandle != FILESYSTEM_INVALID_FIND_HANDLE)
{
Q_FileBase( pszScriptFile, szFileName, sizeof( szFileName ) );
#ifdef CLIENT_DLL
Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/client/%s", szFileName );
#else
Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/server/%s", szFileName );
#endif
VScriptRunScript( szPartialScriptPath );
pszScriptFile = filesystem->FindNext( fileHandle );
}
}
*/
#endif
//-----------------------------------------------------------------------------
static short VSCRIPT_SERVER_SAVE_RESTORE_VERSION = 2;
//-----------------------------------------------------------------------------

View File

@ -45,6 +45,8 @@ extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
#ifdef MAPBASE_VSCRIPT
void RegisterSharedScriptConstants();
void RegisterSharedScriptFunctions();
void RunAddonScripts();
#endif
#endif // VSCRIPT_SHARED_H