Compare commits

...

9 Commits

Author SHA1 Message Date
Roflmuffin
696ecadee4 fix: bad vector math 2024-03-26 12:16:53 +10:00
Roflmuffin
e4d598dba8 fix: main version number 2024-03-25 17:15:31 +10:00
Michael Wilson
5c67d88844 feat: improve version stamping (#389) 2024-03-25 17:11:16 +10:00
Michael Wilson
9d8b6beae6 .NET8 Upgrade (#261)
Co-authored-by: Frederik St-Onge <frederik.stonge@gmail.com>
Co-authored-by: B3none <24966460+B3none@users.noreply.github.com>
2024-03-25 14:16:32 +10:00
ipsvn
39604b7ad7 Fix backwards compatibility in DynamicHook (#388) 2024-03-22 23:04:09 +10:00
luxury fabka
1b1f1d04dd minor menu changes (#373)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
Co-authored-by: Roflmuffin <shortguy014@gmail.com>
2024-03-18 05:00:31 +00:00
Ian Lucas
dbc348c1bf Add RemoveAll method to NetworkedVector class (#380) 2024-03-18 14:56:29 +10:00
Michael Wilson
d295589c44 fix: update collision groups (#376) 2024-03-13 16:10:42 +10:00
Michael Wilson
16767fd494 feat: add Server.RunOnTick method which allows tick scheduling (#374) 2024-03-11 23:08:54 +10:00
47 changed files with 488 additions and 187 deletions

View File

@@ -3,22 +3,46 @@ name: Build & Publish
on:
push:
paths-ignore:
- 'docfx/**'
branches: [ "main", "dev" ]
- "docfx/**"
branches: ["main", "dev"]
pull_request:
branches: [ "main", "dev" ]
branches: ["main", "dev"]
env:
BUILD_TYPE: Release
jobs:
setup:
permissions:
contents: write
runs-on: ubuntu-latest
outputs:
buildnumber: ${{ steps.buildnumber.outputs.build_number }}
steps:
- name: Generate build number
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
id: buildnumber
uses: onyxmueller/build-tag-number@v1
with:
token: ${{secrets.github_token}}
build_windows:
needs: setup
runs-on: windows-latest
steps:
- name: Prepare env
shell: bash
run: echo "GITHUB_SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Fallback build number
if: ${{ github.event_name == 'pull_request' || github.ref != 'refs/heads/main' }}
shell: bash
run: echo "BUILD_NUMBER=0" >> $GITHUB_ENV
- name: Main build number
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run: echo "BUILD_NUMBER=${{ needs.setup.outputs.buildnumber }}" >> $GITHUB_ENV
- name: Visual Studio environment
shell: cmd
run: |
@@ -34,7 +58,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
submodules: "recursive"
- name: Build
run: |
@@ -56,6 +80,7 @@ jobs:
path: build/output/
build_linux:
needs: setup
runs-on: ubuntu-latest
# Could not figure out how to run in a container only on some matrix paths, so I've split it out into its own build.
container:
@@ -65,9 +90,18 @@ jobs:
shell: bash
run: echo "GITHUB_SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Fallback build number
if: ${{ github.event_name == 'pull_request' || github.ref != 'refs/heads/main' }}
shell: bash
run: echo "BUILD_NUMBER=0" >> $GITHUB_ENV
- name: Main build number
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run: echo "BUILD_NUMBER=${{ needs.setup.outputs.buildnumber }}" >> $GITHUB_ENV
- uses: actions/checkout@v3
with:
submodules: 'recursive'
submodules: "recursive"
- name: Build
run: |
@@ -87,11 +121,10 @@ jobs:
path: build/output/
build_managed:
needs: setup
permissions:
contents: write
runs-on: ubuntu-latest
outputs:
buildnumber: ${{ steps.buildnumber.outputs.build_number }}
steps:
- name: Prepare env
shell: bash
@@ -102,20 +135,17 @@ jobs:
shell: bash
run: echo "BUILD_NUMBER=0" >> $GITHUB_ENV
- name: Main build number
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run: echo "BUILD_NUMBER=${{ needs.setup.outputs.buildnumber }}" >> $GITHUB_ENV
# We don't need expensive submodules for the managed side.
- uses: actions/checkout@v3
- name: Generate build number
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
id: buildnumber
uses: onyxmueller/build-tag-number@v1
with:
token: ${{secrets.github_token}}
- name: Build runtime v${{ env.BUILD_NUMBER }}
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.0.x'
dotnet-version: "8.0.x"
- name: Install dependencies
run: dotnet restore managed/CounterStrikeSharp.sln
@@ -133,7 +163,7 @@ jobs:
- name: Publish artifacts
run: |
dotnet publish -c Release /p:Version=1.0.${{ env.BUILD_NUMBER }} managed/CounterStrikeSharp.API
dotnet pack -c Release /p:Version=1.0.${{ env.BUILD_NUMBER }} managed/CounterStrikeSharp.API
dotnet pack -c Release /p:Version=1.0.${{ env.BUILD_NUMBER }} managed/CounterStrikeSharp.API
- uses: actions/upload-artifact@v3
with:
@@ -144,7 +174,7 @@ jobs:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
permissions:
contents: write
needs: [ "build_linux", "build_windows", "build_managed" ]
needs: ["setup", "build_linux", "build_windows", "build_managed"]
runs-on: ubuntu-latest
steps:
- name: Prepare env
@@ -171,49 +201,48 @@ jobs:
run: |
mkdir -p build/linux/addons/counterstrikesharp/api
mkdir -p build/windows/addons/counterstrikesharp/api
cp -r build/api/net7.0/publish/* build/linux/addons/counterstrikesharp/api
cp -r build/api/net7.0/publish/* build/windows/addons/counterstrikesharp/api
cp -r build/api/net8.0/publish/* build/linux/addons/counterstrikesharp/api
cp -r build/api/net8.0/publish/* build/windows/addons/counterstrikesharp/api
- name: Zip Builds
run: |
(cd build/linux && zip -qq -r ../../counterstrikesharp-build-${{ needs.build_managed.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip *)
(cd build/windows && zip -qq -r ../../counterstrikesharp-build-${{ needs.build_managed.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip *)
(cd build/linux && zip -qq -r ../../counterstrikesharp-build-${{ needs.setup.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip *)
(cd build/windows && zip -qq -r ../../counterstrikesharp-build-${{ needs.setup.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip *)
- name: Add dotnet runtime
run: |
mkdir -p build/linux/addons/counterstrikesharp/dotnet
curl -s -L https://download.visualstudio.microsoft.com/download/pr/dc2c0a53-85a8-4fda-a283-fa28adb5fbe2/8ccade5bc400a5bb40cd9240f003b45c/aspnetcore-runtime-7.0.11-linux-x64.tar.gz \
curl -s -L https://download.visualstudio.microsoft.com/download/pr/c1371dc2-eed2-47be-9af3-ae060dbe3c7d/bd509e0a87629764ed47608466d183e6/aspnetcore-runtime-8.0.3-linux-x64.tar.gz \
| tar xvz -C build/linux/addons/counterstrikesharp/dotnet
mv build/linux/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/7.0.11/* build/linux/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/
mkdir -p build/windows/addons/counterstrikesharp/dotnet
curl -s -L https://download.visualstudio.microsoft.com/download/pr/a99861c8-2e00-4587-aaef-60366ca77307/a44ceec2c5d34165ae881600f52edc43/aspnetcore-runtime-7.0.11-win-x64.zip -o dotnet.zip
curl -s -L https://download.visualstudio.microsoft.com/download/pr/086d1dd6-57a5-437a-a1ef-549cf702fb48/dd4a8fe6c53a1016a414d6f2925c1323/aspnetcore-runtime-8.0.3-win-x64.zip -o dotnet.zip
unzip -qq dotnet.zip -d build/windows/addons/counterstrikesharp/dotnet
- name: Zip Builds
run: |
(cd build/linux && zip -qq -r ../../counterstrikesharp-with-runtime-build-${{ needs.build_managed.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip *)
(cd build/windows && zip -qq -r ../../counterstrikesharp-with-runtime-build-${{ needs.build_managed.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip *)
(cd build/linux && zip -qq -r ../../counterstrikesharp-with-runtime-build-${{ needs.setup.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip *)
(cd build/windows && zip -qq -r ../../counterstrikesharp-with-runtime-build-${{ needs.setup.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip *)
- name: Release
id: release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ needs.build_managed.outputs.buildnumber }}
tag_name: v${{ needs.setup.outputs.buildnumber }}
files: |
counterstrikesharp-build-${{ needs.build_managed.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip
counterstrikesharp-with-runtime-build-${{ needs.build_managed.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip
counterstrikesharp-build-${{ needs.build_managed.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip
counterstrikesharp-with-runtime-build-${{ needs.build_managed.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip
counterstrikesharp-build-${{ needs.setup.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip
counterstrikesharp-with-runtime-build-${{ needs.setup.outputs.buildnumber }}-windows-${{ env.GITHUB_SHA_SHORT }}.zip
counterstrikesharp-build-${{ needs.setup.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip
counterstrikesharp-with-runtime-build-${{ needs.setup.outputs.buildnumber }}-linux-${{ env.GITHUB_SHA_SHORT }}.zip
- name: Publish NuGet package
run: |
dotnet nuget push build/api/CounterStrikeSharp.API.1.0.${{ needs.build_managed.outputs.buildnumber }}.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
dotnet nuget push build/api/CounterStrikeSharp.API.1.0.${{ needs.build_managed.outputs.buildnumber }}.snupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
dotnet nuget push build/api/CounterStrikeSharp.API.1.0.${{ needs.setup.outputs.buildnumber }}.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
dotnet nuget push build/api/CounterStrikeSharp.API.1.0.${{ needs.setup.outputs.buildnumber }}.snupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
- name: Send Notification to Discord
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
uses: Ilshidur/action-discord@0.3.2
with:
args: "A new release of CS# has been tagged (v${{ needs.build_managed.outputs.buildnumber }}) at ${{ steps.release.outputs.url }}"
args: "A new release of CS# has been tagged (v${{ needs.setup.outputs.buildnumber }}) at ${{ steps.release.outputs.url }}"

2
.gitignore vendored
View File

@@ -1,6 +1,6 @@
.ccls-cache/
.cmake/
cmake-build-debug*/
cmake-build-*/
.kdev4/
.vscode/
generated/

View File

@@ -49,6 +49,8 @@ SET(SOURCE_FILES
src/core/managers/event_manager.cpp
src/core/timer_system.h
src/core/timer_system.cpp
src/core/tick_scheduler.h
src/core/tick_scheduler.cpp
src/scripting/autonative.h
src/scripting/natives/natives_engine.cpp
src/core/engine_trace.h

View File

@@ -9,7 +9,7 @@ How to write your first plugin for CounterStrikeSharp
## Creating a New Project
First, ensure you have the relevant .NET 7.0 SDK for your platform installed on your machine. You can find the links to the latest downloads on the <a href="https://dotnet.microsoft.com/en-us/download/dotnet/7.0" target="_blank"> official Microsoft download page</a>.
First, ensure you have the relevant .NET 8.0 SDK for your platform installed on your machine. You can find the links to the latest downloads on the <a href="https://dotnet.microsoft.com/en-us/download/dotnet/8.0" target="_blank"> official Microsoft download page</a>.
### Creating a Class Library
@@ -25,7 +25,7 @@ Use your IDE (Visual Studio/Rider) to add a reference to the `CounterStrikeSharp
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
@@ -65,7 +65,7 @@ public class HelloWorldPlugin : BasePlugin
}
```
Now build your project using your ide or the `dotnet build` command. You should now have a built binary file in your `bin/Debug/net7.0` subdirectory in the project.
Now build your project using your ide or the `dotnet build` command. You should now have a built binary file in your `bin/Debug/net8.0` subdirectory in the project.
### Installing your Plugin

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -29,6 +29,18 @@ set(SOURCESDK_LIB ${SOURCESDK}/lib)
add_definitions(-DMETA_IS_SOURCE2)
if(DEFINED ENV{GITHUB_SHA_SHORT})
add_definitions(-DGITHUB_SHA="$ENV{GITHUB_SHA_SHORT}")
else()
add_definitions(-DGITHUB_SHA="Local")
endif()
if(DEFINED ENV{BUILD_NUMBER})
add_definitions(-DBUILD_NUMBER="$ENV{BUILD_NUMBER}")
else()
add_definitions(-DBUILD_NUMBER="0")
endif()
include_directories(
${SOURCESDK}
${SOURCESDK}/thirdparty/protobuf-3.21.8/src

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

View File

@@ -13,4 +13,14 @@ public class Api
{
return Assembly.GetAssembly(typeof(BasePlugin))!.GetName().Version!.Build;
}
/// <summary>
/// Returns the assembly version of CounterStrikeSharp running on the server as a string including git commit hash
/// </summary>
/// <example>1.0.0+9d8b6be</example>
public static string GetVersionString()
{
return Assembly.GetAssembly(typeof(BasePlugin))!.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!
.InformationalVersion;
}
}

View File

@@ -439,6 +439,12 @@
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Core.NativeAPI.GetGameFrameTime</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Core.NativeAPI.QueueTaskForNextFrame(System.IntPtr)</Target>
@@ -469,6 +475,18 @@
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Modules.Memory.DynamicFunctions.DynamicHook.GetReturn``1(System.Int32)</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Server.get_GameFrameTime</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Core.IPlugin.OnAllPluginsLoaded(System.Boolean)</Target>
@@ -487,6 +505,12 @@
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:CounterStrikeSharp.API.Modules.Menu.IMenu.ExitButton</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0010</DiagnosticId>
<Target>T:CounterStrikeSharp.API.Core.RenderMultisampleType_t</Target>

View File

@@ -315,16 +315,6 @@ namespace CounterStrikeSharp.API.Core
}
}
public static float GetGameFrameTime(){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.SetIdentifier(0x97E331CA);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (float)ScriptContext.GlobalScriptContext.GetResult(typeof(float));
}
}
public static double GetEngineTime(){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
@@ -512,6 +502,17 @@ namespace CounterStrikeSharp.API.Core
}
}
public static void QueueTaskForFrame(int tick, InputArgument callback){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(tick);
ScriptContext.GlobalScriptContext.Push((InputArgument)callback);
ScriptContext.GlobalScriptContext.SetIdentifier(0x2F92C340);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static void QueueTaskForNextWorldUpdate(InputArgument callback){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
@@ -1095,6 +1096,16 @@ namespace CounterStrikeSharp.API.Core
}
}
public static void RemoveAllNetworkVectorElements(IntPtr vec){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(vec);
ScriptContext.GlobalScriptContext.SetIdentifier(0x67206C08);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static short GetSchemaOffset(string classname, string propname){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();

View File

@@ -106,13 +106,13 @@ namespace CounterStrikeSharp.API.Core
[RequiresPermissions("@css/generic")]
private void OnCSSCommand(CCSPlayerController? caller, CommandInfo info)
{
var currentVersion = Api.GetVersion();
var versionString = $"v{Api.GetVersion()} ({Api.GetVersionString()})";
info.ReplyToCommand(
" CounterStrikeSharp was created and is maintained by Michael \"roflmuffin\" Wilson.\n" +
" Counter-Strike Sharp uses code borrowed from SourceMod, Source.Python, FiveM, Saul Rennison, source2gen and CS2Fixes.\n" +
" See ACKNOWLEDGEMENTS.md for more information.\n" +
" Current API Version: " + currentVersion);
" Current API Version: " + versionString);
return;
}

View File

@@ -33,6 +33,11 @@ public partial class NetworkedVector<T> : NativeObject, IReadOnlyCollection<T>
}
}
public void RemoveAll()
{
NativeAPI.RemoveAllNetworkVectorElements(Handle);
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < Count; i++)

View File

@@ -1,63 +1,74 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>
<EnablePackageValidation>true</EnablePackageValidation>
<NoWarn>$(NoWarn);CS1591;CP0003</NoWarn>
<Nullable>enable</Nullable>
<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>
<Authors>Roflmuffin</Authors>
<Description>Official server side runtime assembly for CounterStrikeSharp</Description>
<PackageProjectUrl>http://docs.cssharp.dev/</PackageProjectUrl>
<RepositoryUrl>https://github.com/roflmuffin/CounterStrikeSharp</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<!-- <GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile> -->
</PropertyGroup>
<PropertyGroup>
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
<ApiCompatContractAssembly>.\ApiCompat\v151.dll</ApiCompatContractAssembly>
</PropertyGroup>
<ItemGroup>
<None Remove="Modules\Commands\CommandInfo" />
<None Remove="Modules\Disabled\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.DotNet.ApiCompat.Task" Version="7.0.404" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.3" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Scrutor" Version="4.2.2" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Core\Schema\" />
<Folder Include="Modules\Errors" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Modules\Disabled\**" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="Modules\Disabled\**" />
</ItemGroup>
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!-- <Target Name="PreBuild" BeforeTargets="PreBuildEvent">-->
<!-- <Exec Command="dotnet run &#45;&#45;project ../../tooling/CodeGen.Natives" />-->
<!-- </Target>-->
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>
<EnablePackageValidation>true</EnablePackageValidation>
<NoWarn>$(NoWarn);CS1591;CP0003</NoWarn>
<Nullable>enable</Nullable>
<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>
<Authors>Roflmuffin</Authors>
<Description>Official server side runtime assembly for CounterStrikeSharp</Description>
<PackageProjectUrl>http://docs.cssharp.dev/</PackageProjectUrl>
<RepositoryUrl>https://github.com/roflmuffin/CounterStrikeSharp</RepositoryUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<SourceControlInformationFeatureSupported>true</SourceControlInformationFeatureSupported>
<!-- <GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile> -->
</PropertyGroup>
<PropertyGroup>
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
<ApiCompatContractAssembly>.\ApiCompat\v151.dll</ApiCompatContractAssembly>
</PropertyGroup>
<ItemGroup>
<None Remove="Modules\Commands\CommandInfo"/>
<None Remove="Modules\Disabled\**"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0"/>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0"/>
<PackageReference Include="Microsoft.DotNet.ApiCompat.Task" Version="8.0.203"/>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0"/>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0"/>
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.3"/>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0"/>
<PackageReference Include="Scrutor" Version="4.2.2"/>
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0"/>
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.0"/>
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0"/>
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Core\Schema\"/>
<Folder Include="Modules\Errors"/>
</ItemGroup>
<ItemGroup>
<Compile Remove="Modules\Disabled\**"/>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="Modules\Disabled\**"/>
</ItemGroup>
<PropertyGroup/>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<Target Name="SetSourceRevisionId" BeforeTargets="InitializeSourceControlInformation">
<Exec
Command="git describe --long --always --exclude=* --abbrev=7"
ConsoleToMSBuild="True"
IgnoreExitCode="False"
>
<Output PropertyName="SourceRevisionId" TaskParameter="ConsoleOutput"/>
</Exec>
</Target>
<!-- <Target Name="PreBuild" BeforeTargets="PreBuildEvent">-->
<!-- <Exec Command="dotnet run &#45;&#45;project ../../tooling/CodeGen.Natives" />-->
<!-- </Target>-->
</Project>

View File

@@ -18,34 +18,37 @@ namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum CollisionGroup
{
COLLISION_GROUP_NONE = 0,
COLLISION_GROUP_DEBRIS, // Collides with nothing but world and static stuff
COLLISION_GROUP_DEBRIS_TRIGGER, // Same as debris, but hits triggers
COLLISION_GROUP_INTERACTIVE_DEBRIS, // Collides with everything except other interactive debris or debris
COLLISION_GROUP_INTERACTIVE, // Collides with everything except interactive debris or debris
COLLISION_GROUP_NONE = 0,
COLLISION_GROUP_NEVER,
COLLISION_GROUP_TRIGGER,
COLLISION_GROUP_CONDITIONALLY_SOLID,
COLLISION_GROUP_DEFAULT,
COLLISION_GROUP_DEBRIS, // Collides with nothing but world and static stuff
COLLISION_GROUP_INTERACTIVE_DEBRIS, // Collides with everything except other interactive debris or debris
COLLISION_GROUP_INTERACTIVE, // Collides with everything except interactive debris or debris
COLLISION_GROUP_PLAYER,
COLLISION_GROUP_BREAKABLE_GLASS,
COLLISION_GROUP_VEHICLE,
COLLISION_GROUP_PLAYER_MOVEMENT, // For HL2, same as Collision_Group_Player, for
// TF2, this filters out other players and CBaseObjects
COLLISION_GROUP_NPC, // Generic NPC group
COLLISION_GROUP_IN_VEHICLE, // for any entity inside a vehicle
COLLISION_GROUP_WEAPON, // for any weapons that need collision detection
COLLISION_GROUP_VEHICLE_CLIP, // vehicle clip brush to restrict vehicle movement
COLLISION_GROUP_PROJECTILE, // Projectiles!
COLLISION_GROUP_DOOR_BLOCKER, // Blocks entities not permitted to get near moving doors
COLLISION_GROUP_PASSABLE_DOOR, // Doors that the player shouldn't collide with
COLLISION_GROUP_DISSOLVING, // Things that are dissolving are in this group
COLLISION_GROUP_PUSHAWAY, // Nonsolid on client and server, pushaway in player code
COLLISION_GROUP_PLAYER_MOVEMENT, // For HL2, same as Collision_Group_Player, for
COLLISION_GROUP_NPC_ACTOR, // Used so NPCs in scripts ignore the player.
COLLISION_GROUP_NPC_SCRIPTED, // USed for NPCs in scripts that should not collide with each other
// TF2, this filters out other players and CBaseObjects
COLLISION_GROUP_NPC, // Generic NPC group
COLLISION_GROUP_IN_VEHICLE, // for any entity inside a vehicle
COLLISION_GROUP_WEAPON, // for any weapons that need collision detection
COLLISION_GROUP_VEHICLE_CLIP, // vehicle clip brush to restrict vehicle movement
COLLISION_GROUP_PROJECTILE, // Projectiles!
COLLISION_GROUP_DOOR_BLOCKER, // Blocks entities not permitted to get near moving doors
COLLISION_GROUP_PASSABLE_DOOR, // Doors that the player shouldn't collide with
COLLISION_GROUP_DISSOLVING, // Things that are dissolving are in this group
COLLISION_GROUP_PUSHAWAY, // Nonsolid on client and server, pushaway in player code
COLLISION_GROUP_NPC_ACTOR, // Used so NPCs in scripts ignore the player.
COLLISION_GROUP_NPC_SCRIPTED, // USed for NPCs in scripts that should not collide with each other
COLLISION_GROUP_PZ_CLIP,
COLLISION_GROUP_DEBRIS_BLOCK_PROJECTILE, // Only collides with bullets
COLLISION_GROUP_PROPS,
LAST_SHARED_COLLISION_GROUP
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using CounterStrikeSharp.API.Core;
namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
@@ -14,6 +14,12 @@ public class DynamicHook : NativeObject
return NativeAPI.DynamicHookGetParam<T>(Handle, (int)typeof(T).ToValidDataType(), index);
}
[Obsolete("Use GetReturn<T>() instead")]
public T GetReturn<T>(int index)
{
return GetReturn<T>();
}
public T GetReturn<T>()
{
return NativeAPI.DynamicHookGetReturn<T>(Handle, (int)typeof(T).ToValidDataType());
@@ -28,4 +34,4 @@ public class DynamicHook : NativeObject
{
NativeAPI.DynamicHookSetReturn(Handle, (int)typeof(T).ToValidDataType(), value);
}
}
}

View File

@@ -30,7 +30,8 @@ public abstract class BaseMenu : IMenu
public string Title { get; set; }
public List<ChatMenuOption> MenuOptions { get; } = new();
public PostSelectAction PostSelectAction { get; set; } = PostSelectAction.Reset;
public bool ExitButton { get; set; } = true;
protected BaseMenu(string title)
{
Title = title;
@@ -76,8 +77,8 @@ public abstract class BaseMenuInstance : IMenuInstance
}
protected bool HasPrevButton => Page > 0;
protected bool HasNextButton => CurrentOffset + NumPerPage < Menu.MenuOptions.Count;
protected int MenuItemsPerPage => NumPerPage + 2 - (HasNextButton ? 1 : 0) - (HasPrevButton ? 1 : 0);
protected bool HasNextButton => Menu.MenuOptions.Count > NumPerPage && CurrentOffset + NumPerPage < Menu.MenuOptions.Count;
protected virtual int MenuItemsPerPage => NumPerPage;
public virtual void Display()
{
@@ -142,7 +143,7 @@ public abstract class BaseMenuInstance : IMenuInstance
PrevPageOffsets.Clear();
}
public void Close()
public virtual void Close()
{
MenuManager.CloseActiveMenu(Player);
}

View File

@@ -24,14 +24,15 @@ public class CenterHtmlMenu : BaseMenu
public CenterHtmlMenu(string title) : base(ModifyTitle(title))
{
}
public override ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false)
public override ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect,
bool disabled = false)
{
var option = new ChatMenuOption(ModifyOptionDisplay(display), disabled, onSelect);
MenuOptions.Add(option);
return option;
}
private static string ModifyTitle(string title)
{
if (title.Length > 32)
@@ -59,14 +60,15 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
{
private readonly BasePlugin _plugin;
public override int NumPerPage => 5; // one less than the actual number of items per page to avoid truncated options
protected override int MenuItemsPerPage => (Menu.ExitButton ? 0 : 1) + ((HasPrevButton && HasNextButton) ? NumPerPage - 1 : NumPerPage);
public CenterHtmlMenuInstance(BasePlugin plugin, CCSPlayerController player, IMenu menu) : base(player, menu)
{
_plugin = plugin;
RemoveOnTickListener();
plugin.RegisterListener<Core.Listeners.OnTick>(Display);
}
public override void Display()
{
if (MenuManager.GetActiveMenu(Player) != this)
@@ -74,7 +76,7 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
Reset();
return;
}
var builder = new StringBuilder();
builder.Append($"<b><font color='yellow'>{Menu.Title}</font></b>");
builder.AppendLine("<br>");
@@ -88,7 +90,7 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
builder.Append($"<font color='{color}'>!{keyOffset++}</font> {option.Text}");
builder.AppendLine("<br>");
}
if (HasPrevButton)
{
builder.AppendFormat("<font color='yellow'>!7</font> &#60;- Prev");
@@ -101,18 +103,21 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
builder.AppendLine("<br>");
}
builder.AppendFormat("<font color='red'>!9</font> -> Close");
builder.AppendLine("<br>");
if (Menu.ExitButton)
{
builder.AppendFormat("<font color='red'>!9</font> -> Close");
builder.AppendLine("<br>");
}
var currentPageText = builder.ToString();
Player.PrintToCenterHtml(currentPageText);
}
public override void Reset()
public override void Close()
{
base.Reset();
base.Close();
RemoveOnTickListener();
// Send a blank message to clear the menu
Player.PrintToCenterHtml(" ");
}

