From d6a546210c4e8ca85f17665b0558dd9cb0320b8b Mon Sep 17 00:00:00 2001 From: rtldg Date: Thu, 6 Mar 2025 13:58:38 +0000 Subject: [PATCH 01/14] WIP VScript integration for checkpoints --- .../sourcemod/scripting/include/vscript.inc | 721 ++++++++++++++++++ .../sourcemod/scripting/shavit-checkpoints.sp | 189 +++++ 2 files changed, 910 insertions(+) create mode 100644 addons/sourcemod/scripting/include/vscript.inc diff --git a/addons/sourcemod/scripting/include/vscript.inc b/addons/sourcemod/scripting/include/vscript.inc new file mode 100644 index 000000000..cf1f3ba24 --- /dev/null +++ b/addons/sourcemod/scripting/include/vscript.inc @@ -0,0 +1,721 @@ +#if defined _vscript_included + #endinput +#endif +#define _vscript_included + +#include +#include + +// These field values does NOT reflect with actual game values, as it vaires between games. +// This should only be used with this plugin natives. +enum fieldtype_t +{ + FIELD_VOID, + FIELD_FLOAT, + FIELD_VECTOR, + FIELD_INTEGER, + FIELD_BOOLEAN, + FIELD_TYPEUNKNOWN, + FIELD_CSTRING, + FIELD_HSCRIPT, + FIELD_VARIANT, + FIELD_QANGLE, + FIELD_UINT32, +}; + +enum ScriptStatus_t +{ + SCRIPT_ERROR = -1, + SCRIPT_DONE, + SCRIPT_RUNNING, +}; + +methodmap Address {} + +methodmap HSCRIPT < Address +{ + // Gets the key name by interator in hscript + // + // @param interator Interator number, 0 for the first key. + // @param buffer Buffer to store name. + // @param length Size of buffer. + // @param field Field type value to store, FIELD_VOID if null. + // @return Interator number to get next key, -1 if there is no more to interator through. + public native int GetKey(int interator, char[] buffer, int length, fieldtype_t &field = FIELD_VOID); + + // Gets the field value from key + // + // @param key Key name to get. + // @return Value of the key. + // @error Invalid key name or value is null. + public native fieldtype_t GetValueField(const char[] key); + + // Gets the value from key + // + // @param key Key name to get. + // @return Value of the key. + // @error Invalid key name or field usage. + public native any GetValue(const char[] key); + + // Gets the string value from key + // + // @param key Key name to get. + // @param buffer Buffer to store string. + // @param length Size of buffer. + // @error Invalid key name or field usage. + public native void GetValueString(const char[] key, char[] buffer, int length); + + // Gets the vector value from key + // + // @param key Key name to get. + // @param buffer Buffer to store vector. + // @error Invalid key name or field usage. + public native void GetValueVector(const char[] key, float buffer[3]); + + // Returns whenever key value is null + // + // @param key Key name to test. + // @return True is value is null, false otherwise. + // @error Invalid key name. + public native bool IsValueNull(const char[] key); + + // Sets a value to key + // + // @param key Key name to set. + // @param field Field to use to set. + // @param value Value to set. + public native void SetValue(const char[] key, fieldtype_t field, any value); + + // Sets a string value to key + // + // @param key Key name to set. + // @param field Field to use to set. + // @param value String value to set. + public native void SetValueString(const char[] key, fieldtype_t field, const char[] value); + + // Sets a vector value to key + // + // @param key Key name to set. + // @param field Field to use to set. + // @param value Vector value to set. + public native void SetValueVector(const char[] key, fieldtype_t field, const float value[3]); + + // Sets a null value to key + // + // @param key Key name to set. + public native void SetValueNull(const char[] key); + + // Returns whenever key name exists, key with null value returns true + // + // @param key Key name to test. + // @return True if key exists, false otherwise. + public native bool ValueExists(const char[] key); + + // Clears a key and it's value + // + // @param key Key name to clear. + public native void ClearValue(const char[] key); + + // Get the address of instance + property Address Instance + { + public native get(); + } + + // Frees a HSCRIPT memory + public native void Release(); + + // Frees a HSCRIPT memory. This is only used for script scopes. + public native void ReleaseScope(); + + // Frees a HSCRIPT memory. This is only used for compiled scripts. + public native void ReleaseScript(); +} + +// Several functions accept null HScript as g_pScriptVM for root table +const HSCRIPT HSCRIPT_RootTable = view_as(0); + +methodmap VScriptFunction < Address +{ + // Gets the script name + // + // @param buffer Buffer to store name. + // @param length Size of buffer. + public native void GetScriptName(char[] buffer, int length); + + // Sets a script name + // + // @param value Name to set. + public native void SetScriptName(const char[] value); + + // Gets the function name, this is only for display purpose + // + // @param buffer Buffer to store name. + // @param length Size of buffer. + public native void GetFunctionName(char[] buffer, int length); + + // Sets a function name, this is only for display purpose + // + // @param value Name to set. + public native void SetFunctionName(const char[] value); + + // Gets the description + // + // @param buffer Buffer to store name. + // @param length Size of buffer. + public native void GetDescription(char[] buffer, int length); + + // Sets the description + // + // @param value Description to set. + public native void SetDescription(const char[] value); + + // Gets the address of the binding + // Binding gets automatically updated when SetFunctionEmpty is called when possible. + property Address Binding + { + public native get(); + } + + // Gets/Sets the address of the function + property Address Function + { + public native get(); + public native set(Address func); + } + + // Gets the offset of a virtual function from class, -1 if function is not a virtual + property int Offset + { + public native get(); + } + + // Set the function as empty, doing nothing. This is used when wanting to create a new function only to be used for detour. + // This MUST be used after return and params has been set. If return is not void, 0 or null is returned by default. + public native void SetFunctionEmpty(); + + // Gets/Sets the return field type + property fieldtype_t Return + { + public native get(); + public native set(fieldtype_t field); + } + + // Gets amount of parameters function has + property int ParamCount + { + public native get(); + } + + // Gets the field type of a parameter + // + // @param param Parameter number, starting from 1. + // @return Field type of a parameter. + // @error Parameter number out of range. + public native fieldtype_t GetParam(int param); + + // Sets the field type of a parameter, creating any new param values when needed, initialized as FIELD_VOID + // + // @param param Parameter number, starting from 1. + // @param field Field type to set. + public native void SetParam(int param, fieldtype_t field); + + // Copy all datas from another function + // + // @param from A function to copy from. + public native void CopyFrom(VScriptFunction from); + + // Register this as a global function until when g_pScriptVM has been reset. This should be called inside VScript_OnScriptVMInitialized forward. + public native void Register(); + + // Creates an SDKCall with parameters auto filled + // + // @return SDKCall handle, must be deleted when not needed. + public native Handle CreateSDKCall(); + + // Creates a detour handle from DynamicDetour with parameters auto filled + // + // @return DynamicDetour handle, must be deleted when not needed. + public native DynamicDetour CreateDetour(); + + // Creates a hook handle from DynamicHook with parameters auto filled + // + // @return DynamicHook handle, must be deleted when not needed. Returns null if function is not a virtual. + public native DynamicHook CreateHook(); + + // Gets the class that this function is associated to it, Address_Null if global function + property VScriptClass Class + { + public native get(); + } +} + +methodmap VScriptClass < Address +{ + // Gets the script name + // + // @param buffer Buffer to store script name. + // @param length Size of buffer. + public native void GetScriptName(char[] buffer, int length); + + // Sets the script name + // + // @param value Script name to set. + public native void SetScriptName(const char[] value); + + // Gets the class name + // + // @param buffer Buffer to store class name. + // @param length Size of buffer. + public native void GetClassName(char[] buffer, int length); + + // Sets the class name + // + // @param value Class name to set. + public native void SetClassName(const char[] value); + + // Gets the description + // + // @param buffer Buffer to store name. + // @param length Size of buffer. + public native void GetDescription(char[] buffer, int length); + + // Sets the description + // + // @param value Description to set. + public native void SetDescription(const char[] value); + + // Get all of the functions used for this class + // + // @return Arrays of VScriptFunction, handle must be deleted when not needed. + public native ArrayList GetAllFunctions(); + + // Gets VScriptFunction from this class + // + // @param functionName Function name. + // @return Address of VScriptFunction, null if does not exist. + public native VScriptFunction GetFunction(const char[] functionName); + + // Creates a new VScriptFunction connected from this class. Function will need to be filled in then call VScript_ResetScriptVM + // + // @param functionName Function name. + // @return Address of VScriptFunction. + public native VScriptFunction CreateFunction(); + + // Register this class as an instance. This should be used inside VScript_OnScriptVMInitialized forward. + // + // @param instance Name of an instance in script. + // @return Created HSCRIPT instance. + public native HSCRIPT RegisterInstance(const char[] instance); + + // Gets the class that this is based on, Address_Null if does not have base class + property VScriptClass Base + { + public native get(); + } + + // Return whenever if this class function is derived from other class base + // + // @param base Function base to find if derived at. + // @return True if derived from, false otherwise. + public bool IsDerivedFrom(VScriptClass base) + { + while (base) + { + if (this == base) + return true; + + base = base.Base; + } + + return false; + } + +} + +methodmap VScriptExecute < Handle +{ + // Creates a new handle to execute a script function + // + // @param script Script address to execute. + // @param scope The script scope to execute the script inside of. + public native VScriptExecute(HSCRIPT script, HSCRIPT scope = HSCRIPT_RootTable); + + // Adds a new parameter at the end + // + // @param type Type of field to set. + // @param value Value to set. + public native void AddParam(fieldtype_t type, any value); + + // Adds a new string parameter at the end + // + // @param type Type of field to set. + // @param value String value to set. + public native void AddParamString(fieldtype_t type, const char[] value); + + // Adds a new vector parameter at the end + // + // @param type Type of field to set. + // @param value Vector value to set. + public native void AddParamVector(fieldtype_t type, const float value[3]); + + // Sets a given parameter with value + // + // @param param Parameter to set. + // @param type Type of field to set. + // @param value Value to set. + public native void SetParam(int param, fieldtype_t type, any value); + + // Sets a given parameter with string value + // + // @param param Parameter to set. + // @param type Type of field to set. + // @param value String value to set. + public native void SetParamString(int param, fieldtype_t type, const char[] value); + + // Sets a given parameter with vector value + // + // @param param Parameter to set. + // @param type Type of field to set. + // @param value Vector value to set. + public native void SetParamVector(int param, fieldtype_t type, const float value[3]); + + // Executes a function + // + // @return Script status after executed. + public native ScriptStatus_t Execute(); + + // Gets return field type, FIELD_VOID if null + property fieldtype_t ReturnType + { + public native get(); + } + + // Gets return value + property any ReturnValue + { + public native get(); + } + + // Gets a return string value + // + // @param buffer Buffer to store string. + // @param length Size of buffer. + public native void GetReturnString(char[] buffer, int length); + + // Gets a return vector value + // + // @param buffer Buffer to store vector. + // @param length Size of buffer. + public native void GetReturnVector(float buffer[3]); +} + + +/** + * Called when g_pScriptVM has been fully initialized, this is where VScriptClass.RegisterInstance and VScriptFunction.Register should be called + * @note This forward does not get called on plugin lateload, use VScript_IsScriptVMInitialized to determine whenever to manually call this forward + */ +forward void VScript_OnScriptVMInitialized(); + +/** + * Returns whenever g_pScriptVM has been initialized, useful for plugin start to determine whenever to call VScript_ResetScriptVM or VScript_OnScriptVMInitialized if this were to return true + * + * @return True if script vm is initialized, false otherwise + */ +native bool VScript_IsScriptVMInitialized(); + +/** + * Deletes g_pScriptVM and creates a new one. This should be used when VScriptClass or VScriptFunction has been modified, including adding new functions to class + */ +native void VScript_ResetScriptVM(); + +/** + * Compiles a script. + * + * @param script Script to compile + * @param id Optional ID to set + * + * @return HSCRIPT of script, null if could not compile. This MUST be freed when not in use by using HSCRIPT.ReleaseScript(). + */ +native HSCRIPT VScript_CompileScript(const char[] script, const char[] id = NULL_STRING); + +/** + * Compiles a script file. + * + * @param filepath Filepath to get a script, 'scripts/vscripts/' are automatically added to the filepath + * + * @return HSCRIPT of script, null if could not compile. This MUST be freed when not in use by using HSCRIPT.ReleaseScript(). + * @error Invalid filepath. + */ +native HSCRIPT VScript_CompileScriptFile(const char[] filepath); + +/** + * Creates a new HSCRIPT scope, it MUST be deleted when no longer needed by using HSCRIPT.ReleaseScope() + * + * @param name Name to set the scope + * @param parent Parent of the HSCRIPT to set as + * + * @return HSCRIPT of scope. + */ +native HSCRIPT VScript_CreateScope(const char[] name, HSCRIPT parent = HSCRIPT_RootTable); + +/** + * Creates a new HSCRIPT table, it MUST be deleted when no longer needed by using HSCRIPT.Release() + * + * @return HSCRIPT of table. + */ +native HSCRIPT VScript_CreateTable(); + +/** + * Creates a new HSCRIPT instance, this is only to be used on non-entity script class that needs it's script instance created + * @note You may need to manually set property to an instance to point where the newly created hscript are at + * + * @param class Script class an instance uses + * @param instance Instance pointer address to use + * + * @return HSCRIPT of an instance, null if could not create one. + */ +native HSCRIPT VScript_CreateInstance(VScriptClass class, Address instance); + +/** + * Get all the classes used for vscript + * + * @return Arrays of VScriptClass, handle must be deleted when not needed. + */ +native ArrayList VScript_GetAllClasses(); + +/** + * Gets VScriptClass from class + * + * @param className Class name. + * + * @return Address of VScriptClass + * @error Invalid class name + */ +native VScriptClass VScript_GetClass(const char[] className); + +/** + * Gets VScriptClass from class or creates one if don't exist. VScriptClass.RegisterInstance must be called after params are filled. + * + * @param className Class name. + * + * @return Address of VScriptClass, either existing or newly created + */ +native VScriptClass VScript_CreateClass(const char[] className); + +/** + * Gets VScriptFunction from class + * + * @param className Class name. + * @param functionName Function name. + * + * @return Address of VScriptFunction, null if class does not have one + * @error Invalid class name + */ +native VScriptFunction VScript_GetClassFunction(const char[] className, const char[] functionName); + +/** + * Get all global functions used for vscript + * + * @return Arrays of VScriptFunction, handle must be deleted when not needed. + */ +native ArrayList VScript_GetAllGlobalFunctions(); + +/** + * Gets VScriptFunction from a global + * + * @param functionName Function name. + * + * @return Address of VScriptFunction + */ +native VScriptFunction VScript_GetGlobalFunction(const char[] functionName); + +/** + * Creates a new VScriptFunction as a pointer. VScriptFunction.Register should be called for function to come into effect. + * + * @return Address of VScriptFunction + */ +native VScriptFunction VScript_CreateFunction(); + +/** + * Gets the script scope of an entity + * + * @param entity Entity index. + * + * @return Address of the HScript scope + * @error Invalid entity + */ +native HSCRIPT VScript_GetEntityScriptScope(int entity); + +/** + * Gets the HScript address of an entity + * + * @param entity Entity index. + * + * @return Address of the HScript + * @error Invalid entity + */ +native HSCRIPT VScript_EntityToHScript(int entity); + +/** + * Gets the entity index from HScript address + * + * @param hscript HScript address. + * + * @return Entity index + */ +native int VScript_HScriptToEntity(HSCRIPT hscript); + +/** + * Gets VScriptFunction from class or creates one if don't exist + * + * @param className Class name. + * @param functionName Function name. + * + * @return Address of VScriptFunction, either existing or newly created + * @error Invalid class name + */ +stock VScriptFunction VScript_CreateClassFunction(const char[] className, const char[] functionName) +{ + VScriptFunction func = VScript_GetClassFunction(className, functionName); + if (func) + return func; + + VScriptClass class = VScript_GetClass(className); + func = class.CreateFunction(); + func.SetScriptName(functionName); + return func; +} + +/** + * Gets VScriptFunction from global or creates one if don't exist + * + * @param functionName Function name. + * + * @return Address of VScriptFunction, either existing or newly created + */ +stock VScriptFunction VScript_CreateGlobalFunction(const char[] functionName) +{ + VScriptFunction func = VScript_GetGlobalFunction(functionName); + if (func) + return func; + + func = VScript_CreateFunction(); + func.SetScriptName(functionName); + return func; +} + +/** + * Returns the value of a constant + * + * @param table Enum or bitfield name to get. + * @param name Value name to get. + * + * @return Value of the enum key. + * @error Invalid enum, bitfield or value name to get. + */ +stock any VScript_GetConstantsValue(const char[] table, const char[] name) +{ + HSCRIPT constants = HSCRIPT_RootTable.GetValue("Constants"); + HSCRIPT keys = constants.GetValue(table); + return keys.GetValue(name); +} + +public SharedPlugin __pl_vscript = +{ + name = "vscript", + file = "vscript.smx", + #if defined REQUIRE_PLUGIN + required = 1, + #else + required = 0, + #endif +}; + +#if !defined REQUIRE_PLUGIN +public void __pl_vscript_SetNTVOptional() +{ + MarkNativeAsOptional("HSCRIPT.GetKey"); + MarkNativeAsOptional("HSCRIPT.GetValueField"); + MarkNativeAsOptional("HSCRIPT.GetValue"); + MarkNativeAsOptional("HSCRIPT.GetValueString"); + MarkNativeAsOptional("HSCRIPT.GetValueVector"); + MarkNativeAsOptional("HSCRIPT.IsValueNull"); + MarkNativeAsOptional("HSCRIPT.SetValue"); + MarkNativeAsOptional("HSCRIPT.SetValueString"); + MarkNativeAsOptional("HSCRIPT.SetValueVector"); + MarkNativeAsOptional("HSCRIPT.SetValueNull"); + MarkNativeAsOptional("HSCRIPT.ValueExists"); + MarkNativeAsOptional("HSCRIPT.ClearValue"); + MarkNativeAsOptional("HSCRIPT.Instance.get"); + MarkNativeAsOptional("HSCRIPT.Release"); + MarkNativeAsOptional("HSCRIPT.ReleaseScope"); + MarkNativeAsOptional("HSCRIPT.ReleaseScript"); + + MarkNativeAsOptional("VScriptFunction.GetScriptName"); + MarkNativeAsOptional("VScriptFunction.SetScriptName"); + MarkNativeAsOptional("VScriptFunction.GetFunctionName"); + MarkNativeAsOptional("VScriptFunction.SetFunctionName"); + MarkNativeAsOptional("VScriptFunction.GetDescription"); + MarkNativeAsOptional("VScriptFunction.SetDescription"); + MarkNativeAsOptional("VScriptFunction.Binding.get"); + MarkNativeAsOptional("VScriptFunction.Function.get"); + MarkNativeAsOptional("VScriptFunction.Function.set"); + MarkNativeAsOptional("VScriptFunction.Offset.get"); + MarkNativeAsOptional("VScriptFunction.SetFunctionEmpty"); + MarkNativeAsOptional("VScriptFunction.Return.get"); + MarkNativeAsOptional("VScriptFunction.Return.set"); + MarkNativeAsOptional("VScriptFunction.ParamCount.get"); + MarkNativeAsOptional("VScriptFunction.GetParam"); + MarkNativeAsOptional("VScriptFunction.SetParam"); + MarkNativeAsOptional("VScriptFunction.CopyFrom"); + MarkNativeAsOptional("VScriptFunction.Register"); + MarkNativeAsOptional("VScriptFunction.CreateSDKCall"); + MarkNativeAsOptional("VScriptFunction.CreateDetour"); + MarkNativeAsOptional("VScriptFunction.CreateHook"); + MarkNativeAsOptional("VScriptFunction.Class.get"); + + MarkNativeAsOptional("VScriptClass.GetScriptName"); + MarkNativeAsOptional("VScriptClass.SetScriptName"); + MarkNativeAsOptional("VScriptClass.GetClassName"); + MarkNativeAsOptional("VScriptClass.SetClassName"); + MarkNativeAsOptional("VScriptClass.GetDescription"); + MarkNativeAsOptional("VScriptClass.SetDescription"); + MarkNativeAsOptional("VScriptClass.GetAllFunctions"); + MarkNativeAsOptional("VScriptClass.GetFunction"); + MarkNativeAsOptional("VScriptClass.CreateFunction"); + MarkNativeAsOptional("VScriptClass.RegisterInstance"); + MarkNativeAsOptional("VScriptClass.Base.get"); + + MarkNativeAsOptional("VScriptExecute.VScriptExecute"); + MarkNativeAsOptional("VScriptExecute.AddParam"); + MarkNativeAsOptional("VScriptExecute.AddParamString"); + MarkNativeAsOptional("VScriptExecute.AddParamVector"); + MarkNativeAsOptional("VScriptExecute.SetParam"); + MarkNativeAsOptional("VScriptExecute.SetParamString"); + MarkNativeAsOptional("VScriptExecute.SetParamVector"); + MarkNativeAsOptional("VScriptExecute.Execute"); + MarkNativeAsOptional("VScriptExecute.ReturnType.get"); + MarkNativeAsOptional("VScriptExecute.ReturnValue.get"); + MarkNativeAsOptional("VScriptExecute.GetReturnString"); + MarkNativeAsOptional("VScriptExecute.GetReturnVector"); + + MarkNativeAsOptional("VScript_IsScriptVMInitialized"); + MarkNativeAsOptional("VScript_ResetScriptVM"); + MarkNativeAsOptional("VScript_CompileScript"); + MarkNativeAsOptional("VScript_CompileScriptFile"); + MarkNativeAsOptional("VScript_CreateScope"); + MarkNativeAsOptional("VScript_CreateTable"); + MarkNativeAsOptional("VScript_CreateInstance"); + MarkNativeAsOptional("VScript_GetAllClasses"); + MarkNativeAsOptional("VScript_GetClass"); + MarkNativeAsOptional("VScript_CreateClass"); + MarkNativeAsOptional("VScript_GetClassFunction"); + MarkNativeAsOptional("VScript_GetAllGlobalFunctions"); + MarkNativeAsOptional("VScript_GetGlobalFunction"); + MarkNativeAsOptional("VScript_CreateFunction"); + MarkNativeAsOptional("VScript_GetEntityScriptScope"); + MarkNativeAsOptional("VScript_EntityToHScript"); + MarkNativeAsOptional("VScript_HScriptToEntity"); +} +#endif diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index 88ca93e2a..92ce26c7c 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -33,6 +33,7 @@ #include #include #include +#include #pragma newdecls required #pragma semicolon 1 @@ -103,6 +104,7 @@ ArrayList gA_PersistentData = null; bool gB_Eventqueuefix = false; bool gB_ReplayRecorder = false; +bool gB_VScript = false; DynamicHook gH_CommitSuicide = null; float gF_NextSuicide[MAXPLAYERS+1]; @@ -114,6 +116,26 @@ int gI_Offset_m_lastLadderPos = 0; int gI_Offset_m_afButtonDisabled = 0; int gI_Offset_m_afButtonForced = 0; +// vscript!!! you're going to break all my checkpoints!!! +#if 0 +VScriptExecute gH_VScript_OnStart; +VScriptExecute gH_VScript_OnEnd; +#endif +VScriptExecute gH_VScript_Timer_OnCheckpointSave; +VScriptExecute gH_VScript_Timer_OnCheckpointLoadPre; +VScriptExecute gH_VScript_Timer_OnCheckpointLoadPost; +VScriptFunction gH_VScript_Timer_SetCheckpointCustomData; +VScriptFunction gH_VScript_Timer_GetCheckpointCustomData; + +enum VScript_Checkpoint_State +{ + VCS_NO_TOUCH = 0, + VCS_Saving, + VCS_Loading, +} +VScript_Checkpoint_State gI_VScript_Checkpointing[MAXPLAYERS+1]; +StringMap gH_VScript_Checkpoint_CustomData[MAXPLAYERS+1]; + public Plugin myinfo = { name = "[shavit] Checkpoints", @@ -220,6 +242,7 @@ public void OnPluginStart() // modules gB_Eventqueuefix = LibraryExists("eventqueuefix"); gB_ReplayRecorder = LibraryExists("shavit-replay-recorder"); + gB_VScript = LibraryExists("vscript"); if (gB_Late) { @@ -299,6 +322,10 @@ public void OnLibraryAdded(const char[] name) { gB_Eventqueuefix = true; } + else if (StrEqual(name, "vscript")) + { + gB_VScript = true; + } } public void OnLibraryRemoved(const char[] name) @@ -311,6 +338,10 @@ public void OnLibraryRemoved(const char[] name) { gB_Eventqueuefix = false; } + else if (StrEqual(name, "vscript")) + { + gB_VScript = false; + } } public void OnMapStart() @@ -1752,6 +1783,21 @@ void SaveCheckpointCache(int saver, int target, cp_cache_t cpcache, int index, H Call_PushCell(index); Call_PushCell(target); Call_Finish(); + + // NOTE THAT TARGET COULD BE A BOT OR WHATEVER SO GOD HELP US + if (gB_VScript) + { + gI_VScript_Checkpointing[target] = VCS_Saving; + gH_VScript_Checkpoint_CustomData[target] = cpcache.customdata; + + if (gH_VScript_Timer_OnCheckpointSave) + { + gH_VScript_Timer_OnCheckpointSave.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(target)); + gH_VScript_Timer_OnCheckpointSave.Execute(); + } + + gI_VScript_Checkpointing[target] = VCS_NO_TOUCH; + } } void TeleportToCheckpoint(int client, int index, bool suppressMessage, int target=0) @@ -1850,6 +1896,20 @@ bool LoadCheckpointCache(int client, cp_cache_t cpcache, int index, bool force = bool isPersistentData = (index == -1); + if (gB_VScript) + { + gI_VScript_Checkpointing[client] = VCS_Loading; + gH_VScript_Checkpoint_CustomData[client] = cpcache.customdata; + + if (gH_VScript_Timer_OnCheckpointLoadPre) + { + gH_VScript_Timer_OnCheckpointLoadPre.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + gH_VScript_Timer_OnCheckpointLoadPre.Execute(); + } + + gI_VScript_Checkpointing[client] = VCS_NO_TOUCH; + } + SetEntityMoveType(client, cpcache.iMoveType); SetEntityFlags(client, cpcache.iFlags); @@ -1895,6 +1955,8 @@ bool LoadCheckpointCache(int client, cp_cache_t cpcache, int index, bool force = Call_PushCell(index); Call_Finish(); + Do_Timer_OnCheckpointLoadPost(client, cpcache.customdata); + return true; } @@ -1961,6 +2023,8 @@ bool LoadCheckpointCache(int client, cp_cache_t cpcache, int index, bool force = Call_PushCell(index); Call_Finish(); + Do_Timer_OnCheckpointLoadPost(client, cpcache.customdata); + return true; } @@ -2221,3 +2285,128 @@ public any Native_SaveCheckpointCache(Handle plugin, int numParams) SaveCheckpointCache(saver, target, cache, index, plugin); return SetNativeArray(3, cache, sizeof(cp_cache_t)); } + +public void VScript_OnScriptVMInitialized() +{ +#if 0 + // ::Timer_OnStart <- function(player) + if (VScript_GetGlobalFunction("Timer_OnStart")) + gH_VScript_OnStart = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnStart")); + else + gH_VScript_OnStart = view_as(Address_Null); + // ::Timer_OnEnd <- function(player) + if (VScript_GetGlobalFunction("Timer_OnEnd")) + gH_VScript_OnEnd = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnEnd")); + else + gH_VScript_OnEnd = view_as(Address_Null); +#endif + + // ::Timer_OnCheckpointSave <- function(player) + if (VScript_GetGlobalFunction("Timer_OnCheckpointSave")) + gH_VScript_Timer_OnCheckpointSave = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointSave")); + else + gH_VScript_Timer_OnCheckpointSave = view_as(Address_Null); + + // ::Timer_OnCheckpointLoadPre <- function(player) + if (VScript_GetGlobalFunction("Timer_OnCheckpointLoadPre")) + gH_VScript_Timer_OnCheckpointLoadPre = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPre")); + else + gH_VScript_Timer_OnCheckpointLoadPre = view_as(Address_Null); + + // ::Timer_OnCheckpointLoadPost <- function(player) + if (VScript_GetGlobalFunction("Timer_OnCheckpointLoadPost")) + gH_VScript_Timer_OnCheckpointLoadPost = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPost")); + else + gH_VScript_Timer_OnCheckpointLoadPost = view_as(Address_Null); + + // function Timer_SetCheckpointCustomData(player, key, value) + gH_VScript_Timer_SetCheckpointCustomData = VScript_CreateFunction(); + gH_VScript_Timer_SetCheckpointCustomData.SetScriptName("Timer_SetCheckpointCustomData"); + gH_VScript_Timer_SetCheckpointCustomData.Return = FIELD_VOID; + gH_VScript_Timer_SetCheckpointCustomData.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_SetCheckpointCustomData.SetParam(2, FIELD_CSTRING); + gH_VScript_Timer_SetCheckpointCustomData.SetParam(3, FIELD_CSTRING); + gH_VScript_Timer_SetCheckpointCustomData.SetFunctionEmpty(); + gH_VScript_Timer_SetCheckpointCustomData.Register(); + gH_VScript_Timer_SetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_SetCheckpointCustomData); + + // function Timer_GetCheckpointCustomData(player, key, value) + gH_VScript_Timer_GetCheckpointCustomData = VScript_CreateFunction(); + gH_VScript_Timer_SetCheckpointCustomData.SetScriptName("Timer_GetCheckpointCustomData"); + gH_VScript_Timer_GetCheckpointCustomData.Return = FIELD_CSTRING; + gH_VScript_Timer_GetCheckpointCustomData.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetCheckpointCustomData.SetParam(2, FIELD_CSTRING); + gH_VScript_Timer_GetCheckpointCustomData.SetFunctionEmpty(); + gH_VScript_Timer_GetCheckpointCustomData.Register(); + gH_VScript_Timer_GetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetCheckpointCustomData); +} + +MRESReturn Detour_Timer_SetCheckpointCustomData(DHookParam params) +{ + int client = VScript_HScriptToEntity(params.Get(1)); + + if (client < 1 || client > MaxClients || !IsClientInGame(client)) + { + // Log error or something... + return MRES_Supercede; + } + + if (gI_VScript_Checkpointing[client] != VCS_Saving) + { + // Log error or something because this should only be called in Timer_OnCheckpointSave + return MRES_Supercede; + } + + char key[512], value[512]; + params.GetString(2, key, sizeof(key)); + params.GetString(3, value, sizeof(value)); + + if (gH_VScript_Checkpoint_CustomData[client]) + gH_VScript_Checkpoint_CustomData[client].SetString(key, value, true); + + return MRES_Supercede; +} + +MRESReturn Detour_Timer_GetCheckpointCustomData(DHookReturn hret, DHookParam params) +{ + int client = VScript_HScriptToEntity(params.Get(1)); + + if (client < 1 || client > MaxClients || !IsClientInGame(client)) + { + // Log error or something... + return MRES_Supercede; + } + + if (gI_VScript_Checkpointing[client] != VCS_Loading) + { + // Log error or something because this should only be called in Timer_OnCheckpointLoad{Pre,Post} + return MRES_Supercede; + } + + char key[512], value[512]; + params.GetString(2, key, sizeof(key)); + + if (gH_VScript_Checkpoint_CustomData[client]) + gH_VScript_Checkpoint_CustomData[client].GetString(key, value, sizeof(value)); + + hret.SetString(value); + + return MRES_Supercede; +} + +void Do_Timer_OnCheckpointLoadPost(int client, StringMap customdata) +{ + if (gB_VScript) + { + gI_VScript_Checkpointing[client] = VCS_Loading; + gH_VScript_Checkpoint_CustomData[client] = customdata; + + if (gH_VScript_Timer_OnCheckpointLoadPost) + { + gH_VScript_Timer_OnCheckpointLoadPost.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + gH_VScript_Timer_OnCheckpointLoadPost.Execute(); + } + + gI_VScript_Checkpointing[client] = VCS_NO_TOUCH; + } +} From ba5a922c8343ff395409bcfdfb5c80dc7d1c4385 Mon Sep 17 00:00:00 2001 From: rtldg Date: Sun, 9 Mar 2025 07:58:17 +0000 Subject: [PATCH 02/14] little fucking typos, man --- addons/sourcemod/scripting/shavit-checkpoints.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index 92ce26c7c..24dc2c068 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -2332,7 +2332,7 @@ public void VScript_OnScriptVMInitialized() // function Timer_GetCheckpointCustomData(player, key, value) gH_VScript_Timer_GetCheckpointCustomData = VScript_CreateFunction(); - gH_VScript_Timer_SetCheckpointCustomData.SetScriptName("Timer_GetCheckpointCustomData"); + gH_VScript_Timer_GetCheckpointCustomData.SetScriptName("Timer_GetCheckpointCustomData"); gH_VScript_Timer_GetCheckpointCustomData.Return = FIELD_CSTRING; gH_VScript_Timer_GetCheckpointCustomData.SetParam(1, FIELD_HSCRIPT); gH_VScript_Timer_GetCheckpointCustomData.SetParam(2, FIELD_CSTRING); From 2b24012652ffc12e492b7c696591d51835adcf24 Mon Sep 17 00:00:00 2001 From: rtldg Date: Sun, 9 Mar 2025 08:03:09 +0000 Subject: [PATCH 03/14] add Timer_GetTime to vscript --- .../sourcemod/scripting/shavit-checkpoints.sp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index 24dc2c068..d1960d0ca 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -126,6 +126,7 @@ VScriptExecute gH_VScript_Timer_OnCheckpointLoadPre; VScriptExecute gH_VScript_Timer_OnCheckpointLoadPost; VScriptFunction gH_VScript_Timer_SetCheckpointCustomData; VScriptFunction gH_VScript_Timer_GetCheckpointCustomData; +VScriptFunction gH_VScript_Timer_GetTime; enum VScript_Checkpoint_State { @@ -2339,6 +2340,15 @@ public void VScript_OnScriptVMInitialized() gH_VScript_Timer_GetCheckpointCustomData.SetFunctionEmpty(); gH_VScript_Timer_GetCheckpointCustomData.Register(); gH_VScript_Timer_GetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetCheckpointCustomData); + + // function Timer_GetTime(player) // returns a float + gH_VScript_Timer_GetTime = VScript_CreateFunction(); + gH_VScript_Timer_GetTime.SetScriptName("Timer_GetTime"); + gH_VScript_Timer_GetTime.Return = FIELD_FLOAT; + gH_VScript_Timer_GetTime.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetTime.SetFunctionEmpty(); + gH_VScript_Timer_GetTime.Register(); + gH_VScript_Timer_GetTime.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetTime); } MRESReturn Detour_Timer_SetCheckpointCustomData(DHookParam params) @@ -2410,3 +2420,18 @@ void Do_Timer_OnCheckpointLoadPost(int client, StringMap customdata) gI_VScript_Checkpointing[client] = VCS_NO_TOUCH; } } + +MRESReturn Detour_Timer_GetTime(DHookReturn hret, DHookParam params) +{ + int client = VScript_HScriptToEntity(params.Get(1)); + + if (client < 1 || client > MaxClients || !IsClientInGame(client)) + { + // Log error or something... + return MRES_Supercede; + } + + hret.Value = Shavit_GetClientTime(client); + + return MRES_Supercede; +} From 6daa5953ca637c960a91e1ce03122a072f896978 Mon Sep 17 00:00:00 2001 From: rtldg Date: Sat, 22 Mar 2025 17:12:37 +0000 Subject: [PATCH 04/14] Add Timer_GetStatus() and move things around --- .../sourcemod/scripting/shavit-checkpoints.sp | 44 +---------- addons/sourcemod/scripting/shavit-core.sp | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+), 43 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index d1960d0ca..53d9c0f3a 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -117,17 +117,11 @@ int gI_Offset_m_afButtonDisabled = 0; int gI_Offset_m_afButtonForced = 0; // vscript!!! you're going to break all my checkpoints!!! -#if 0 -VScriptExecute gH_VScript_OnStart; -VScriptExecute gH_VScript_OnEnd; -#endif VScriptExecute gH_VScript_Timer_OnCheckpointSave; VScriptExecute gH_VScript_Timer_OnCheckpointLoadPre; VScriptExecute gH_VScript_Timer_OnCheckpointLoadPost; VScriptFunction gH_VScript_Timer_SetCheckpointCustomData; VScriptFunction gH_VScript_Timer_GetCheckpointCustomData; -VScriptFunction gH_VScript_Timer_GetTime; - enum VScript_Checkpoint_State { VCS_NO_TOUCH = 0, @@ -137,6 +131,7 @@ enum VScript_Checkpoint_State VScript_Checkpoint_State gI_VScript_Checkpointing[MAXPLAYERS+1]; StringMap gH_VScript_Checkpoint_CustomData[MAXPLAYERS+1]; + public Plugin myinfo = { name = "[shavit] Checkpoints", @@ -2289,19 +2284,6 @@ public any Native_SaveCheckpointCache(Handle plugin, int numParams) public void VScript_OnScriptVMInitialized() { -#if 0 - // ::Timer_OnStart <- function(player) - if (VScript_GetGlobalFunction("Timer_OnStart")) - gH_VScript_OnStart = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnStart")); - else - gH_VScript_OnStart = view_as(Address_Null); - // ::Timer_OnEnd <- function(player) - if (VScript_GetGlobalFunction("Timer_OnEnd")) - gH_VScript_OnEnd = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnEnd")); - else - gH_VScript_OnEnd = view_as(Address_Null); -#endif - // ::Timer_OnCheckpointSave <- function(player) if (VScript_GetGlobalFunction("Timer_OnCheckpointSave")) gH_VScript_Timer_OnCheckpointSave = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointSave")); @@ -2340,15 +2322,6 @@ public void VScript_OnScriptVMInitialized() gH_VScript_Timer_GetCheckpointCustomData.SetFunctionEmpty(); gH_VScript_Timer_GetCheckpointCustomData.Register(); gH_VScript_Timer_GetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetCheckpointCustomData); - - // function Timer_GetTime(player) // returns a float - gH_VScript_Timer_GetTime = VScript_CreateFunction(); - gH_VScript_Timer_GetTime.SetScriptName("Timer_GetTime"); - gH_VScript_Timer_GetTime.Return = FIELD_FLOAT; - gH_VScript_Timer_GetTime.SetParam(1, FIELD_HSCRIPT); - gH_VScript_Timer_GetTime.SetFunctionEmpty(); - gH_VScript_Timer_GetTime.Register(); - gH_VScript_Timer_GetTime.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetTime); } MRESReturn Detour_Timer_SetCheckpointCustomData(DHookParam params) @@ -2420,18 +2393,3 @@ void Do_Timer_OnCheckpointLoadPost(int client, StringMap customdata) gI_VScript_Checkpointing[client] = VCS_NO_TOUCH; } } - -MRESReturn Detour_Timer_GetTime(DHookReturn hret, DHookParam params) -{ - int client = VScript_HScriptToEntity(params.Get(1)); - - if (client < 1 || client > MaxClients || !IsClientInGame(client)) - { - // Log error or something... - return MRES_Supercede; - } - - hret.Value = Shavit_GetClientTime(client); - - return MRES_Supercede; -} diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 999a711eb..92581350b 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,15 @@ DynamicHook gH_AcceptInput; // used for hooking player_speedmod's AcceptInput DynamicHook gH_TeleportDhook = null; Address gI_TF2PreventBunnyJumpingAddr = Address_Null; +// vscript (non-checkpoint natives) +#if 0 +VScriptExecute gH_VScript_OnStart; +VScriptExecute gH_VScript_OnEnd; +#endif +VScriptFunction gH_VScript_Timer_GetTime; +VScriptFunction gH_VScript_Timer_GetStatus; + + // database handle Database gH_SQL = null; int gI_Driver = Driver_unknown; @@ -3882,3 +3892,67 @@ void UpdateStyleSettings(int client) UpdateAiraccelerate(client, GetStyleSettingFloat(gA_Timers[client].bsStyle, "airaccelerate")); } } + +public void VScript_OnScriptVMInitialized() +{ +#if 0 + // ::Timer_OnStart <- function(player) + if (VScript_GetGlobalFunction("Timer_OnStart")) + gH_VScript_OnStart = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnStart")); + else + gH_VScript_OnStart = view_as(Address_Null); + // ::Timer_OnEnd <- function(player) + if (VScript_GetGlobalFunction("Timer_OnEnd")) + gH_VScript_OnEnd = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnEnd")); + else + gH_VScript_OnEnd = view_as(Address_Null); +#endif + + // function Timer_GetTime(player) // returns a float + gH_VScript_Timer_GetTime = VScript_CreateFunction(); + gH_VScript_Timer_GetTime.SetScriptName("Timer_GetTime"); + gH_VScript_Timer_GetTime.Return = FIELD_FLOAT; + gH_VScript_Timer_GetTime.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetTime.SetFunctionEmpty(); + gH_VScript_Timer_GetTime.Register(); + gH_VScript_Timer_GetTime.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetTime); + + // function gH_VScript_Timer_GetStatus(player) // returns a int -- 0=stopped, 1=running, 2=paused + gH_VScript_Timer_GetStatus = VScript_CreateFunction(); + gH_VScript_Timer_GetStatus.SetScriptName("Timer_GetStatus"); + gH_VScript_Timer_GetStatus.Return = FIELD_INTEGER; + gH_VScript_Timer_GetStatus.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetStatus.SetFunctionEmpty(); + gH_VScript_Timer_GetStatus.Register(); + gH_VScript_Timer_GetStatus.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetStatus); +} + +MRESReturn Detour_Timer_GetTime(DHookReturn hret, DHookParam params) +{ + int client = VScript_HScriptToEntity(params.Get(1)); + + if (client < 1 || client > MaxClients || !IsClientInGame(client)) + { + // Log error or something... + return MRES_Supercede; + } + + hret.Value = Shavit_GetClientTime(client); + + return MRES_Supercede; +} + +MRESReturn Detour_Timer_GetStatus(DHookReturn hret, DHookParam params) +{ + int client = VScript_HScriptToEntity(params.Get(1)); + + if (client < 1 || client > MaxClients || !IsClientInGame(client)) + { + // Log error or something... + return MRES_Supercede; + } + + hret.Value = view_as(GetTimerStatus(client)); + + return MRES_Supercede; +} From 4cd43629b39c2ca21941cf25c3b1799f17c49947 Mon Sep 17 00:00:00 2001 From: rtldg Date: Sat, 22 Mar 2025 17:19:53 +0000 Subject: [PATCH 05/14] Handle null players kind of --- .../sourcemod/scripting/shavit-checkpoints.sp | 20 ++++++++++++++-- addons/sourcemod/scripting/shavit-core.sp | 24 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index 53d9c0f3a..f253b5b87 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -2326,7 +2326,15 @@ public void VScript_OnScriptVMInitialized() MRESReturn Detour_Timer_SetCheckpointCustomData(DHookParam params) { - int client = VScript_HScriptToEntity(params.Get(1)); + HSCRIPT clienthandle = params.Get(1); + + if (clienthandle == view_as(0)) + { + // null object passed in probably + return MRES_Supercede; + } + + int client = VScript_HScriptToEntity(clienthandle); if (client < 1 || client > MaxClients || !IsClientInGame(client)) { @@ -2352,7 +2360,15 @@ MRESReturn Detour_Timer_SetCheckpointCustomData(DHookParam params) MRESReturn Detour_Timer_GetCheckpointCustomData(DHookReturn hret, DHookParam params) { - int client = VScript_HScriptToEntity(params.Get(1)); + HSCRIPT clienthandle = params.Get(1); + + if (clienthandle == view_as(0)) + { + // null object passed in probably + return MRES_Supercede; + } + + int client = VScript_HScriptToEntity(clienthandle); if (client < 1 || client > MaxClients || !IsClientInGame(client)) { diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 92581350b..10b256f21 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -3929,11 +3929,21 @@ public void VScript_OnScriptVMInitialized() MRESReturn Detour_Timer_GetTime(DHookReturn hret, DHookParam params) { - int client = VScript_HScriptToEntity(params.Get(1)); + HSCRIPT clienthandle = params.Get(1); + + if (clienthandle == view_as(0)) + { + // null object passed in probably + hret.Value = 0.0; + return MRES_Supercede; + } + + int client = VScript_HScriptToEntity(clienthandle); if (client < 1 || client > MaxClients || !IsClientInGame(client)) { // Log error or something... + hret.Value = 0.0; return MRES_Supercede; } @@ -3944,11 +3954,21 @@ MRESReturn Detour_Timer_GetTime(DHookReturn hret, DHookParam params) MRESReturn Detour_Timer_GetStatus(DHookReturn hret, DHookParam params) { - int client = VScript_HScriptToEntity(params.Get(1)); + HSCRIPT clienthandle = params.Get(1); + + if (clienthandle == view_as(0)) + { + // null object passed in probably + hret.Value = 0; + return MRES_Supercede; + } + + int client = VScript_HScriptToEntity(clienthandle); if (client < 1 || client > MaxClients || !IsClientInGame(client)) { // Log error or something... + hret.Value = 0; return MRES_Supercede; } From 791cf0de2cf027c480c6a45fef55967ae087389c Mon Sep 17 00:00:00 2001 From: rtldg Date: Wed, 26 Mar 2025 13:13:39 +0000 Subject: [PATCH 06/14] Add OnStart & OnFinish and rework some things --- .../sourcemod/scripting/shavit-checkpoints.sp | 51 +++++++----- addons/sourcemod/scripting/shavit-core.sp | 82 +++++++++++++------ 2 files changed, 88 insertions(+), 45 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index f253b5b87..f02401b89 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -243,6 +243,11 @@ public void OnPluginStart() if (gB_Late) { Shavit_OnChatConfigLoaded(); + + if (gB_VScript && VScript_IsScriptVMInitialized()) + { + VScript_OnScriptVMInitialized(); + } } } @@ -2284,44 +2289,48 @@ public any Native_SaveCheckpointCache(Handle plugin, int numParams) public void VScript_OnScriptVMInitialized() { + delete gH_VScript_Timer_OnCheckpointSave; + delete gH_VScript_Timer_OnCheckpointLoadPre; + delete gH_VScript_Timer_OnCheckpointLoadPost; + // ::Timer_OnCheckpointSave <- function(player) if (VScript_GetGlobalFunction("Timer_OnCheckpointSave")) gH_VScript_Timer_OnCheckpointSave = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointSave")); - else - gH_VScript_Timer_OnCheckpointSave = view_as(Address_Null); // ::Timer_OnCheckpointLoadPre <- function(player) if (VScript_GetGlobalFunction("Timer_OnCheckpointLoadPre")) gH_VScript_Timer_OnCheckpointLoadPre = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPre")); - else - gH_VScript_Timer_OnCheckpointLoadPre = view_as(Address_Null); // ::Timer_OnCheckpointLoadPost <- function(player) if (VScript_GetGlobalFunction("Timer_OnCheckpointLoadPost")) gH_VScript_Timer_OnCheckpointLoadPost = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPost")); - else - gH_VScript_Timer_OnCheckpointLoadPost = view_as(Address_Null); // function Timer_SetCheckpointCustomData(player, key, value) - gH_VScript_Timer_SetCheckpointCustomData = VScript_CreateFunction(); - gH_VScript_Timer_SetCheckpointCustomData.SetScriptName("Timer_SetCheckpointCustomData"); - gH_VScript_Timer_SetCheckpointCustomData.Return = FIELD_VOID; - gH_VScript_Timer_SetCheckpointCustomData.SetParam(1, FIELD_HSCRIPT); - gH_VScript_Timer_SetCheckpointCustomData.SetParam(2, FIELD_CSTRING); - gH_VScript_Timer_SetCheckpointCustomData.SetParam(3, FIELD_CSTRING); - gH_VScript_Timer_SetCheckpointCustomData.SetFunctionEmpty(); + if (!gH_VScript_Timer_SetCheckpointCustomData) + { + gH_VScript_Timer_SetCheckpointCustomData = VScript_CreateFunction(); + gH_VScript_Timer_SetCheckpointCustomData.SetScriptName("Timer_SetCheckpointCustomData"); + gH_VScript_Timer_SetCheckpointCustomData.Return = FIELD_VOID; + gH_VScript_Timer_SetCheckpointCustomData.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_SetCheckpointCustomData.SetParam(2, FIELD_CSTRING); + gH_VScript_Timer_SetCheckpointCustomData.SetParam(3, FIELD_CSTRING); + gH_VScript_Timer_SetCheckpointCustomData.SetFunctionEmpty(); + gH_VScript_Timer_SetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_SetCheckpointCustomData); + } gH_VScript_Timer_SetCheckpointCustomData.Register(); - gH_VScript_Timer_SetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_SetCheckpointCustomData); // function Timer_GetCheckpointCustomData(player, key, value) - gH_VScript_Timer_GetCheckpointCustomData = VScript_CreateFunction(); - gH_VScript_Timer_GetCheckpointCustomData.SetScriptName("Timer_GetCheckpointCustomData"); - gH_VScript_Timer_GetCheckpointCustomData.Return = FIELD_CSTRING; - gH_VScript_Timer_GetCheckpointCustomData.SetParam(1, FIELD_HSCRIPT); - gH_VScript_Timer_GetCheckpointCustomData.SetParam(2, FIELD_CSTRING); - gH_VScript_Timer_GetCheckpointCustomData.SetFunctionEmpty(); + if (!gH_VScript_Timer_GetCheckpointCustomData) + { + gH_VScript_Timer_GetCheckpointCustomData = VScript_CreateFunction(); + gH_VScript_Timer_GetCheckpointCustomData.SetScriptName("Timer_GetCheckpointCustomData"); + gH_VScript_Timer_GetCheckpointCustomData.Return = FIELD_CSTRING; + gH_VScript_Timer_GetCheckpointCustomData.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetCheckpointCustomData.SetParam(2, FIELD_CSTRING); + gH_VScript_Timer_GetCheckpointCustomData.SetFunctionEmpty(); + gH_VScript_Timer_GetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetCheckpointCustomData); + } gH_VScript_Timer_GetCheckpointCustomData.Register(); - gH_VScript_Timer_GetCheckpointCustomData.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetCheckpointCustomData); } MRESReturn Detour_Timer_SetCheckpointCustomData(DHookParam params) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 10b256f21..4d1241369 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -62,10 +62,8 @@ DynamicHook gH_TeleportDhook = null; Address gI_TF2PreventBunnyJumpingAddr = Address_Null; // vscript (non-checkpoint natives) -#if 0 VScriptExecute gH_VScript_OnStart; -VScriptExecute gH_VScript_OnEnd; -#endif +VScriptExecute gH_VScript_OnFinish; VScriptFunction gH_VScript_Timer_GetTime; VScriptFunction gH_VScript_Timer_GetStatus; @@ -135,6 +133,7 @@ bool gB_ReplayPlayback = false; bool gB_Rankings = false; bool gB_HUD = false; bool gB_AdminMenu = false; +bool gB_VScript = false; TopMenu gH_AdminMenu = null; TopMenuObject gH_TimerCommands = INVALID_TOPMENUOBJECT; @@ -452,6 +451,11 @@ public void OnPluginStart() OnClientPutInServer(i); } } + + if (gB_VScript && VScript_IsScriptVMInitialized()) + { + VScript_OnScriptVMInitialized(); + } } } @@ -648,6 +652,10 @@ public void OnLibraryAdded(const char[] name) { gB_AdminMenu = true; } + else if (StrEqual(name, "vscript")) + { + gB_VScript = true; + } } public void OnLibraryRemoved(const char[] name) @@ -678,6 +686,10 @@ public void OnLibraryRemoved(const char[] name) gH_AdminMenu = null; gH_TimerCommands = INVALID_TOPMENUOBJECT; } + else if (StrEqual(name, "vscript")) + { + gB_VScript = false; + } } public void OnMapStart() @@ -2032,6 +2044,15 @@ public int Native_FinishMap(Handle handler, int numParams) Call_PushCell(timestamp); Call_Finish(); + if (gB_VScript) + { + if (gH_VScript_OnFinish) + { + gH_VScript_OnFinish.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + gH_VScript_OnFinish.Execute(); + } + } + StopTimer(client); return 1; } @@ -2610,6 +2631,15 @@ void StartTimer(int client, int track, bool skipGroundCheck) Call_PushCell(client); Call_PushCell(track); Call_Finish(); + + if (gB_VScript) + { + if (gH_VScript_OnStart) + { + gH_VScript_OnStart.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + gH_VScript_OnStart.Execute(); + } + } } #if 0 else if(result == Plugin_Handled || result == Plugin_Stop) @@ -3895,36 +3925,40 @@ void UpdateStyleSettings(int client) public void VScript_OnScriptVMInitialized() { -#if 0 + delete gH_VScript_OnStart; + delete gH_VScript_OnFinish; + // ::Timer_OnStart <- function(player) if (VScript_GetGlobalFunction("Timer_OnStart")) gH_VScript_OnStart = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnStart")); - else - gH_VScript_OnStart = view_as(Address_Null); - // ::Timer_OnEnd <- function(player) - if (VScript_GetGlobalFunction("Timer_OnEnd")) - gH_VScript_OnEnd = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnEnd")); - else - gH_VScript_OnEnd = view_as(Address_Null); -#endif + + // ::Timer_OnFinish <- function(player) + if (VScript_GetGlobalFunction("Timer_OnFinish")) + gH_VScript_OnFinish = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnFinish")); // function Timer_GetTime(player) // returns a float - gH_VScript_Timer_GetTime = VScript_CreateFunction(); - gH_VScript_Timer_GetTime.SetScriptName("Timer_GetTime"); - gH_VScript_Timer_GetTime.Return = FIELD_FLOAT; - gH_VScript_Timer_GetTime.SetParam(1, FIELD_HSCRIPT); - gH_VScript_Timer_GetTime.SetFunctionEmpty(); + if (!gH_VScript_Timer_GetTime) + { + gH_VScript_Timer_GetTime = VScript_CreateFunction(); + gH_VScript_Timer_GetTime.SetScriptName("Timer_GetTime"); + gH_VScript_Timer_GetTime.Return = FIELD_FLOAT; + gH_VScript_Timer_GetTime.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetTime.SetFunctionEmpty(); + gH_VScript_Timer_GetTime.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetTime); + } gH_VScript_Timer_GetTime.Register(); - gH_VScript_Timer_GetTime.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetTime); // function gH_VScript_Timer_GetStatus(player) // returns a int -- 0=stopped, 1=running, 2=paused - gH_VScript_Timer_GetStatus = VScript_CreateFunction(); - gH_VScript_Timer_GetStatus.SetScriptName("Timer_GetStatus"); - gH_VScript_Timer_GetStatus.Return = FIELD_INTEGER; - gH_VScript_Timer_GetStatus.SetParam(1, FIELD_HSCRIPT); - gH_VScript_Timer_GetStatus.SetFunctionEmpty(); + if (!gH_VScript_Timer_GetStatus) + { + gH_VScript_Timer_GetStatus = VScript_CreateFunction(); + gH_VScript_Timer_GetStatus.SetScriptName("Timer_GetStatus"); + gH_VScript_Timer_GetStatus.Return = FIELD_INTEGER; + gH_VScript_Timer_GetStatus.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetStatus.SetFunctionEmpty(); + gH_VScript_Timer_GetStatus.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetStatus); + } gH_VScript_Timer_GetStatus.Register(); - gH_VScript_Timer_GetStatus.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetStatus); } MRESReturn Detour_Timer_GetTime(DHookReturn hret, DHookParam params) From 2bcf9facf4f4a495e56acd47b45a8215875ba91c Mon Sep 17 00:00:00 2001 From: rtldg Date: Wed, 26 Mar 2025 13:19:39 +0000 Subject: [PATCH 07/14] Add Timer_GetTrack --- addons/sourcemod/scripting/shavit-core.sp | 42 ++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 4d1241369..70ee5d2ec 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -66,6 +66,7 @@ VScriptExecute gH_VScript_OnStart; VScriptExecute gH_VScript_OnFinish; VScriptFunction gH_VScript_Timer_GetTime; VScriptFunction gH_VScript_Timer_GetStatus; +VScriptFunction gH_VScript_Timer_GetTrack; // database handle @@ -2049,6 +2050,7 @@ public int Native_FinishMap(Handle handler, int numParams) if (gH_VScript_OnFinish) { gH_VScript_OnFinish.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + gH_VScript_OnFinish.SetParam(2, FIELD_INTEGER, snapshot.iTimerTrack); gH_VScript_OnFinish.Execute(); } } @@ -2637,6 +2639,7 @@ void StartTimer(int client, int track, bool skipGroundCheck) if (gH_VScript_OnStart) { gH_VScript_OnStart.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + gH_VScript_OnStart.SetParam(2, FIELD_INTEGER, track); gH_VScript_OnStart.Execute(); } } @@ -3948,7 +3951,7 @@ public void VScript_OnScriptVMInitialized() } gH_VScript_Timer_GetTime.Register(); - // function gH_VScript_Timer_GetStatus(player) // returns a int -- 0=stopped, 1=running, 2=paused + // function Timer_GetStatus(player) // returns an int -- 0=stopped, 1=running, 2=paused if (!gH_VScript_Timer_GetStatus) { gH_VScript_Timer_GetStatus = VScript_CreateFunction(); @@ -3959,6 +3962,18 @@ public void VScript_OnScriptVMInitialized() gH_VScript_Timer_GetStatus.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetStatus); } gH_VScript_Timer_GetStatus.Register(); + + // function Timer_GetTrack(player) // returns an int -- 0=main, 1 or higher = a bonus track + if (!gH_VScript_Timer_GetTrack) + { + gH_VScript_Timer_GetTrack = VScript_CreateFunction(); + gH_VScript_Timer_GetTrack.SetScriptName("Timer_GetTrack"); + gH_VScript_Timer_GetTrack.Return = FIELD_INTEGER; + gH_VScript_Timer_GetTrack.SetParam(1, FIELD_HSCRIPT); + gH_VScript_Timer_GetTrack.SetFunctionEmpty(); + gH_VScript_Timer_GetTrack.CreateDetour().Enable(Hook_Pre, Detour_Timer_GetTrack); + } + gH_VScript_Timer_GetTrack.Register(); } MRESReturn Detour_Timer_GetTime(DHookReturn hret, DHookParam params) @@ -4010,3 +4025,28 @@ MRESReturn Detour_Timer_GetStatus(DHookReturn hret, DHookParam params) return MRES_Supercede; } + +MRESReturn Detour_Timer_GetTrack(DHookReturn hret, DHookParam params) +{ + HSCRIPT clienthandle = params.Get(1); + + if (clienthandle == view_as(0)) + { + // null object passed in probably + hret.Value = -1; + return MRES_Supercede; + } + + int client = VScript_HScriptToEntity(clienthandle); + + if (client < 1 || client > MaxClients || !IsClientInGame(client)) + { + // Log error or something... + hret.Value = -1; + return MRES_Supercede; + } + + hret.Value = view_as(gA_Timers[client].iTimerTrack); + + return MRES_Supercede; +} From 47fec34d841bc0e78431b6201540d55be0c76a0d Mon Sep 17 00:00:00 2001 From: rtldg Date: Wed, 26 Mar 2025 13:24:27 +0000 Subject: [PATCH 08/14] increase vscript string value size to 4096 because we're crazy --- addons/sourcemod/scripting/shavit-checkpoints.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index f02401b89..42fc0870a 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -2357,7 +2357,7 @@ MRESReturn Detour_Timer_SetCheckpointCustomData(DHookParam params) return MRES_Supercede; } - char key[512], value[512]; + char key[512], value[4096]; params.GetString(2, key, sizeof(key)); params.GetString(3, value, sizeof(value)); @@ -2391,7 +2391,7 @@ MRESReturn Detour_Timer_GetCheckpointCustomData(DHookReturn hret, DHookParam par return MRES_Supercede; } - char key[512], value[512]; + char key[512], value[4096]; params.GetString(2, key, sizeof(key)); if (gH_VScript_Checkpoint_CustomData[client]) From e668ef83953a535ed0abfed2a12d55fa4d54cd38 Mon Sep 17 00:00:00 2001 From: rtldg Date: Wed, 26 Mar 2025 13:43:46 +0000 Subject: [PATCH 09/14] Add vscript & sourcescramble to workflow --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82ea637e6..341295977 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,13 @@ jobs: tar --strip-components=1 -xvzf v5.0.1.tar.gz sm-json-5.0.1/addons/sourcemod/scripting/include wget https://github.com/hermansimensen/eventqueue-fix/archive/refs/heads/main.tar.gz tar --strip-components=1 -xvzf main.tar.gz -C addons/sourcemod - rm -rf *.zip *.tar.gz addons/sourcemod/.git* addons/sourcemod/LICENSE + wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.tar.gz + tar --strip-components=1 -xvzf package.tar.gz + wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.zip + unzip package.zip "addons/sourcemod/scripting/extensions/*" + wget https://github.com/FortyTwoFortyTwo/VScript/archive/refs/tags/1.10.0.90.tar.gz + tar --strip-components=1 -xvzf 1.10.0.90.tar.gz + rm -rf *.zip *.tar.gz addons/sourcemod/.git* addons/sourcemod/LICENSE scripts - name: Run compiler shell: bash From 2cff72b36f8a390e6ca9d3b30fa4029faeec483a Mon Sep 17 00:00:00 2001 From: rtldg Date: Wed, 26 Mar 2025 13:44:34 +0000 Subject: [PATCH 10/14] path typo --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 341295977..8e45dfd5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.tar.gz tar --strip-components=1 -xvzf package.tar.gz wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.zip - unzip package.zip "addons/sourcemod/scripting/extensions/*" + unzip package.zip "addons/sourcemod/extensions/*" wget https://github.com/FortyTwoFortyTwo/VScript/archive/refs/tags/1.10.0.90.tar.gz tar --strip-components=1 -xvzf 1.10.0.90.tar.gz rm -rf *.zip *.tar.gz addons/sourcemod/.git* addons/sourcemod/LICENSE scripts From 1376f3b6ba2b54732b5bf870ef201378be642e37 Mon Sep 17 00:00:00 2001 From: rtldg Date: Wed, 26 Mar 2025 13:48:18 +0000 Subject: [PATCH 11/14] Bloatflow should work now --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e45dfd5f..6c0e54ddb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,12 +33,12 @@ jobs: wget https://github.com/hermansimensen/eventqueue-fix/archive/refs/heads/main.tar.gz tar --strip-components=1 -xvzf main.tar.gz -C addons/sourcemod wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.tar.gz - tar --strip-components=1 -xvzf package.tar.gz + tar --strip-components=2 -xvzf package.tar.gz -C addons/sourcemod wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.zip unzip package.zip "addons/sourcemod/extensions/*" wget https://github.com/FortyTwoFortyTwo/VScript/archive/refs/tags/1.10.0.90.tar.gz - tar --strip-components=1 -xvzf 1.10.0.90.tar.gz - rm -rf *.zip *.tar.gz addons/sourcemod/.git* addons/sourcemod/LICENSE scripts + tar --strip-components=1 -xvzf 1.10.0.90.tar.gz -C addons/sourcemod + rm -rf *.zip *.tar.gz addons/sourcemod/{.git*,LICENSE,plugins,scripts,scripting/vscript_test.sp,README.md} - name: Run compiler shell: bash From 52df730a4f712eafb372dcf5791e88faa6e91a20 Mon Sep 17 00:00:00 2001 From: rtldg Date: Mon, 31 Mar 2025 11:17:50 +0000 Subject: [PATCH 12/14] VScript_GetGlobalFunction is worthless garbage --- addons/sourcemod/scripting/shavit-checkpoints.sp | 7 ++++--- addons/sourcemod/scripting/shavit-core.sp | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index 42fc0870a..13fe3d0c7 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -2287,6 +2287,7 @@ public any Native_SaveCheckpointCache(Handle plugin, int numParams) return SetNativeArray(3, cache, sizeof(cp_cache_t)); } +// This is called after mapspawn.nut for reference. (Which is before OnMapStart() too) public void VScript_OnScriptVMInitialized() { delete gH_VScript_Timer_OnCheckpointSave; @@ -2294,15 +2295,15 @@ public void VScript_OnScriptVMInitialized() delete gH_VScript_Timer_OnCheckpointLoadPost; // ::Timer_OnCheckpointSave <- function(player) - if (VScript_GetGlobalFunction("Timer_OnCheckpointSave")) + if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointSave")) gH_VScript_Timer_OnCheckpointSave = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointSave")); // ::Timer_OnCheckpointLoadPre <- function(player) - if (VScript_GetGlobalFunction("Timer_OnCheckpointLoadPre")) + if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointLoadPre")) gH_VScript_Timer_OnCheckpointLoadPre = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPre")); // ::Timer_OnCheckpointLoadPost <- function(player) - if (VScript_GetGlobalFunction("Timer_OnCheckpointLoadPost")) + if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointLoadPost")) gH_VScript_Timer_OnCheckpointLoadPost = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPost")); // function Timer_SetCheckpointCustomData(player, key, value) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 70ee5d2ec..68a26a361 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -3926,17 +3926,18 @@ void UpdateStyleSettings(int client) } } +// This is called after mapspawn.nut for reference. (Which is before OnMapStart() too) public void VScript_OnScriptVMInitialized() { delete gH_VScript_OnStart; delete gH_VScript_OnFinish; // ::Timer_OnStart <- function(player) - if (VScript_GetGlobalFunction("Timer_OnStart")) + if (HSCRIPT_RootTable.ValueExists("Timer_OnStart")) gH_VScript_OnStart = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnStart")); // ::Timer_OnFinish <- function(player) - if (VScript_GetGlobalFunction("Timer_OnFinish")) + if (HSCRIPT_RootTable.ValueExists("Timer_OnFinish")) gH_VScript_OnFinish = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnFinish")); // function Timer_GetTime(player) // returns a float From 0458b67ac7f7c7c5ef6a57c848e2f4d12a1a84fd Mon Sep 17 00:00:00 2001 From: rtldg Date: Thu, 24 Apr 2025 00:07:01 +0000 Subject: [PATCH 13/14] Fetch callbacks for each call --- .../sourcemod/scripting/shavit-checkpoints.sp | 46 ++++++++----------- addons/sourcemod/scripting/shavit-core.sp | 34 ++++++-------- 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index 13fe3d0c7..618b8c8d5 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -117,9 +117,6 @@ int gI_Offset_m_afButtonDisabled = 0; int gI_Offset_m_afButtonForced = 0; // vscript!!! you're going to break all my checkpoints!!! -VScriptExecute gH_VScript_Timer_OnCheckpointSave; -VScriptExecute gH_VScript_Timer_OnCheckpointLoadPre; -VScriptExecute gH_VScript_Timer_OnCheckpointLoadPost; VScriptFunction gH_VScript_Timer_SetCheckpointCustomData; VScriptFunction gH_VScript_Timer_GetCheckpointCustomData; enum VScript_Checkpoint_State @@ -1791,10 +1788,13 @@ void SaveCheckpointCache(int saver, int target, cp_cache_t cpcache, int index, H gI_VScript_Checkpointing[target] = VCS_Saving; gH_VScript_Checkpoint_CustomData[target] = cpcache.customdata; - if (gH_VScript_Timer_OnCheckpointSave) + if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointSave")) { - gH_VScript_Timer_OnCheckpointSave.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(target)); - gH_VScript_Timer_OnCheckpointSave.Execute(); + // ::Timer_OnCheckpointSave <- function(player) + VScriptExecute Timer_OnCheckpointSave = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointSave")); + Timer_OnCheckpointSave.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(target)); + Timer_OnCheckpointSave.Execute(); + delete Timer_OnCheckpointSave; } gI_VScript_Checkpointing[target] = VCS_NO_TOUCH; @@ -1902,10 +1902,13 @@ bool LoadCheckpointCache(int client, cp_cache_t cpcache, int index, bool force = gI_VScript_Checkpointing[client] = VCS_Loading; gH_VScript_Checkpoint_CustomData[client] = cpcache.customdata; - if (gH_VScript_Timer_OnCheckpointLoadPre) + if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointLoadPre")) { - gH_VScript_Timer_OnCheckpointLoadPre.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); - gH_VScript_Timer_OnCheckpointLoadPre.Execute(); + // ::Timer_OnCheckpointLoadPre <- function(player) + VScriptExecute Timer_OnCheckpointLoadPre = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPre")); + Timer_OnCheckpointLoadPre.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + Timer_OnCheckpointLoadPre.Execute(); + delete Timer_OnCheckpointLoadPre; } gI_VScript_Checkpointing[client] = VCS_NO_TOUCH; @@ -2290,22 +2293,6 @@ public any Native_SaveCheckpointCache(Handle plugin, int numParams) // This is called after mapspawn.nut for reference. (Which is before OnMapStart() too) public void VScript_OnScriptVMInitialized() { - delete gH_VScript_Timer_OnCheckpointSave; - delete gH_VScript_Timer_OnCheckpointLoadPre; - delete gH_VScript_Timer_OnCheckpointLoadPost; - - // ::Timer_OnCheckpointSave <- function(player) - if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointSave")) - gH_VScript_Timer_OnCheckpointSave = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointSave")); - - // ::Timer_OnCheckpointLoadPre <- function(player) - if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointLoadPre")) - gH_VScript_Timer_OnCheckpointLoadPre = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPre")); - - // ::Timer_OnCheckpointLoadPost <- function(player) - if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointLoadPost")) - gH_VScript_Timer_OnCheckpointLoadPost = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPost")); - // function Timer_SetCheckpointCustomData(player, key, value) if (!gH_VScript_Timer_SetCheckpointCustomData) { @@ -2410,10 +2397,13 @@ void Do_Timer_OnCheckpointLoadPost(int client, StringMap customdata) gI_VScript_Checkpointing[client] = VCS_Loading; gH_VScript_Checkpoint_CustomData[client] = customdata; - if (gH_VScript_Timer_OnCheckpointLoadPost) + if (HSCRIPT_RootTable.ValueExists("Timer_OnCheckpointLoadPost")) { - gH_VScript_Timer_OnCheckpointLoadPost.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); - gH_VScript_Timer_OnCheckpointLoadPost.Execute(); + // ::Timer_OnCheckpointLoadPost <- function(player) + VScriptExecute Timer_OnCheckpointLoadPost = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnCheckpointLoadPost")); + Timer_OnCheckpointLoadPost.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + Timer_OnCheckpointLoadPost.Execute(); + delete Timer_OnCheckpointLoadPost; } gI_VScript_Checkpointing[client] = VCS_NO_TOUCH; diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 7ed07134a..e052af977 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -62,8 +62,6 @@ DynamicHook gH_TeleportDhook = null; Address gI_TF2PreventBunnyJumpingAddr = Address_Null; // vscript (non-checkpoint natives) -VScriptExecute gH_VScript_OnStart; -VScriptExecute gH_VScript_OnFinish; VScriptFunction gH_VScript_Timer_GetTime; VScriptFunction gH_VScript_Timer_GetStatus; VScriptFunction gH_VScript_Timer_GetTrack; @@ -2051,11 +2049,14 @@ public int Native_FinishMap(Handle handler, int numParams) if (gB_VScript) { - if (gH_VScript_OnFinish) + if (HSCRIPT_RootTable.ValueExists("Timer_OnFinish")) { - gH_VScript_OnFinish.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); - gH_VScript_OnFinish.SetParam(2, FIELD_INTEGER, snapshot.iTimerTrack); - gH_VScript_OnFinish.Execute(); + // ::Timer_OnFinish <- function(player) + VScriptExecute Timer_OnFinish = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnFinish")); + Timer_OnFinish.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + Timer_OnFinish.SetParam(2, FIELD_INTEGER, snapshot.iTimerTrack); + Timer_OnFinish.Execute(); + delete Timer_OnFinish; } } @@ -2656,11 +2657,13 @@ void StartTimer(int client, int track, bool skipGroundCheck) if (gB_VScript) { - if (gH_VScript_OnStart) + if (HSCRIPT_RootTable.ValueExists("Timer_OnStart")) { - gH_VScript_OnStart.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); - gH_VScript_OnStart.SetParam(2, FIELD_INTEGER, track); - gH_VScript_OnStart.Execute(); + VScriptExecute Timer_OnStart = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnStart")); + Timer_OnStart.SetParam(1, FIELD_HSCRIPT, VScript_EntityToHScript(client)); + Timer_OnStart.SetParam(2, FIELD_INTEGER, track); + Timer_OnStart.Execute(); + delete Timer_OnStart; } } } @@ -3953,17 +3956,6 @@ void UpdateStyleSettings(int client) // This is called after mapspawn.nut for reference. (Which is before OnMapStart() too) public void VScript_OnScriptVMInitialized() { - delete gH_VScript_OnStart; - delete gH_VScript_OnFinish; - - // ::Timer_OnStart <- function(player) - if (HSCRIPT_RootTable.ValueExists("Timer_OnStart")) - gH_VScript_OnStart = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnStart")); - - // ::Timer_OnFinish <- function(player) - if (HSCRIPT_RootTable.ValueExists("Timer_OnFinish")) - gH_VScript_OnFinish = new VScriptExecute(HSCRIPT_RootTable.GetValue("Timer_OnFinish")); - // function Timer_GetTime(player) // returns a float if (!gH_VScript_Timer_GetTime) { From fd597c3a818d86023f3746b5ef4b081d5d49c2fd Mon Sep 17 00:00:00 2001 From: rtldg Date: Tue, 29 Apr 2025 23:22:35 +0000 Subject: [PATCH 14/14] bump sourcescramble version --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c0e54ddb..57f60755f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,9 +32,9 @@ jobs: tar --strip-components=1 -xvzf v5.0.1.tar.gz sm-json-5.0.1/addons/sourcemod/scripting/include wget https://github.com/hermansimensen/eventqueue-fix/archive/refs/heads/main.tar.gz tar --strip-components=1 -xvzf main.tar.gz -C addons/sourcemod - wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.tar.gz + wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.8.1.1/package.tar.gz tar --strip-components=2 -xvzf package.tar.gz -C addons/sourcemod - wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.7.1.4/package.zip + wget https://github.com/nosoop/SMExt-SourceScramble/releases/download/0.8.1.1/package.zip unzip package.zip "addons/sourcemod/extensions/*" wget https://github.com/FortyTwoFortyTwo/VScript/archive/refs/tags/1.10.0.90.tar.gz tar --strip-components=1 -xvzf 1.10.0.90.tar.gz -C addons/sourcemod