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

View file

@ -104,30 +104,46 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download Linux artifact
uses: actions/download-artifact@v4
with:
name: RayTrace-linux
path: ./build/linux
path: ./artifacts/linux
- name: Download Windows artifact
uses: actions/download-artifact@v4
with:
name: RayTrace-windows
path: ./build/windows
path: ./artifacts/windows
- name: Archive packages
- name: Prepare release packages
run: |
version="${GITHUB_REF#refs/tags/}"
tar -czf RayTrace-${version}-linux.tar.gz -C build/linux .
tar -czf RayTrace-${version}-windows.tar.gz -C build/windows .
- name: Upload release archive
mkdir release
# Linux MM plugin
tar -czf release/RayTrace-MM-${version}-linux.tar.gz \
-C artifacts/linux .
# Windows MM plugin
tar -czf release/RayTrace-MM-${version}-windows.tar.gz \
-C artifacts/windows .
# CS# package (platform independent)
mkdir cs
cp -r artifacts/linux/addons/counterstrikesharp cs/
tar -czf release/RayTrace-CSSharp-${version}.tar.gz \
-C cs .
- name: Upload release archives
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: RayTrace-*.tar.gz
file: release/*.tar.gz
tag: ${{ github.ref }}
file_glob: true
release_name: "${{ github.ref_name }} - Download"
release_name: "${{ github.ref_name }}"

116
README.md
View file

@ -1,12 +1,13 @@
# 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
@ -80,14 +81,14 @@ 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
@ -118,20 +119,29 @@ 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)
@ -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;
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

View file

@ -16,7 +16,11 @@ RUN apt update && apt install -y \
pkg-config \
libcurl4-openssl-dev \
libmaxminddb-dev \
curl
curl \
&& curl -sSL https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -o packages-microsoft-prod.deb \
&& dpkg -i packages-microsoft-prod.deb \
&& rm packages-microsoft-prod.deb \
&& apt update && apt install -y dotnet-sdk-8.0
RUN git config --system --add safe.directory '*'

View file

@ -20,13 +20,13 @@ rm -rf "$SDK_DIR"
mkdir -p "$SDK_DIR"
echo "=== Downloading HL2SDK-CS2 ==="
git clone --depth=1 -b cs2 https://github.com/alliedmodders/hl2sdk "$HL2SDK_DIR"
git clone --recursive --branch SlynxCZ/cs2 --single-branch https://github.com/FUNPLAY-pro-CS2/hl2sdk.git "$HL2SDK_DIR"
echo "=== Downloading Metamod-Source ==="
git clone --depth=1 https://github.com/alliedmodders/metamod-source "$MMSOURCE_DIR"
git clone --recursive --branch master --single-branch https://github.com/alliedmodders/metamod-source.git "$MMSOURCE_DIR"
echo "=== Downloading Protobufs ==="
git clone --depth=1 https://github.com/SteamDatabase/Protobufs "$CSGO_PROTO_DIR"
git clone --recursive https://github.com/SteamDatabase/Protobufs "$CSGO_PROTO_DIR"
### --- Export env vars for CMake ------------------------------------------
export HL2SDKCS2="$HL2SDK_DIR"
@ -51,3 +51,21 @@ cmake .. \
echo "=== Building with GCC | Release | All ==="
cmake --build . --config Release -j"$(nproc)"
cd ../
mkdir -p build/addons/counterstrikesharp/plugins
mkdir -p build/addons/counterstrikesharp/shared/RayTraceApi
dotnet publish managed/RayTrace/RayTraceImpl/RayTraceImpl.csproj \
-c Release \
-o build/addons/counterstrikesharp/plugins/RayTraceImpl \
--no-self-contained \
/p:PublishSingleFile=false \
/p:CopyLocalLockFileAssemblies=false
dotnet publish managed/RayTrace/RayTraceApi/RayTraceApi.csproj \
-c Release \
-o build/addons/counterstrikesharp/shared/RayTraceApi \
--no-self-contained \
/p:PublishSingleFile=false \
/p:CopyLocalLockFileAssemblies=false

View file

@ -5,6 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>

View file

@ -1,8 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RayTraceImpl", "RayTraceImpl.csproj", "{0D0FD0C6-A1A6-47A7-8370-29CCE2CD4598}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RayTraceImpl", "RayTraceImpl/RayTraceImpl.csproj", "{0D0FD0C6-A1A6-47A7-8370-29CCE2CD4598}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RayTraceApi", "RayTraceApi.csproj", "{13E6E993-1E09-4B9A-9888-98481E1C3178}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RayTraceApi", "RayTraceApi/RayTraceApi.csproj", "{13E6E993-1E09-4B9A-9888-98481E1C3178}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View file

@ -18,7 +18,7 @@ using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using RayTraceAPI;
namespace RayTrace;
namespace RayTraceImpl;
// ReSharper disable once InconsistentNaming
// ReSharper disable once UnusedType.Global

View file

@ -5,25 +5,15 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>..\0Harmony.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="*" />
<PackageReference Include="Lib.Harmony" Version="2.3.6" />
</ItemGroup>
<PropertyGroup>
<DefineConstants>
$(DefineConstants);
SEMVER="$(SEMVER)";
GITHUB_SHA_SHORT="$(GITHUB_SHA_SHORT)";
</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\RayTraceApi\RayTraceApi.csproj" />
</ItemGroup>
</Project>