View File

@@ -18,10 +18,11 @@ using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Menu;
public class ChatMenu: BaseMenu
public class ChatMenu : BaseMenu
{
public ChatMenu(string title) : base(title)
{
ExitButton = false;
}
}
@@ -37,15 +38,11 @@ public class ChatMenuInstance : BaseMenuInstance
Player.PrintToChat("---");
var keyOffset = 1;
for (var i = CurrentOffset;
i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count);
i++)
for (var i = CurrentOffset; i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count); i++)
{
var option = Menu.MenuOptions[i];
Player.PrintToChat(
$" {(option.Disabled ? ChatColors.Grey : ChatColors.Green)} !{keyOffset++} {ChatColors.Default}{option.Text}");
Player.PrintToChat($" {(option.Disabled ? ChatColors.Grey : ChatColors.Green)} !{keyOffset++} {ChatColors.Default}{option.Text}");
}
if (HasPrevButton)
@@ -57,6 +54,11 @@ public class ChatMenuInstance : BaseMenuInstance
{
Player.PrintToChat($" {ChatColors.Yellow}!8 {ChatColors.Default}-> Next");
}
if (Menu.ExitButton)
{
Player.PrintToChat($" {ChatColors.Red}!9 {ChatColors.Default}-> Close");
}
}
}

