Giter Club home page Giter Club logo

vscript's Introduction

VScript

SourceMod plugin that exposes many VScript features to make use of it. Currently supports L4D2 and TF2.

Builds

All builds can be found here. To download latest build version, select latest package then "Artifacts" section underneath.

Requirements

Features

vscript.inc and vscript_test.sp should give enough documentation on how to make use of it, but below gives some basic examples on common features:

Compiles and Executes a script

Compiles and executes a script code with params and returns, helpful when RunScriptCode input does not support receiving returns.

public void OnPluginStart()
{
	HSCRIPT script = VScript_CompileScript("printl(\"Wow a message!\"); return 4242; function PrintMessage(param) { printl(param) }");
	
	VScriptExecute execute = new VScriptExecute(script);
	execute.Execute();
	int ret = execute.ReturnValue;
	PrintToServer("%d", ret);	// Expected to print 4242
	
	delete execute;
	
	// Call a PrintMessage function
	execute = new VScriptExecute(HSCRIPT_RootTable.GetValue("PrintMessage"));
	execute.SetParamString(1, FIELD_CSTRING, "Hello!");
	execute.Execute();
	
	delete execute;
	script.ReleaseScript();
}

SDKCall/DHook native function

This allows to directly call or detour a function without needing to manually get gamedata signatures. Parameters and returns are automatically set to the handle.

Handle g_SDKCallGetAngles;

public void OnPluginStart()
{
	VScriptFunction func = VScript_GetClassFunction("CBaseEntity", "GetAngles");
	g_SDKCallGetAngles = func.CreateSDKCall();
	DynamicDetour detour = func.CreateDetour();
	detour.Enable(Hook_Post, Detour_GetAngles);
	
	RegConsoleCmd("sm_getangles", Command_GetAngles);
}

Action Command_GetAngles(int client, int args)
{
	float angles[3];
	SDKCall(g_SDKCallGetAngles, client, angles);
	ReplyToCommand(client, "result: x = %.2f, y = %.2f, z = %.2f", angles[0], angles[1], angles[2]);
	return Plugin_Handled;
}

MRESReturn Detour_GetAngles(int entity, DHookReturn ret)
{
	float angles[3];
	ret.GetVector(angles);
	PrintToServer("entity %d angles: x = %.2f, y = %.2f, z = %.2f", entity, angles[0], angles[1], angles[2]);
	return MRES_Ignored;
}

Create new native function

Creates a new native function where scripts can make use of it. Does nothing by default but can use VScriptFunction.CreateDetour above to do actions and set return.

VScriptFunction g_NewFunction;

public void OnPluginStart()
{
	// Create a new function, or get an existing one if name already exists
	g_NewFunction = VScript_CreateGlobalFunction("NewFunction");
	g_NewFunction.SetParam(1, FIELD_FLOAT);
	g_NewFunction.Return = FIELD_INTEGER;
	g_NewFunction.SetFunctionEmpty();
}

public void OnMapStart()
{
	// Global function need to be registered everytime g_pScriptVM has been reset, which usually happens on mapchange
	g_NewFunction.Register();
}

VScript_EntityToHScript and VScript_HScriptToEntity

VScript uses FIELD_HSCRIPT to interact with entities, so VScript_EntityToHScript and VScript_HScriptToEntity are helpful functions to convert between entity index and hscript object to manage with it.

Known Issues

In L4D2 linux, attempting to reset g_pScriptVM will eventually cause a crash. For now a plugin prevents any attempts to reset such, meaning that not everything may work properly until a mapchange occurs.

vscript's People

Contributors

fortytwofortytwo avatar kitrifty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

pmarkive kitrifty

vscript's Issues

Error detected in plugin startup (see error logs)

I am trying to run the plugin, but I am getting this error:

[SM] Unrecognized library "vscript" (gameconf "/home/container/tf/addons/sourcemod/gamedata/vscript.txt")
[SM] Unrecognized library "vscript" (gameconf "/home/container/tf/addons/sourcemod/gamedata/vscript.txt")
[SM] Exception reported: Invalid address 0x5c is pointing to reserved memory.
[SM] Blaming: vscript.smx
[SM] Call stack trace:
[SM] [0] LoadFromAddress
[SM] [1] Line 129, vscript\vtable.sp::VTable_GetAddressFromName
[SM] [2] Line 94, vscript\util.sp::CreateSDKCall
[SM] [3] Line 30, vscript\entity.sp::Entity_LoadGamedata
[SM] [4] Line 157, C:\Users\yop\Documents\scripting\vscript.sp::OnPluginStart
[SM] [6] ServerCommandEx
[SM] [7] Line 402, /home/builds/sourcemod/debian9-1.11/build/plugins/basecommands.sp::Command_Rcon

