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 runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
steps: steps:
- name: Download Linux artifact - name: Download Linux artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: RayTrace-linux name: RayTrace-linux
path: ./build/linux path: ./artifacts/linux
- name: Download Windows artifact - name: Download Windows artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: RayTrace-windows name: RayTrace-windows
path: ./build/windows path: ./artifacts/windows
- name: Archive packages - name: Prepare release packages
run: | run: |
version="${GITHUB_REF#refs/tags/}" 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 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: RayTrace-*.tar.gz file: release/*.tar.gz
tag: ${{ github.ref }} tag: ${{ github.ref }}
file_glob: true 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 # Ray-Trace
**Shared ray tracing interface for Metamod:Source & CounterStrikeSharp plugins** **Shared ray tracing interface for Metamod:Source & CounterStrikeSharp
plugins**
------------------------------------------------------------------------ ------------------------------------------------------------------------
## Overview ## Overview
`Ray-Trace` is a lightweight **Metamod interface module** for `Ray-Trace` is a lightweight **Metamod interface module** for\
**Counter-Strike 2** servers. **Counter-Strike 2** servers.
It exposes a shared interface: `CRayTraceInterface001` which can be It exposes a shared interface: `CRayTraceInterface001` which can be
@ -80,14 +81,14 @@ public:
TraceResult* pOutResult TraceResult* pOutResult
) = 0; ) = 0;
}; };
```` ```
**Return value:** **Return value:**
* `true` → trace hit something, `TraceResult` is valid - `true` → trace hit something, `TraceResult` is valid\
* `false` → no hit - `false` → no hit
--- ------------------------------------------------------------------------
## Getting the interface ## Getting the interface
@ -118,20 +119,29 @@ bool LoadRayTrace()
### C# (CounterStrikeSharp plugin) ### C# (CounterStrikeSharp plugin)
For managed plugins, use the provided official wrapper: There are **two ways** to use the managed side:
``` 1. `public/Example.cs` (reference implementation, for learning / custom
public/Example.cs 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 - Install **RayTraceImpl** as a CS# plugin:
* Native-compatible struct layouts (`TraceOptions`, `TraceResult`)
* High-level safe API for tracing
* No need to manually bind delegates
--- 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) ## Calling methods from C++ (Metamod)
@ -167,32 +177,46 @@ if (g_pRayTrace && g_bRayTraceLoaded)
} }
``` ```
--- ------------------------------------------------------------------------
## Calling methods from C# (CounterStrikeSharp plugin) ## Calling methods from C# (CounterStrikeSharp plugin)
The official managed API is implemented in: After installing RayTraceImpl + RayTraceApi from releases:
``` 1. Add reference in your plugin `.csproj`:
public/Example.cs
``` xml
<ItemGroup>
<Reference Include="RayTraceApi">
<HintPath>libs/RayTraceApi.dll</HintPath>
</Reference>
</ItemGroup>
``` ```
### Example usage 2. Use the API:
``` csharp ``` csharp
using RayTrace; using RayTraceAPI;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
internal static PluginCapability<CRayTraceInterface> RayTraceInterface { get; } = new("raytrace:craytraceinterface");
public void DoTrace(CCSPlayerController player) public void DoTrace(CCSPlayerController player)
{ {
Vector origin = player.PlayerPawn.Value!.AbsOrigin; var rayTrace = RayTraceInterface.Get();
QAngle angles = player.PlayerPawn.Value!.EyeAngles; if (rayTrace == null)
return;
TraceOptions options = new( var playerPawn = player.PlayerPawn.Value;
InteractionLayers.MASK_SHOT_PHYSICS 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($"Hit fraction: {result.Fraction}");
Console.WriteLine($"EndPos: {result.EndPos}"); 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) ## VTable offsets (ABI note)
@ -211,28 +242,29 @@ Due to C++ ABI differences:
| Linux (Itanium ABI) | 2 | 3 | 4 | | Linux (Itanium ABI) | 2 | 3 | 4 |
| Windows (MSVC ABI) | 1 | 2 | 3 | | 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 ## Notes about ABI & Destructor
* `CRayTraceInterface` has a virtual destructor. - `CRayTraceInterface` has a virtual destructor.
* The object is owned by the Ray-Trace Metamod module. - The object is owned by the Ray-Trace Metamod module.
* Plugins must never call `delete` on the interface pointer. - Plugins must never call `delete` on the interface pointer.
* C# must only clear its handle on unload. - C# must only clear its handle on unload.
* All parameters are passed as native pointers (`nint`). - All parameters are passed as native pointers (`nint`).
--- ------------------------------------------------------------------------
## License ## License
GPLv3 GPLv3\
[https://www.gnu.org/licenses/gpl-3.0.en.html](https://www.gnu.org/licenses/gpl-3.0.en.html) https://www.gnu.org/licenses/gpl-3.0.en.html
--- ------------------------------------------------------------------------
## Author ## Author
**Michal "Slynx" Přikryl** **Michal "Slynx" Přikryl**\
[https://slynxdev.cz](https://slynxdev.cz) https://slynxdev.cz

View file

@ -16,7 +16,11 @@ RUN apt update && apt install -y \
pkg-config \ pkg-config \
libcurl4-openssl-dev \ libcurl4-openssl-dev \
libmaxminddb-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 '*' RUN git config --system --add safe.directory '*'

View file

@ -20,13 +20,13 @@ rm -rf "$SDK_DIR"
mkdir -p "$SDK_DIR" mkdir -p "$SDK_DIR"
echo "=== Downloading HL2SDK-CS2 ===" 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 ===" 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 ===" 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 env vars for CMake ------------------------------------------
export HL2SDKCS2="$HL2SDK_DIR" export HL2SDKCS2="$HL2SDK_DIR"
@ -51,3 +51,21 @@ cmake .. \
echo "=== Building with GCC | Release | All ===" echo "=== Building with GCC | Release | All ==="
cmake --build . --config Release -j"$(nproc)" 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> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View file

@ -1,8 +1,8 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 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 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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View file

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

View file

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