mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-06 08:03:12 -08:00
Compare commits
143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
765c56a38a | ||
|
|
204850fb55 | ||
|
|
bac31b9190 | ||
|
|
289f95a6b7 | ||
|
|
7b45a884d4 | ||
|
|
6ea6d0a22d | ||
|
|
12523455c0 | ||
|
|
db63fdc00c | ||
|
|
57747f2e1c | ||
|
|
66b5f77a2d | ||
|
|
8dbcb6d531 | ||
|
|
2f0d34b271 | ||
|
|
2a59544fbc | ||
|
|
f80f2ae949 | ||
|
|
f68a0abc61 | ||
|
|
a07dd9d7d4 | ||
|
|
d527038fba | ||
|
|
ca85922270 | ||
|
|
b837479f98 | ||
|
|
1e42f72655 | ||
|
|
1ad1828e30 | ||
|
|
563a5d7b3a | ||
|
|
983b673b4c | ||
|
|
74fd0e0832 | ||
|
|
44e3f2240c | ||
|
|
8af219e7a8 | ||
|
|
bff04e7795 | ||
|
|
d495ac6230 | ||
|
|
f78abf0c81 | ||
|
|
bcacc42d0e | ||
|
|
8235d5e728 | ||
|
|
56739356d5 | ||
|
|
aaba87551d | ||
|
|
a3466dd5d1 | ||
|
|
c8604760f2 | ||
|
|
d50a945317 | ||
|
|
55396e005c | ||
|
|
98b2b01992 | ||
|
|
a537be89e4 | ||
|
|
c07d5d2aa9 | ||
|
|
1cc95555fe | ||
|
|
378c28dfd0 | ||
|
|
c7343c3b7a | ||
|
|
62f6b09f50 | ||
|
|
2a15a8de71 | ||
|
|
1d6bee02cd | ||
|
|
72e1f22e14 | ||
|
|
a8a238bdee | ||
|
|
cec8ef3d30 | ||
|
|
c7384df396 | ||
|
|
84d4998a72 | ||
|
|
1b194318af | ||
|
|
22d0dd8200 | ||
|
|
7baf0a25e2 | ||
|
|
9fdbb9500b | ||
|
|
0ab3cf429a | ||
|
|
1f9630b92d | ||
|
|
02bf2483d3 | ||
|
|
cb181b6a49 | ||
|
|
cc21dca5a0 | ||
|
|
5721d060ea | ||
|
|
220521d571 | ||
|
|
5698b511e9 | ||
|
|
48c9d195ff | ||
|
|
603827d331 | ||
|
|
e557d54c32 | ||
|
|
48d3ade5cf | ||
|
|
77b05e912e | ||
|
|
1354b4972d | ||
|
|
8b5eb7e38d | ||
|
|
2dd62c44d3 | ||
|
|
f811338ce4 | ||
|
|
194c340ae7 | ||
|
|
6b0912d3cd | ||
|
|
2d3aa09aa4 | ||
|
|
911084e71e | ||
|
|
5b99206568 | ||
|
|
4bfdf28beb | ||
|
|
9bcd0f7e92 | ||
|
|
11c6486ec5 | ||
|
|
ee69560a66 | ||
|
|
d37e5e194a | ||
|
|
c4740d1cc9 | ||
|
|
7e92f178fd | ||
|
|
107ca08132 | ||
|
|
8cda8d9a50 | ||
|
|
3d59a05de8 | ||
|
|
77b7040d6c | ||
|
|
75de9732ef | ||
|
|
575c859ddb | ||
|
|
e12a7cb17a | ||
|
|
7c7f52a219 | ||
|
|
cd593fb238 | ||
|
|
c5cc65be48 | ||
|
|
59928bbcc5 | ||
|
|
319b116c5f | ||
|
|
e0dc053d22 | ||
|
|
f2e0dac32d | ||
|
|
4e8c18abc7 | ||
|
|
8d1891a3a8 | ||
|
|
6bc43444f7 | ||
|
|
f0c7869f4a | ||
|
|
3e38ed3c77 | ||
|
|
7e9e7c6665 | ||
|
|
9a018f295b | ||
|
|
8b725d435f | ||
|
|
ea3596417a | ||
|
|
123f41914e | ||
|
|
8f69076405 | ||
|
|
44a85d1201 | ||
|
|
20f50289ee | ||
|
|
bb5fb5de72 | ||
|
|
6147739cfa | ||
|
|
3ab5893f22 | ||
|
|
50ce09a7b3 | ||
|
|
9c7944e6f1 | ||
|
|
bc71aa7739 | ||
|
|
16a1efc0cb | ||
|
|
8ae85cedf4 | ||
|
|
8e2234ff25 | ||
|
|
04e7ed682a | ||
|
|
15e1260146 | ||
|
|
517607d962 | ||
|
|
0f72631eb0 | ||
|
|
75fcf21fb7 | ||
|
|
0ddf6bcdfa | ||
|
|
98661cd069 | ||
|
|
86a5699b40 | ||
|
|
414710d05c | ||
|
|
b09c2b62c8 | ||
|
|
31760518ed | ||
|
|
6a160bcc3d | ||
|
|
9c8e9db56e | ||
|
|
e2e0eab87d | ||
|
|
43292bb1d2 | ||
|
|
12c54cd4fc | ||
|
|
e155a70873 | ||
|
|
69d9b5d2c8 | ||
|
|
933fdf9d81 | ||
|
|
18e9e37a98 | ||
|
|
fe236806e1 | ||
|
|
2c4e9bca42 | ||
|
|
8f3e0c226b |
219
.github/workflows/cmake-single-platform.yml
vendored
219
.github/workflows/cmake-single-platform.yml
vendored
@@ -3,96 +3,209 @@ name: Build & Publish
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- 'docfx/**'
|
||||
branches: [ "main" ]
|
||||
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest
|
||||
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Prepare env
|
||||
shell: bash
|
||||
run: echo "GITHUB_SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup protobuf
|
||||
shell: bash
|
||||
run: sudo apt-get update && sudo apt install -y protobuf-compiler
|
||||
- name: Visual Studio environment
|
||||
shell: cmd
|
||||
run: |
|
||||
:: See https://github.com/microsoft/vswhere/wiki/Find-VC
|
||||
for /f "usebackq delims=*" %%i in (`vswhere -latest -property installationPath`) do (
|
||||
call "%%i"\Common7\Tools\vsdevcmd.bat -arch=x64 -host_arch=x64
|
||||
)
|
||||
|
||||
:: Loop over all environment variables and make them global.
|
||||
for /f "delims== tokens=1,2" %%a in ('set') do (
|
||||
echo>>"%GITHUB_ENV%" %%a=%%b
|
||||
)
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Generate build number
|
||||
id: buildnumber
|
||||
uses: onyxmueller/build-tag-number@v1
|
||||
with:
|
||||
token: ${{secrets.github_token}}
|
||||
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
- 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
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Build
|
||||
# Build your program with the given configuration
|
||||
run: cmake --build build --config ${{env.BUILD_TYPE}}
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} ..
|
||||
cmake --build . --config ${{env.BUILD_TYPE}} -- /m:16
|
||||
|
||||
- name: Clean build directory
|
||||
run: |
|
||||
mkdir -p build/addons/counterstrikesharp/bin/win64
|
||||
mv build/${{env.BUILD_TYPE}}/*.dll build/addons/counterstrikesharp/bin/win64
|
||||
mkdir build/output/
|
||||
mv build/addons build/output
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: counterstrikesharp-build-windows-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: build/output/
|
||||
|
||||
build_linux:
|
||||
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:
|
||||
image: registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest
|
||||
steps:
|
||||
- name: Prepare env
|
||||
shell: bash
|
||||
run: echo "GITHUB_SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} ..
|
||||
cmake --build . --config ${{env.BUILD_TYPE}} -- -j16
|
||||
|
||||
- name: Clean build directory
|
||||
run: |
|
||||
mkdir build/output/
|
||||
mv build/addons build/output
|
||||
|
||||
- name: Add API to Artifacts
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: counterstrikesharp-build-linux-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: build/output/
|
||||
|
||||
build_managed:
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
buildnumber: ${{ steps.buildnumber.outputs.build_number }}
|
||||
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'
|
||||
shell: bash
|
||||
run: echo "BUILD_NUMBER=0" >> $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'
|
||||
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'
|
||||
|
||||
- name: Install dependencies
|
||||
run: dotnet restore managed/CounterStrikeSharp.sln
|
||||
|
||||
- name: Run tests
|
||||
run: dotnet test --logger trx --results-directory "TestResults-${{ env.GITHUB_SHA_SHORT }}" managed/CounterStrikeSharp.API.Tests/CounterStrikeSharp.API.Tests.csproj
|
||||
|
||||
- name: Upload dotnet test results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: TestResults-${{ env.GITHUB_SHA_SHORT }}
|
||||
if: ${{ always() }}
|
||||
|
||||
- name: Publish artifacts
|
||||
run: |
|
||||
mkdir -p build/output/addons/counterstrikesharp/api
|
||||
cp -r managed/CounterStrikeSharp.API/bin/Release/net7.0/publish/* build/output/addons/counterstrikesharp/api
|
||||
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
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: counterstrikesharp-build-${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: build/output/
|
||||
name: counterstrikesharp-build-api-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: managed/CounterStrikeSharp.API/bin/Release
|
||||
|
||||
- name: Zip CounterStrikeSharp Build
|
||||
run: (cd build/output && zip -qq -r ../../counterstrikesharp-build-${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}.zip *)
|
||||
publish:
|
||||
if: github.event_name == 'push'
|
||||
permissions:
|
||||
contents: write
|
||||
needs: [ "build_linux", "build_windows", "build_managed" ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Prepare env
|
||||
shell: bash
|
||||
run: echo "GITHUB_SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: counterstrikesharp-build-windows-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: build/windows
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: counterstrikesharp-build-linux-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: build/linux
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: counterstrikesharp-build-api-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: build/api
|
||||
|
||||
# TODO: This stuff should really be in a matrix
|
||||
- name: Add API to Artifacts
|
||||
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
|
||||
|
||||
- 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 *)
|
||||
|
||||
- name: Add dotnet runtime
|
||||
run: |
|
||||
mkdir -p build/output/addons/counterstrikesharp/dotnet
|
||||
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 \
|
||||
| tar xvz -C build/output/addons/counterstrikesharp/dotnet
|
||||
mv build/output/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/7.0.11/* build/output/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/
|
||||
| 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
|
||||
unzip -qq dotnet.zip -d build/windows/addons/counterstrikesharp/dotnet
|
||||
|
||||
- name: Zip CounterStrikeSharp Runtime Build
|
||||
run: (cd build/output && zip -qq -r ../../counterstrikesharp-with-runtime-build-${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}.zip *)
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: counterstrikesharp-with-runtime-build-${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}
|
||||
path: build/output/
|
||||
- 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 *)
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
tag_name: v${{ env.BUILD_NUMBER }}
|
||||
tag_name: v${{ needs.build_managed.outputs.buildnumber }}
|
||||
files: |
|
||||
counterstrikesharp-build-${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}.zip
|
||||
counterstrikesharp-with-runtime-build-${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}.zip
|
||||
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
|
||||
|
||||
- name: Publish NuGet package
|
||||
run: |
|
||||
dotnet nuget push managed/CounterStrikeSharp.API/bin/Release/CounterStrikeSharp.API.1.0.${{ env.BUILD_NUMBER }}.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
|
||||
dotnet nuget push managed/CounterStrikeSharp.API/bin/Release/CounterStrikeSharp.API.1.0.${{ env.BUILD_NUMBER }}.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.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
|
||||
53
.github/workflows/pr-checks.yml
vendored
53
.github/workflows/pr-checks.yml
vendored
@@ -1,53 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest
|
||||
permissions:
|
||||
pull-requests: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
csharp:
|
||||
- managed/**/*
|
||||
- src/scripting/natives/**/*
|
||||
cpp:
|
||||
- src/**/*
|
||||
|
||||
- uses: actions/setup-dotnet@v3
|
||||
if: steps.changes.outputs.csharp == 'true'
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
|
||||
- if: steps.changes.outputs.csharp == 'true'
|
||||
run: dotnet build -c Release managed/CounterStrikeSharp.API
|
||||
|
||||
- name: Setup protobuf
|
||||
shell: bash
|
||||
if: steps.changes.outputs.cpp == 'true'
|
||||
run: sudo apt-get update && sudo apt install -y protobuf-compiler
|
||||
|
||||
- name: Configure CMake
|
||||
if: steps.changes.outputs.cpp == 'true'
|
||||
run: cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Build
|
||||
# Build your program with the given configuration
|
||||
if: steps.changes.outputs.cpp == 'true'
|
||||
run: cmake --build build --config ${{env.BUILD_TYPE}}
|
||||
58
.github/workflows/publish-docs.yml
vendored
58
.github/workflows/publish-docs.yml
vendored
@@ -1,42 +1,46 @@
|
||||
name: Deploy to GitHub Pages
|
||||
|
||||
on:
|
||||
# Trigger the workflow every time you push to the `main` branch
|
||||
# Using a different branch name? Replace `main` with your branch’s name
|
||||
push:
|
||||
paths:
|
||||
- 'docs/**'
|
||||
branches: [ main ]
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab on GitHub.
|
||||
workflow_dispatch:
|
||||
|
||||
# Allow this job to clone the repo and create a page deployment
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout your repository using git
|
||||
uses: actions/checkout@v3
|
||||
- name: Install, build, and upload your site
|
||||
uses: withastro/action@v1
|
||||
with:
|
||||
path: ./docs # The root location of your Astro project inside the repository. (optional)
|
||||
node-version: 20 # The specific version of Node that should be used to build your site. Defaults to 18. (optional)
|
||||
package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
jobs:
|
||||
publish-docs:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Dotnet Setup
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 8.x
|
||||
|
||||
- run: dotnet tool update -g docfx
|
||||
|
||||
- run: docfx docfx/docfx.json
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v3
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
with:
|
||||
path: "docfx/_site"
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
||||
uses: actions/deploy-pages@v2
|
||||
|
||||
14
.gitignore
vendored
14
.gitignore
vendored
@@ -1,12 +1,17 @@
|
||||
.ccls-cache/
|
||||
.cmake/
|
||||
cmake-build-debug/
|
||||
cmake-build-debug*/
|
||||
.kdev4/
|
||||
.vscode/
|
||||
generated/
|
||||
|
||||
# configure_file auto generated.
|
||||
configs/addons/metamod/counterstrikesharp.vdf
|
||||
|
||||
libraries/mono/
|
||||
|
||||
CMakeSettings.json
|
||||
|
||||
build/
|
||||
build_test/
|
||||
|
||||
@@ -543,4 +548,9 @@ $RECYCLE.BIN/
|
||||
|
||||
_NCrunch*
|
||||
|
||||
.idea/
|
||||
.idea/
|
||||
|
||||
# docfx
|
||||
docfx/_site/
|
||||
docfx/api/
|
||||
docfx/_exported_templates/
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -17,3 +17,9 @@
|
||||
[submodule "libraries/GameTracking-CS2"]
|
||||
path = libraries/GameTracking-CS2
|
||||
url = https://github.com/SteamDatabase/GameTracking-CS2
|
||||
[submodule "libraries/DynoHook"]
|
||||
path = libraries/DynoHook
|
||||
url = git@github.com:qubka/DynoHook.git
|
||||
[submodule "libraries/asmjit"]
|
||||
path = libraries/asmjit
|
||||
url = git@github.com:asmjit/asmjit.git
|
||||
|
||||
@@ -22,6 +22,22 @@ saul/demofile-net, https://github.com/saul/demofile-net/blob/main/LICENSE:
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
neverlosecc/source2gen, https://github.com/neverlosecc/source2gen
|
||||
source2gen - Source2 games SDK generator
|
||||
Copyright 2023 neverlosecc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Source2ZE/CS2Fixes:
|
||||
alliedmodders/sourcemod:
|
||||
Source-Python-Dev-Team/Source.Python:
|
||||
|
||||
200
CMakeLists.txt
200
CMakeLists.txt
@@ -1,99 +1,123 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
Project(counterstrikesharp C CXX)
|
||||
# You must set ASM, otherwise CMAKE_ASM_COMPILE_OBJECT will not work on MSVC
|
||||
project(counterstrikesharp C CXX ASM)
|
||||
|
||||
include("makefiles/shared.cmake")
|
||||
|
||||
add_subdirectory(libraries/spdlog)
|
||||
add_subdirectory(libraries/dyncall)
|
||||
add_subdirectory(libraries/funchook)
|
||||
add_subdirectory(libraries/DynoHook)
|
||||
|
||||
set_property(TARGET dynohook PROPERTY DYNO_ARCH_X86 64)
|
||||
set_property(TARGET funchook-static PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
SET(SOURCE_FILES
|
||||
src/mm_plugin.cpp
|
||||
src/mm_plugin.h
|
||||
libraries/hl2sdk-cs2/tier1/convar.cpp
|
||||
libraries/hl2sdk-cs2/tier1/generichash.cpp
|
||||
libraries/hl2sdk-cs2/entity2/entitysystem.cpp
|
||||
libraries/hl2sdk-cs2/public/tier0/memoverride.cpp
|
||||
libraries/dotnet/hostfxr.h
|
||||
libraries/dotnet/coreclr_delegates.h
|
||||
"libraries/metamod-source/core/sourcehook/sourcehook.cpp"
|
||||
"libraries/metamod-source/core/sourcehook/sourcehook_impl_chookidman.cpp"
|
||||
"libraries/metamod-source/core/sourcehook/sourcehook_impl_chookmaninfo.cpp"
|
||||
"libraries/metamod-source/core/sourcehook/sourcehook_impl_cvfnptr.cpp"
|
||||
"libraries/metamod-source/core/sourcehook/sourcehook_impl_cproto.cpp"
|
||||
src/scripting/dotnet_host.h
|
||||
src/scripting/dotnet_host.cpp
|
||||
src/core/utils.h
|
||||
src/core/globals.h
|
||||
src/core/globals.cpp
|
||||
src/core/log.h
|
||||
src/core/log.cpp
|
||||
src/scripting/script_engine.h
|
||||
src/scripting/script_engine.cpp
|
||||
src/core/global_listener.h
|
||||
src/scripting/callback_manager.h
|
||||
src/scripting/callback_manager.cpp
|
||||
src/core/managers/event_manager.h
|
||||
src/core/managers/event_manager.cpp
|
||||
src/core/timer_system.h
|
||||
src/core/timer_system.cpp
|
||||
src/scripting/autonative.h
|
||||
src/scripting/natives/natives_engine.cpp
|
||||
src/core/engine_trace.h
|
||||
src/core/engine_trace.cpp
|
||||
src/scripting/natives/natives_callbacks.cpp
|
||||
src/core/managers/player_manager.h
|
||||
src/core/managers/player_manager.cpp
|
||||
src/scripting/natives/natives_vector.cpp
|
||||
src/scripting/natives/natives_timers.cpp
|
||||
src/utils/virtual.h
|
||||
src/scripting/natives/natives_events.cpp
|
||||
src/core/memory.cpp
|
||||
src/core/memory.h
|
||||
src/core/managers/con_command_manager.cpp
|
||||
src/core/managers/con_command_manager.h
|
||||
src/scripting/natives/natives_commands.cpp
|
||||
src/core/memory_module.h
|
||||
src/core/cs2_sdk/interfaces/cgameresourceserviceserver.h
|
||||
src/core/cs2_sdk/interfaces/cschemasystem.h
|
||||
src/core/cs2_sdk/interfaces/cs2_interfaces.h
|
||||
src/core/cs2_sdk/interfaces/cs2_interfaces.cpp
|
||||
src/core/cs2_sdk/schema.h
|
||||
src/core/cs2_sdk/schema.cpp
|
||||
src/core/function.cpp
|
||||
src/core/function.h
|
||||
src/scripting/natives/natives_memory.cpp
|
||||
src/scripting/natives/natives_schema.cpp
|
||||
src/scripting/natives/natives_entities.cpp
|
||||
src/core/managers/entity_manager.cpp
|
||||
src/core/managers/entity_manager.h
|
||||
src/core/managers/chat_manager.cpp
|
||||
src/core/managers/chat_manager.h
|
||||
src/core/managers/client_command_manager.cpp
|
||||
src/core/managers/client_command_manager.h
|
||||
src/core/managers/server_manager.cpp
|
||||
src/core/managers/server_manager.h
|
||||
src/scripting/natives/natives_server.cpp
|
||||
libraries/nlohmann/json.hpp
|
||||
src/mm_plugin.cpp
|
||||
src/mm_plugin.h
|
||||
libraries/hl2sdk-cs2/tier1/convar.cpp
|
||||
libraries/hl2sdk-cs2/tier1/generichash.cpp
|
||||
libraries/hl2sdk-cs2/entity2/entityidentity.cpp
|
||||
libraries/hl2sdk-cs2/entity2/entitysystem.cpp
|
||||
libraries/dotnet/hostfxr.h
|
||||
libraries/dotnet/coreclr_delegates.h
|
||||
libraries/metamod-source/core/sourcehook/sourcehook.cpp
|
||||
libraries/metamod-source/core/sourcehook/sourcehook_impl_chookidman.cpp
|
||||
libraries/metamod-source/core/sourcehook/sourcehook_impl_chookmaninfo.cpp
|
||||
libraries/metamod-source/core/sourcehook/sourcehook_impl_cvfnptr.cpp
|
||||
libraries/metamod-source/core/sourcehook/sourcehook_impl_cproto.cpp
|
||||
src/scripting/dotnet_host.h
|
||||
src/scripting/dotnet_host.cpp
|
||||
src/core/utils.h
|
||||
src/core/globals.h
|
||||
src/core/globals.cpp
|
||||
src/core/coreconfig.h
|
||||
src/core/coreconfig.cpp
|
||||
src/core/gameconfig.h
|
||||
src/core/gameconfig.cpp
|
||||
src/core/log.h
|
||||
src/core/log.cpp
|
||||
src/scripting/script_engine.h
|
||||
src/scripting/script_engine.cpp
|
||||
src/core/global_listener.h
|
||||
src/scripting/callback_manager.h
|
||||
src/scripting/callback_manager.cpp
|
||||
src/core/managers/event_manager.h
|
||||
src/core/managers/event_manager.cpp
|
||||
src/core/timer_system.h
|
||||
src/core/timer_system.cpp
|
||||
src/scripting/autonative.h
|
||||
src/scripting/natives/natives_engine.cpp
|
||||
src/core/engine_trace.h
|
||||
src/core/engine_trace.cpp
|
||||
src/scripting/natives/natives_callbacks.cpp
|
||||
src/core/managers/player_manager.h
|
||||
src/core/managers/player_manager.cpp
|
||||
src/scripting/natives/natives_vector.cpp
|
||||
src/scripting/natives/natives_timers.cpp
|
||||
src/utils/virtual.h
|
||||
src/scripting/natives/natives_events.cpp
|
||||
src/core/memory.cpp
|
||||
src/core/memory.h
|
||||
src/core/managers/con_command_manager.cpp
|
||||
src/core/managers/con_command_manager.h
|
||||
src/scripting/natives/natives_commands.cpp
|
||||
src/core/memory_module.h
|
||||
src/core/memory_module.cpp
|
||||
src/core/cs2_sdk/interfaces/cgameresourceserviceserver.h
|
||||
src/core/cs2_sdk/interfaces/cschemasystem.h
|
||||
src/core/cs2_sdk/interfaces/cs2_interfaces.h
|
||||
src/core/cs2_sdk/interfaces/cs2_interfaces.cpp
|
||||
src/core/cs2_sdk/schema.h
|
||||
src/core/cs2_sdk/schema.cpp
|
||||
src/core/function.cpp
|
||||
src/core/function.h
|
||||
src/scripting/natives/natives_memory.cpp
|
||||
src/scripting/natives/natives_schema.cpp
|
||||
src/scripting/natives/natives_entities.cpp
|
||||
src/scripting/natives/natives_voice.cpp
|
||||
src/core/managers/entity_manager.cpp
|
||||
src/core/managers/entity_manager.h
|
||||
src/core/managers/chat_manager.cpp
|
||||
src/core/managers/chat_manager.h
|
||||
src/core/managers/server_manager.cpp
|
||||
src/core/managers/server_manager.h
|
||||
src/scripting/natives/natives_server.cpp
|
||||
libraries/nlohmann/json.hpp
|
||||
src/core/managers/voice_manager.cpp
|
||||
src/core/managers/voice_manager.h
|
||||
src/scripting/natives/natives_dynamichooks.cpp
|
||||
)
|
||||
|
||||
|
||||
if (LINUX)
|
||||
# memoverride.cpp is not usable on CMake Windows, cuz CMake default link libraries (seems) always link ucrt.lib
|
||||
set(SOURCE_FILES
|
||||
${SOURCE_FILES}
|
||||
libraries/hl2sdk-cs2/public/tier0/memoverride.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(PROTO_DIRS -I${CMAKE_CURRENT_SOURCE_DIR}/libraries/GameTracking-CS2/Protobufs)
|
||||
file(GLOB PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/GameTracking-CS2/Protobufs/*.proto")
|
||||
|
||||
## Generate protobuf source & headers
|
||||
#add_custom_command(
|
||||
# OUTPUT protobuf_output_stamp
|
||||
# COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/compile.sh
|
||||
# COMMENT "Generating protobuf files using compile.sh script"
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf
|
||||
# DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/compile.sh
|
||||
# VERBATIM
|
||||
#)
|
||||
#
|
||||
#SET(SOURCE_FILES ${SOURCE_FILES} protobuf_output_stamp)
|
||||
if (LINUX)
|
||||
set(PROTOC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2/devtools/bin/linux/protoc)
|
||||
elseif(WIN32)
|
||||
set(PROTOC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2/devtools/bin/protoc.exe)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT protobuf_output_stamp
|
||||
COMMAND ${PROTOC_EXECUTABLE} --proto_path=thirdparty/protobuf-3.21.8/src --proto_path=common --cpp_out=common common/network_connection.proto
|
||||
COMMENT "Generating protobuf file"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
SET(SOURCE_FILES ${SOURCE_FILES} protobuf_output_stamp)
|
||||
|
||||
# Sources
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${NATIVES_SOURCES} ${CONVERSIONS_SOURCES} ${CONVERSIONS_HEADERS})
|
||||
@@ -105,15 +129,25 @@ target_include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/core/cs2_sdk
|
||||
)
|
||||
|
||||
include("makefiles/linux.base.cmake")
|
||||
if (LINUX)
|
||||
include("makefiles/linux.base.cmake")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/addons/counterstrikesharp/bin/linuxsteamrt64"
|
||||
)
|
||||
elseif(WIN32)
|
||||
include("makefiles/windows.base.cmake")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/addons/counterstrikesharp/bin/win64"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# Libraries
|
||||
target_link_libraries(${PROJECT_NAME} ${COUNTER_STRIKE_SHARP_LINK_LIBRARIES})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/addons/counterstrikesharp/bin/linuxsteamrt64"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
|
||||
43
README.md
43
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
CounterStrikeSharp is a server side modding framework for Counter-Strike: Global Offensive. This project attempts to implement a .NET Core scripting layer on top of a Metamod Source Plugin, allowing developers to create plugins that interact with the game server in a modern language (C#) to facilitate the creation of maintainable and testable code.
|
||||
|
||||
[Come and join our Discord](https://discord.gg/X7r3PmuYKq)
|
||||
[Come and join our Discord](https://discord.gg/eAZU3guKWU)
|
||||
|
||||
## History
|
||||
|
||||
@@ -10,26 +10,21 @@ This project is an ongoing migration of a previous project (titled [VSP.NET](htt
|
||||
|
||||
Due to the architectural changes of CS2, the plugin is being rebuilt on the ground up, to support Linux 64-bit, something which was previously impossible.
|
||||
|
||||
## Philosophy
|
||||
|
||||
As a result, there are a few key philosophies and trade-offs that drive the project.
|
||||
- Only 64 bit is supported.
|
||||
- .NET only supports x64 on Linux; CSGO previously only supported 32 bit servers, but CS2 supports 64 bit on Linux.
|
||||
- Supporting both platforms is a lot of work for 1 person, so there are no real plans to support Windows.
|
||||
|
||||
## Install
|
||||
|
||||
Download the latest build from [here](https://github.com/roflmuffin/CounterStrikeSharp/releases). (Download the with runtime version if this is your first time installing).
|
||||
|
||||
Detailed installation instructions can be found in the [docs](https://docs.cssharp.dev/guides/getting-started/).
|
||||
Detailed installation instructions can be found in the [docs](https://docs.cssharp.dev/docs/guides/getting-started.html).
|
||||
|
||||
## What works?
|
||||
|
||||
_(Note, these were features in the previous VSP.NET project, but have not been implemented yet in this project)_
|
||||
|
||||
These features are the core of the platform and work pretty well/have a low risk of causing issues.
|
||||
|
||||
- [x] Console Commands, Server Commands (e.g. css_mycommand)
|
||||
- [x] Chat Commands with `!` and `/` prefixes (e.g. !mycommand)
|
||||
- [ ] **(In Progress)** Console Variables
|
||||
- [x] Console Commands, Server Commands (e.g. css_mycommand)
|
||||
- [x] Chat Commands with `!` and `/` prefixes (e.g. !mycommand)
|
||||
- [ ] **(In Progress)** Console Variables
|
||||
- [x] Game Event Handlers & Custom Events (e.g. player_death)
|
||||
- [x] Basic event value get/set (string, bool, int32, float)
|
||||
- [x] Complex event values get/set (ehandle, pawn, player controller)
|
||||
@@ -40,14 +35,15 @@ These features are the core of the platform and work pretty well/have a low risk
|
||||
- [x] OnMapStart
|
||||
- [x] OnTick
|
||||
- [x] Server Information (current map, game time, tick rate, model precaching)
|
||||
- [x] Schema System Access (access player values like current weapon, money, location etc.)
|
||||
- [x] Schema System Access (access player values like current weapon, money, location etc.)
|
||||
|
||||
## Links
|
||||
- [Join the Discord](https://discord.gg/X7r3PmuYKq): Ask questions, provide suggestions
|
||||
|
||||
- [Join the Discord](https://discord.gg/eAZU3guKWU): Ask questions, provide suggestions
|
||||
- [Read the docs](https://docs.cssharp.dev/): Getting started guide, hello world plugin example
|
||||
- [Issue tracker](https://github.com/roflmuffin/CounterStrikeSharp/issues): Raise any issues here
|
||||
- [Builds](https://github.com/roflmuffin/CounterStrikeSharp/actions): Download latest unstable dev snapshot
|
||||
- [Install Docs](https://docs.cssharp.dev/guides/getting-started/): Installation instructions
|
||||
- [Install Docs](https://docs.cssharp.dev/docs/guides/getting-started.html): Installation instructions
|
||||
- [Example Plugin](managed/TestPlugin/TestPlugin.cs): Test plugin with basic functionality
|
||||
|
||||
## Examples
|
||||
@@ -67,16 +63,20 @@ public class HelloWorldPlugin : BasePlugin
|
||||
|
||||
public override string ModuleVersion => "0.0.1";
|
||||
|
||||
public override string ModuleAuthor => "roflmuffin";
|
||||
|
||||
public override string ModuleDescription => "Simple hello world plugin";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Console.WriteLine("Hello World!");
|
||||
Logger.LogInformation("Plugin loaded successfully!");
|
||||
}
|
||||
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerConnect(EventPlayerConnect @event, GameEventInfo info)
|
||||
{
|
||||
// Userid will give you a reference to a CCSPlayerController class
|
||||
Log($"Player {@event.Userid.PlayerName} has connected!");
|
||||
Logger.LogInformation("Player {Name} has connected!", @event.Userid.PlayerName);
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
@@ -84,19 +84,19 @@ public class HelloWorldPlugin : BasePlugin
|
||||
[ConsoleCommand("issue_warning", "Issue warning to player")]
|
||||
public void OnCommand(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
Log("You shouldn't be doing that!");
|
||||
Logger.LogWarning("Player shouldn't be doing that");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
A lot of code has been borrowed from SourceMod as well as Source.Python, two pioneering source engine plugin frameworks which this project lends a lot of its credit to.
|
||||
I've also used the scripting context & native system that is implemented in FiveM for GTA5. Also shoutout to the [CS2Fixes](https://github.com/Source2ZE/CS2Fixes) project for providing good reverse-engineering information so shortly after CS2 release.
|
||||
A lot of code has been borrowed from [SourceMod](https://github.com/alliedmodders/sourcemod) as well as [Source.Python](https://github.com/Source-Python-Dev-Team/Source.Python), two pioneering source engine plugin frameworks which this project lends a lot of its credit to.
|
||||
I've also used the scripting context & native system that is implemented in [FiveM](https://github.com/citizenfx/fivem) for GTA5. Also shoutout to the [CS2Fixes](https://github.com/Source2ZE/CS2Fixes) project for providing good reverse-engineering information so shortly after CS2 release.
|
||||
|
||||
## How to Build
|
||||
|
||||
Building requires CMake on Linux.
|
||||
Building requires CMake.
|
||||
|
||||
Clone the repository
|
||||
|
||||
@@ -128,3 +128,4 @@ Build
|
||||
```bash
|
||||
cmake --build . --config Debug
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"#css/admin": {
|
||||
"flags": [
|
||||
"@css/reservation",
|
||||
"@css/generic",
|
||||
"@css/kick",
|
||||
"@css/ban",
|
||||
"@css/unban",
|
||||
"@css/vip",
|
||||
"@css/slay",
|
||||
"@css/changemap",
|
||||
"@css/cvar",
|
||||
"@css/config",
|
||||
"@css/chat",
|
||||
"@css/vote",
|
||||
"@css/password",
|
||||
"@css/rcon",
|
||||
"@css/cheats",
|
||||
"@css/root"
|
||||
],
|
||||
"immunity": 100
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"example_command": {
|
||||
"flags": [
|
||||
"@css/custom-permission"
|
||||
],
|
||||
"check_type": "all",
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"Erikj": {
|
||||
"identity": "76561197960265731",
|
||||
"immunity": 100,
|
||||
"flags": [
|
||||
"@css/custom-flag-1",
|
||||
"@css/custom-flag-2"
|
||||
],
|
||||
"groups": [
|
||||
"#css/admin"
|
||||
],
|
||||
"command_overrides": {
|
||||
"css_plugins": true,
|
||||
"css": false
|
||||
}
|
||||
},
|
||||
"Another erikj": {
|
||||
"identity": "STEAM_0:1:1",
|
||||
"flags": ["@mycustomplugin/admin"]
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"Erikj": {
|
||||
"identity": "76561197960265731",
|
||||
"flags": [
|
||||
"@css/kick",
|
||||
"@css/ban"
|
||||
]
|
||||
},
|
||||
"Another erikj": {
|
||||
"identity": "STEAM_0:1:1",
|
||||
"flags": [
|
||||
"@anotherscope/foobar"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"PublicChatTrigger": [ "!" ],
|
||||
"SilentChatTrigger": [ "/" ],
|
||||
"FollowCS2ServerGuidelines": true,
|
||||
"PluginHotReloadEnabled": true,
|
||||
"ServerLanguage": "en"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
Place your plugin configurations here.
|
||||
|
||||
TestPlugin/TestPlugin.json
|
||||
AnotherPlugin/AnotherPlugin.json
|
||||
@@ -2,46 +2,202 @@
|
||||
"UTIL_ClientPrintAll": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x89\\x5C\\x24\\x08\\x48\\x89\\x6C\\x24\\x10\\x48\\x89\\x74\\x24\\x18\\x57\\x48\\x81\\xEC\\x70\\x01\\x2A\\x2A\\x8B\\xE9",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x49\\x89\\xD7\\x41\\x56\\x49\\x89\\xF6\\x41\\x55\\x41\\x89\\xFD"
|
||||
}
|
||||
},
|
||||
"ClientPrint": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x85\\xC9\\x0F\\x84\\x2A\\x2A\\x2A\\x2A\\x48\\x8B\\xC4\\x48\\x89\\x58\\x18",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x49\\x89\\xCF\\x41\\x56\\x49\\x89\\xD6\\x41\\x55\\x41\\x89\\xF5\\x41\\x54\\x4C\\x8D\\xA5\\xA0\\xFE\\xFF\\xFF"
|
||||
}
|
||||
},
|
||||
"CCSPlayerController_SwitchTeam": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x40\\x56\\x57\\x48\\x81\\xEC\\x2A\\x2A\\x2A\\x2A\\x48\\x8B\\xF9\\x8B\\xF2\\x8B\\xCA",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x55\\x49\\x89\\xFD\\x89\\xF7"
|
||||
}
|
||||
},
|
||||
"CCSPlayerController_ChangeTeam": {
|
||||
"offsets": {
|
||||
"windows": 90,
|
||||
"linux": 89
|
||||
}
|
||||
},
|
||||
"CCSPlayerController_Respawn": {
|
||||
"offsets": {
|
||||
"windows": 242,
|
||||
"linux": 244
|
||||
}
|
||||
},
|
||||
"CCSPlayerPawn_Respawn": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x40\\x53\\x48\\x83\\xEC\\x20\\x8B\\x91\\x38\\x0B\\x00\\x00\\x48\\x8B\\xD9",
|
||||
"linux": "\\x8B\\x8F\\x40\\x0E\\x00\\x00\\x83\\xF9\\xFF\\x0F\\x84\\xD9\\x01"
|
||||
}
|
||||
},
|
||||
"CCSPlayerPawnBase_PostThink": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x8B\\xC4\\x48\\x89\\x48\\x08\\x55\\x53\\x56\\x57\\x41\\x56\\x48\\x8D\\xA8\\xD8\\xFE\\xFF\\xFF",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x49\\x89\\xFF\\x41\\x56\\x41\\x55\\x41\\x54\\x53\\x48\\x81\\xEC\\x2A\\x2A\\x2A\\x2A\\xE8\\x2A\\x2A\\x2A\\x2A\\x4C"
|
||||
}
|
||||
},
|
||||
"GiveNamedItem": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x89\\x5C\\x24\\x18\\x48\\x89\\x74\\x24\\x20\\x55\\x57\\x41\\x54\\x41\\x56\\x41\\x57\\x48\\x8D\\x6C\\x24\\xD9",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x49\\x89\\xCE\\x41\\x55\\x49\\x89\\xF5\\x41\\x54\\x49\\x89\\xD4"
|
||||
}
|
||||
},
|
||||
"UTIL_Remove": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x85\\xC9\\x74\\x2A\\x48\\x8B\\xD1\\x48\\x8B\\x0D\\x2A\\x2A\\x2A\\x2A",
|
||||
"linux": "\\x48\\x89\\xFE\\x48\\x85\\xFF\\x74\\x2A\\x48\\x8D\\x05\\x2A\\x2A\\x2A\\x2A\\x48"
|
||||
}
|
||||
},
|
||||
"Host_Say": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x44\\x89\\x4C\\x24\\x20\\x44\\x88\\x44\\x24\\x18",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x49\\x89\\xFF\\x41\\x56\\x41\\x55\\x41\\x54\\x4D\\x89\\xC4"
|
||||
}
|
||||
},
|
||||
"CBaseModelEntity_SetModel": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x89\\x5C\\x24\\x10\\x48\\x89\\x7C\\x24\\x20\\x55\\x48\\x8B\\xEC\\x48\\x83\\xEC\\x50",
|
||||
"linux": "\\x55\\x48\\x89\\xF2\\x48\\x89\\xE5\\x41\\x54\\x49\\x89\\xFC\\x48\\x8D\\x2A\\x2A\\x48\\x83\\x2A\\x2A\\x2A\\x8D\\x05\\x2A\\x2A\\x2A\\x00\\x48\\x8B\\x30\\x48\\x8B\\x06\\xFF\\x2A\\x2A\\x48\\x8B\\x45\\x2A\\x48\\x8D\\x2A\\x2A\\x4C\\x89\\x2A\\x48\\x89\\x45\\x2A\\x2A\\x68\\xFC"
|
||||
}
|
||||
},
|
||||
"CCSPlayer_ItemServices_DropActivePlayerWeapon": {
|
||||
"offsets": {
|
||||
"windows": 18,
|
||||
"linux": 19
|
||||
}
|
||||
},
|
||||
"CCSPlayer_ItemServices_RemoveWeapons": {
|
||||
"offsets": {
|
||||
"windows": 21,
|
||||
"linux": 20
|
||||
}
|
||||
},
|
||||
"CGameSceneNode_GetSkeletonInstance": {
|
||||
"offsets": {
|
||||
"windows": 8,
|
||||
"linux": 8
|
||||
}
|
||||
},
|
||||
"CCSGameRules_TerminateRound": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x8B\\xC4\\x4C\\x89\\x48\\x20\\x55\\x56",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x49\\x89\\xFD\\x41\\x54\\x53\\x48\\x81\\xEC\\xE8"
|
||||
}
|
||||
},
|
||||
"UTIL_CreateEntityByName": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x83\\xEC\\x48\\xC6\\x44\\x24\\x30\\x00\\x4C\\x8B\\xC1",
|
||||
"linux": "\\x48\\x8D\\x05\\x2A\\x2A\\x2A\\x2A\\x55\\x48\\x89\\xFA"
|
||||
}
|
||||
},
|
||||
"CBaseEntity_DispatchSpawn": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x89\\x5C\\x24\\x10\\x57\\x48\\x83\\xEC\\x30\\x48\\x8B\\xDA\\x48\\x8B\\xF9\\x48\\x85\\xC9",
|
||||
"linux": "\\x48\\x85\\xFF\\x74\\x4B\\x55\\x48\\x89\\xE5\\x41\\x56"
|
||||
}
|
||||
},
|
||||
"CEntityInstance_AcceptInput": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x89\\x5C\\x24\\x10\\x48\\x89\\x74\\x24\\x18\\x57\\x48\\x83\\xEC\\x40\\x49\\x8B\\xF0",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x49\\x89\\xFF\\x41\\x56\\x48\\x8D\\x7D\\xC0"
|
||||
}
|
||||
},
|
||||
"LegacyGameEventListener": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x8B\\x15\\x2A\\x2A\\x2A\\x2A\\x48\\x85\\xD2\\x74\\x2A\\x85\\xC9\\x74",
|
||||
"linux": "\\x48\\x8B\\x05\\x2A\\x2A\\x2A\\x2A\\x48\\x85\\xC0\\x74\\x2A\\x83\\xFF\\x3F\\x76\\x2A\\x31\\xC0"
|
||||
}
|
||||
},
|
||||
"CBasePlayerPawn_CommitSuicide": {
|
||||
"offsets": {
|
||||
"linux": 355
|
||||
"windows": 357,
|
||||
"linux": 357
|
||||
}
|
||||
},
|
||||
"CBasePlayerPawn_RemovePlayerItem": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"linux": "\\x55\\x48\\x89\\x2A\\x41\\x2A\\x49\\x89\\x2A\\x41\\x2A\\x49\\x89\\x2A\\xE8\\x2A\\x2A\\x2A\\x2A\\x49\\x39",
|
||||
"windows": "\\x48\\x85\\xD2\\x0F\\x84\\x2A\\x2A\\x2A\\x2A\\x48\\x89\\x5C\\x24\\x08\\x57\\x48\\x83\\xEC\\x30\\x48\\x8B\\xDA"
|
||||
}
|
||||
},
|
||||
"CBaseEntity_Teleport": {
|
||||
"offsets": {
|
||||
"linux": 147
|
||||
"windows": 149,
|
||||
"linux": 148
|
||||
}
|
||||
},
|
||||
"CBaseEntity_TakeDamageOld": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x40\\x56\\x57\\x48\\x83\\xEC\\x58\\x48\\x8B\\x41\\x10",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x49\\x89\\xFC\\x53\\x48\\x83\\xEC\\x38\\x4C\\x8D\\x2D\\x2A\\x2A\\x2A\\x2A\\x49\\x8B\\x7D\\x00\\x48\\x85\\xFF\\x0F\\x84\\x2A\\x2A\\x2A\\x2A"
|
||||
}
|
||||
},
|
||||
"CBaseTrigger_StartTouch": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x41\\x56\\x41\\x57\\x48\\x83\\xEC\\x58\\x48\\x8B\\x01",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x56\\x49\\x89\\xF6\\x41\\x55\\x49\\x89\\xFD\\x41\\x54\\x53\\xBB"
|
||||
}
|
||||
},
|
||||
"CBaseTrigger_EndTouch": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x40\\x53\\x57\\x41\\x55\\x48\\x83\\xEC\\x40",
|
||||
"linux": "\\x55\\xBA\\xFF\\xFF\\xFF\\xFF\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x49"
|
||||
}
|
||||
},
|
||||
"StateChanged": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x40\\x55\\x53\\x56\\x41\\x55\\x41\\x57\\x48\\x8D\\x6C\\x24\\xB0",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x53\\x89\\xD3"
|
||||
}
|
||||
},
|
||||
"NetworkStateChanged": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x4C\\x8B\\xC9\\x48\\x8B\\x09\\x48\\x85\\xC9\\x74\\x2A\\x48\\x8B\\x41\\x10",
|
||||
"linux": "\\x4C\\x8B\\x07\\x4D\\x85\\xC0\\x74\\x2A\\x49\\x8B\\x40\\x10"
|
||||
}
|
||||
},
|
||||
"GameEntitySystem": {
|
||||
"offsets": {
|
||||
"windows": 88,
|
||||
"linux": 80
|
||||
}
|
||||
},
|
||||
"GameEventManager": {
|
||||
"offsets": {
|
||||
"windows": 91,
|
||||
"linux": 91
|
||||
}
|
||||
},
|
||||
"CEntityIOOutput_FireOutputInternal": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x8B\\xC4\\x4C\\x89\\x48\\x20\\x55\\x57\\x41\\x54\\x41\\x56",
|
||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x53\\x48\\x83\\xEC\\x58\\x4C\\x8B\\x6F\\x08"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
"Metamod Plugin"
|
||||
{
|
||||
"alias" "counterstrikesharp"
|
||||
"file" "addons/counterstrikesharp/bin/linuxsteamrt64/counterstrikesharp"
|
||||
}
|
||||
3
docfx/404.md
Normal file
3
docfx/404.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 404
|
||||
|
||||
We recently changed our docs. Your page may exist at a different location.
|
||||
46
docfx/docfx.json
Normal file
46
docfx/docfx.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"metadata": [
|
||||
{
|
||||
"src": [
|
||||
{
|
||||
"src": "../managed/CounterStrikeSharp.API",
|
||||
"files": ["**/*.csproj"],
|
||||
"exclude": ["**/bin/**", "**/obj/**"]
|
||||
}
|
||||
],
|
||||
"filter": "filterConfig.yml",
|
||||
"dest": "api",
|
||||
"namespaceLayout": "nested"
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
"content": [
|
||||
{
|
||||
"files": ["**/*.{md,yml}"],
|
||||
"exclude": ["_site/**"]
|
||||
}
|
||||
],
|
||||
"resource": [
|
||||
{
|
||||
"files": ["images/**"]
|
||||
}
|
||||
],
|
||||
"output": "_site",
|
||||
"template": ["default", "modern", "layouts/cssharp"],
|
||||
"globalMetadata": {
|
||||
"_appFaviconPath": "images/cssharp.svg",
|
||||
"_appFooter": "<a href=\"https://docs.cssharp.dev\">docs.cssharp.dev</a>",
|
||||
"_appLogoPath": "images/cssharp.svg",
|
||||
"_appName": "CounterStrikeSharp",
|
||||
"_appTitle": "CounterStrikeSharp",
|
||||
"_disableNewTab": true,
|
||||
"_enableNewTab": true,
|
||||
"_enableSearch": true,
|
||||
"pdf": false
|
||||
},
|
||||
"sitemap": {
|
||||
"baseUrl": "https://docs.cssharp.dev",
|
||||
"changefreq": "hourly"
|
||||
}
|
||||
}
|
||||
}
|
||||
51
docfx/docs/admin-framework/admin-command-attributes.md
Normal file
51
docfx/docs/admin-framework/admin-command-attributes.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Admin Command Attributes
|
||||
description: A guide on using the Admin Command Attributes in plugins.
|
||||
---
|
||||
|
||||
# Admin Command Attributes
|
||||
|
||||
A guide on using the Admin Command Attributes in plugins.
|
||||
|
||||
## Assigning permissions to a Command
|
||||
|
||||
Assigning permissions to a Command is as easy as tagging the Command method (function callback) with either a `RequiresPermissions` or `RequiresPermissionsOr` attribute. The difference between the two attributes is that `RequiresPermissionsOr` needs only one permission to be present on the caller to be passed, while `RequiresPermissions` needs the caller to have all permissions listed. CounterStrikeSharp handles all of the permission checks behind the scenes for you.
|
||||
|
||||
```csharp
|
||||
[RequiresPermissions("@css/slay", "@custom/permission")]
|
||||
public void OnMyCommand(CCSPlayerController? caller, CommandInfo info)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
```csharp
|
||||
[RequiresPermissionsOr("@css/ban", "@custom/permission-2")]
|
||||
public void OnMyOtherCommand(CCSPlayerController? caller, CommandInfo info)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You can even stack the attributes on top of each other, and all of them will be checked.
|
||||
|
||||
```csharp
|
||||
// Requires (@css/cvar AND @custom/permission-1) AND either (@custom/permission-1 OR @custom/permission-2).
|
||||
[RequiresPermissions("@css/cvar", "@custom/permission-1")]
|
||||
[RequiresPermissionsOr("@css/ban", "@custom/permission-2")]
|
||||
public void OnMyComplexCommand(CCSPlayerController? caller, CommandInfo info)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You can also check for groups using the same attributes.
|
||||
|
||||
```csharp
|
||||
[RequiresPermissions("#css/simple-admin")]
|
||||
public void OnMyGroupCommand(CCSPlayerController? caller, CommandInfo info)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
46
docfx/docs/admin-framework/defining-admin-groups.md
Normal file
46
docfx/docs/admin-framework/defining-admin-groups.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: Defining Admin Groups
|
||||
description: A guide on how to define admin groups for CounterStrikeSharp.
|
||||
---
|
||||
|
||||
# Defining Admin Groups
|
||||
|
||||
A guide on how to define admin groups for CounterStrikeSharp.
|
||||
|
||||
## Adding Groups
|
||||
|
||||
Groups can be created to group a series of permissions together under one tag. They are defined in `configs/admin_groups.json`. The important things you need to declare is the name of the group and the permissions they have.
|
||||
|
||||
```json
|
||||
"#css/simple-admin": {
|
||||
"flags": [
|
||||
"@css/generic",
|
||||
"@css/reservation",
|
||||
"@css/ban",
|
||||
"@css/slay",
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can add admins to groups using the `groups` array in `configs/admins.json`
|
||||
```json
|
||||
{
|
||||
"erikj": {
|
||||
"identity": "76561198808392634",
|
||||
"flags": ["@mycustomplugin/admin"],
|
||||
"groups": ["#css/simple-admin"]
|
||||
},
|
||||
"Another erikj": {
|
||||
"identity": "STEAM_0:1:1",
|
||||
"flags": ["@mycustomplugin/admin"],
|
||||
"groups": ["#css/simple-admin"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> All group names MUST start with a hashtag # character, otherwise CounterStrikeSharp won't recognize the group.
|
||||
|
||||
|
||||
Admins can be assigned to multiple groups and they will inherit their flags. You can manually assign groups to players in code with `AdminManager.AddPlayerToGroup` and `AdminManager.RemovePlayerFromGroup`.
|
||||
|
||||
39
docfx/docs/admin-framework/defining-admin-immunity.md
Normal file
39
docfx/docs/admin-framework/defining-admin-immunity.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Defining Admin Immunity
|
||||
description: A guide on how to define immunity for admins for CounterStrikeSharp.
|
||||
---
|
||||
|
||||
# Defining Admin Immunity
|
||||
|
||||
A guide on how to define immunity for admins for CounterStrikeSharp.
|
||||
|
||||
## Player Immunity
|
||||
|
||||
Admins can be assigned an immunity value, similar to SourceMod. If an admin or player with a lower immunity value targets another admin or player with a larger immunity value, then the command will fail. You can define an immunity value by adding the `immunity` key to each admin in `configs/admins.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"ZoNiCaL": {
|
||||
"identity": "76561198808392634",
|
||||
"flags": ["@css/changemap", "@css/generic"],
|
||||
"immunity": 100
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can even assign an immunity value to groups. If an admin has a lower immunity value, the group's value will be used instead.
|
||||
|
||||
```json
|
||||
"#css/simple-admin": {
|
||||
"flags": [
|
||||
"@css/generic",
|
||||
"@css/reservation",
|
||||
"@css/ban",
|
||||
"@css/slay",
|
||||
],
|
||||
"immunity": 100
|
||||
}
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> CounterStrikeSharp does not automatically handle immunity checking. It is up to individual plugins to handle immunity checks as they can implement different ways of targeting players. This can be done in code with `AdminManager.CanPlayerTarget`. You can also set a player's immunity in code with `AdminManager.SetPlayerImmunity`.
|
||||
62
docfx/docs/admin-framework/defining-admins.md
Normal file
62
docfx/docs/admin-framework/defining-admins.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: Defining Admins
|
||||
description: A guide on how to define admins for CounterStrikeSharp.
|
||||
---
|
||||
|
||||
# Defining Admins
|
||||
|
||||
A guide on how to define admins for CounterStrikeSharp.
|
||||
|
||||
## Admin Framework
|
||||
|
||||
CounterStrikeSharp has a basic framework which allows plugin developers to assign permissions to commands. When CSS is initialized, a list of admins are loaded from `configs/admins.json`.
|
||||
|
||||
## Adding Admins
|
||||
|
||||
Adding an Admin is as simple as creating a new entry in the `configs/admins.json` file. The important things you need to declare are the SteamID identifier and the permissions they have. CounterStrikeSharp will do all the heavy-lifting to decipher your SteamID. If you're familiar with SourceMod, permission definitions are slightly different as they're defined by an array of strings instead of a string of characters.
|
||||
|
||||
```json
|
||||
{
|
||||
"ZoNiCaL": {
|
||||
"identity": "76561198808392634",
|
||||
"flags": ["@css/changemap", "@css/generic"]
|
||||
},
|
||||
"another ZoNiCaL": {
|
||||
"identity": "STEAM_0:1:1",
|
||||
"flags": ["@css/generic"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also manually assign permissions to players in code with `AdminManager.AddPlayerPermissions` and `AdminManager.RemovePlayerPermissions`. These changes are not saved to `configs/admins.json`.
|
||||
|
||||
> [!NOTE]
|
||||
> All user permissions MUST start with an at-symbol @ character, otherwise CounterStrikeSharp will not recognize the permission.
|
||||
|
||||
### Standard Permissions
|
||||
|
||||
Because the flag system is just a list of strings associated with a user, there is no real list of letter based flags like there was previously in something like SourceMod. This means as a plugin author you can declare your own flags, scoped with an `@` symbol, like `@roflmuffin/guns`, which might be the permission to allow spawning of guns in a given command.
|
||||
|
||||
However there is a somewhat standardized list of flags that it is advised you use if you are adding functionality that aligns with their purpose, and these are based on the original SourceMod flags:
|
||||
|
||||
```shell
|
||||
@css/reservation # Reserved slot access.
|
||||
@css/generic # Generic admin.
|
||||
@css/kick # Kick other players.
|
||||
@css/ban # Ban other players.
|
||||
@css/unban # Remove bans.
|
||||
@css/vip # General vip status.
|
||||
@css/slay # Slay/harm other players.
|
||||
@css/changemap # Change the map or major gameplay features.
|
||||
@css/cvar # Change most cvars.
|
||||
@css/config # Execute config files.
|
||||
@css/chat # Special chat privileges.
|
||||
@css/vote # Start or create votes.
|
||||
@css/password # Set a password on the server.
|
||||
@css/rcon # Use RCON commands.
|
||||
@css/cheats # Change sv_cheats or use cheating commands.
|
||||
@css/root # Magically enables all flags and ignores immunity values.
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> CounterStrikeSharp does not implement traditional admin command such as `!slay`, `!kick`, and `!ban`. It is up to individual plugins to implement these commands.
|
||||
57
docfx/docs/admin-framework/defining-command-overrides.md
Normal file
57
docfx/docs/admin-framework/defining-command-overrides.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Defining Command Overrides
|
||||
description: A guide on how to define command overrides for CounterStrikeSharp.
|
||||
---
|
||||
|
||||
# Defining Command Overrides
|
||||
|
||||
A guide on how to define command overrides for CounterStrikeSharp.
|
||||
|
||||
## Defining Admin and Group specific overrides
|
||||
|
||||
Command permissions can be overriden so specific admins or groups can execute the command, regardless of any permissions they may or may not have. You can define command overrides by adding the `command_overrides` key to each admin in `configs/admins.json` or group in `configs/admin_groups.json`. Command overrides can either be set to `true`, meaning the admin/group can execute the command, or `false`, meaning the admin/group cannot execute the command at all.
|
||||
|
||||
```json
|
||||
{
|
||||
"ZoNiCaL": {
|
||||
"identity": "76561198808392634",
|
||||
"flags": ["@css/changemap", "@css/generic"],
|
||||
"immunity": 100,
|
||||
"command_overrides": {
|
||||
"example_command": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
"#css/simple-admin": {
|
||||
"flags": [
|
||||
"@css/generic",
|
||||
"@css/reservation",
|
||||
"@css/ban",
|
||||
"@css/slay",
|
||||
],
|
||||
"command_overrides": {
|
||||
"example_command_2": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can set a command override for a player in code using `AdminManager.SetPlayerCommandOverride`.
|
||||
|
||||
## Replacing Command permissions
|
||||
|
||||
Command permissions can be entirely replaced. These are defined in `configs/admin_overrides.json`. The important things you need to declare are what commands are being changed and what their new flags are. Command overrides can be set to be enabled or disabled, and you can toggle them in code with `AdminManager.SetCommandOverrideState`. You can also specify whether the command override requires the caller to have all of the new permissions (similar to a `RequiresPermissions` attribute check) or only one or more permissions (similar to a `RequirePermissionsOr` attribute check). You cannot stack permission checks.
|
||||
|
||||
```json
|
||||
"css": {
|
||||
"flags": [
|
||||
"@css/custom-permission"
|
||||
],
|
||||
"check_type": "all",
|
||||
"enabled": true
|
||||
}
|
||||
```
|
||||
|
||||
You can check if a command has been overriden in code using `AdminManager.CommandIsOverriden`, and you can manipulate the command override permissions using `AdminManager.AddPermissionOverride` and `AdminManager.RemovePermissionOverride`.
|
||||
14
docfx/docs/admin-framework/toc.yml
Normal file
14
docfx/docs/admin-framework/toc.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- name: Admin Command Attributes
|
||||
href: admin-command-attributes.md
|
||||
|
||||
- name: Defining Admins
|
||||
href: defining-admins.md
|
||||
|
||||
- name: Defining Command Overrides
|
||||
href: defining-command-overrides.md
|
||||
|
||||
- name: Defining Admin Groups
|
||||
href: defining-admin-groups.md
|
||||
|
||||
- name: Defining Admin Immunity
|
||||
href: defining-admin-immunity.md
|
||||
@@ -3,6 +3,10 @@ title: Console Commands
|
||||
description: How to add a new console command
|
||||
---
|
||||
|
||||
# Console Commands
|
||||
|
||||
How to add a new console command
|
||||
|
||||
## Adding a Console Command
|
||||
|
||||
### Automatic registration
|
||||
@@ -3,6 +3,10 @@ title: Console Variables
|
||||
description: How to read & write console variables (ConVars).
|
||||
---
|
||||
|
||||
# Console Variables
|
||||
|
||||
How to read & write console variables (ConVars).
|
||||
|
||||
## Finding a ConVar
|
||||
|
||||
Use the `ConVar.Find` static method to find a reference to an existing ConVar (or `null`).
|
||||
@@ -3,22 +3,30 @@ title: Game Events
|
||||
description: How to listen to Source 1 style game events.
|
||||
---
|
||||
|
||||
# Game Events
|
||||
|
||||
How to listen to Source 1 style game events.
|
||||
|
||||
## Adding an Event Listener
|
||||
|
||||
### Automatic registration
|
||||
|
||||
CounterStrikeSharp will automatically register event listeners marked with a `GameEventHandler` attribute on the `BasePlugin` class. These listeners are automatically registered/deregistered for you on hot reload.
|
||||
|
||||
:::note
|
||||
The first parameter type must be a subclass of the `GameEvent` class. The names are automatically generated from the [game event list](https://cs2.poggu.me/dumped-data/game-events).
|
||||
:::
|
||||
> [!NOTE]
|
||||
> The first parameter type must be a subclass of the `GameEvent` class. The names are automatically generated from the [game event list](https://cs2.poggu.me/dumped-data/game-events).
|
||||
|
||||
```csharp
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerConnect(EventPlayerConnect @event, GameEventInfo info)
|
||||
{
|
||||
// Userid will give you a reference to a CCSPlayerController class
|
||||
Log($"Player {@event.Userid.PlayerName} has connected!");
|
||||
// Userid will give you a reference to a CCSPlayerController class.
|
||||
// Before accessing any of its fields, you must first check if the Userid
|
||||
// handle is actually valid, otherwise you may run into runtime exceptions.
|
||||
// See the documentation section on Referencing Players for details.
|
||||
if (@event.Userid.IsValid) {
|
||||
Logger.LogInformation("Player {Name} has connected!", @event.Userid.PlayerName);
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
@@ -33,7 +41,7 @@ public override void Load(bool hotReload)
|
||||
{
|
||||
RegisterEventHandler<EventRoundStart>((@event, info) =>
|
||||
{
|
||||
Console.WriteLine($"Round has started with time limit of {@event.Timelimit}");
|
||||
Logger.LogInformation("Round has started with time limit of {Timelimit}", @event.Timelimit);
|
||||
|
||||
return HookResult.Continue;
|
||||
});
|
||||
@@ -3,6 +3,10 @@ title: Global Listeners
|
||||
description: How to subscribe to CounterStrikeSharp global listeners.
|
||||
---
|
||||
|
||||
# Global Listeners
|
||||
|
||||
How to subscribe to CounterStrikeSharp global listeners.
|
||||
|
||||
## Adding a Listener
|
||||
|
||||
Global listeners come in a variety of shapes so there is no automatic registration for these, they must be registered in the `OnLoad` of your plugin (or anywhere you have access to the plugin instance). You can find the full list of event listeners in the `Listeners` class as seen below.
|
||||
@@ -22,7 +26,7 @@ public override void Load(bool hotReload)
|
||||
projectile.SmokeColor.X = Random.Shared.NextSingle() * 255.0f;
|
||||
projectile.SmokeColor.Y = Random.Shared.NextSingle() * 255.0f;
|
||||
projectile.SmokeColor.Z = Random.Shared.NextSingle() * 255.0f;
|
||||
Log($"Smoke grenade spawned with color {projectile.SmokeColor}");
|
||||
Logger.LogInformation("Smoke grenade spawned with color {SmokeColor}", projectile.SmokeColor);
|
||||
});
|
||||
});
|
||||
}
|
||||
11
docfx/docs/features/toc.yml
Normal file
11
docfx/docs/features/toc.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
- name: Console Commands
|
||||
href: console-commands.md
|
||||
|
||||
- name: Console Variables
|
||||
href: console-variables.md
|
||||
|
||||
- name: Game Events
|
||||
href: game-events.md
|
||||
|
||||
- name: Global Listeners
|
||||
href: global-listeners.md
|
||||
73
docfx/docs/guides/dependency-injection.md
Normal file
73
docfx/docs/guides/dependency-injection.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Dependency Injection
|
||||
description: How to make use of dependency injection in CounterStrikeSharp
|
||||
---
|
||||
|
||||
# Dependency Injection
|
||||
|
||||
How to make use of dependency injection in CounterStrikeSharp
|
||||
|
||||
`CounterStrikeSharp` uses a standard <a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-8.0" target="_blank">`IServiceCollection`</a> to allow for dependency injection in plugins.
|
||||
|
||||
There are a handful of standard services that are predefined for you (`ILogger` for logging for instance), with more to come in the future. To add your own scoped & singleton services to the container, you can create a new class that implements the `IPluginServiceCollection<T>` interface for your plugin.
|
||||
|
||||
```csharp
|
||||
public class TestPlugin : BasePlugin
|
||||
{
|
||||
// Plugin code...
|
||||
}
|
||||
|
||||
public class TestPluginServiceCollection : IPluginServiceCollection<TestPlugin>
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddScoped<ExampleInjectedClass>();
|
||||
serviceCollection.AddLogging(builder => ...);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
CounterStrikeSharp will search your assembly for any implementations of `IPlugin` and then any implementations of `IPluginServiceCollection<T>` where `T` is your plugin. It will then configure the service provider and then request a singleton instance of your plugin before proceeding to the load step.
|
||||
|
||||
In this way, any dependencies that are listed in your plugin class constructor will automatically get injected at instantation time (before load).
|
||||
|
||||
### Example
|
||||
|
||||
```csharp
|
||||
public class TestInjectedClass
|
||||
{
|
||||
private readonly ILogger<TestInjectedClass> _logger;
|
||||
|
||||
public TestInjectedClass(ILogger<TestInjectedClass> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Hello()
|
||||
{
|
||||
_logger.LogInformation("Hello World from Test Injected Class");
|
||||
}
|
||||
}
|
||||
|
||||
public class TestPluginServiceCollection : IPluginServiceCollection<SamplePlugin>
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddScoped<TestInjectedClass>();
|
||||
}
|
||||
}
|
||||
|
||||
public class SamplePlugin : BasePlugin
|
||||
{
|
||||
private readonly TestInjectedClass _testInjectedClass;
|
||||
public SamplePlugin(TestInjectedClass testInjectedClass)
|
||||
{
|
||||
_testInjectedClass = testInjectedClass;
|
||||
}
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
_testInjectedClass.Hello();
|
||||
}
|
||||
}
|
||||
```
|
||||
72
docfx/docs/guides/getting-started.md
Normal file
72
docfx/docs/guides/getting-started.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: Getting Started
|
||||
description: How to get started installing & using CounterStrikeSharp.
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
In this guide you will learn how to install CounterStrikeSharp onto your vanilla Counter-Strike 2 server. `CounterStrikeSharp` uses `Metamod:Source` as its main way of communicating with the game server, so both frameworks will need to be installed.
|
||||
|
||||
If you're more of a visual person, here is a <a href="https://www.youtube.com/watch?v=FlsKzStHJuY" target="_blank">Youtube video</a> that covers everything.
|
||||
|
||||
## Prerequisites
|
||||
- <a href="https://www.sourcemm.net/downloads.php/?branch=master" target="_blank">Metamod: Source 2.X Dev Build</a>
|
||||
- <a href="https://github.com/roflmuffin/CounterStrikeSharp/releases" target="_blank">CounterStrikeSharp With Runtime</a>
|
||||
|
||||
## Installing Metamod
|
||||
|
||||
1. Extract Metamod and copy the `/addons/` directory to `/game/csgo/`.
|
||||
2. Inside `/game/csgo/`, locate `gameinfo.gi`.
|
||||
3. Create a new line underneath `Game_LowViolence csgo_lv` and add `Game csgo/addons/metamod`.
|
||||
4. Restart your game server.
|
||||
|
||||
Your `gameinfo.gi` should look like <a href="../../images/gameinfogi-example.png" target="_blank">this</a>. Type `meta list` in your server console to see if Metamod is loaded.
|
||||
|
||||
## Installing CounterStrikeSharp
|
||||
|
||||
1. Extract CounterStrikeSharp and copy the `/addons/` directory to `/game/csgo/`.
|
||||
2. Restart your game server.
|
||||
|
||||
Running the command `meta list` in the console should show 1 plugin loaded 🎉
|
||||
|
||||
```shell
|
||||
meta list
|
||||
Listing 1 plugin:
|
||||
[01] CounterStrikeSharp (0.1.0) by Roflmuffin
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> For Windows servers, you must have <a href="https://aka.ms/vs/17/release/vc_redist.x64.exe" target="_blank">Visual Studio Redistributables</a> installed otherwise CounterStrikeSharp will not work.
|
||||
|
||||
## Upgrading CounterStrikeSharp
|
||||
|
||||
To upgrade CounterStrikeSharp you simply need to download the latest release and copy it to your server, the same as the original installation.
|
||||
|
||||
CounterStrikeSharp is designed in a way where your configuration files will not be overwritten if you do this. As CounterStrikeSharp is already installed, you may download the non `with-runtime` build, but you will need to ensure your .NET runtime is up-to-date yourself.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- If this is your first time installing, you **MUST** download the `with-runtime` version. This includes a copy of the .NET runtime, which is required to run the plugin.
|
||||
- Depending on your OS you might also either need to install `libicu` / `icu-libs` / `libicu-dev` using your package manager for .NET to run.
|
||||
- If you get `Unknown Command` when typing `meta list` into your console, double-check the folders are copied over correctly and that your `gameinfo.gi` file is correctly modified.
|
||||
|
||||
Your folder structure should look like this:
|
||||
|
||||
```shell
|
||||
<server_path>/game/csgo/addons > tree -L 2
|
||||
addons
|
||||
├── counterstrikesharp
|
||||
│ ├── api
|
||||
│ ├── bin
|
||||
│ ├── dotnet
|
||||
│ ├── plugins
|
||||
│ └── gamedata
|
||||
│
|
||||
├── metamod
|
||||
│ ├── bin
|
||||
│ ├── counterstrikesharp.vdf
|
||||
│ ├── metaplugins.ini
|
||||
│ └── README.txt
|
||||
├── metamod.vdf
|
||||
└── metamod_x64.vdf
|
||||
```
|
||||
@@ -3,6 +3,10 @@ title: Hello World Plugin
|
||||
description: How to write your first plugin for CounterStrikeSharp
|
||||
---
|
||||
|
||||
# Hello World Plugin
|
||||
|
||||
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>.
|
||||
@@ -34,6 +38,12 @@ Use your IDE (Visual Studio/Rider) to add a reference to the `CounterStrikeSharp
|
||||
</Project>
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Instead of manually adding a reference to `CounterStrikeSharp.Api.dll`, you can > install the NuGet package `CounterStrikeSharp.Api` using the following:
|
||||
> ```shell
|
||||
> dotnet add package CounterStrikeSharp.API
|
||||
> ```
|
||||
|
||||
### Creating a Plugin File
|
||||
|
||||
Rename the default class file that came with your new project (by default it should be `Class1.cs`) to something more accurate, like `HelloWorldPlugin.cs`. Inside this file, we will insert the stub hello world plugin. Be sure to change the name and namespace so it matches your project name.
|
||||
@@ -59,29 +69,27 @@ Now build your project using your ide or the `dotnet build` command. You should
|
||||
|
||||
### Installing your Plugin
|
||||
|
||||
Locate the `plugins` folder in your CS2 dedicated server (`/game/csgo/addons/counterstrikesharp/plugins`) and create a new folder with the exact same name as your output .dll file. In this example it would be `HelloWorldPlugin.dll`, so I will make a new folder called `HelloWorldPlugin`. Inside of this folder, copy and paste all of the `.dll` files _except_ the `CounterStrikeSharp.API.dll` file. Once completed, the folder should look as follows:
|
||||
Locate the `plugins` folder in your CS2 dedicated server (`/game/csgo/addons/counterstrikesharp/plugins`) and create a new folder with the exact same name as your output .dll file. In this example it would be `HelloWorldPlugin.dll`, so I will make a new folder called `HelloWorldPlugin`. Inside of this folder, copy and paste the: `HelloWorldPlugin.deps.json`, `HelloWorldPlugin.dll`, and `HelloWorldPlugin.pdb` files. Once completed, the folder should look as follows:
|
||||
|
||||
```shell
|
||||
.
|
||||
└── SamplePlugin
|
||||
├── McMaster.NETCore.Plugins.dll
|
||||
├── Microsoft.DotNet.PlatformAbstractions.dll
|
||||
├── Microsoft.Extensions.DependencyModel.dll
|
||||
├── SamplePlugin.deps.json
|
||||
├── SamplePlugin.dll
|
||||
└── SamplePlugin.pdb
|
||||
└── HelloWorldPlugin
|
||||
├── HelloWorldPlugin.deps.json
|
||||
├── HelloWorldPlugin.dll
|
||||
└── HelloWorldPlugin.pdb
|
||||
```
|
||||
|
||||
:::note
|
||||
Note that some of these dependencies may change depending on the version of CounterStrikeSharp being used.
|
||||
:::
|
||||
> [!CAUTION]
|
||||
> If you have installed external nuget packages for your plugin, you may need to include their respective `.dll`s. For example, if you utilize the `Stateless` C# library, include `stateless.dll` in your `HelloWorld` plugin directory.
|
||||
|
||||
> [!NOTE]
|
||||
> Note that some of these dependencies may change depending on the version of CounterStrikeSharp being used.
|
||||
|
||||
### Start the Server
|
||||
|
||||
Now start your CS2 dedicated server. Just before the `CounterStrikeSharp.API Loaded Successfully.` message you should see your `Hello World!` console write that we called from the load function, neat!
|
||||
|
||||
:::note[Hot Reloading!]
|
||||
By default, CounterStrikeSharp will automatically hot reload your plugin if you replace the .dll file in your plugin folder. When it does so, it will call the `Unload` and `Load` functions respectively, with the `hotReload` flag set to true.
|
||||
|
||||
It is worth noting that the framework will automatically deregister any event handlers or listeners for you automatically, so you can safely reregister these on load without checking this flag. However you may want to do some specific actions on a hot reload, which you can do in your `Load()` call by checking the flag!
|
||||
:::
|
||||
> [!NOTE]
|
||||
> By default, CounterStrikeSharp will automatically hot reload your plugin if you replace the .dll file in your plugin folder. When it does so, it will call the `Unload` and `Load` functions respectively, with the `hotReload` flag set to true.
|
||||
>
|
||||
> It is worth noting that the framework will automatically deregister any event handlers or listeners for you automatically, so you can safely reregister these on load without checking this flag. However you may want to do some specific actions on a hot reload, which you can do in your `Load()` call by checking the flag!
|
||||
8
docfx/docs/guides/toc.yml
Normal file
8
docfx/docs/guides/toc.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
- name: Getting Started
|
||||
href: getting-started.md
|
||||
|
||||
- name: Hello World Plugin
|
||||
href: hello-world-plugin.md
|
||||
|
||||
- name: Dependency Injection
|
||||
href: dependency-injection.md
|
||||
38
docfx/docs/reference/core-configuration.md
Normal file
38
docfx/docs/reference/core-configuration.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: Core Configuration
|
||||
description: Summary for core configuration values
|
||||
---
|
||||
|
||||
# Core Configuration
|
||||
|
||||
Summary for core configuration values
|
||||
|
||||
## PublicChatTrigger
|
||||
|
||||
List of characters to use for public chat triggers.
|
||||
|
||||
## SilentChatTrigger
|
||||
|
||||
List of characters to use for silent chat triggers.
|
||||
|
||||
## FollowCS2ServerGuidelines
|
||||
|
||||
Per [CS2 Server Guidelines](https://blog.counter-strike.net/index.php/server_guidelines/), certain plugin
|
||||
functionality will trigger all of the game server owner's Game Server Login Tokens
|
||||
(GSLTs) to get banned when executed on a Counter-Strike 2 game server.
|
||||
|
||||
Enabling this option will block plugins from using functionality that is known to cause this.
|
||||
This option only has any effect on CS2. Note that this does NOT guarantee that you cannot
|
||||
receive a ban.
|
||||
|
||||
> [!NOTE]
|
||||
> Disable this option at your own risk.
|
||||
|
||||
|
||||
## PluginHotReloadEnabled
|
||||
|
||||
When enabled, plugins are automatically reloaded when their .dll file is updated.
|
||||
|
||||
## ServerLanguage
|
||||
|
||||
Configures the default language to use for server commands & messages. The format for the culture name based on RFC 4646 is `languagecode2-country`/`regioncode2`, where `languagecode2` is the two-letter language code and `country/regioncode2` is the two-letter subculture code. Examples include `ja-JP` for Japanese (Japan) and `en-US` for English (United States). Defaults to "en".
|
||||
@@ -3,6 +3,10 @@ title: Referencing Players
|
||||
description: Difference between player slots, indexes, userids, controllers & pawns.
|
||||
---
|
||||
|
||||
# Referencing Players
|
||||
|
||||
Difference between player slots, indexes, userids, controllers & pawns.
|
||||
|
||||
## Controllers & Pawns
|
||||
|
||||
All players in CS2 are split between a player controller & a player pawn. The player controller represents the player on the server, and the player pawn represents the players physical character in the game world. This means to edit a players health for example, you would need to edit their `PlayerPawn`'s health; but to check for a player's SteamID, you would check the `PlayerController`.
|
||||
@@ -44,13 +48,12 @@ var player = Utilities.GetPlayerFromIndex(index);
|
||||
var player = Utilities.GetPlayerFromSlot(slot);
|
||||
```
|
||||
|
||||
:::note[Entity Safety]
|
||||
Wherever possible, you should check the validity of any handle you are accessing before assuming it is safe to use.
|
||||
```csharp
|
||||
RegisterEventHandler<EventPlayerSpawn>((@event, info) =>
|
||||
{
|
||||
if (!@event.Userid.IsValid) return 0; // Checks that the PlayerController is valid
|
||||
if (!@event.Userid.PlayerPawn.IsValid) return 0; // Checks that the value of the CHandle is pointing to a valid PlayerPawn.
|
||||
}
|
||||
```
|
||||
:::
|
||||
> [!NOTE]
|
||||
> Wherever possible, you should check the validity of any handle you are accessing before assuming it is safe to use.
|
||||
> ```csharp
|
||||
> RegisterEventHandler<EventPlayerSpawn>((@event, info) =>
|
||||
> {
|
||||
> if (!@event.Userid.IsValid) return 0; // Checks that the PlayerController is valid
|
||||
> if (!@event.Userid.PlayerPawn.IsValid) return 0; // Checks that the value of the CHandle is pointing to a valid PlayerPawn.
|
||||
> }
|
||||
> ```
|
||||
5
docfx/docs/reference/toc.yml
Normal file
5
docfx/docs/reference/toc.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
- name: Core Configuration
|
||||
href: core-configuration.md
|
||||
|
||||
- name: Referencing Players
|
||||
href: referencing-players.md
|
||||
16
docfx/docs/toc.yml
Normal file
16
docfx/docs/toc.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
items:
|
||||
- name: Guides
|
||||
href: guides/toc.yml
|
||||
expanded: true
|
||||
|
||||
- name: Features
|
||||
href: features/toc.yml
|
||||
expanded: true
|
||||
|
||||
- name: Admin Framework
|
||||
href: admin-framework/toc.yml
|
||||
expanded: true
|
||||
|
||||
- name: Reference
|
||||
href: reference/toc.yml
|
||||
expanded: true
|
||||
5
docfx/examples/HelloWorld.md
Normal file
5
docfx/examples/HelloWorld.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [HelloWorld](../../examples/HelloWorld/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/HelloWorld" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/HelloWorld/HelloWorldPlugin.cs)]
|
||||
13
docfx/examples/WarcraftPlugin.md
Normal file
13
docfx/examples/WarcraftPlugin.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Warcraft Plugin
|
||||
|
||||
This Warcraft plugin is migrated from the previous VSP.NET project to give you an idea of the kind of power this scripting runtime is capable of.
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WarcraftPlugin" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
## Demonstrated
|
||||
- Hook events
|
||||
- Create commands
|
||||
- Use third party libraries
|
||||
- SQLite
|
||||
- Entity manipulation
|
||||
|
||||
5
docfx/examples/WithCommands.md
Normal file
5
docfx/examples/WithCommands.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithCommands](../../examples/WithCommands/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithCommands" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithCommands/WithCommandsPlugin.cs)]
|
||||
5
docfx/examples/WithConfig.md
Normal file
5
docfx/examples/WithConfig.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithConfig](../../examples/WithConfig/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithConfig" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithConfig/WithConfigPlugin.cs)]
|
||||
5
docfx/examples/WithDatabase.md
Normal file
5
docfx/examples/WithDatabase.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [Database](../../examples/WithDatabaseDapper/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithDatabaseDapper" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithDatabaseDapper/WithDatabaseDapperPlugin.cs)]
|
||||
5
docfx/examples/WithDependencyInjection.md
Normal file
5
docfx/examples/WithDependencyInjection.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithDependencyInjection](../../examples/WithDependencyInjection/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithDependencyInjection" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithDependencyInjection/WithDependencyInjectionPlugin.cs)]
|
||||
5
docfx/examples/WithEntityOutputHooks.md
Normal file
5
docfx/examples/WithEntityOutputHooks.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithEntityOutputHooks](../../examples/WithEntityOutputHooks/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithEntityOutputHooks" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithEntityOutputHooks/WithEntityOutputHooksPlugin.cs)]
|
||||
5
docfx/examples/WithGameEventHandlers.md
Normal file
5
docfx/examples/WithGameEventHandlers.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithGameEventHandlers](../../examples/WithGameEventHandlers/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithGameEventHandlers" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithGameEventHandlers/WithGameEventHandlersPlugin.cs)]
|
||||
5
docfx/examples/WithTranslations.md
Normal file
5
docfx/examples/WithTranslations.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithTranslations](../../examples/WithTranslations/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithTranslations" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithTranslations/WithTranslationsPlugin.cs)]
|
||||
5
docfx/examples/WithVoiceOverrides.md
Normal file
5
docfx/examples/WithVoiceOverrides.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithVoiceOverrides](../../examples/WithVoiceOverrides/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithVoiceOverrides" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithVoiceOverrides/WithVoiceOverridesPlugin.cs)]
|
||||
21
docfx/examples/toc.yml
Normal file
21
docfx/examples/toc.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
items:
|
||||
- name: Hello World
|
||||
href: HelloWorld.md
|
||||
- name: Commands
|
||||
href: WithCommands.md
|
||||
- name: Config
|
||||
href: WithConfig.md
|
||||
- name: Dependency Injection
|
||||
href: WithDependencyInjection.md
|
||||
- name: Entity Output Hooks
|
||||
href: WithEntityOutputHooks.md
|
||||
- name: Game Event Handlers
|
||||
href: WithGameEventHandlers.md
|
||||
- name: Database (Dapper)
|
||||
href: WithDatabase.md
|
||||
- name: Translations
|
||||
href: WithTranslations.md
|
||||
- name: Voice Overrides
|
||||
href: WithVoiceOverrides.md
|
||||
- name: Warcraft Plugin
|
||||
href: WarcraftPlugin.md
|
||||
4
docfx/filterConfig.yml
Normal file
4
docfx/filterConfig.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
apiRules:
|
||||
- exclude:
|
||||
uidRegex: ^System\.Object
|
||||
type: Type
|
||||
1
docfx/images/cssharp.svg
Normal file
1
docfx/images/cssharp.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" fill="none"><path fill="#F89A0F" d="m37.456 1.262-19.008.148a91.03 91.03 0 0 0-5.96.215A26.294 26.294 0 0 0 1.523 4.793C.643 5.26 0 6.07 0 7.06a2.464 2.464 0 0 0 3.704 2.128l.015-.007a20.538 20.538 0 0 1 7.93-2.495c8.024-.858 13.602 2.018 17.367 5.397 4.138 3.712 7.967 11.271 6.576 19.56-.831 4.962-3.122 9.146-6.69 12.397l-.007.007c-.646.59-1.18 1.274-1.18 2.147a2.547 2.547 0 0 0 4.158 1.965c.102-.075.22-.185.276-.238a27.692 27.692 0 0 0 6.652-9.698l10.126-24.027c.476-1.085.877-2.203 1.001-3.292.537-4.762-2.007-7.502-5.227-8.769-1.648-.65-3.968-.846-6.5-.869l-.745-.004Zm2.74 3.032c1.799.075 3.553 1.372 3.326 3.741-.276 2.865-3.137 4.865-4.384 6.747h4.384c.264.385.264 1.637 0 2.022-2.204-.215-4.66-.178-7.083-.17-1.036-3.783 5.367-6.327 4.72-9.441-.306-1.47-2.403-1.512-2.025.676h-2.529c-.045-2.506 1.796-3.651 3.59-3.575Z"/><path fill="#A079DF" d="M28.422 21.551a2.807 2.807 0 0 0-.34-1.413 2.7 2.7 0 0 0-1.028-.998c-3.772-2.174-7.54-4.34-11.304-6.516a2.774 2.774 0 0 0-3.01.03c-1.5.888-9.01 5.186-11.247 6.486A2.616 2.616 0 0 0 .12 21.55V34.66c0 .525.113.982.333 1.387a2.6 2.6 0 0 0 1.039 1.02c2.237 1.3 9.748 5.602 11.248 6.49a2.778 2.778 0 0 0 3.008.026c3.765-2.173 7.54-4.339 11.309-6.512.434-.24.794-.594 1.04-1.024.226-.427.339-.904.328-1.387l-.004-13.108Z"/><path fill="#270068" d="M14.317 28.06.454 36.05a2.6 2.6 0 0 0 1.039 1.02c2.237 1.3 9.748 5.601 11.248 6.49a2.778 2.778 0 0 0 3.008.026c3.765-2.173 7.54-4.339 11.309-6.512.434-.24.794-.594 1.04-1.024l-13.781-7.99Z"/><path fill="#390091" d="M28.422 21.551a2.807 2.807 0 0 0-.34-1.413l-13.769 7.925 13.78 7.983c.227-.427.34-.904.33-1.387V21.55Z"/><path fill="#fff" d="M22.48 25.078v1.492h1.494v-1.492h.744v1.492h1.493v.745h-1.493v1.493h1.493v.748h-1.493v1.49h-.744v-1.49H22.48v1.49h-.748v-1.49H20.24v-.748h1.493v-1.493H20.24v-.745h1.493v-1.492h.748Zm1.494 2.237H22.48v1.493h1.493v-1.493Z"/><path fill="#fff" d="M14.347 17.583c3.893 0 7.295 2.116 9.109 5.253l-.015-.026-4.58 2.638a5.236 5.236 0 0 0-4.453-2.582h-.06a5.238 5.238 0 1 0 4.565 7.809l-.023.038 4.574 2.645a10.519 10.519 0 0 1-8.996 5.27h-.12a10.522 10.522 0 1 1 0-21.045Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
BIN
docfx/images/gameinfogi-example.png
Normal file
BIN
docfx/images/gameinfogi-example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 275 KiB |
24
docfx/index.md
Normal file
24
docfx/index.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
_layout: landing
|
||||
uid: home
|
||||
title: CounterStrikeSharp
|
||||
_appTitle: ''
|
||||
description: Write Counter-Strike 2 server plugins in C#.
|
||||
---
|
||||
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col-12 col-lg-10 col-xl-8 col-xxl-6">
|
||||
<div class="text-center">
|
||||
<img src="images/cssharp.svg" height="128" width="128">
|
||||
<h1 class="h1">CounterStrikeSharp</h1>
|
||||
<span>CounterStrikeSharp is a simpler way to write CS2 server plugins.</span>
|
||||
<div>
|
||||
<a href="docs/guides/getting-started.md" class="btn btn-primary btn-lg fw-bold my-5">Get Started <i class="bi bi-arrow-right"></a>
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/releases/latest" class="btn btn-secondary btn-lg fw-bold my-5">Download <i class="bi bi-download"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
[!code-csharp[](../examples/HelloWorld/HelloWorldPlugin.cs)]
|
||||
|
||||
</div>
|
||||
</div>
|
||||
152
docfx/layouts/cssharp/layout/_master.tmpl
Normal file
152
docfx/layouts/cssharp/layout/_master.tmpl
Normal file
@@ -0,0 +1,152 @@
|
||||
{{!Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license.}}
|
||||
{{!include(/^public/.*/)}}
|
||||
{{!include(favicon.ico)}}
|
||||
{{!include(logo.svg)}}
|
||||
<!DOCTYPE html>
|
||||
<html {{#_lang}}lang="{{_lang}}"{{/_lang}}>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{{#redirect_url}}
|
||||
<meta http-equiv="refresh" content="0;URL='{{redirect_url}}'">
|
||||
{{/redirect_url}}
|
||||
{{^redirect_url}}
|
||||
<title>{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}">
|
||||
{{#_description}}<meta name="description" content="{{_description}}">{{/_description}}
|
||||
<link rel="icon" href="{{_rel}}{{{_appFaviconPath}}}{{^_appFaviconPath}}favicon.ico{{/_appFaviconPath}}">
|
||||
<link rel="stylesheet" href="{{_rel}}public/docfx.min.css">
|
||||
<link rel="stylesheet" href="{{_rel}}public/main.css">
|
||||
<meta name="docfx:navrel" content="{{_navRel}}">
|
||||
<meta name="docfx:tocrel" content="{{_tocRel}}">
|
||||
{{#_noindex}}<meta name="searchOption" content="noindex">{{/_noindex}}
|
||||
{{#_enableSearch}}<meta name="docfx:rel" content="{{_rel}}">{{/_enableSearch}}
|
||||
{{#_disableNewTab}}<meta name="docfx:disablenewtab" content="true">{{/_disableNewTab}}
|
||||
{{#_disableTocFilter}}<meta name="docfx:disabletocfilter" content="true">{{/_disableTocFilter}}
|
||||
{{#docurl}}<meta name="docfx:docurl" content="{{docurl}}">{{/docurl}}
|
||||
<meta name="loc:inThisArticle" content="{{__global.inThisArticle}}">
|
||||
<meta name="loc:searchResultsCount" content="{{__global.searchResultsCount}}">
|
||||
<meta name="loc:searchNoResults" content="{{__global.searchNoResults}}">
|
||||
<meta name="loc:tocFilter" content="{{__global.tocFilter}}">
|
||||
<meta name="loc:nextArticle" content="{{__global.nextArticle}}">
|
||||
<meta name="loc:prevArticle" content="{{__global.prevArticle}}">
|
||||
<meta name="loc:themeLight" content="{{__global.themeLight}}">
|
||||
<meta name="loc:themeDark" content="{{__global.themeDark}}">
|
||||
<meta name="loc:themeAuto" content="{{__global.themeAuto}}">
|
||||
<meta name="loc:changeTheme" content="{{__global.changeTheme}}">
|
||||
<meta name="loc:copy" content="{{__global.copy}}">
|
||||
<meta name="loc:downloadPdf" content="{{__global.downloadPdf}}">
|
||||
{{/redirect_url}}
|
||||
<script data-goatcounter="https://cssharp.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100;0,9..40,200;0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;0,9..40,800;0,9..40,900;0,9..40,1000;1,9..40,100;1,9..40,200;1,9..40,300;1,9..40,400;1,9..40,500;1,9..40,600;1,9..40,700;1,9..40,800;1,9..40,900;1,9..40,1000&family=JetBrains+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
{{^redirect_url}}
|
||||
<script type="module" src="./{{_rel}}public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
{{#_googleAnalyticsTagId}}
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id={{_googleAnalyticsTagId}}"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() { dataLayer.push(arguments); }
|
||||
gtag('js', new Date());
|
||||
gtag('config', '{{_googleAnalyticsTagId}}');
|
||||
</script>
|
||||
{{/_googleAnalyticsTagId}}
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="{{_layout}}{{layout}}" data-yaml-mime="{{yamlmime}}">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="{{_appLogoUrl}}{{^_appLogoUrl}}{{_rel}}index.html{{/_appLogoUrl}}">
|
||||
<img id="logo" class="svg" src="{{_rel}}{{{_appLogoPath}}}{{^_appLogoPath}}logo.svg{{/_appLogoPath}}" alt="{{_appName}}" >
|
||||
{{_appName}}
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
{{#_enableSearch}}
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="{{__global.search}}" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
{{/_enableSearch}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" style="margin-top: -.65em; margin-left: -.8em"
|
||||
type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas"
|
||||
aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="{{uid}}">
|
||||
{{!body}}
|
||||
</article>
|
||||
|
||||
{{^_disableContribution}}
|
||||
<div class="contribution d-print-none">
|
||||
{{#sourceurl}}
|
||||
<a href="{{sourceurl}}" class="edit-link">{{__global.improveThisDoc}}</a>
|
||||
{{/sourceurl}}
|
||||
{{^sourceurl}}{{#docurl}}
|
||||
<a href="{{docurl}}" class="edit-link">{{__global.improveThisDoc}}</a>
|
||||
{{/docurl}}{{/sourceurl}}
|
||||
</div>
|
||||
{{/_disableContribution}}
|
||||
|
||||
{{^_disableNextArticle}}
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
{{/_disableNextArticle}}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{#_enableSearch}}
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
{{/_enableSearch}}
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
{{{_appFooter}}}{{^_appFooter}}<span>Made with <a href="https://dotnet.github.io/docfx">docfx</a></span>{{/_appFooter}}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
{{/redirect_url}}
|
||||
</html>
|
||||
4
docfx/layouts/cssharp/public/main.css
Normal file
4
docfx/layouts/cssharp/public/main.css
Normal file
@@ -0,0 +1,4 @@
|
||||
:root {
|
||||
--bs-font-sans-serif: "DM Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: "Jetbrains Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
14
docfx/layouts/cssharp/public/main.js
Normal file
14
docfx/layouts/cssharp/public/main.js
Normal file
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
iconLinks: [
|
||||
{
|
||||
icon: "github",
|
||||
href: "https://github.com/roflmuffin/CounterStrikeSharp",
|
||||
title: "GitHub",
|
||||
},
|
||||
{
|
||||
icon: "discord",
|
||||
href: "https://discord.gg/eAZU3guKWU",
|
||||
title: "Discord",
|
||||
},
|
||||
],
|
||||
};
|
||||
6
docfx/toc.yml
Normal file
6
docfx/toc.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- name: Docs
|
||||
href: docs/
|
||||
- name: Examples
|
||||
href: examples/
|
||||
- name: API
|
||||
href: api/
|
||||
21
docs/.gitignore
vendored
21
docs/.gitignore
vendored
@@ -1,21 +0,0 @@
|
||||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": true
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
import starlight from '@astrojs/starlight';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
starlight({
|
||||
title: 'CounterStrikeSharp Docs',
|
||||
customCss: [
|
||||
'@fontsource/dm-sans/400.css',
|
||||
'@fontsource/dm-sans/500.css',
|
||||
'@fontsource/dm-sans/700.css',
|
||||
'@fontsource/jetbrains-mono/400.css',
|
||||
'@fontsource/jetbrains-mono/600.css',
|
||||
'./src/styles/custom.css',
|
||||
],
|
||||
head: [
|
||||
{
|
||||
tag: 'script',
|
||||
attrs: {
|
||||
src: 'https://gc.zgo.at/count.js',
|
||||
'data-goatcounter': 'https://cssharp.goatcounter.com/count',
|
||||
async: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
social: {
|
||||
github: 'https://github.com/roflmuffin/CounterStrikeSharp',
|
||||
},
|
||||
sidebar: [
|
||||
{
|
||||
label: 'Guides',
|
||||
autogenerate: { directory: 'guides' },
|
||||
},
|
||||
{
|
||||
label: 'Features',
|
||||
autogenerate: { directory: 'features' },
|
||||
},
|
||||
{
|
||||
label: 'Reference',
|
||||
autogenerate: { directory: 'reference' },
|
||||
},
|
||||
],
|
||||
editLink: {
|
||||
baseUrl:
|
||||
'https://github.com/roflmuffin/CounterStrikeSharp/edit/main/docs/',
|
||||
},
|
||||
}),
|
||||
],
|
||||
base: '/',
|
||||
site: 'https://docs.cssharp.dev',
|
||||
markdown: {
|
||||
shikiConfig: {
|
||||
wrap: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/starlight": "^0.11.1",
|
||||
"@fontsource/dm-sans": "^5.0.15",
|
||||
"@fontsource/jetbrains-mono": "^5.0.15",
|
||||
"astro": "^3.2.3",
|
||||
"sharp": "^0.32.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.0.3"
|
||||
}
|
||||
}
|
||||
4118
docs/pnpm-lock.yaml
generated
4118
docs/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
import { defineCollection } from 'astro:content';
|
||||
import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';
|
||||
|
||||
export const collections = {
|
||||
docs: defineCollection({ schema: docsSchema() }),
|
||||
i18n: defineCollection({ type: 'data', schema: i18nSchema() }),
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
title: Admin Framework
|
||||
description: A guide on using the Admin Framework in plugins.
|
||||
---
|
||||
|
||||
## Admin Framework
|
||||
|
||||
CounterStrikeSharp has a basic framework which allows plugin developers to assign permissions to commands. When CSS is initialized, a list of admins are loaded from `configs/admins.json`.
|
||||
|
||||
## Adding Admins
|
||||
|
||||
Adding an Admin is as simple as creating a new entry in the `configs/admins.json` file. The important things you need to declare are the SteamID identifier and the permissions they have. CounterStrikeSharp will do all the heavy-lifting to decipher your SteamID. If you're familar with SourceMod, permission definitions are slightly different as they're defined by an array of strings instead of a string of characters.
|
||||
|
||||
```json
|
||||
{
|
||||
"ZoNiCaL": {
|
||||
"identity": "76561198808392634",
|
||||
"flags": ["can_manipulate_players", "admin_messages"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also manually assign permissions to players in code with `AddPlayerPermissions` and `RemovePlayerPermissions`. These changes are not saved to `configs/admins.json`.
|
||||
|
||||
## Assigning permissions to a Command
|
||||
|
||||
Assigning permissions to a Command is as easy as tagging the Command method (function callback) with a `RequiresPermissions` attribute.
|
||||
|
||||
```csharp
|
||||
[RequiresPermissions("can_execute_test_command", "other_permission")]
|
||||
public void OnMyCommand(CCSPlayerController? caller, CommandInfo info)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
CounterStrikeSharp handles all of the permission checks behind the scenes for you.
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
title: Getting Started
|
||||
description: How to get started installing & using CounterStrikeSharp.
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
### Installing Metamod
|
||||
|
||||
`CounterStrikeSharp` uses `Metamod:Source` as its main way of communicating with the game server. To install it, you can follow the detailed instructions found <a href="https://cs2.poggu.me/metamod/installation/" target="_blank">here</a>.
|
||||
|
||||
### Installing CounterStrikeSharp
|
||||
|
||||
Download the latest release of CounterStrikeSharp from <a href="https://github.com/roflmuffin/CounterStrikeSharp/actions/workflows/cmake-single-platform.yml" target="_blank">GitHub actions build pages</a> (just choose the latest development snapshot). **You may need to be logged into GitHub to gain access to the downloads**.
|
||||
|
||||
:::caution[.NET Runtime]
|
||||
If this is your first time installing, you will need to download the `with-runtime` version. This includes a copy of the .NET runtime, which is required to run the plugin.
|
||||
Depending on the os you might also either need to install `libicu` / `icu-libs` / `libicu-dev` using your package manager for .NET to run or setting `DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true` in your servers environment variables. You can find more infos about that <a href="https://github.com/dotnet/runtime/blob/main/docs/design/features/globalization-invariant-mode.md#enabling-the-invariant-mode" target="_blank">here</a>
|
||||
|
||||
Subsequent upgrades will not require the runtime, unless a version bump of the .NET runtime is required (i.e. from 7.0.x to 8.0.x). We will inform you when this occurs.
|
||||
:::
|
||||
|
||||
Extract the `addons` folder to the `/csgo/` directory of the dedicated server. The contents of your addons folder should contain both the `counterstrikesharp` folder and the `metamod` folder as seen below.
|
||||
|
||||
```shell
|
||||
<server_path>/game/csgo/addons > tree -L 2
|
||||
addons
|
||||
├── counterstrikesharp
|
||||
│ ├── api
|
||||
│ ├── bin
|
||||
│ ├── dotnet
|
||||
│ ├── plugins
|
||||
│ └── gamedata
|
||||
│
|
||||
├── metamod
|
||||
│ ├── bin
|
||||
│ ├── counterstrikesharp.vdf
|
||||
│ ├── metaplugins.ini
|
||||
│ └── README.txt
|
||||
├── metamod.vdf
|
||||
└── metamod_x64.vdf
|
||||
```
|
||||
|
||||
### Start the Server
|
||||
|
||||
Launch your CS2 dedicated server as normal. If everything is working correctly, you should see a message in the console that says `CSSharp: CounterStrikeSharp.API Loaded Successfully.`.
|
||||
|
||||
Running the command `meta list` in the console should show 1 plugin loaded 🎉
|
||||
|
||||
```shell
|
||||
meta list
|
||||
Listing 1 plugin:
|
||||
[01] CounterStrikeSharp (0.1.0) by Roflmuffin
|
||||
```
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: CounterStrikeSharp
|
||||
description: Write Counter-Strike 2 server plugins in C#.
|
||||
template: splash
|
||||
hero:
|
||||
tagline: <code class="csharp">CounterStrikeSharp</code> is a simpler way to write CS2 server plugins.
|
||||
actions:
|
||||
- text: Get started
|
||||
link: ./guides/getting-started/
|
||||
icon: right-arrow
|
||||
variant: primary
|
||||
- text: Browse source
|
||||
link: https://github.com/roflmuffin/CounterStrikeSharp/
|
||||
icon: github
|
||||
---
|
||||
|
||||
```csharp
|
||||
using CounterStrikeSharp.API.Core;
|
||||
|
||||
namespace HelloWorldPlugin;
|
||||
|
||||
public class HelloWorldPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Hello World Plugin";
|
||||
|
||||
public override string ModuleVersion => "0.0.1";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Console.WriteLine("Hello World!");
|
||||
}
|
||||
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerConnect(EventPlayerConnect @event, GameEventInfo info)
|
||||
{
|
||||
// Userid will give you a reference to a CCSPlayerController class
|
||||
Log($"Player {@event.Userid.PlayerName} has connected!");
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
[ConsoleCommand("issue_warning", "Issue warning to player")]
|
||||
public void OnCommand(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
Log("You shouldn't be doing that!");
|
||||
}
|
||||
}
|
||||
```
|
||||
2
docs/src/env.d.ts
vendored
2
docs/src/env.d.ts
vendored
@@ -1,2 +0,0 @@
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
/// <reference types="astro/client" />
|
||||
@@ -1,19 +0,0 @@
|
||||
:root {
|
||||
--sl-font: 'DM Sans', serif;
|
||||
--sl-font-mono: 'Jetbrains Mono', monospace;
|
||||
}
|
||||
|
||||
.hero {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.hero .copy {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hero .actions {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hero {
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict"
|
||||
}
|
||||
12
examples/HelloWorld/HelloWorld.csproj
Normal file
12
examples/HelloWorld/HelloWorld.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
24
examples/HelloWorld/HelloWorldPlugin.cs
Normal file
24
examples/HelloWorld/HelloWorldPlugin.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace HelloWorld;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class HelloWorldPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: Hello World";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that says hello world!";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Hello World! We are loading!");
|
||||
}
|
||||
|
||||
public override void Unload(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Hello World! We are unloading!");
|
||||
}
|
||||
}
|
||||
2
examples/HelloWorld/README.md
Normal file
2
examples/HelloWorld/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Hello World
|
||||
This is a minimal "Hello World" example that executes code on load & unload.
|
||||
@@ -73,7 +73,7 @@ namespace WarcraftPlugin
|
||||
var victim = @event.Userid;
|
||||
var headshot = @event.Headshot;
|
||||
|
||||
if (attacker.IsValid && victim.IsValid && (attacker.EntityIndex.Value.Value != victim.EntityIndex.Value.Value) && !attacker.IsBot)
|
||||
if (attacker.IsValid && victim.IsValid && (attacker != victim) && !attacker.IsBot)
|
||||
{
|
||||
var weaponName = attacker.PlayerPawn.Value.WeaponServices.ActiveWeapon.Value.DesignerName;
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
|
||||
4
examples/WithCommands/README.md
Normal file
4
examples/WithCommands/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# With Commands
|
||||
This is an example that shows how to register chat & console commands.
|
||||
|
||||
All commands that are prefixed with "css_" will automatically be registered as a chat command without the prefix. i.e. `css_ping` can be called with `!ping` or `/ping`.
|
||||
12
examples/WithCommands/WithCommands.csproj
Normal file
12
examples/WithCommands/WithCommands.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
63
examples/WithCommands/WithCommandsPlugin.cs
Normal file
63
examples/WithCommands/WithCommandsPlugin.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
|
||||
namespace WithCommands;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithCommandsPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Commands";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that registers some commands";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
// All commands that are prefixed with "css_" will automatically be registered as a chat command without the prefix.
|
||||
// i.e. `css_ping` can be called with `!ping` or `/ping`.
|
||||
// Commands can be registered using the instance `AddCommand` method.
|
||||
AddCommand("css_ping", "Responds to the caller with \"pong\"", (player, commandInfo) =>
|
||||
{
|
||||
// The player is null, then the command has been called by the server console.
|
||||
if (player == null)
|
||||
{
|
||||
commandInfo.ReplyToCommand("pong server");
|
||||
return;
|
||||
}
|
||||
|
||||
commandInfo.ReplyToCommand("pong");
|
||||
});
|
||||
}
|
||||
|
||||
// Commands can also be registered using the `Command` attribute.
|
||||
[ConsoleCommand("css_hello", "Responds to the caller with \"pong\"")]
|
||||
// The `CommandHelper` attribute can be used to provide additional information about the command.
|
||||
[CommandHelper(minArgs: 1, usage: "[name]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
[RequiresPermissions("@css/cvar")]
|
||||
public void OnHelloCommand(CCSPlayerController? player, CommandInfo commandInfo)
|
||||
{
|
||||
// The first argument is the command name, in this case "css_hello".
|
||||
commandInfo.GetArg(0); // css_hello
|
||||
|
||||
// The second argument is the first argument passed to the command, in this case "name".
|
||||
// The `minArgs` helper parameter is used to ensure that the second argument is present.
|
||||
var name = commandInfo.GetArg(1);
|
||||
|
||||
commandInfo.ReplyToCommand($"Hello {name}");
|
||||
}
|
||||
|
||||
// Permissions can be added to commands using the `RequiresPermissions` attribute.
|
||||
// See the admin documentation for more information on permissions.
|
||||
[RequiresPermissions("@css/kick")]
|
||||
[CommandHelper(minArgs: 1, usage: "[id]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnSpecialCommand(CCSPlayerController? player, CommandInfo commandInfo)
|
||||
{
|
||||
var id = commandInfo.GetArg(1);
|
||||
|
||||
Server.ExecuteCommand($"kick {id}");
|
||||
}
|
||||
}
|
||||
2
examples/WithConfig/README.md
Normal file
2
examples/WithConfig/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Config
|
||||
This example shows how you can implement the `IPluginConfig` interface to allow for semi-automatic config parsing & loading.
|
||||
12
examples/WithConfig/WithConfig.csproj
Normal file
12
examples/WithConfig/WithConfig.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
38
examples/WithConfig/WithConfigPlugin.cs
Normal file
38
examples/WithConfig/WithConfigPlugin.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
|
||||
namespace WithConfig;
|
||||
|
||||
public class SampleConfig : BasePluginConfig
|
||||
{
|
||||
[JsonPropertyName("ChatPrefix")] public string ChatPrefix { get; set; } = "My Cool Plugin";
|
||||
|
||||
[JsonPropertyName("ChatInterval")] public float ChatInterval { get; set; } = 60;
|
||||
}
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithConfigPlugin : BasePlugin, IPluginConfig<SampleConfig>
|
||||
{
|
||||
public override string ModuleName => "Example: With Config";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
|
||||
public SampleConfig Config { get; set; }
|
||||
|
||||
public void OnConfigParsed(SampleConfig config)
|
||||
{
|
||||
// Do manual verification of the config and override any invalid values
|
||||
if (config.ChatInterval > 60)
|
||||
{
|
||||
config.ChatInterval = 60;
|
||||
}
|
||||
|
||||
if (config.ChatPrefix.Length > 25)
|
||||
{
|
||||
throw new Exception($"Invalid value has been set to config value 'ChatPrefix': {config.ChatPrefix}");
|
||||
}
|
||||
|
||||
// Once we've validated the config, we can set it to the instance
|
||||
Config = config;
|
||||
}
|
||||
}
|
||||
2
examples/WithDatabaseDapper/README.md
Normal file
2
examples/WithDatabaseDapper/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Database (Dapper)
|
||||
Simple SQLite database example using Dapper library to track kills.
|
||||
16
examples/WithDatabaseDapper/WithDatabaseDapper.csproj
Normal file
16
examples/WithDatabaseDapper/WithDatabaseDapper.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dapper" Version="2.1.24" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.14" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
89
examples/WithDatabaseDapper/WithDatabaseDapperPlugin.cs
Normal file
89
examples/WithDatabaseDapper/WithDatabaseDapperPlugin.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using Dapper;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithDatabaseDapper;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithDatabaseDapperPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Database (Dapper)";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A plugin that reads and writes from the database.";
|
||||
|
||||
private SqliteConnection _connection = null!;
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Loading database from {Path}", Path.Join(ModuleDirectory, "database.db"));
|
||||
_connection = new SqliteConnection($"Data Source={Path.Join(ModuleDirectory, "database.db")}");
|
||||
_connection.Open();
|
||||
|
||||
// Create the table if it doesn't exist
|
||||
// Run in a separate thread to avoid blocking the main thread
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await _connection.ExecuteAsync(@"
|
||||
CREATE TABLE IF NOT EXISTS `players` (
|
||||
`steamid` UNSIGNED BIG INT NOT NULL,
|
||||
`kills` INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`steamid`));");
|
||||
});
|
||||
}
|
||||
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerKilled(EventPlayerDeath @event, GameEventInfo info)
|
||||
{
|
||||
// Don't count suicides.
|
||||
if (@event.Attacker == @event.Userid) return HookResult.Continue;
|
||||
|
||||
// Capture the steamid of the player as `@event` will not be available outside of this function.
|
||||
var steamId = @event.Attacker.AuthorizedSteamID?.SteamId64;
|
||||
|
||||
if (steamId == null) return HookResult.Continue;
|
||||
|
||||
// Run in a separate thread to avoid blocking the main thread
|
||||
Task.Run(async () =>
|
||||
{
|
||||
// insert or update the player's kills
|
||||
await _connection.ExecuteAsync(@"
|
||||
INSERT INTO `players` (`steamid`, `kills`) VALUES (@SteamId, 1)
|
||||
ON CONFLICT(`steamid`) DO UPDATE SET `kills` = `kills` + 1;",
|
||||
new
|
||||
{
|
||||
SteamId = steamId
|
||||
});
|
||||
});
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_kills", "Get count of kills for a player")]
|
||||
public void OnKillsCommand(CCSPlayerController? player, CommandInfo commandInfo)
|
||||
{
|
||||
if (player == null) return;
|
||||
|
||||
// Capture the SteamID of the player as `@event` will not be available outside of this function.
|
||||
var steamId = player.AuthorizedSteamID.SteamId64;
|
||||
|
||||
// Run in a separate thread to avoid blocking the main thread
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var result = await _connection.QueryFirstOrDefaultAsync(@"SELECT `kills` FROM `players` WHERE `steamid` = @SteamId;",
|
||||
new
|
||||
{
|
||||
SteamId = steamId
|
||||
});
|
||||
|
||||
// Print the result to the player's chat. Note that this needs to be run on the game thread.
|
||||
// So we use `Server.NextFrame` to run it on the next game tick.
|
||||
Server.NextFrame(() => { player.PrintToChat($"Kills: {result?.kills ?? 0}"); });
|
||||
});
|
||||
}
|
||||
}
|
||||
2
examples/WithDependencyInjection/README.md
Normal file
2
examples/WithDependencyInjection/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Dependency Injection
|
||||
This example shows how can you implement the `IPluginServiceCollection` interface to register your services in a provided DI container.
|
||||
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,50 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithDependencyInjection;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithDependencyInjectionPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: Dependency Injection";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "An example plugin that uses dependency injection.";
|
||||
|
||||
private readonly TestInjectedClass _testInjectedClass;
|
||||
|
||||
public WithDependencyInjectionPlugin(TestInjectedClass testInjectedClass)
|
||||
{
|
||||
_testInjectedClass = testInjectedClass;
|
||||
}
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
_testInjectedClass.SayHello();
|
||||
}
|
||||
}
|
||||
|
||||
public class WithDependencyInjectionPluginServiceCollection : IPluginServiceCollection<WithDependencyInjectionPlugin>
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddSingleton<TestInjectedClass>();
|
||||
}
|
||||
}
|
||||
|
||||
public class TestInjectedClass
|
||||
{
|
||||
private readonly ILogger<TestInjectedClass> _logger;
|
||||
|
||||
public TestInjectedClass(ILogger<TestInjectedClass> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void SayHello()
|
||||
{
|
||||
_logger.LogInformation("Hello World from Test Injected Class");
|
||||
}
|
||||
}
|
||||
2
examples/WithEntityOutputHooks/README.md
Normal file
2
examples/WithEntityOutputHooks/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Entity Output Hooks
|
||||
This example shows how to implement hooks for entity output, such as StartTouch, OnPickup etc.
|
||||
12
examples/WithEntityOutputHooks/WithEntityOutputHooks.csproj
Normal file
12
examples/WithEntityOutputHooks/WithEntityOutputHooks.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,43 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithEntityOutputHooks;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithEntityOutputHooksPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Entity Output Hooks";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that showcases entity output hooks";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
HookEntityOutput("weapon_knife", "OnPlayerPickup", (CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay) =>
|
||||
{
|
||||
Logger.LogInformation("weapon_knife called OnPlayerPickup ({name}, {activator}, {caller}, {delay})", name, activator.DesignerName, caller.DesignerName, delay);
|
||||
|
||||
return HookResult.Continue;
|
||||
});
|
||||
}
|
||||
|
||||
// Output hooks can use wildcards to match multiple entities
|
||||
[EntityOutputHook("*", "OnPlayerPickup")]
|
||||
public HookResult OnPickup(CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay)
|
||||
{
|
||||
Logger.LogInformation("[EntityOutputHook Attribute] Called OnPlayerPickup ({name}, {activator}, {caller}, {delay})", name, activator.DesignerName, caller.DesignerName, delay);
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
// Output hooks can use wildcards to match multiple output names
|
||||
[EntityOutputHook("func_buyzone", "*")]
|
||||
public HookResult OnTouchStart(CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay)
|
||||
{
|
||||
Logger.LogInformation("[EntityOutputHook Attribute] Buyzone called output ({name}, {activator}, {caller}, {delay})", name, activator.DesignerName, caller.DesignerName, delay);
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
2
examples/WithGameEventHandlers/README.md
Normal file
2
examples/WithGameEventHandlers/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Game Event Handlers
|
||||
This is example shows how you can subscribe to legacy Source 1 game events.
|
||||
12
examples/WithGameEventHandlers/WithGameEventHandlers.csproj
Normal file
12
examples/WithGameEventHandlers/WithGameEventHandlers.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,54 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithGameEventHandlers;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithGameEventHandlersPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Game Event Handlers";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that subscribes to game events";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
// Subscriptions can be added via the instance method
|
||||
RegisterEventHandler<EventPlayerDeath>((@event, info) =>
|
||||
{
|
||||
// You can use `info.DontBroadcast` to set the dont broadcast flag on the event (in pre handlers)
|
||||
// This will prevent the event from being broadcast to other clients.
|
||||
// In this example we prevent kill-feed messages from being broadcast if it was not a headshot.
|
||||
if (!@event.Headshot)
|
||||
{
|
||||
@event.Attacker.PrintToChat($"Skipping player_death broadcast");
|
||||
info.DontBroadcast = true;
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}, HookMode.Pre);
|
||||
}
|
||||
|
||||
// Subscriptions can be added via an attribute
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerBlind(EventPlayerBlind @event, GameEventInfo info)
|
||||
{
|
||||
Logger.LogInformation("Player was just blinded for {Duration}", @event.BlindDuration);
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
// The event name is inferred from the event type you pass to the first argument.
|
||||
// e.g. EventRoundStart becomes "round_start"
|
||||
// Note: You can use the `HookMode` enum to specify the hook mode
|
||||
// If you do not specify a hook mode, it will default to `HookMode.Post`
|
||||
[GameEventHandler(HookMode.Pre)]
|
||||
public HookResult OnEventRoundStartPre(EventRoundStart @event, GameEventInfo info)
|
||||
{
|
||||
Logger.LogInformation("Round has started with Timelimit: {Timelimit}", @event.Timelimit);
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
8
examples/WithTranslations/README.md
Normal file
8
examples/WithTranslations/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# With Translations
|
||||
This example shows how to use an `IStringLocalizer` and language `json` files to provide localization for your plugins.
|
||||
|
||||
## How to use
|
||||
1. Add the `IStringLocalizer` to your services with dependency injection, or use the `Localizer` provided on the plugin instance.
|
||||
2. Add a `lang` folder to your plugin, and add a `json` file for each language you want to support. The name of the file should be a locale code, like `en.json` or `fr.json` etc.
|
||||
3. Ensure that the `lang` folder is shipped with your plugin, see the example `.csproj` file for an example to auto-copy to the output folder.
|
||||
4. Use the `IStringLocalizer` to localize your strings.
|
||||
15
examples/WithTranslations/WithTranslations.csproj
Normal file
15
examples/WithTranslations/WithTranslations.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="lang\**\*.*" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
52
examples/WithTranslations/WithTranslationsPlugin.cs
Normal file
52
examples/WithTranslations/WithTranslationsPlugin.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Globalization;
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Core.Translations;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithTranslations;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithTranslationsPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Translations";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that provides translations";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
// A global `Localizer` is provided on the plugin instance.
|
||||
// You can also use dependency injection to inject `IStringLocalizer` in your own services.
|
||||
Logger.LogInformation("This message is in the server language: {Message}", Localizer["test.translation"]);
|
||||
|
||||
// IStringLocalizer can accept standard string format arguments.
|
||||
// "This number has 2 decimal places {0:n2}" -> "This number has 2 decimal places 123.55"
|
||||
Logger.LogInformation(Localizer["test.format", 123.551]);
|
||||
|
||||
// This message has colour codes
|
||||
Server.PrintToChatAll(Localizer["test.colors"]);
|
||||
|
||||
// This message has colour codes and formatted values
|
||||
Server.PrintToChatAll(Localizer["test.colors.withformat", 123.551]);
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_replylanguage", "Test Translations")]
|
||||
public void OnCommandReplyLanguage(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
// Commands are executed in a players provided culture (or fallback to server culture).
|
||||
// Players can configure their language using the `!lang` or `css_lang` command.
|
||||
Logger.LogInformation("Current Culture is {Culture}", CultureInfo.CurrentCulture);
|
||||
command.ReplyToCommand(Localizer["test.translation"]);
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
// You can also get the players language using the `GetLanguage` extension method.
|
||||
// This will always return a culture, defaulting to the server culture if the user has not configured it.
|
||||
var language = player.GetLanguage();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
examples/WithTranslations/lang/en-GB.json
Normal file
3
examples/WithTranslations/lang/en-GB.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"test.translation": "This is the english (GB) translation"
|
||||
}
|
||||
6
examples/WithTranslations/lang/en.json
Normal file
6
examples/WithTranslations/lang/en.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"test.translation": "This is the english translation",
|
||||
"test.format": "This number has 2 decimal places {0:n2}",
|
||||
"test.colors": "{orange}This{default} text has {green}green{default} text",
|
||||
"test.colors.withformat": "{orange}{0:n2}{default}"
|
||||
}
|
||||
3
examples/WithTranslations/lang/fr.json
Normal file
3
examples/WithTranslations/lang/fr.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"test.translation": "This is the french translation"
|
||||
}
|
||||
2
examples/WithVoiceOverrides/README.md
Normal file
2
examples/WithVoiceOverrides/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Voice Overrides
|
||||
Provides examples how to manipulate player voice flags & listening overrides to prevent certain players from hearing others.
|
||||
12
examples/WithVoiceOverrides/WithVoiceOverrides.csproj
Normal file
12
examples/WithVoiceOverrides/WithVoiceOverrides.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
79
examples/WithVoiceOverrides/WithVoiceOverridesPlugin.cs
Normal file
79
examples/WithVoiceOverrides/WithVoiceOverridesPlugin.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithVoiceOverrides;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithVoiceOverridesPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Voice Overrides";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A plugin that manipulates voice flags";
|
||||
|
||||
[ConsoleCommand("css_hearall")]
|
||||
public void OnHearAllCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (caller is null) return;
|
||||
|
||||
if (caller.VoiceFlags.HasFlag(VoiceFlags.ListenAll))
|
||||
{
|
||||
caller.VoiceFlags = VoiceFlags.Normal;
|
||||
command.ReplyToCommand("Voice set back to default");
|
||||
}
|
||||
else
|
||||
{
|
||||
caller.VoiceFlags = VoiceFlags.ListenAll;
|
||||
command.ReplyToCommand("Can hear both teams");
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_muteself")]
|
||||
public void OnMuteSelfCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (caller is null) return;
|
||||
|
||||
if (caller.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
{
|
||||
caller.VoiceFlags = VoiceFlags.Normal;
|
||||
command.ReplyToCommand("Unmuted yourself");
|
||||
}
|
||||
else
|
||||
{
|
||||
caller.VoiceFlags = VoiceFlags.Muted;
|
||||
command.ReplyToCommand("Muted yourself");
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_muteothers")]
|
||||
[CommandHelper(minArgs: 1, usage: "[target]")]
|
||||
public void OnMuteOthersCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (caller is null) return;
|
||||
|
||||
var targetResult = command.GetArgTargetResult(1);
|
||||
|
||||
foreach (var player in targetResult.Players)
|
||||
{
|
||||
if (player == caller) continue;
|
||||
|
||||
|
||||
var existingOverride = caller.GetListenOverride(player);
|
||||
if (existingOverride == ListenOverride.Mute)
|
||||
{
|
||||
caller.SetListenOverride(player, ListenOverride.Default);
|
||||
command.ReplyToCommand($"Now hearing {player.PlayerName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
caller.SetListenOverride(player, ListenOverride.Mute);
|
||||
command.ReplyToCommand($"Muted {player.PlayerName}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user