Function address incorrect on virtuals in TF2

in TF2, ScriptFunctionBindingStorageType_t is sized 16 bytes to support call virtual functions, which also means that attempting to sdkcall or detour a virtual function will cause it to crash.

Currently there are only 4 vscript functions that are virtuals:

  • CEconEntity::ReapplyProvision
  • CTFBot::PressFireButton
  • CTFBot::PressAltFireButton
  • CTFBot::PressSpecialFireButton

The way this is preformed and stored is different between windows and linux, and not many functions use virtuals, so this is considered to be a low priority to fix for now.

FindDataMapInfo on startup stops plugin from loading

On TF2 Windows/Linux with version 1.6.5.50, the plugin fails to load on initial startup with the following error:

L 06/19/2023 - 00:54:52: [SM] Exception reported: Entity 0 (0) is invalid
L 06/19/2023 - 00:54:52: [SM] Blaming: libs/vscript.smx
L 06/19/2023 - 00:54:52: [SM] Call stack trace:
L 06/19/2023 - 00:54:52: [SM]   [0] FindDataMapInfo
L 06/19/2023 - 00:54:52: [SM]   [1] Line 35, vscript/entity.sp::Entity_LoadGamedata
L 06/19/2023 - 00:54:52: [SM]   [2] Line 139, vscript.sp::OnPluginStart

However, the plugin loads correctly after manually reloading it after startup.

`VENCODE_FLAG_COPYBACK` causes HSCRIPT.SetValue to return bad value

On TF2 Windows, the HSCRIPT.SetValue native returns false even if the actual operation was successful.

For example, running the line HSCRIPT_RootTable.SetValue("m_test_value", FIELD_INTEGER, 123); will throw the error "Invalid HSCRIPT object '0'".

However, the value was actually assigned successfully when viewing it using the command script printl(m_test_value) in the server console:

image

After stripping the VENCODE_FLAG_COPYBACK encode flag from the CreateSDKCall function, the native no longer throws an error.

[L4D2] vscript class not registered on load

Indeed that L4D2 load classes differently to CSGO and TF2, as it only registers it when actually needed. So plugin will have a harder time trying to get all classes, needing to rely on existing entities in map to collect it. I'm not sure if there is a way to automatically collect all of it, would love to hear it.

This causes some issues, need to find some solution

Detouring functions that do not belong to any class/created from vscript?

Say there's a function defined within scriptedmode_addon.nut (L4D2)

//::CommandIssued <- function (...)
getroottable().CommandIssued <- function ( cmd = 0, subject = -1, target = -1 )
{
	if (cmd == -1)
		return true;
	// some code
	return false;
}

How would one make a detour for said function? It doesn't seem to appear in VScript_GetAllGlobalFunctions()
Neither readme not vscript_test.sp has any examples that cover this case.

[L4D2] server crash

OS: Linux

  • console
sm plugins load vscript
VSCRIPT: Running mapspawn.nut
CSpeechScriptBridge was double-initialized: tearing down and rebuilding
        HSCRIPT loaded successfully
[SM] Loaded plugin vscript.smx successfully.

changelevel c1m1_hotel
Segmentation fault (core dumped)
**** server crash ****

[Feature Request] Add a forward that fires after VScriptServerInit

In order to fetch VScript functions and use them, the script system needs to be initialized. You can do this in OnMapStart but since this calls every map, it's not ideal.

It would be better to have a OnVScriptServerInitPost (suggested name) forward. It should also be late-called when the plugin first loads and the script system is already initialized. That way plugins using this library have a one-stop function to fetch and initialize everything requiring VScript functions.

public void OnPluginStart()
{
	// Script system might not be initialized when this calls e.g. on server start.
}

public void OnVScriptServerInitPost()
{
	// Script system is guaranteed to be initialized here.
	VScriptFunction hScriptGetSubType = VScript_GetClassFunction("CBaseCombatWeapon", "GetSubType");
	if (hScriptGetSubType)
		g_hSDKCallGetSubType = hScriptGetSubType.CreateSDKCall();
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.