From fce464175308e5ed9dd883d0326a4363cb3009eb Mon Sep 17 00:00:00 2001 From: roflmuffin Date: Thu, 11 Dec 2025 04:11:32 +0000 Subject: [PATCH 1/3] feat: bring offset virtual functions to latest --- .../Generated/Natives/API.cs | 37 ++ .../DynamicFunctions/BaseMemoryFunction.cs | 91 ++++- .../DynamicFunctions/MemoryFunctionVoid.cs | 373 +++++++++++++++++- .../MemoryFunctionWithReturn.cs | 362 +++++++++++++++++ .../Modules/Memory/VTable.cs | 181 +++++++++ .../Modules/Memory/VirtualFunctionVoid.cs | 313 +++++++++------ .../Memory/VirtualFunctionWithReturn.cs | 320 +++++++++------ src/scripting/natives/natives_memory.cpp | 124 ++++++ src/scripting/natives/natives_memory.yaml | 2 + 9 files changed, 1570 insertions(+), 233 deletions(-) create mode 100644 managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs diff --git a/managed/CounterStrikeSharp.API/Generated/Natives/API.cs b/managed/CounterStrikeSharp.API/Generated/Natives/API.cs index e093a0cbe..f5743dee8 100644 --- a/managed/CounterStrikeSharp.API/Generated/Natives/API.cs +++ b/managed/CounterStrikeSharp.API/Generated/Natives/API.cs @@ -1406,6 +1406,43 @@ public static IntPtr CreateVirtualFunctionBySignature(IntPtr pointer, string bin } } + public static IntPtr CreateVirtualFunctionBySymbol(string binaryname, string symbolname, int vtableoffset, int numarguments, int returntype, object[] arguments){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(binaryname); + ScriptContext.GlobalScriptContext.Push(symbolname); + ScriptContext.GlobalScriptContext.Push(vtableoffset); + ScriptContext.GlobalScriptContext.Push(numarguments); + ScriptContext.GlobalScriptContext.Push(returntype); + foreach (var obj in arguments) + { + ScriptContext.GlobalScriptContext.Push(obj); + } + ScriptContext.GlobalScriptContext.SetIdentifier(0xF873189F); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + + public static IntPtr CreateVirtualFunctionFromVTable(IntPtr pointer, int vtableoffset, int numarguments, int returntype, object[] arguments){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(pointer); + ScriptContext.GlobalScriptContext.Push(vtableoffset); + ScriptContext.GlobalScriptContext.Push(numarguments); + ScriptContext.GlobalScriptContext.Push(returntype); + foreach (var obj in arguments) + { + ScriptContext.GlobalScriptContext.Push(obj); + } + ScriptContext.GlobalScriptContext.SetIdentifier(0xE9D17E63); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + public static void HookFunction(IntPtr function, InputArgument hook, bool post){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs index c9d8ed018..14f656899 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs @@ -1,14 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using CounterStrikeSharp.API.Core; - -namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; public abstract class BaseMemoryFunction : NativeObject { private static Dictionary _createdFunctions = new(); + internal static Dictionary _createdOffsetFunctions = new(); + private static IntPtr CreateValveFunctionBySignature(string signature, DataType returnType, DataType[] argumentTypes) { @@ -47,6 +44,56 @@ private static IntPtr CreateValveFunctionBySignature(string signature, string bi return function; } + private static IntPtr CreateValveFunctionByOffset(string symbolName, int offset, DataType returnType, + DataType[] argumentTypes, Func nativeCaller) + { + string constructKey = $"{symbolName}_{offset}"; + + if (!_createdOffsetFunctions.TryGetValue(constructKey, out var function)) + { + try + { + function = nativeCaller(); + _createdOffsetFunctions[constructKey] = function; + } + catch (Exception) + { + } + } + + return function; + } + + private static IntPtr CreateValveFunctionByOffset(IntPtr objectPtr, string symbolName, int offset, DataType returnType, + DataType[] argumentTypes) + { + return CreateValveFunctionByOffset(symbolName, offset, returnType, argumentTypes, () => + { + return NativeAPI.CreateVirtualFunction(objectPtr, offset, argumentTypes.Length, + (int)returnType, argumentTypes.Cast().ToArray()); + }); + } + + private static IntPtr CreateValveFunctionBySymbol(string symbolName, string binaryPath, int offset, DataType returnType, + DataType[] argumentTypes) + { + return CreateValveFunctionByOffset(symbolName, offset, returnType, argumentTypes, () => + { + return NativeAPI.CreateVirtualFunctionBySymbol(binaryPath, symbolName, offset, argumentTypes.Length, + (int)returnType, argumentTypes.Cast().ToArray()); + }); + } + + private static IntPtr CreateValveFunctionFromVTable(string symbolName, IntPtr vtable, int offset, DataType returnType, + DataType[] argumentTypes) + { + return CreateValveFunctionByOffset(symbolName, offset, returnType, argumentTypes, () => + { + return NativeAPI.CreateVirtualFunctionFromVTable(vtable, offset, argumentTypes.Length, + (int)returnType, argumentTypes.Cast().ToArray()); + }); + } + public BaseMemoryFunction(string signature, DataType returnType, DataType[] parameters) : base( CreateValveFunctionBySignature(signature, returnType, parameters)) { @@ -57,6 +104,38 @@ public BaseMemoryFunction(string signature, string binarypath, DataType returnTy { } + /// + /// WARNING: this is only supposed to be used with and variants. + /// + internal BaseMemoryFunction(IntPtr objectPtr, string symbolName, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionByOffset(objectPtr, symbolName, offset, returnType, parameters)) + { + } + + /// + /// WARNING: this is only supposed to be used with and variants. + /// + internal BaseMemoryFunction(string symbolName, string binaryPath, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionBySymbol(symbolName, binaryPath, offset, returnType, parameters)) + { + } + + /// + /// WARNING: this is only supposed to be used with and variants. + /// + internal BaseMemoryFunction(string symbolName, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionBySymbol(symbolName, Addresses.ServerPath, offset, returnType, parameters)) + { + } + + /// + /// WARNING: this is only supposed to be used with and variants. + /// + internal BaseMemoryFunction(string symbolName, IntPtr vtable, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionFromVTable(symbolName, vtable, offset, returnType, parameters)) + { + } + public void Hook(Func handler, HookMode mode) { NativeAPI.HookFunction(Handle, handler, mode == HookMode.Post); diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs index 867c5b096..d1990b893 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs @@ -11,7 +11,8 @@ public MemoryFunctionVoid(string signature) : base(signature, DataType.DATA_TYPE { } - public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID, Array.Empty()) + public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID, + Array.Empty()) { } @@ -38,6 +39,27 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { + } + public void Invoke(T1 arg1) { InvokeInternalVoid(false, arg1); @@ -61,6 +83,27 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + public void Invoke(T1 arg1, T2 arg2) { InvokeInternalVoid(false, arg1, arg2); @@ -84,6 +127,27 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3) { InvokeInternalVoid(false, arg1, arg2, arg3); @@ -115,6 +179,43 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { InvokeInternalVoid(false, arg1, arg2, arg3, arg4); @@ -148,6 +249,47 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { InvokeInternalVoid(false, arg1, arg2, arg3, arg4, arg5); @@ -181,6 +323,47 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { InvokeInternalVoid(false, arg1, arg2, arg3, arg4, arg5, arg6); @@ -216,6 +399,51 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { InvokeInternalVoid(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7); @@ -251,6 +479,51 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { InvokeInternalVoid(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); @@ -288,6 +561,55 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { InvokeInternalVoid(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); @@ -325,6 +647,55 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { InvokeInternalVoid(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs index 7d121bf3d..13b170f12 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs @@ -40,6 +40,29 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { + } + public TResult Invoke(T1 arg1) { return InvokeInternal(false, arg1); @@ -63,6 +86,29 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + public TResult Invoke(T1 arg1, T2 arg2) { return InvokeInternal(false, arg1, arg2); @@ -86,6 +132,29 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3) { return InvokeInternal(false, arg1, arg2, arg3); @@ -117,6 +186,45 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { return InvokeInternal(false, arg1, arg2, arg3, arg4); @@ -148,6 +256,45 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { return InvokeInternal(false, arg1, arg2, arg3, arg4, arg5); @@ -179,6 +326,45 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { return InvokeInternal(false, arg1, arg2, arg3, arg4, arg5, arg6); @@ -212,6 +398,49 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { return InvokeInternal(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7); @@ -245,6 +474,49 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { return InvokeInternal(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); @@ -278,6 +550,49 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { return InvokeInternal(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); @@ -313,6 +628,53 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, + typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { return InvokeInternal(false, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs new file mode 100644 index 000000000..6c6c6c269 --- /dev/null +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs @@ -0,0 +1,181 @@ +/* + * This file is part of CounterStrikeSharp. + * CounterStrikeSharp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CounterStrikeSharp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CounterStrikeSharp. If not, see . * + */ + +namespace CounterStrikeSharp.API.Modules.Memory +{ + public abstract class VTableBase : NativeObject + { + internal VTableBase(IntPtr ptr) : base(ptr) + { } + + internal VTableBase(string symbolName) : this(NativeAPI.FindVirtualTable(Addresses.ServerPath, symbolName)) + { } + + internal VTableBase(string symbolName, string binaryPath) : this(NativeAPI.FindVirtualTable(binaryPath, symbolName)) + { } + } + + /// + /// Represents a low-level virtual table. + /// + public sealed class VTable : VTableBase + { + public VTable(IntPtr ptr) : base(ptr) + { } + + public VTable(string symbolName) : base(symbolName) + { } + + public VTable(string symbolName, string binaryPath) : base(binaryPath, symbolName) + { } + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + } + + /// + /// Represents a low-level virtual table. + /// This version is meant to be used with explicit class type. TClass will be passed as TArg1 on invocation. + /// + public sealed class VTable : VTableBase + { + public VTable(IntPtr ptr) : base(ptr) + { } + + public VTable() : base(typeof(TClass).Name) + { } + + public VTable(string binaryPath) : base(typeof(TClass).Name, binaryPath) + { } + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + } +} \ No newline at end of file diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs index 08f9630fd..d82d0209e 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs @@ -14,274 +14,365 @@ * along with CounterStrikeSharp. If not, see . * */ +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; + namespace CounterStrikeSharp.API.Modules.Memory; -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public void Invoke() + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function(); } -} -public partial class VirtualFunctionVoid -{ - private Action Function; + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1) + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } + + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3, arg4); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } + + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5); } } -public partial class VirtualFunctionVoid +public partial class + VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6); } } -public partial class VirtualFunctionVoid +public partial class + VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } + + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } } -public partial class VirtualFunctionVoid +public partial class + VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } + + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } } -public partial class VirtualFunctionVoid +public partial class + VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } + + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } } -public partial class VirtualFunctionVoid +public partial class + VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } + + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10) + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } } \ No newline at end of file diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs index 489bb40b0..ddd1ebb35 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs @@ -14,279 +14,369 @@ * along with CounterStrikeSharp. If not, see . * */ +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; + namespace CounterStrikeSharp.API.Modules.Memory; -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - - public VirtualFunctionWithReturn(string signature, string binarypath) + + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke() + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(); } -} -public partial class VirtualFunctionWithReturn -{ - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1) + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } + + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3); } } -public partial class VirtualFunctionWithReturn +public partial class + VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3, arg4); } } -public partial class VirtualFunctionWithReturn +public partial class + VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } + + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5); } } -public partial class VirtualFunctionWithReturn +public partial class + VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6); } } -public partial class VirtualFunctionWithReturn +public partial class + VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } + + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } } -public partial class VirtualFunctionWithReturn +public partial class + VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } + + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } } -public partial class VirtualFunctionWithReturn +public partial class + VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } + + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } } -public partial class VirtualFunctionWithReturn +public partial class + VirtualFunctionWithReturn : MemoryFunctionWithReturn< + TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult> { - private Func Function; + public VirtualFunctionWithReturn(string signature) : base(signature) + { + } + + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) + { + } + + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10) + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } } \ No newline at end of file diff --git a/src/scripting/natives/natives_memory.cpp b/src/scripting/natives/natives_memory.cpp index 69af5151d..540553eb1 100644 --- a/src/scripting/natives/natives_memory.cpp +++ b/src/scripting/natives/natives_memory.cpp @@ -21,9 +21,16 @@ #include "core/function.h" #include "core/log.h" #include "core/memory.h" +#include "core/memory_module.h" #include "scripting/autonative.h" #include "scripting/script_engine.h" +#ifdef _WIN32 +#define CALL_CONV CONV_THISCALL +#else +#define CALL_CONV CONV_CDECL +#endif + namespace counterstrikesharp { template inline void hash_combine(std::size_t& seed, const T& v) @@ -134,6 +141,121 @@ ValveFunction* CreateVirtualFunctionBySignature(ScriptContext& script_context) return function; } +ValveFunction* CreateVirtualFunctionBySymbol(ScriptContext& script_context) +{ + const auto* binary_name = script_context.GetArgument(0); + const auto* symbol_name = script_context.GetArgument(1); + auto vtable_offset = script_context.GetArgument(2); + auto num_arguments = script_context.GetArgument(3); + auto return_type = script_context.GetArgument(4); + + auto module = modules::GetModuleByName(binary_name); + + if (!module) + { + script_context.ThrowNativeError("Failed to get module %s", binary_name); + return nullptr; + } + + auto* vtable = module->FindVirtualTable(symbol_name); + + if (!vtable) + { + script_context.ThrowNativeError("Failed to get VTable %s from module %s", symbol_name, binary_name); + return nullptr; + } + + auto function_addr = static_cast(vtable)[vtable_offset]; + + if (function_addr == nullptr) + { + script_context.ThrowNativeError("Could not find virtual function at offset %i", vtable_offset); + return nullptr; + } + + auto args = std::vector(); + + for (int i = 0; i < num_arguments; i++) + { + args.push_back(script_context.GetArgument(5 + i)); + } + + VirtualFunctionCacheKey cacheKey; + cacheKey.functionAddr = function_addr; + cacheKey.callingConvention = CALL_CONV; + cacheKey.args = args; + cacheKey.returnType = return_type; + cacheKey.vtableOffset = vtable_offset; + + auto it = m_virtualFunctionCache.find(cacheKey); + if (it != m_virtualFunctionCache.end()) + { + CSSHARP_CORE_TRACE("Virtual function found in cache, reusing existing instance at {}, vtable offset {}", function_addr, + vtable_offset); + return it->second; + } + + auto function = new ValveFunction(function_addr, CALL_CONV, args, return_type); + function->SetOffset(vtable_offset); + m_virtualFunctionCache[cacheKey] = function; + + CSSHARP_CORE_TRACE("Created virtual function, pointer found at {}, symbol {}, offset {}", function_addr, symbol_name, vtable_offset); + + return function; +} + +ValveFunction* CreateVirtualFunctionFromVTable(ScriptContext& script_context) +{ + auto* vtable = script_context.GetArgument(0); + auto vtable_offset = script_context.GetArgument(1); + auto num_arguments = script_context.GetArgument(2); + auto return_type = script_context.GetArgument(3); + + if (!vtable) + { + script_context.ThrowNativeError("VTable is null"); + return nullptr; + } + + auto* function_addr = static_cast(vtable)[vtable_offset]; + + if (function_addr == nullptr) + { + script_context.ThrowNativeError("Could not find virtual function at offset %i", vtable_offset); + return nullptr; + } + + auto args = std::vector(); + + for (int i = 0; i < num_arguments; i++) + { + args.push_back(script_context.GetArgument(4 + i)); + } + + VirtualFunctionCacheKey cacheKey; + cacheKey.functionAddr = function_addr; + cacheKey.callingConvention = CALL_CONV; + cacheKey.args = args; + cacheKey.returnType = return_type; + cacheKey.vtableOffset = vtable_offset; + + auto it = m_virtualFunctionCache.find(cacheKey); + if (it != m_virtualFunctionCache.end()) + { + CSSHARP_CORE_TRACE("Virtual function found in cache, reusing existing instance at {}, vtable offset {}", function_addr, + vtable_offset); + return it->second; + } + + auto* function = new ValveFunction(function_addr, CALL_CONV, args, return_type); + function->SetOffset(vtable_offset); + m_virtualFunctionCache[cacheKey] = function; + + CSSHARP_CORE_TRACE("Created virtual function, pointer found at {}, offset {}", function_addr, vtable_offset); + + return function; +} + ValveFunction* CreateVirtualFunction(ScriptContext& script_context) { auto ptr = script_context.GetArgument(0); @@ -249,6 +371,8 @@ void RemoveAllNetworkVectorElements(ScriptContext& script_context) REGISTER_NATIVES(memory, { ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION", CreateVirtualFunction); ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_BY_SIGNATURE", CreateVirtualFunctionBySignature); + ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_BY_SYMBOL", CreateVirtualFunctionBySymbol); + ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_FROM_V_TABLE", CreateVirtualFunctionFromVTable); ScriptEngine::RegisterNativeHandler("EXECUTE_VIRTUAL_FUNCTION", ExecuteVirtualFunction); ScriptEngine::RegisterNativeHandler("HOOK_FUNCTION", HookFunction); ScriptEngine::RegisterNativeHandler("UNHOOK_FUNCTION", UnhookFunction); diff --git a/src/scripting/natives/natives_memory.yaml b/src/scripting/natives/natives_memory.yaml index aa22ba206..8abed9c6c 100644 --- a/src/scripting/natives/natives_memory.yaml +++ b/src/scripting/natives/natives_memory.yaml @@ -1,5 +1,7 @@ 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 +CREATE_VIRTUAL_FUNCTION_BY_SYMBOL: binaryName:string, symbolName:string, vtableOffset:int, numArguments:int, returnType:int, arguments:object[] -> pointer +CREATE_VIRTUAL_FUNCTION_FROM_V_TABLE: pointer:pointer, vtableOffset:int, numArguments:int, returnType:int, arguments:object[] -> pointer HOOK_FUNCTION: function:pointer, hook:callback, post:bool -> void UNHOOK_FUNCTION: function:pointer, hook:callback, post:bool -> void EXECUTE_VIRTUAL_FUNCTION: function:pointer, bypass:bool, arguments:object[] -> any From 98c94271efc0ffe843119d70eb7dcb6f10b3175d Mon Sep 17 00:00:00 2001 From: roflmuffin Date: Thu, 11 Dec 2025 04:40:12 +0000 Subject: [PATCH 2/3] chore: add docs --- docfx/examples/WithVirtualFunctions.md | 5 + docfx/examples/toc.yml | 2 + .../WithVirtualFunctions.csproj | 12 ++ .../WithVirtualFunctionsPlugin.cs | 146 ++++++++++++++++++ managed/CounterStrikeSharp.sln | 7 + 5 files changed, 172 insertions(+) create mode 100644 docfx/examples/WithVirtualFunctions.md create mode 100644 examples/WithVirtualFunctions/WithVirtualFunctions.csproj create mode 100644 examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs diff --git a/docfx/examples/WithVirtualFunctions.md b/docfx/examples/WithVirtualFunctions.md new file mode 100644 index 000000000..79f9ad53d --- /dev/null +++ b/docfx/examples/WithVirtualFunctions.md @@ -0,0 +1,5 @@ +[!INCLUDE [WithVirtualFunctions](../../examples/WithVirtualFunctions/README.md)] + +View project on Github + +[!code-csharp[](../../examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs)] \ No newline at end of file diff --git a/docfx/examples/toc.yml b/docfx/examples/toc.yml index 41cf87e10..8c447c6cb 100644 --- a/docfx/examples/toc.yml +++ b/docfx/examples/toc.yml @@ -21,6 +21,8 @@ items: href: WithTranslations.md - name: User Messages href: WithUserMessages.md + - name: Virtual Functions + href: WithVirtualFunctions.md - name: Voice Overrides href: WithVoiceOverrides.md - name: Warcraft Plugin diff --git a/examples/WithVirtualFunctions/WithVirtualFunctions.csproj b/examples/WithVirtualFunctions/WithVirtualFunctions.csproj new file mode 100644 index 000000000..1a3c1a887 --- /dev/null +++ b/examples/WithVirtualFunctions/WithVirtualFunctions.csproj @@ -0,0 +1,12 @@ + + + net8.0 + enable + enable + false + false + + + + + diff --git a/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs new file mode 100644 index 000000000..b9cede828 --- /dev/null +++ b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs @@ -0,0 +1,146 @@ +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Memory; +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +using CounterStrikeSharp.API.Modules.Utils; + +using Microsoft.Extensions.Logging; + +namespace WithVirtualFunctions; + +public class WithVirtualFunctionsPlugin : BasePlugin +{ + public override string ModuleName => "Example: With Virtual Functions"; + public override string ModuleVersion => "1.0.0"; + public override string ModuleAuthor => "CounterStrikeSharp & Contributors"; + public override string ModuleDescription => "A simple plugin that hooks virtual functions by signature and offset"; + + // There are 3 ways to access a virtual function: + // 1 -> By signature + // 2 -> By the vtable offset (index) and an instance of the class + // 3 -> By the vtable offset (index) and without an instance of the class, but you need to know the vtable symbol + + // In this example, we are going to cover each method. + // Note: we won't cover RE here. + + // 1 -> Working with a signature: + + // this example shows that you can just pass the signature of the function + // Note: CS# assumes the server binary by default. there are overloads that allow you to specify a different binary. + // this example will continue inside the "Load" method. + private static VirtualFunctionVoid CCSPlayerController_SwitchTeam = new(GameData.GetSignature("CCSPlayerController_SwitchTeam")); + + // 2 -> Working with a vtable offset and an instance of the class + // Since we need an active instance of the class, we can only declare our virtual function here, and the rest of the code will be inside the "Load" method. + // Declare it as a nullable type, because we only set a value when this is being used. + private static VirtualFunctionVoid? CCSPlayer_ItemServices_GiveNamedItem; + + // 3 -> Working with a vtable offset without an instance: + + // this example shows that you can just pass the offset of the function, and CS# will automatically gather the VTable and access the function at the given offset. + // Note: CS# assumes the server binary by default. there are overloads that allow you to specify a different binary. + // Note: here, CS# uses the 'CCSPlayerController' (TArg1) argument type name as the "vtable symbol" and you should only rely on this if you know what you are doing. + // Note: if you need more freedom, there are other variants that supports custom parameters. (Check below) + private static VirtualFunctionVoid CCSPlayerController_ChangeTeam = new(GameData.GetOffset("CCSPlayerController_ChangeTeam")); + + // this example is pretty much the same as above, but you should prefer this method if you are not using explicit types, or the vtable symbol is not the same as a predefined class name. (usually when you use 'nint' instead) + // Note: you can still use the `CCSPlayerController` as TArg1, the main point here is if you explicitly set the vtable symbol name, then that value will be used and CS# will NOT use the TArg1 type name. + private static VirtualFunctionVoid CCSPlayerController_Respawn = new("CCSPlayerController", GameData.GetOffset("CCSPlayerController_Respawn")); + + // this is still the same, the main point here is that you can set the vtable symbol, binary path, and the offset. + // private static VirtualFunctionVoid Random_Function = new("VTABLE_SYMBOL_IN_ENGINE_BINARY", Addresses.EnginePath, 51); // this offset is a random example here + + private static VirtualFunctionWithReturn? CCSGameRules_FindPickerEntity; + + // Also there are wrapper classes that you can use: + // Note that this class actually holds the vtable ptr. (.Handle) + // VTable CCSGameRules_VTable_Symbol = new VTable("CCSGameRules"); // this will look for "CCSGameRules" vtable symbol, and if found, you can use this class to retrieve the functions. + + // this is the same as above, but CS# here will use the `TClass` type name as the vtable symbol, and when you retrieve functions, you don't have to specify the TArg1 each time, just the parameters. + VTable CCSGameRules_VTable = new VTable(); + + // examples can be found in the load method. + + public override void Load(bool hotReload) + { + // 1 -> By signature + // setup a hook on the virtual function that we got using the signature. + CCSPlayerController_SwitchTeam.Hook(OnSwitchTeam, HookMode.Pre); + + // 2 -> By the vtable offset (index) and an instance of the class + // so we need to somehow get an instance of `CCSPlayer_ItemServices`, the following code will be a random example and it depends on context. + + AddCommand("vfunc_2", "Example way of accessing a virtual function", (controller, info) => + { + // we don't want to setup the same thing over and over again + if (CCSPlayer_ItemServices_GiveNamedItem != null) + return; + + // sanity checks are up to you + if (controller == null || !controller.IsValid || controller.IsBot || controller.PlayerPawn.Value == null) + return; + + if (controller.PlayerPawn.Value.ItemServices == null) + return; + + // as you can see we used an active instance of the class (controller.PlayerPawn.Value.ItemServices) to access the virtual function. + // if you hook this function, any and every call to it will be intercepted, regardless of the instance. + // in this way, the instance is only needed to access the function through the vtable. + CCSPlayer_ItemServices_GiveNamedItem = new(controller.PlayerPawn.Value.ItemServices, GameData.GetOffset("CCSPlayer_ItemServices_GiveNamedItem")); + CCSPlayer_ItemServices_GiveNamedItem.Hook(OnGiveNamedItem, HookMode.Pre); + }); + + // 3 -> By the vtable offset (index) and without an instance of the class + + // we have already created our virtual function, so we can just use it here. + CCSPlayerController_ChangeTeam.Hook(OnChangeTeam, HookMode.Pre); + + // Wrapper examples + + // when using the generic variant of the VTable class, you only need to pass the generic parameters of the function, TArg1 is assumed to be `CCSGameRules` + CCSGameRules_FindPickerEntity = CCSGameRules_VTable.GetFunctionWithReturn(GameData.GetOffset("CCSGameRules_FindPickerEntity")); + CCSGameRules_FindPickerEntity.Hook(OnFindPickerEntity, HookMode.Pre); + + // and when you are not using the generic variant, you also need to pass the `CCSGameRules` each time. + // CCSGameRules_VTable_Symbol.GetFunctionWithReturn(GameData.GetOffset("CCSGameRules_FindPickerEntity")).Hook(OnFindPickerEntity, HookMode.Pre); + } + + private HookResult OnChangeTeam(DynamicHook hook) + { + Logger.LogInformation("ON CHANGE TEAM"); + return HookResult.Continue; + } + + private HookResult OnGiveNamedItem(DynamicHook hook) + { + string itemName = hook.GetParam(1); + Logger.LogInformation("ON GIVE NAMED ITEM {0}", itemName); + return HookResult.Continue; + } + + private HookResult OnSwitchTeam(DynamicHook hook) + { + Logger.LogInformation("ON SWITCH TEAM"); + return HookResult.Continue; + } + + private HookResult OnFindPickerEntity(DynamicHook hook) + { + Logger.LogInformation("ON FIND PICKER ENTITY"); + return HookResult.Continue; + } + + public override void Unload(bool hotReload) + { + // Dont forget to release your hooks + + // 1 -> By signature + CCSPlayerController_SwitchTeam.Unhook(OnSwitchTeam, HookMode.Pre); + + // 2 -> By the vtable offset (index) and an instance of the class + CCSPlayer_ItemServices_GiveNamedItem?.Unhook(OnGiveNamedItem, HookMode.Pre); + + //3 -> By the vtable offset (index) and without an instance of the class + CCSPlayerController_ChangeTeam.Unhook(OnChangeTeam, HookMode.Pre); + CCSGameRules_FindPickerEntity?.Unhook(OnFindPickerEntity, HookMode.Pre); + } +} \ No newline at end of file diff --git a/managed/CounterStrikeSharp.sln b/managed/CounterStrikeSharp.sln index e1a4d9416..a3c67f3ec 100644 --- a/managed/CounterStrikeSharp.sln +++ b/managed/CounterStrikeSharp.sln @@ -49,6 +49,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithCheckTransmit", "..\exa EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeTestsPlugin", "CounterStrikeSharp.Tests.Native\NativeTestsPlugin.csproj", "{317D3A98-D5C6-40BC-9234-CDAFC033ED0F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithVirtualFunctions", "..\examples\WithVirtualFunctions\WithVirtualFunctions.csproj", "{A12A301B-A2FD-404B-95C0-C7E654D3A03C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -143,6 +145,10 @@ Global {317D3A98-D5C6-40BC-9234-CDAFC033ED0F}.Debug|Any CPU.Build.0 = Debug|Any CPU {317D3A98-D5C6-40BC-9234-CDAFC033ED0F}.Release|Any CPU.ActiveCfg = Release|Any CPU {317D3A98-D5C6-40BC-9234-CDAFC033ED0F}.Release|Any CPU.Build.0 = Release|Any CPU + {A12A301B-A2FD-404B-95C0-C7E654D3A03C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A12A301B-A2FD-404B-95C0-C7E654D3A03C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A12A301B-A2FD-404B-95C0-C7E654D3A03C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A12A301B-A2FD-404B-95C0-C7E654D3A03C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -165,6 +171,7 @@ Global {76AD7BB0-A096-4336-83E2-B32CAE4E9933} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} {A14029BA-CADE-4F25-ADC5-48CF14332F61} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} {854B06B5-0E7B-438A-BA51-3F299557F884} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} + {A12A301B-A2FD-404B-95C0-C7E654D3A03C} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {069C4CD4-BACA-446A-A6B8-0194E4F75355} From 43dedd2f294b531cfd4e47f9da02d66fdf138f35 Mon Sep 17 00:00:00 2001 From: roflmuffin Date: Thu, 11 Dec 2025 05:15:20 +0000 Subject: [PATCH 3/3] fix: allow nullable datatypes to be interrogated --- .../WithVirtualFunctionsPlugin.cs | 4 ++-- .../Modules/Memory/DataType.cs | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs index b9cede828..81f3cd251 100644 --- a/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs +++ b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs @@ -49,7 +49,7 @@ public class WithVirtualFunctionsPlugin : BasePlugin // this is still the same, the main point here is that you can set the vtable symbol, binary path, and the offset. // private static VirtualFunctionVoid Random_Function = new("VTABLE_SYMBOL_IN_ENGINE_BINARY", Addresses.EnginePath, 51); // this offset is a random example here - private static VirtualFunctionWithReturn? CCSGameRules_FindPickerEntity; + private static VirtualFunctionWithReturn? CCSGameRules_FindPickerEntity; // Also there are wrapper classes that you can use: // Note that this class actually holds the vtable ptr. (.Handle) @@ -97,7 +97,7 @@ public override void Load(bool hotReload) // Wrapper examples // when using the generic variant of the VTable class, you only need to pass the generic parameters of the function, TArg1 is assumed to be `CCSGameRules` - CCSGameRules_FindPickerEntity = CCSGameRules_VTable.GetFunctionWithReturn(GameData.GetOffset("CCSGameRules_FindPickerEntity")); + CCSGameRules_FindPickerEntity = CCSGameRules_VTable.GetFunctionWithReturn(GameData.GetOffset("CCSGameRules_FindPickerEntity")); CCSGameRules_FindPickerEntity.Hook(OnFindPickerEntity, HookMode.Pre); // and when you are not using the generic variant, you also need to pass the `CCSGameRules` each time. diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DataType.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DataType.cs index c8537a07a..2237fce5a 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DataType.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DataType.cs @@ -47,6 +47,7 @@ public static class DataTypeExtensions private static Dictionary types = new Dictionary() { { typeof(float), DataType.DATA_TYPE_FLOAT }, + { typeof(double), DataType.DATA_TYPE_DOUBLE }, { typeof(IntPtr), DataType.DATA_TYPE_POINTER }, { typeof(int), DataType.DATA_TYPE_INT }, { typeof(uint), DataType.DATA_TYPE_UINT }, @@ -61,6 +62,11 @@ public static class DataTypeExtensions public static DataType? ToDataType(this Type type) { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + return Nullable.GetUnderlyingType(type)!.ToDataType(); + } + if (types.ContainsKey(type)) return types[type]; if (typeof(NativeObject).IsAssignableFrom(type)) @@ -72,14 +78,19 @@ public static class DataTypeExtensions { return types[Enum.GetUnderlyingType(type)]; } - + Core.Application.Instance.Logger.LogWarning("Error retrieving data type for type {Type}", type.FullName); return null; } - + public static DataType ToValidDataType(this Type type) { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + return Nullable.GetUnderlyingType(type)!.ToValidDataType(); + } + if (types.ContainsKey(type)) return types[type]; if (typeof(NativeObject).IsAssignableFrom(type)) @@ -91,7 +102,7 @@ public static DataType ToValidDataType(this Type type) { return types[Enum.GetUnderlyingType(type)]; } - + throw new NotSupportedException("Data type not supported:" + type.FullName); } }