From 37b085a9f57d6a0c28966a876a979f12ce2ce0fd Mon Sep 17 00:00:00 2001 From: Roflmuffin Date: Mon, 23 Oct 2023 12:34:53 +1000 Subject: [PATCH] feat: add network vector support --- managed/CounterStrikeSharp.API/Core/API.cs | 23 +++++++++++ .../Core/Model/NetworkedVector.cs | 39 ++++++++++++++++++- managed/TestPlugin/TestPlugin.cs | 6 +++ src/scripting/natives/natives_memory.cpp | 15 +++++++ src/scripting/natives/natives_memory.yaml | 4 +- 5 files changed, 84 insertions(+), 3 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs index f6df2e19..4071dc1d 100644 --- a/managed/CounterStrikeSharp.API/Core/API.cs +++ b/managed/CounterStrikeSharp.API/Core/API.cs @@ -726,6 +726,29 @@ namespace CounterStrikeSharp.API.Core } } + public static int GetNetworkVectorSize(IntPtr vec){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(vec); + ScriptContext.GlobalScriptContext.SetIdentifier(0xA585F34E); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int)); + } + } + + public static IntPtr GetNetworkVectorElementAt(IntPtr vec, int index){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(vec); + ScriptContext.GlobalScriptContext.Push(index); + ScriptContext.GlobalScriptContext.SetIdentifier(0x67A31E3F); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + public static short GetSchemaOffset(string classname, string propname){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); diff --git a/managed/CounterStrikeSharp.API/Core/Model/NetworkedVector.cs b/managed/CounterStrikeSharp.API/Core/Model/NetworkedVector.cs index 35a4785a..93e2a4e3 100644 --- a/managed/CounterStrikeSharp.API/Core/Model/NetworkedVector.cs +++ b/managed/CounterStrikeSharp.API/Core/Model/NetworkedVector.cs @@ -1,13 +1,48 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Reflection.Metadata; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; +using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Utils; namespace CounterStrikeSharp.API.Core; -public partial class NetworkedVector +public partial class NetworkedVector : NativeObject, IReadOnlyCollection { + public NetworkedVector(IntPtr pointer) : base(pointer) + { + } + + public unsafe uint Size => Unsafe.Read((void*)Handle); -} + public unsafe int Count => NativeAPI.GetNetworkVectorSize(Handle); + + public T this[int index] + { + get + { + if (!typeof(T).IsGenericType || typeof(T).GetGenericTypeDefinition() != typeof(CHandle<>)) + { + throw new NotSupportedException("Networked vectors currently only support CHandle"); + } + + return (T)Activator.CreateInstance(typeof(T), NativeAPI.GetNetworkVectorElementAt(Handle, index)); + } + } + + public IEnumerator GetEnumerator() + { + for (int i = 0; i < Count; i++) + { + yield return this[i]; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} \ No newline at end of file diff --git a/managed/TestPlugin/TestPlugin.cs b/managed/TestPlugin/TestPlugin.cs index d6cb1e43..ebed8099 100644 --- a/managed/TestPlugin/TestPlugin.cs +++ b/managed/TestPlugin/TestPlugin.cs @@ -71,7 +71,13 @@ namespace TestPlugin var player = @event.Userid; var pawn = player.PlayerPawn.Value; var activeWeapon = @event.Userid.PlayerPawn.Value.WeaponServices?.ActiveWeapon.Value; + var weapons = @event.Userid.PlayerPawn.Value.WeaponServices?.MyWeapons; + Server.NextFrame(() => + { + player.PrintToCenter(string.Join("\n", weapons.Select(x => x.Value.DesignerName))); + }); + activeWeapon.ReserveAmmo[0] = 250; activeWeapon.Clip1 = 250; diff --git a/src/scripting/natives/natives_memory.cpp b/src/scripting/natives/natives_memory.cpp index ff389090..497e6c10 100644 --- a/src/scripting/natives/natives_memory.cpp +++ b/src/scripting/natives/natives_memory.cpp @@ -206,6 +206,19 @@ void ExecuteVirtualFunction(ScriptContext &script_context) { // globals::hook_manager.Unhook(function, entity_index, callback, post); // } +int GetNetworkVectorSize(ScriptContext &script_context) { + auto vec = script_context.GetArgument*>(0); + + return vec->Count(); +} + +void* GetNetworkVectorElementAt(ScriptContext &script_context) { + auto vec = script_context.GetArgument*>(0); + auto index = script_context.GetArgument(1); + + return &vec->Element(index); +} + REGISTER_NATIVES(memory, { ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION", CreateVirtualFunction); ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_BY_SIGNATURE", @@ -214,5 +227,7 @@ REGISTER_NATIVES(memory, { // ScriptEngine::RegisterNativeHandler("HOOK_FUNCTION", HookFunction); // ScriptEngine::RegisterNativeHandler("UNHOOK_FUNCTION", UnhookFunction); ScriptEngine::RegisterNativeHandler("FIND_SIGNATURE", FindSignature); + ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_SIZE", GetNetworkVectorSize); + ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_ELEMENT_AT", GetNetworkVectorElementAt); }) } // namespace counterstrikesharp diff --git a/src/scripting/natives/natives_memory.yaml b/src/scripting/natives/natives_memory.yaml index f654b30e..33ae1c7f 100644 --- a/src/scripting/natives/natives_memory.yaml +++ b/src/scripting/natives/natives_memory.yaml @@ -1,4 +1,6 @@ CREATE_VIRTUAL_FUNCTION: pointer:pointer,vtableOffset:int,numArguments:int,returnType:int,arguments:object[] -> pointer CREATE_VIRTUAL_FUNCTION_BY_SIGNATURE: pointer:pointer,binaryName:string,signature:string,numArguments:int,returnType:int,arguments:object[] -> pointer EXECUTE_VIRTUAL_FUNCTION: function:pointer,arguments:object[] -> any -FIND_SIGNATURE: modulePath:string, signature:string -> pointer \ No newline at end of file +FIND_SIGNATURE: modulePath:string, signature:string -> pointer +GET_NETWORK_VECTOR_SIZE: vec:pointer -> int +GET_NETWORK_VECTOR_ELEMENT_AT: vec:pointer, index:int -> pointer \ No newline at end of file