View File

@@ -42,7 +42,7 @@ public class ConsoleMenuInstance : BaseMenuInstance
{
var option = Menu.MenuOptions[i];
Player.PrintToConsole($"{(option.Disabled ? "[Enabled]" : "[Disabled] - ")} css_{keyOffset++} {option.Text}");
Player.PrintToConsole($"{(option.Disabled ? "[Disabled] - " : "[Enabled]")} css_{keyOffset++} {option.Text}");
}
if (HasPrevButton)
@@ -54,5 +54,10 @@ public class ConsoleMenuInstance : BaseMenuInstance
{
Player.PrintToConsole("css_8 -> Next");
}
if (Menu.ExitButton)
{
Player.PrintToConsole("css_9 -> Close");
}
}
}

View File

@@ -27,6 +27,7 @@ public interface IMenu
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public bool ExitButton { get; set; }
public ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false);
}

View File

@@ -1,4 +1,4 @@
/*
/*
* 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
@@ -75,7 +75,7 @@ namespace CounterStrikeSharp.API.Modules.Utils
{
this.X += vector.X;
this.Y += vector.Y;
this.Z = this.Z = vector.Z;
this.Z += vector.Z;
}

View File

@@ -28,19 +28,66 @@ namespace CounterStrikeSharp.API
{
public class Server
{
public static float TickInterval => NativeAPI.GetTickInterval();
/// <summary>
/// Duration of a single game tick in seconds, based on a 64 tick server (hard coded in CS2).
/// </summary>
public static float TickInterval => 0.015625f;
/// <summary>
/// Executes a command on the server, as if it was entered from the console.
/// </summary>
/// <param name="command"></param>
public static void ExecuteCommand(string command) => NativeAPI.IssueServerCommand(command);
public static string MapName => NativeAPI.GetMapName();
// public static void PrintToConsole(string message) => NativeAPI.PrintToConsole(message);
/// <summary>
/// Returns the total time the server has been running in seconds.
/// </summary>
/// <remarks>Does not increment when server is hibernating</remarks>
public static double TickedTime => NativeAPI.GetTickedTime();
/// <summary>
/// Returns the current map time in seconds, as an interval of the server's tick interval.
/// e.g. 70.046875 would represent 70 seconds of map time and the 4483rd tick of the server (70.046875 / 0.015625).
/// </summary>
/// <remarks>Increments even when server is hibernating</remarks>
public static float CurrentTime => NativeAPI.GetCurrentTime();
/// <summary>
/// Returns the current map tick count.
/// CS2 is a 64 tick server, so the value will increment by 64 every second.
/// </summary>
public static int TickCount => NativeAPI.GetTickCount();
public static float GameFrameTime => NativeAPI.GetGameFrameTime();
/// <summary>
/// Returns the total time the server has been running in seconds.
/// </summary>
/// <remarks>Increments even when server is hibernating</remarks>
public static double EngineTime => NativeAPI.GetEngineTime();
public static void PrecacheModel(string name) => NativeAPI.PrecacheModel(name);
/// <summary>
/// <inheritdoc cref="RunOnTick"/>
/// Returns Task that completes once the synchronous task has been completed.
/// </summary>
public static Task RunOnTickAsync(int tick, Action task)
{
var functionReference = FunctionReference.Create(task, FunctionLifetime.SingleUse);
NativeAPI.QueueTaskForFrame(tick, functionReference);
return functionReference.CompletionTask;
}
/// <summary>
/// Queue a task to be executed on the specified tick.
/// See <see cref="TickCount"/> to retrieve the current tick.
/// <remarks>Does not execute if the server is hibernating.</remarks>
/// </summary>
public static void RunOnTick(int tick, Action task)
{
RunOnTickAsync(tick, task);
}
/// <summary>
/// <inheritdoc cref="NextFrame"/>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

View File

@@ -1,6 +1,7 @@
#include "mm_plugin.h"
#include "core/globals.h"
#include "core/managers/player_manager.h"
#include "core/tick_scheduler.h"
#include "iserver.h"
#include "managers/event_manager.h"
#include "scripting/callback_manager.h"
@@ -79,6 +80,7 @@ EntityManager entityManager;
ChatManager chatManager;
ServerManager serverManager;
VoiceManager voiceManager;
TickScheduler tickScheduler;
bool gameLoopInitialized = false;
GetLegacyGameEventListener_t* GetLegacyGameEventListener = nullptr;

View File

@@ -47,6 +47,7 @@ class CallbackManager;
class ConVarManager;
class PlayerManager;
class MenuManager;
class TickScheduler;
class TimerSystem;
class ChatCommands;
class HookManager;
@@ -100,6 +101,7 @@ extern ChatCommands chatCommands;
extern ChatManager chatManager;
extern ServerManager serverManager;
extern VoiceManager voiceManager;
extern TickScheduler tickScheduler;
extern HookManager hookManager;
extern SourceHook::ISourceHook *source_hook;

View File

@@ -0,0 +1,45 @@
/*
* 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 <https://www.gnu.org/licenses/>. *
*/
#include "tick_scheduler.h"
namespace counterstrikesharp {
void TickScheduler::schedule(int tick, std::function<void()> callback)
{
std::lock_guard<std::mutex> lock(taskMutex);
scheduledTasks.push(std::make_pair(tick, callback));
}
std::vector<std::function<void()>> TickScheduler::getCallbacks(int currentTick)
{
std::vector<std::function<void()>> callbacksToRun;
std::lock_guard<std::mutex> lock(taskMutex);
if (scheduledTasks.empty()) {
return callbacksToRun;
}
// Process tasks due for the current tick
while (!scheduledTasks.empty() && scheduledTasks.top().first <= currentTick) {
callbacksToRun.push_back(scheduledTasks.top().second);
scheduledTasks.pop();
}
return callbacksToRun;
}
} // namespace counterstrikesharp

44
src/core/tick_scheduler.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* 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 <https://www.gnu.org/licenses/>. *
*/
#include <functional>
#include <queue>
#include <mutex>
#include <condition_variable>
namespace counterstrikesharp {
class TickScheduler
{
public:
struct TaskComparator
{
bool operator()(const std::pair<int, std::function<void()>>& a,
const std::pair<int, std::function<void()>>& b) const
{
return a.first > b.first;
}
};
void schedule(int tick, std::function<void()> callback);
std::vector<std::function<void()>> getCallbacks(int currentTick);
private:
std::priority_queue<std::pair<int, std::function<void()>>,
std::vector<std::pair<int, std::function<void()>>>,
TaskComparator>
scheduledTasks;
std::mutex taskMutex;
};
} // namespace counterstrikesharp

View File

@@ -22,6 +22,7 @@
#include "core/gameconfig.h"
#include "core/game_system.h"
#include "core/timer_system.h"
#include "core/tick_scheduler.h"
#include "core/utils.h"
#include "core/managers/entity_manager.h"
#include "igameeventsystem.h"
@@ -32,6 +33,9 @@
#include "entity2/entitysystem.h"
#include "interfaces/cs2_interfaces.h"
#define VERSION_STRING "v" BUILD_NUMBER " @ " GITHUB_SHA
#define BUILD_TIMESTAMP __DATE__ " " __TIME__
counterstrikesharp::GlobalClass* counterstrikesharp::GlobalClass::head = nullptr;
CGameEntitySystem *GameEntitySystem()
@@ -48,6 +52,7 @@ DLL_EXPORT void InvokeNative(counterstrikesharp::fxNativeContext& context)
if (context.nativeIdentifier != counterstrikesharp::hash_string_const("QUEUE_TASK_FOR_NEXT_FRAME") &&
context.nativeIdentifier != counterstrikesharp::hash_string_const("QUEUE_TASK_FOR_NEXT_WORLD_UPDATE") &&
context.nativeIdentifier != counterstrikesharp::hash_string_const("QUEUE_TASK_FOR_FRAME") &&
counterstrikesharp::globals::gameThreadId != std::this_thread::get_id())
{
counterstrikesharp::ScriptContextRaw scriptContext(context);
@@ -218,6 +223,16 @@ void CounterStrikeSharpMMPlugin::Hook_GameFrame(bool simulating, bool bFirstTick
out_list[i]();
}
}
auto callbacks = globals::tickScheduler.getCallbacks(globals::getGlobalVars()->tickcount);
if (callbacks.size() > 0) {
CSSHARP_CORE_TRACE("Executing frame specific tasks of size: {0} on tick number {1}", callbacks.size(),
globals::getGlobalVars()->tickcount);
for (auto& callback : callbacks) {
callback();
}
}
}
// Potentially might not work
@@ -253,9 +268,9 @@ bool CounterStrikeSharpMMPlugin::Unpause(char* error, size_t maxlen) { return tr
const char* CounterStrikeSharpMMPlugin::GetLicense() { return "GNU GPLv3"; }
const char* CounterStrikeSharpMMPlugin::GetVersion() { return "0.1.0"; }
const char* CounterStrikeSharpMMPlugin::GetVersion() { return VERSION_STRING; }
const char* CounterStrikeSharpMMPlugin::GetDate() { return __DATE__; }
const char* CounterStrikeSharpMMPlugin::GetDate() { return BUILD_TIMESTAMP; }
const char* CounterStrikeSharpMMPlugin::GetLogTag() { return "CSSHARP"; }

View File

@@ -100,10 +100,10 @@ bool load_hostfxr()
namespace css = counterstrikesharp;
#if _WIN32
std::wstring buffer =
std::wstring(css::widen(base_dir) + L"\\dotnet\\host\\fxr\\7.0.11\\hostfxr.dll");
std::wstring(css::widen(base_dir) + L"\\dotnet\\host\\fxr\\8.0.3\\hostfxr.dll");
CSSHARP_CORE_INFO("Loading hostfxr from {0}", css::narrow(buffer).c_str());
#else
std::string buffer = std::string(base_dir + "/dotnet/host/fxr/7.0.11/libhostfxr.so");
std::string buffer = std::string(base_dir + "/dotnet/host/fxr/8.0.3/libhostfxr.so");
CSSHARP_CORE_INFO("Loading hostfxr from {0}", buffer.c_str());
#endif

View File

@@ -32,6 +32,7 @@
#include "core/function.h"
#include "core/managers/player_manager.h"
#include "core/managers/server_manager.h"
#include "core/tick_scheduler.h"
// clang-format on
#if _WIN32
@@ -238,6 +239,15 @@ void QueueTaskForNextWorldUpdate(ScriptContext& script_context)
globals::serverManager.AddTaskForNextWorldUpdate([func]() { reinterpret_cast<voidfunc*>(func)(); });
}
void QueueTaskForFrame(ScriptContext& script_context)
{
auto tick = script_context.GetArgument<int>(0);
auto func = script_context.GetArgument<void*>(1);
typedef void(voidfunc)(void);
globals::tickScheduler.schedule(tick, reinterpret_cast<voidfunc*>(func));
}
enum InterfaceType
{
Engine,
@@ -331,6 +341,7 @@ REGISTER_NATIVES(engine, {
ScriptEngine::RegisterNativeHandler("GET_TICKED_TIME", GetTickedTime);
ScriptEngine::RegisterNativeHandler("QUEUE_TASK_FOR_NEXT_FRAME", QueueTaskForNextFrame);
ScriptEngine::RegisterNativeHandler("QUEUE_TASK_FOR_NEXT_WORLD_UPDATE", QueueTaskForNextWorldUpdate);
ScriptEngine::RegisterNativeHandler("QUEUE_TASK_FOR_FRAME", QueueTaskForFrame);
ScriptEngine::RegisterNativeHandler("GET_VALVE_INTERFACE", GetValveInterface);
ScriptEngine::RegisterNativeHandler("GET_COMMAND_PARAM_VALUE", GetCommandParamValue);
ScriptEngine::RegisterNativeHandler("PRINT_TO_SERVER_CONSOLE", PrintToServerConsole);

View File

@@ -4,7 +4,6 @@ IS_MAP_VALID: mapname:string -> bool
GET_TICK_INTERVAL: -> float
GET_CURRENT_TIME: -> float
GET_TICK_COUNT: -> int
GET_GAME_FRAME_TIME: -> float
GET_ENGINE_TIME: -> double
GET_MAX_CLIENTS: -> int
ISSUE_SERVER_COMMAND: command:string -> void
@@ -22,6 +21,7 @@ TRACE_FILTER_PROXY_SET_SHOULD_HIT_ENTITY_CALLBACK: trace_filter:pointer, callbac
NEW_TRACE_RESULT: -> pointer
GET_TICKED_TIME: -> double
QUEUE_TASK_FOR_NEXT_FRAME: callback:func -> void
QUEUE_TASK_FOR_FRAME: tick:int, callback:func -> void
QUEUE_TASK_FOR_NEXT_WORLD_UPDATE: callback:func -> void
GET_VALVE_INTERFACE: interfaceType:int, interfaceName:string -> pointer
GET_COMMAND_PARAM_VALUE: param:string, dataType:DataType_t, defaultValue:any -> any

View File

@@ -159,6 +159,13 @@ void* GetNetworkVectorElementAt(ScriptContext& script_context)
return &vec->Element(index);
}
void RemoveAllNetworkVectorElements(ScriptContext& script_context)
{
auto vec = script_context.GetArgument<CUtlVector<CEntityHandle>*>(0);
vec->RemoveAll();
}
REGISTER_NATIVES(memory, {
ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION", CreateVirtualFunction);
ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_BY_SIGNATURE",
@@ -169,5 +176,6 @@ REGISTER_NATIVES(memory, {
ScriptEngine::RegisterNativeHandler("FIND_SIGNATURE", FindSignatureNative);
ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_SIZE", GetNetworkVectorSize);
ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_ELEMENT_AT", GetNetworkVectorElementAt);
ScriptEngine::RegisterNativeHandler("REMOVE_ALL_NETWORK_VECTOR_ELEMENTS", RemoveAllNetworkVectorElements);
})
} // namespace counterstrikesharp

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>