Update: add CS# api

This commit is contained in:
SlynxCZ 2026-02-11 21:36:29 +04:00
parent cd1b5aabd7
commit 4104ff8de4
9 changed files with 164 additions and 103 deletions

146
README.md
View file

@ -1,19 +1,20 @@
# Ray-Trace
**Shared ray tracing interface for Metamod:Source & CounterStrikeSharp plugins**
**Shared ray tracing interface for Metamod:Source & CounterStrikeSharp
plugins**
------------------------------------------------------------------------
## Overview
`Ray-Trace` is a lightweight **Metamod interface module** for
`Ray-Trace` is a lightweight **Metamod interface module** for\
**Counter-Strike 2** servers.
It exposes a shared interface: `CRayTraceInterface001` which can be
consumed from:
- Native **Metamod C++ plugins**
- Managed **CounterStrikeSharp C# plugins**
- Native **Metamod C++ plugins**
- Managed **CounterStrikeSharp C# plugins**
The interface is implemented as a **C++ virtual class** and is accessed
from C# by calling its **vtable functions directly** using a native
@ -26,21 +27,21 @@ worlds without duplicating engine detours.
## Features
- Metamod meta interface (`CRayTraceInterface001`)
- Works in **C++ and C#**
- Physics / hitbox / world trace presets
- Custom collision masks
- Optional debug beam rendering
- Zero configuration
- Ultra low overhead
- ABI-safe (no STL types in interface)
- Virtual destructor for safe lifetime management
- Metamod meta interface (`CRayTraceInterface001`)
- Works in **C++ and C#**
- Physics / hitbox / world trace presets
- Custom collision masks
- Optional debug beam rendering
- Zero configuration
- Ultra low overhead
- ABI-safe (no STL types in interface)
- Virtual destructor for safe lifetime management
------------------------------------------------------------------------
## Exposed Interface (C++)
```cpp
``` cpp
class CRayTraceInterface
{
public:
@ -80,20 +81,20 @@ public:
TraceResult* pOutResult
) = 0;
};
````
```
**Return value:**
* `true` → trace hit something, `TraceResult` is valid
* `false` → no hit
- `true` → trace hit something, `TraceResult` is valid\
- `false` → no hit
---
------------------------------------------------------------------------
## Getting the interface
### C++ (Metamod plugin)
```cpp
``` cpp
CRayTraceInterface* g_pRayTrace = nullptr;
bool g_bRayTraceLoaded = false;
@ -118,26 +119,35 @@ bool LoadRayTrace()
### C# (CounterStrikeSharp plugin)
For managed plugins, use the provided official wrapper:
There are **two ways** to use the managed side:
```
public/Example.cs
```
1. `public/Example.cs` (reference implementation, for learning / custom
binding)
2. **Official release packages (recommended)**
This file contains:
The recommended way is to use the prebuilt release components:
* Correct vtable bindings for Linux & Windows
* Native-compatible struct layouts (`TraceOptions`, `TraceResult`)
* High-level safe API for tracing
* No need to manually bind delegates
- Install **RayTraceImpl** as a CS# plugin:
---
addons/counterstrikesharp/plugins/RayTraceImpl/RayTraceImpl.dll
- Install **RayTraceApi** as a shared assembly:
addons/counterstrikesharp/shared/RayTraceApi/RayTraceApi.dll
Then reference `RayTraceApi.dll` in your own plugin project and call the
API normally.
`public/Example.cs` demonstrates manual binding and struct layout, but
in production you should rely on the release bridge + shared API.
------------------------------------------------------------------------
## Calling methods from C++ (Metamod)
### TraceShape example
```cpp
``` cpp
Vector vecOrigin{};
QAngle angView{};
TraceOptions traceOpts{};
@ -167,32 +177,46 @@ if (g_pRayTrace && g_bRayTraceLoaded)
}
```
---
------------------------------------------------------------------------
## Calling methods from C# (CounterStrikeSharp plugin)
The official managed API is implemented in:
After installing RayTraceImpl + RayTraceApi from releases:
```
public/Example.cs
1. Add reference in your plugin `.csproj`:
``` xml
<ItemGroup>
<Reference Include="RayTraceApi">
<HintPath>libs/RayTraceApi.dll</HintPath>
</Reference>
</ItemGroup>
```
### Example usage
2. Use the API:
```csharp
using RayTrace;
``` csharp
using RayTraceAPI;
using CounterStrikeSharp.API.Modules.Utils;
internal static PluginCapability<CRayTraceInterface> RayTraceInterface { get; } = new("raytrace:craytraceinterface");
public void DoTrace(CCSPlayerController player)
{
Vector origin = player.PlayerPawn.Value!.AbsOrigin;
QAngle angles = player.PlayerPawn.Value!.EyeAngles;
var rayTrace = RayTraceInterface.Get();
if (rayTrace == null)
return;
TraceOptions options = new(
InteractionLayers.MASK_SHOT_PHYSICS
);
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null)
return;
if (CRayTrace.TraceShape(origin, angles, null, options, out TraceResult result))
Vector origin = playerPawn.AbsOrigin!;
QAngle angles = playerPawn.EyeAngles!;
TraceOptions options = new();
if (rayTrace.TraceShape(origin, angles, null, options, out TraceResult result))
{
Console.WriteLine($"Hit fraction: {result.Fraction}");
Console.WriteLine($"EndPos: {result.EndPos}");
@ -200,7 +224,14 @@ public void DoTrace(CCSPlayerController player)
}
```
---
The bridge handles:
- Interface lookup via MetaFactory
- Correct vtable offsets (Linux / Windows)
- Delegate binding
- Native struct layout alignment
------------------------------------------------------------------------
## VTable offsets (ABI note)
@ -211,28 +242,29 @@ Due to C++ ABI differences:
| Linux (Itanium ABI) | 2 | 3 | 4 |
| Windows (MSVC ABI) | 1 | 2 | 3 |
`public/Example.cs` applies correct offsets by default.
`public/Example.cs` shows how offsets are applied manually.\
Release builds handle this automatically inside RayTraceImpl.
---
------------------------------------------------------------------------
## Notes about ABI & Destructor
* `CRayTraceInterface` has a virtual destructor.
* The object is owned by the Ray-Trace Metamod module.
* Plugins must never call `delete` on the interface pointer.
* C# must only clear its handle on unload.
* All parameters are passed as native pointers (`nint`).
- `CRayTraceInterface` has a virtual destructor.
- The object is owned by the Ray-Trace Metamod module.
- Plugins must never call `delete` on the interface pointer.
- C# must only clear its handle on unload.
- All parameters are passed as native pointers (`nint`).
---
------------------------------------------------------------------------
## License
GPLv3
[https://www.gnu.org/licenses/gpl-3.0.en.html](https://www.gnu.org/licenses/gpl-3.0.en.html)
GPLv3\
https://www.gnu.org/licenses/gpl-3.0.en.html
---
------------------------------------------------------------------------
## Author
**Michal "Slynx" Přikryl**
[https://slynxdev.cz](https://slynxdev.cz)
**Michal "Slynx" Přikryl**\
https://slynxdev.cz