Skip to content

Add FindVirtualTable method#1075

Merged
roflmuffin merged 1 commit intoroflmuffin:mainfrom
SlynxCZ:slynxcz/find_virtual_table
Oct 18, 2025
Merged

Add FindVirtualTable method#1075
roflmuffin merged 1 commit intoroflmuffin:mainfrom
SlynxCZ:slynxcz/find_virtual_table

Conversation

@SlynxCZ
Copy link
Contributor

@SlynxCZ SlynxCZ commented Oct 17, 2025

Expose internal virtual table resolver to scripting layer for CounterStrikeSharp.


Overview

This change introduces a new native function and corresponding managed API method that allow plugins to find vtable pointers by class name directly from a loaded module (e.g. server.dll).
It provides the same functionality that the native side internally uses via modules::server->FindVirtualTable("ClassName").

The new native makes it possible to dynamically resolve class virtual tables from C# plugins and access or call functions through their indices — enabling advanced integrations such as physics tracing or low-level entity systems.


Added Components

Native Function

FIND_VIRTUAL_TABLE

void* FindVirtualTableNative(ScriptContext& scriptContext)
{
    auto moduleName = scriptContext.GetArgument<const char*>(0);
    auto vtableName = scriptContext.GetArgument<const char*>(1);

    return FindVirtualTable(moduleName, vtableName);
}

void* FindVirtualTable(const char* moduleName, const char* vtableName)
{
    auto module = counterstrikesharp::modules::GetModuleByName(moduleName);
    if (module == nullptr)
    {
        return nullptr;
    }

    return module->FindVirtualTable(vtableName);
}

The function returns a raw pointer (void*) to the vtable of the specified class within the target module.
It is internally backed by the same logic as Module::FindVirtualTable.


Native Registration

ScriptEngine::RegisterNativeHandler("FIND_VIRTUAL_TABLE", FindVirtualTableNative);

The native identifier hash is calculated with the standard CounterStrikeSharp hash_string function:

hash_string("FIND_VIRTUAL_TABLE") = 0xB4A0F13C

Managed API Integration

A corresponding method was added to NativeAPI for use in managed CounterStrikeSharp plugins:

public static IntPtr FindVirtualTable(string modulepath, string vtablename)
{
    lock (ScriptContext.GlobalScriptContext.Lock)
    {
        ScriptContext.GlobalScriptContext.Reset();
        ScriptContext.GlobalScriptContext.Push(modulepath);
        ScriptContext.GlobalScriptContext.Push(vtablename);
        ScriptContext.GlobalScriptContext.SetIdentifier(0xB4A0F13C);
        ScriptContext.GlobalScriptContext.Invoke();
        ScriptContext.GlobalScriptContext.CheckErrors();
        return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr));
    }
}

Example Usage

public static class PhysicsResolver
{
    private static IntPtr s_TraceShape = IntPtr.Zero;

    public static bool Initialize()
    {
        IntPtr vtable = NativeAPI.FindVirtualTable("server.dll", "CNavPhysicsInterface");
        if (vtable == IntPtr.Zero)
        {
            Logger.Critical("Failed to find CNavPhysicsInterface vtable!");
            return false;
        }

        IntPtr traceShapeFn = Marshal.ReadIntPtr(vtable, IntPtr.Size * 5);
        s_TraceShape = traceShapeFn;

        Logger.Info($"TraceShape resolved at 0x{s_TraceShape.ToInt64():X}");
        return true;
    }
}

This replicates the native logic:

void* vtable = modules::server->FindVirtualTable("CNavPhysicsInterface");
auto table = static_cast<void**>(vtable);
s_TraceShape = reinterpret_cast<TraceShapeFn>(table[5]);

Purpose

  • Enables C# plugins to resolve class vtables from game modules.
  • Supports custom function calls via CREATE_VIRTUAL_FUNCTION or manual pointer dereferencing.
  • Useful for advanced features such as physics queries (TraceShape), AI interfaces, or entity extension systems.

Author

Michal "Slynx" Přikryl
slynxdev.cz

@SlynxCZ SlynxCZ marked this pull request as ready for review October 17, 2025 13:25
@SlynxCZ SlynxCZ requested a review from roflmuffin as a code owner October 17, 2025 13:25
@SlynxCZ
Copy link
Contributor Author

SlynxCZ commented Oct 17, 2025

PS. Hey Rofl, could you check my discord DMs? I wrote you few days ago on discord: slyxncz. Thank you!

@roflmuffin
Copy link
Owner

Looks good, thank you

@roflmuffin roflmuffin merged commit 0eb73eb into roflmuffin:main Oct 18, 2025
6 checks passed
@SlynxCZ SlynxCZ deleted the slynxcz/find_virtual_table branch October 20, 2025 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants