Compare commits

...

45 Commits

Author SHA1 Message Date
dependabot[bot]
02d5191e74 chore(deps): bump libraries/hl2sdk-cs2 from f7ed6a0 to 36dd2db (#452)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: roflmuffin <shortguy014@gmail.com>
2024-05-10 11:50:41 +10:00
dependabot[bot]
aec696abc0 chore(deps): bump libraries/hl2sdk-cs2 from 9ddef9a to f7ed6a0 (#451)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-09 00:43:54 +10:00
Roflmuffin
c01aeec14b [no ci] chore: fix dependabot prefix 2024-05-08 20:13:19 +10:00
dependabot[bot]
41e7bee85a chore(deps): update hl2sdk: bump libraries/metamod-source from e857fbe to 607301a (#450)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-08 20:10:01 +10:00
Roflmuffin
9834271956 [no ci] chore: add metamod source dependabot config 2024-05-08 19:59:53 +10:00
Michael Wilson
fb5967d102 Back to C++17 (#447) 2024-05-08 16:34:51 +10:00
dependabot[bot]
928bc3f74d chore(deps): update hl2sdk: bump libraries/hl2sdk-cs2 from 3fc8d0f to 9ddef9a (#446)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-08 15:27:48 +10:00
Roflmuffin
6a7d7dba4f [no ci] feat: add hl2sdk-cs2 dependabot 2024-05-08 14:30:51 +10:00
Roflmuffin
11e5e9972d fix: concommand crash when no description 2024-05-01 14:44:57 +10:00
Michael Wilson
9a221b4ebb chore: bump hl2sdk after update (#434) 2024-05-01 09:38:54 +10:00
Yarukon
e270bdfd44 AcceptInput changes (#433) 2024-05-01 01:12:25 +10:00
Michael Wilson
f591fe58d0 fix: add memoverride on windows, use correct MT flag (#431) 2024-04-30 17:40:25 +10:00
Roflmuffin
052cb4e14e chore: improve ccsplayercontroller helpers validity checks 2024-04-30 11:39:49 +10:00
Michael Wilson
bc3bec4aa8 feat: improve docs and add more null checking for handle accesses (#417) 2024-04-30 11:20:47 +10:00
Roflmuffin
20bab7f4a8 feat: add PrintToCenterAlert player helper 2024-04-29 20:14:58 +10:00
Roflmuffin
c7eac71109 feat: add generic math operators to Vector 2024-04-29 00:56:00 +10:00
Roflmuffin
e3d2370e2e chore: use IDA style sigs for gamedata 2024-04-28 13:57:07 +10:00
Roflmuffin
142242744c chore: update give named item sig for linux 2024-04-28 09:44:51 +10:00
Nukoooo
0eebffd860 Copy bytes of a module to prevent signature scanning failures and some minor changes (#414)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
2024-04-27 10:44:42 +00:00
Michael Wilson
25ca5dbe0c chore: use offsets for give named item (#427) 2024-04-27 19:56:07 +10:00
Nexd
7cae4be96d Fix: new game update broke signatures (#425)
Co-authored-by: KillStr3aK <KillStr3aK@users.noreply.github.com>
Co-authored-by: Roflmuffin <shortguy014@gmail.com>
2024-04-26 16:29:38 +10:00
Nexd
83bc1a95fb Make shared type loader less strict (#424)
Co-authored-by: KillStr3aK <KillStr3aK@users.noreply.github.com>
2024-04-26 10:26:39 +10:00
roflmuffin
71c694b52e [no ci] add windows install script 2024-04-14 13:25:43 +10:00
Michael Wilson
a452d79ba3 [no ci] feat: add install script 2024-04-14 12:58:24 +10:00
Nukoooo
dfc9859806 Make signature support IDA/x64Dbg style (#407)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
2024-04-13 12:11:26 +10:00
Nukoooo
f99f58402a Add mising `GameData.GetSignature to NetworkStateChangedFunc` (#415) 2024-04-13 11:00:51 +10:00
Michael Wilson
6317559bd2 [no ci] Update .clang-format & add formatting tool install scripts (#410) 2024-04-12 12:36:39 +10:00
Michael Wilson
ad6e1ca2e2 chore: bump hl2sdk (#408) 2024-04-11 18:15:50 +10:00
Michael Wilson
2564ef9f39 fix: fix startup server listener 2024-04-11 16:14:16 +10:00
Michael Wilson
83a341d3cf feat: expose TargetTypeMap 2024-04-11 15:34:01 +10:00
Michael Wilson
534fc42444 fix: bad commit 2024-04-11 14:26:21 +10:00
Michael Wilson
41355d05fa docs: add more comments to base plugin 2024-04-11 14:20:24 +10:00
luxury fabka
d9da15be83 Add teleport overloads (#399)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
2024-04-11 00:48:55 +00:00
B3none
75e2f6e8aa [no ci] Rename ACKNOWLEDGEMENTS to ACKNOWLEDGEMENTS.md (#401) 2024-04-10 16:34:15 +10:00
Michael Wilson
37b34e1d41 [no ci] add basic contributing guide 2024-04-08 10:02:18 +10:00
WidovV
5ce04649fd Add CenterHtmlMenu button colors (#398) 2024-04-06 21:43:38 +10:00
Michael Wilson
7b7202fe8a [no ci] Update README.md 2024-04-05 11:54:53 +10:00
Michael Wilson
cadb817ed2 fix: mark center html menu constructor as obsolete, throw error (#396) 2024-04-04 09:33:22 +10:00
luxury fabka
211516cce5 added Open method to each menu type (#385)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
Co-authored-by: Roflmuffin <shortguy014@gmail.com>
2024-04-01 18:04:12 +10:00
Roflmuffin
ab211a42e6 [skip ci] chore: update ApiCompat to v202, disable suppression file 2024-03-26 12:46:42 +10:00
Roflmuffin
696ecadee4 fix: bad vector math 2024-03-26 12:16:53 +10:00
Roflmuffin
e4d598dba8 fix: main version number 2024-03-25 17:15:31 +10:00
Michael Wilson
5c67d88844 feat: improve version stamping (#389) 2024-03-25 17:11:16 +10:00
Michael Wilson
9d8b6beae6 .NET8 Upgrade (#261)
Co-authored-by: Frederik St-Onge <frederik.stonge@gmail.com>
Co-authored-by: B3none <24966460+B3none@users.noreply.github.com>
2024-03-25 14:16:32 +10:00
ipsvn
39604b7ad7 Fix backwards compatibility in DynamicHook (#388) 2024-03-22 23:04:09 +10:00
121 changed files with 105472 additions and 106142 deletions

View File

@@ -1,21 +1,72 @@
BasedOnStyle: LLVM
# Spacing
IndentWidth: 4
ColumnLimit: 100
UseTab: Never
ColumnLimit: 140
# Line Endings
LineEnding: LF
InsertNewlineAtEOF: true
DerivePointerAlignment: false
PointerAlignment: Left
AlignAfterOpenBracket: Align
KeepEmptyLinesAtTheStartOfBlocks: false
SortIncludes: false
SpaceBeforeParens: ControlStatements
AllowAllArgumentsOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
IndentCaseLabels: true
# Line Breaks
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterStruct: true
AfterControlStatement: Always
AfterEnum: true
AfterUnion: true
AfterNamespace: false
AfterFunction: true
AfterNamespace: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
PointerAlignment: Left
SortIncludes: CaseSensitive
IncludeBlocks: Regroup
IncludeCategories:
# External headers in <> with extension or /
- Regex: '<[-\w\/-_]+[\.\/][-\w\/-_]+>'
Priority: 2
# Standard headers in <>
- Regex: '<[-\w\/-_]+>'
Priority: 3
# Local headers in ""
- Regex: '"[-\w\/-_]*"'
Priority: 4
ReflowComments: true
CompactNamespaces: false
Cpp11BracedListStyle: false
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignEscapedNewlines: Left
AlignTrailingComments: Never
AllowShortBlocksOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: OnlyFirstIf
AllowShortLambdasOnASingleLine: Empty
BinPackArguments: true
BinPackParameters: false
LambdaBodyIndentation: OuterScope

14
.editorconfig Normal file
View File

@@ -0,0 +1,14 @@
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
max_line_length = 140
trim_trailing_whitespace = true
[*.json]
indent_size = 2

12
.github/dependabot.yaml vendored Normal file
View File

@@ -0,0 +1,12 @@
version: 2
updates:
# Update the submodule in libraries/hl2sdk-cs2 every day
- package-ecosystem: "gitsubmodule"
directory: "/"
allow:
- dependency-name: "libraries/hl2sdk-cs2"
- dependency-name: "libraries/metamod-source"
schedule:
interval: "daily"
commit-message:
prefix: "chore(deps)"

View File

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

3
.gitignore vendored
View File

@@ -1,8 +1,7 @@
.ccls-cache/
.cmake/
cmake-build-debug*/
cmake-build-*/
.kdev4/
.vscode/
generated/
# configure_file auto generated.

4
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"editor.defaultFormatter": null,
"editor.formatOnSave": true
}

View File

@@ -5,6 +5,8 @@ project(counterstrikesharp C CXX ASM)
include("makefiles/shared.cmake")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
add_subdirectory(libraries/spdlog)
add_subdirectory(libraries/dyncall)
add_subdirectory(libraries/funchook)
@@ -13,7 +15,8 @@ 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
set(SOURCE_FILES
libraries/hl2sdk-cs2/public/tier0/memoverride.cpp
src/mm_plugin.cpp
src/mm_plugin.h
libraries/hl2sdk-cs2/tier1/convar.cpp
@@ -70,7 +73,6 @@ SET(SOURCE_FILES
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
@@ -96,66 +98,55 @@ SET(SOURCE_FILES
src/core/game_system.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/Protobufs/csgo)
file(GLOB PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/Protobufs/csgo/*.proto")
## Generate protobuf source & headers
if (LINUX)
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
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)
set(SOURCE_FILES ${SOURCE_FILES} protobuf_output_stamp)
# Sources
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${NATIVES_SOURCES} ${CONVERSIONS_SOURCES} ${CONVERSIONS_HEADERS})
target_include_directories(
${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/core/cs2_sdk
${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/core/cs2_sdk
)
if (LINUX)
if(LINUX)
include("makefiles/linux.base.cmake")
set_target_properties(${PROJECT_NAME} PROPERTIES
PREFIX ""
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/addons/counterstrikesharp/bin/linuxsteamrt64"
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"
PREFIX ""
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/addons/counterstrikesharp/bin/win64"
)
endif()
# Libraries
target_link_libraries(${PROJECT_NAME} ${COUNTER_STRIKE_SHARP_LINK_LIBRARIES})
add_custom_command(
TARGET ${PROJECT_NAME} PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/configs ${CMAKE_BINARY_DIR}
)
TARGET ${PROJECT_NAME} PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/configs ${CMAKE_BINARY_DIR}
)

103
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,103 @@
# Contributing to CounterStrikeSharp
We'd love for you to contribute to CS# to make it better than it is today!
Here are the guidelines we'd like you to follow:
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Submission Guidelines](#submit)
- [Coding Format](#format)
## <a name="question"></a> Got a Question or Problem?
If you have questions about how to contribute to CounterStrikeSharp, please join our [Discord][discord] server.
## <a name="issue"></a> Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
with a fix.
**Please see the [Submission Guidelines](#submit) below.**
## <a name="submit"></a> Submission Guidelines
### Submitting an Issue
Before you submit your issue please search the archive, maybe your question was already answered.
If your issue appears to be a bug and hasn't been reported, open a new issue. Help us to maximize
the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
Providing the following information will increase the chances of your issue being dealt with
quickly:
* **Overview of the Issue** - if an error is being thrown a stack trace helps
* **Operating System** - is this a problem with a specific OS (Windows or Linux)?
* **Reproduce the Error** - provide details, if possible, on how to reproduce the error
* **Related Issues** - has a similar issue been reported before?
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit)
### Submitting a Pull Request
Before you submit your pull request consider the following guidelines:
* Search [GitHub](https://github.com/roflmuffin/CounterStrikeSharp/pulls) for an open or closed Pull Request
that relates to your submission. You don't want to duplicate effort.
* If adding a feature or enhancement, we recommend you first [start a discussion for
it](https://github.com/roflmuffin/CounterStrikeSharp/discussions) before submitting a Pull Request.
* [Fork](https://help.github.com/articles/fork-a-repo/) this repo.
* [Clone](https://help.github.com/articles/cloning-a-repository/) your copy.
```shell
git clone https://github.com/YOUR_USERNAME/CounterStrikeSharp.git
cd CounterStrikeSharp/
```
* After cloning, set a new remote [upstream](https://help.github.com/articles/configuring-a-remote-for-a-fork/) (this helps to keep your fork up to date)
```shell
git remote add upstream https://github.com/roflmuffin/CounterStrikeSharp.git
```
* Make your changes in a new git branch:
```shell
git checkout -b my-fix-branch master
```
* Create your patch and run appropriate tests.
* Commit your changes using a descriptive commit message that uses the imperative, present tense: "change" not "changed" nor "changes".
```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
* Push your branch to GitHub:
```shell
git push origin my-fix-branch
```
In GitHub, send a pull request to `CounterStrikeSharp:master`.
If we suggest changes, then:
* Make the required updates.
* Re-run CounterStrikeSharp to ensure everything is still working & tests are passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
```shell
git fetch upstream
git rebase upstream/master
git push origin my-fix-branch -f
```
That's it! Thank you for your contribution!
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes
from the main (upstream) repository.
[github]: https://github.com/roflmuffin/CounterStrikeSharp
[discord]: https://discord.gg/eAZU3guKWU

View File

@@ -1,6 +1,6 @@
# CounterStrikeSharp
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.
CounterStrikeSharp is a server side modding framework for Counter-Strike 2. This project implements a .NET 8 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/eAZU3guKWU)
@@ -18,14 +18,12 @@ Detailed installation instructions can be found in the [docs](https://docs.cssha
## 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] Game Event Handlers & Custom Events (e.g. player_death)
- [x] Fake Console Variables (commands which mimic ConVar behaviour as these have not been fully reverse engineered)
- [x] Game Event Handlers & Firing of 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)
- [x] Game Tick Based Timers (e.g. repeating map timers)
@@ -34,7 +32,7 @@ These features are the core of the platform and work pretty well/have a low risk
- [x] Client Listeners (e.g. connect, disconnect, put in server)
- [x] OnMapStart
- [x] OnTick
- [x] Server Information (current map, game time, tick rate, model precaching)
- [x] Server Information (current map, game time)
- [x] Schema System Access (access player values like current weapon, money, location etc.)
## Links

View File

@@ -2,22 +2,22 @@
"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"
"windows": "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 81 EC 70 01 ? ? 8B E9",
"linux": "55 48 89 E5 41 57 49 89 D7 41 56 49 89 F6 41 55 41 89 FD"
}
},
"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"
"windows": "48 85 C9 0F 84 ? ? ? ? 48 8B C4 48 89 58 18",
"linux": "55 48 89 E5 41 57 49 89 CF 41 56 49 89 D6 41 55 41 89 F5 41 54 4C 8D A5 A0 FE FF FF"
}
},
"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"
"windows": "40 56 57 48 81 EC ? ? ? ? 48 8B F9 8B F2 8B CA",
"linux": "55 48 89 E5 41 55 49 89 FD 89 F7"
}
},
"CCSPlayerController_ChangeTeam": {
@@ -28,110 +28,123 @@
},
"CCSPlayerController_Respawn": {
"offsets": {
"windows": 244,
"linux": 246
"windows": 244,
"linux": 246
}
},
"CBasePlayerController_SetPawn": {
"signatures": {
"library": "server",
"windows": "\\x44\\x88\\x4C\\x24\\x20\\x55\\x57\\x41\\x54\\x41\\x56\\x41\\x57\\x48\\x8D\\x6C\\x24\\x2A\\x48\\x81\\xEC\\x2A",
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x49\\x89\\xFC\\x53\\x48\\x89\\xF3\\x48\\x81\\xEC\\xC8\\x00\\x00\\x00"
"windows": "44 88 4C 24 20 55 57 41 54 41 56 41 57 48 8D 6C 24 ? 48 81 EC ?",
"linux": "55 48 89 E5 41 57 41 56 41 55 41 54 49 89 FC 53 48 89 F3 48 81 EC C8 00 00 00"
}
},
"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\\x41\\x56\\x41\\x55\\x41\\x54\\x53\\x48\\x89\\xFB\\x48\\x81\\xEC\\x2A\\x2A\\x2A\\x2A\\xE8\\x2A\\x2A\\x2A\\x2A\\x48\\x89\\xDF"
"windows": "48 ? ? 55 53 56 57 41 ? 48 ? ? ? 48 ? ? ? ? ? ? 4C 89 68",
"linux": "55 48 89 E5 41 56 41 55 41 54 53 48 89 FB 48 83 EC 30 E8 ? ? ? ?"
}
},
"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"
"windows": "48 89 5C 24 ? 48 89 74 24 ? 55 57 41 ? 41 ? 41 ? 48 ? ? ? ? 48 ? ? ? ? ? ? 4D ? ? 48",
"linux": "55 48 89 E5 41 57 41 56 49 89 D6 41 55 49 89 FD 41 54 48"
}
},
"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"
"windows": "48 85 C9 74 ? 48 8B D1 48 8B 0D ? ? ? ?",
"linux": "48 89 FE 48 85 FF 74 ? 48 8D 05 ? ? ? ? 48"
}
},
"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"
"windows": "44 89 4C 24 20 44 88 44 24 18",
"linux": "55 48 89 E5 41 57 49 89 FF 41 56 41 55 41 54 4D 89 C4"
}
},
"CBaseModelEntity_SetModel": {
"signatures": {
"library": "server",
"windows": "\\x48\\x89\\x5C\\x24\\x2A\\x48\\x89\\x7C\\x24\\x2A\\x55\\x48\\x8B\\xEC\\x48\\x83\\xEC\\x50\\x48\\x8B\\xF9\\x4C\\x8B\\xC2",
"linux": "\\x55\\x48\\x89\\xF2\\x48\\x89\\xE5\\x41\\x54\\x49\\x89\\xFC\\x48\\x8D\\x7D\\xE0\\x48\\x83\\xEC\\x2A\\x48\\x8D\\x05\\x2A\\x2A\\x2A\\x2A\\x48\\x8B\\x30\\x48\\x8B\\x06"
"library": "server",
"windows": "48 89 5C 24 ? 48 89 7C 24 ? 55 48 8B EC 48 83 EC 50 48 8B F9 4C 8B C2",
"linux": "55 48 89 F2 48 89 E5 41 54 49 89 FC 48 8D 7D E0 48 83 EC ? 48 8D 05 ? ? ? ? 48 8B 30 48 8B 06"
}
},
"CCSPlayer_WeaponServices_CanUse": {
"signatures": {
"library": "server",
"windows": "\\x48\\x89\\x5C\\x24\\x10\\x48\\x89\\x6C\\x24\\x18\\x56\\x57\\x41\\x56\\x48\\x83\\xEC\\x30\\x80\\xB9\\xA0\\x00\\x00\\x00\\x00",
"linux": "\\x48\\x85\\xF6\\x0F\\x84\\x2A\\x2A\\x2A\\x2A\\x55\\x31\\xC9\\x48\\x89\\xE5\\x41\\x55\\x49\\x89\\xFD"
"windows": "48 89 5C 24 10 48 89 6C 24 18 56 57 41 56 48 83 EC 30 80 B9 A0 00 00 00 00",
"linux": "48 85 F6 0F 84 ? ? ? ? 55 31 C9 48 89 E5 41 55 49 89 FD"
}
},
"CCSPlayer_ItemServices_GiveNamedItem": {
"offsets": {
"windows": 17,
"linux": 18
}
},
"CCSPlayer_ItemServices_DropActivePlayerWeapon": {
"offsets": {
"windows": 18,
"linux": 19
"windows": 18,
"linux": 19
}
},
"CCSPlayer_ItemServices_RemoveWeapons": {
"offsets": {
"windows": 19,
"linux": 20
}
"offsets": {
"windows": 19,
"linux": 20
}
},
"CGameSceneNode_GetSkeletonInstance": {
"offsets": {
"windows": 8,
"linux": 8
"windows": 8,
"linux": 8
}
},
"CCSGameRules_TerminateRound": {
"signatures": {
"library": "server",
"windows": "\\x48\\x8B\\xC4\\x4C\\x89\\x48\\x20\\x55\\x57",
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x49\\x89\\xFC\\x53\\x48\\x81\\xEC\\xE8\\x01\\x00\\x00\\x48\\x8D\\x05\\x2A\\x2A\\x2A\\x2A"
}
"library": "server",
"windows": "48 ? ? 4C 89 48 ? 48 89 48 ? 55 41",
"linux": "55 48 89 E5 41 57 41 56 41 55 41 54 49 89 FC 53 48 81 EC E8 01 00 00 48 8D 05 ? ? ? ?"
}
},
"UTIL_CreateEntityByName": {
"signatures": {
"library": "server",
"windows": "\\x48\\x83\\xEC\\x48\\xC6\\x44\\x24\\x30\\x00",
"linux": "\\x48\\x8D\\x05\\x2A\\x2A\\x2A\\x2A\\x55\\x48\\x89\\xFA"
}
"library": "server",
"windows": "48 83 EC 48 C6 44 24 30 00",
"linux": "48 8D 05 ? ? ? ? 55 48 89 FA"
}
},
"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\\x2A\\x55\\x48\\x89\\xE5\\x41\\x56"
}
"library": "server",
"windows": "48 89 5C 24 10 57 48 83 EC 30 48 8B DA 48 8B F9 48 85 C9",
"linux": "48 85 FF 74 ? 55 48 89 E5 41 56"
}
},
"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"
"windows": "48 89 5C 24 10 48 89 74 24 18 57 48 83 EC 40 49 8B F0",
"linux": "55 48 89 E5 41 57 49 89 FF 41 56 48 8D 7D C0"
}
},
"CEntitySystem_AddEntityIOEvent": {
"signatures": {
"library": "server",
"windows": "48 89 5C 24 ? 48 89 74 24 ? 57 48 ? ? ? 49 ? ? 48 ? ? 48 ? ? 74",
"linux": "55 41 BA FF FF FF FF"
}
},
"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"
"windows": "48 8B 15 ? ? ? ? 48 85 D2 74 ? 85 C9 74",
"linux": "48 8B 05 ? ? ? ? 48 85 C0 74 ? 83 FF 3F 76 ? 31 C0"
}
},
"CBasePlayerPawn_CommitSuicide": {
@@ -143,8 +156,8 @@
"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"
"windows": "48 ? ? 0F 84 ? ? ? ? 48 89 5C 24 ? 57 48 ? ? ? 48 ? ? 48 ? ? E8",
"linux": "55 48 89 ? 41 ? 49 89 ? 41 ? 49 89 ? E8 ? ? ? ? 49 39"
}
},
"CBaseEntity_Teleport": {
@@ -156,36 +169,36 @@
"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"
"windows": "40 56 57 48 83 EC 58 48 8B 41 10",
"linux": "55 48 89 E5 41 57 41 56 41 55 41 54 49 89 FC 53 48 83 EC 38 4C 8D 2D ? ? ? ? 49 8B 7D 00 48 85 FF 0F 84 ? ? ? ?"
}
},
"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"
"windows": "41 56 41 57 48 83 EC 58 48 8B 01",
"linux": "55 48 89 E5 41 56 49 89 F6 41 55 49 89 FD 41 54 53 BB"
}
},
"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\\x89\\xF5\\x41"
"windows": "40 53 57 41 55 48 83 EC 40",
"linux": "55 BA FF FF FF FF 48 89 E5 41 57 41 56 41 55 49 89 F5 41"
}
},
"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"
"windows": "40 55 53 56 41 55 41 57 48 8D 6C 24 B0",
"linux": "55 48 89 E5 41 57 41 56 41 55 41 54 53 89 D3"
}
},
"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"
"windows": "4C 8B C9 48 8B 09 48 85 C9 74 ? 48 8B 41 10",
"linux": "4C 8B 07 4D 85 C0 74 ? 49 8B 40 10"
}
},
"GameEntitySystem": {
@@ -203,15 +216,15 @@
"CEntityIOOutput_FireOutputInternal": {
"signatures": {
"library": "server",
"windows": "\\x4C\\x89\\x4C\\x24\\x20\\x53\\x55\\x57\\x41\\x54\\x41\\x56\\x48\\x81\\xEC",
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x49\\x89\\xD4\\x53\\x48\\x89\\xF3\\x48\\x83\\xEC\\x58"
"windows": "4C 89 4C 24 20 53 55 57 41 54 41 56 48 81 EC",
"linux": "55 48 89 E5 41 57 41 56 41 55 41 54 49 89 D4 53 48 89 F3 48 83 EC 58"
}
},
"IGameSystem_InitAllSystems_pFirst": {
"signatures": {
"library": "server",
"windows": "\\x48\\x8B\\x1D\\x2A\\x2A\\x2A\\x2A\\x48\\x85\\xDB\\x0F\\x84\\x2A\\x2A\\x2A\\x2A\\xBE\\x2A\\x2A\\x2A\\x2A\\x0F\\x1F\\x00\\x48\\x8B\\x7B\\x10",
"linux": "\\x4C\\x8B\\x35\\x2A\\x2A\\x2A\\x2A\\x4D\\x85\\xF6\\x75\\x2D\\xE9\\x2A\\x2A\\x2A\\x2A\\x0F\\x1F\\x40\\x00\\x48\\x8B\\x05"
"windows": "48 8B 1D ? ? ? ? 48 85 DB 0F 84 ? ? ? ? BE ? ? ? ? 0F 1F 00 48 8B 7B 10",
"linux": "4C 8B 35 ? ? ? ? 4D 85 F6 75 2D E9 ? ? ? ? 0F 1F 40 00 48 8B 05"
}
},
"CEntityResourceManifest_AddResource": {

View File

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

View File

@@ -0,0 +1,37 @@
# Tool taken from dotnet/runtime
# https://github.com/dotnet/runtime/blob/a8158c170b694f8c1dbae114c63c346b38244901/eng/formatting/download-tools.ps1
function DownloadClangTool {
param (
[string]
$toolName,
[string]
$downloadOutputPath
)
$clangVersion = "17.0.6"
$clangToolsRootUrl = "https://clrjit2.blob.core.windows.net/clang-tools"
$clangPlatform = "windows-x64"
$toolUrl = "$clangToolsRootUrl/$clangVersion/$clangPlatform/$toolName.exe"
$targetPath = "$downloadOutputPath\$toolName.exe"
if (-not $(ls $downloadOutputPath | Where-Object { $_.Name -eq "$toolName.exe" })) {
Write-Output "Downloading '$toolUrl' to '$targetPath'"
# Pass -PassThru as otherwise Invoke-WebRequest leaves a corrupted file if the download fails. With -PassThru the download is buffered first.
# -UseBasicParsing is necessary for older PowerShells when Internet Explorer might not be installed/configured
$null = Invoke-WebRequest -Uri "$toolUrl" -OutFile $(Join-Path $downloadOutputPath -ChildPath "$toolName.exe") -PassThru -UseBasicParsing
}
else {
Write-Output "Found '$targetPath'"
}
}
$downloadPathFolder = Split-Path $PSScriptRoot -Parent | Split-Path -Parent | Join-Path -ChildPath "artifacts" | Join-Path -ChildPath "tools"
mkdir $downloadPathFolder -ErrorAction SilentlyContinue
DownloadClangTool "clang-format" "$downloadPathFolder"
# Add to path to enable scripts to skip additional downloading steps since the tools will already be on the path.
$env:PATH = "$downloadPathFolder;$env:PATH"

View File

@@ -0,0 +1,60 @@
# Tool taken from dotnet/runtime
# https://github.com/dotnet/runtime/blob/a8158c170b694f8c1dbae114c63c346b38244901/eng/formatting/download-tools.sh
#!/usr/bin/env bash
set -ue
source="${BASH_SOURCE[0]}"
# resolve $source until the file is no longer a symlink
while [[ -h "$source" ]]; do
scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
source="$(readlink "$source")"
# if $source was a relative symlink, we need to resolve it relative to the path where the
# symlink file was located
[[ $source != /* ]] && source="$scriptroot/$source"
done
scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
function DownloadClangTool {
clangVersion="17.0.6"
clangToolsRootUrl="https://clrjit2.blob.core.windows.net/clang-tools"
clangPlatform="$(dotnet --info | grep 'RID:')"
clangPlatform="${clangPlatform##*RID:* }"
echo "dotnet RID: ${clangPlatform}"
# override common RIDs with compatible version so we don't need to upload binaries for each RID
case $clangPlatform in
ubuntu.*-x64)
clangPlatform=linux-x64
;;
esac
toolUrl="${clangToolsRootUrl}/${clangVersion}/${clangPlatform}/$1"
toolOutput=$2/$1
echo "Downloading $1 from ${toolUrl} to ${toolOutput}"
if [[ ! -x "$toolOutput" ]]; then
curl --silent --retry 5 --fail -o "${toolOutput}" "$toolUrl"
chmod 751 $toolOutput
fi
if [[ ! -x "$toolOutput" ]]; then
echo "Failed to download $1"
exit 1
fi
}
engFolder="$(cd -P "$( dirname "$scriptroot" )" && pwd )"
downloadPathFolder="$(cd -P "$( dirname "$engFolder" )" && pwd )/artifacts/tools"
mkdir -p "$downloadPathFolder"
DownloadClangTool "clang-format" "$downloadPathFolder"
export PATH=$downloadPathFolder:$PATH

29
eng/formatting/format.sh Normal file
View File

@@ -0,0 +1,29 @@
# Tool taken from dotnet/runtime
# https://github.com/dotnet/runtime/blob/a8158c170b694f8c1dbae114c63c346b38244901/eng/formatting/format.sh
#!/bin/sh
LC_ALL=C
# Select files to format
NATIVE_FILES=$(git diff --cached --name-only --diff-filter=ACM "*.h" "*.hpp" "*.c" "*.cpp" "*.inl" | sed 's| |\\ |g')
MANAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM "*.cs" "*.vb" | sed 's| |\\ |g')
exec 1>&2
if [ -n "$NATIVE_FILES" ]; then
# Format all selected files
echo "$NATIVE_FILES" | cat | xargs | sed -e 's/ /,/g' | xargs "./artifacts/tools/clang-format" -style=file -i
# Add back the modified files to staging
echo "$NATIVE_FILES" | xargs git add
fi
if [ -n "$MANAGED_FILES" ]; then
# Format all selected files
echo "$MANAGED_FILES" | cat | xargs | sed -e 's/ /,/g' | dotnet format whitespace --include - --folder
# Add back the modified files to staging
echo "$MANAGED_FILES" | xargs git add
fi
exit 0

71
eng/install/install.ps1 Normal file
View File

@@ -0,0 +1,71 @@
# Install script that downloads Metamod:Source and Counter-Strike Sharp (with runtime)
$MM_DOWNLOAD_URL = "https://mms.alliedmods.net/mmsdrop/2.0/mmsource-2.0.0-git1286-windows.zip"
$TARGET_DIR = "./game/csgo"
$GAMEINFO_FILE = Join-Path $TARGET_DIR "gameinfo.gi"
$ProgressPreference = 'SilentlyContinue'
# Verification
if (-not (Test-Path $GAMEINFO_FILE)) {
Write-Error "Error: $GAMEINFO_FILE does not exist in the specified directory."
exit 1
}
# GitHub API for Counter-Strike Sharp Releases
$RELEASE_INFO = (Invoke-WebRequest -Uri "https://api.github.com/repos/roflmuffin/CounterStrikeSharp/releases/latest").Content | ConvertFrom-Json
# Filtering download URLs
$CSSHARP_DOWNLOAD_URL = $RELEASE_INFO.assets |
Where-Object { $_.browser_download_url -like '*windows*.zip*' -and $_.browser_download_url -notlike '*with-runtime*' } |
Select-Object -First 1 -ExpandProperty browser_download_url
$CSSHARP_RUNTIME_DOWNLOAD_URL = $RELEASE_INFO.assets |
Where-Object { $_.browser_download_url -like '*windows*.zip*' -and $_.browser_download_url -like '*with-runtime*' } |
Select-Object -First 1 -ExpandProperty browser_download_url
### METAMOD:SOURCE ###
Write-Output "Downloading Metamod:Source..."
Invoke-WebRequest -Uri $MM_DOWNLOAD_URL -OutFile metamod.zip
Write-Output "Extracting Metamod:Source to $TARGET_DIR..."
Expand-Archive -Force -Path metamod.zip -DestinationPath $TARGET_DIR
Remove-Item metamod.zip
### GAMEINFO.GI UPDATE ###
$NEW_ENTRY = " Game csgo/addons/metamod"
$FILE_CONTENT = Get-Content $GAMEINFO_FILE
Write-Output "Updating $GAMEINFO_FILE..."
if ($FILE_CONTENT -contains $NEW_ENTRY) {
Write-Output "The entry '$NEW_ENTRY' already exists in $GAMEINFO_FILE. No changes were made."
} else {
$Pattern = "Game_LowViolence"
$Modified = $false
$NewContent = @()
foreach ($line in $FILE_CONTENT) {
if ($line -match $Pattern -and -not $Modified) {
$NewContent += $line
$NewContent += $NEW_ENTRY
$Modified = $true
} else {
$NewContent += $line
}
}
$NewContent | Set-Content $GAMEINFO_FILE
Write-Host "The file $GAMEINFO_FILE has been modified successfully. '$NEW_ENTRY' has been added."
}
### COUNTER-STRIKE SHARP ###
Write-Output "Downloading Counter-Strike Sharp (with runtime)..."
# Determine if runtime needs to be downloaded
if (-not (Test-Path "./game/csgo/addons/CounterStrikeSharp/dotnet/dotnet.exe")) {
$CSSHARP_DOWNLOAD_URL = $CSSHARP_RUNTIME_DOWNLOAD_URL
}
Invoke-WebRequest -Uri $CSSHARP_DOWNLOAD_URL -OutFile cssharp.zip
Write-Output "Extracting Counter-Strike Sharp to $TARGET_DIR..."
Expand-Archive -Force -Path cssharp.zip -DestinationPath $TARGET_DIR
Remove-Item cssharp.zip

72
eng/install/install.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
# Install script that downloads Metamod:Source and Counter-Strike Sharp (with runtime)
MM_DOWNLOAD_URL="https://mms.alliedmods.net/mmsdrop/2.0/mmsource-2.0.0-git1286-linux.tar.gz"
TARGET_DIR="./game/csgo"
GAMEINFO_FILE="${TARGET_DIR}/gameinfo.gi"
if [ ! -f "${GAMEINFO_FILE}" ]; then
printf "Error: %s does not exist in the specified directory.\n" "$GAMEINFO_FILE"
exit 1
fi
RELEASE_INFO=$(curl -s https://api.github.com/repos/roflmuffin/CounterStrikeSharp/releases/latest)
# Filter and store download URLs
CSSHARP_DOWNLOAD_URL=$(echo "$RELEASE_INFO" | grep -o "browser_download_url.*linux.*\.zip" | cut -d '"' -f 3 | grep -v "with-runtime")
CSSHARP_RUNTIME_DOWNLOAD_URL=$(echo "$RELEASE_INFO" | grep -o "browser_download_url.*linux.*\.zip" | cut -d '"' -f 3 | grep "with-runtime")
### METAMOD:SOURCE ###
printf "Downloading Metamod:Source...\n"
curl -s -L -o metamod.tar.gz "$MM_DOWNLOAD_URL"
if [ $? -eq 0 ]; then
printf "Extracting Metamod:Source to %s...\n" "$TARGET_DIR"
tar -xzf metamod.tar.gz -C "$TARGET_DIR"
rm metamod.tar.gz
else
echo "Download failed. Please check the URL and your connection."
fi
### GAMEINFO.GI UPDATE ###
NEW_ENTRY=" Game csgo/addons/metamod"
printf "Updating %s...\n" "$GAMEINFO_FILE"
if grep -Fxq "$NEW_ENTRY" "$GAMEINFO_FILE"; then
echo "The entry '$(echo $NEW_ENTRY | xargs)' already exists in ${GAMEINFO_FILE}. No changes were made."
else
awk -v new_entry="$NEW_ENTRY" '
BEGIN { found=0; }
// {
if (found) {
print new_entry;
found=0;
}
print;
}
/Game_LowViolence/ { found=1; }
' "$GAMEINFO_FILE" > "$GAMEINFO_FILE.tmp" && mv "$GAMEINFO_FILE.tmp" "$GAMEINFO_FILE"
printf "The file %s has been modified successfully. '%s' has been added.\n" "$GAMEINFO_FILE" "$(echo $NEW_ENTRY | xargs)"
fi
printf "Downloading Counter-Strike Sharp (with runtime)...\n"
# If ./game/csgo/addons/CounterStrikeSharp/dotnet/dotnet does not exist, use the runtime download url
if [ ! -f "./game/csgo/addons/CounterStrikeSharp/dotnet/dotnet" ]; then
CSSHARP_DOWNLOAD_URL="$CSSHARP_RUNTIME_DOWNLOAD_URL"
fi
curl -s -L -o cssharp.zip "$CSSHARP_DOWNLOAD_URL"
if [ $? -eq 0 ]; then
printf "Extracting Counter-Strike Sharp to %s...\n" "$TARGET_DIR"
unzip -q -o cssharp.zip -d "$TARGET_DIR"
rm cssharp.zip
else
echo "Download failed. Please check the URL and your connection."
fi

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,5 @@
#set(_ITERATOR_DEBUG_LEVEL 2)
add_definitions(-D_LINUX -DPOSIX -DLINUX -DGNUC -DCOMPILER_GCC -DPLATFORM_64BITS)
add_definitions(-D_LINUX -DPOSIX -DLINUX -DGNUC -DCOMPILER_GCC -DPLATFORM_64BITS -D_FILE_OFFSET_BITS=64)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dstrnicmp=strncasecmp -D_snprintf=snprintf")
@@ -16,16 +15,18 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-offsetof -Wno-reorder")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse -fno-strict-aliasing")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics -v -fvisibility=default")
SET(
COUNTER_STRIKE_SHARP_LINK_LIBRARIES
${SOURCESDK_LIB}/linux64/libtier0.so
${SOURCESDK_LIB}/linux64/tier1.a
${SOURCESDK_LIB}/linux64/interfaces.a
${SOURCESDK_LIB}/linux64/mathlib.a
spdlog
dynload_s
dyncall_s
distorm
funchook-static
dynohook
)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -static-libstdc++")
set(
COUNTER_STRIKE_SHARP_LINK_LIBRARIES
${SOURCESDK_LIB}/linux64/libtier0.so
${SOURCESDK_LIB}/linux64/tier1.a
${SOURCESDK_LIB}/linux64/interfaces.a
${SOURCESDK_LIB}/linux64/mathlib.a
spdlog
dynload_s
dyncall_s
distorm
funchook-static
dynohook
)

View File

@@ -1,8 +1,8 @@
if (UNIX AND NOT APPLE)
if(UNIX AND NOT APPLE)
set(LINUX TRUE)
endif()
if (WIN32 AND NOT MSVC)
if(WIN32 AND NOT MSVC)
message(FATAL "MSVC restricted.")
endif()
@@ -11,10 +11,9 @@ set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING
FORCE
)
# TODO: Use C++20 instead.
set(CMAKE_CXX_STANDARD 17)
if (LINUX)
if(LINUX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
endif()
@@ -29,6 +28,18 @@ set(SOURCESDK_LIB ${SOURCESDK}/lib)
add_definitions(-DMETA_IS_SOURCE2)
if(DEFINED ENV{GITHUB_SHA_SHORT})
add_definitions(-DGITHUB_SHA="$ENV{GITHUB_SHA_SHORT}")
else()
add_definitions(-DGITHUB_SHA="Local")
endif()
if(DEFINED ENV{BUILD_NUMBER})
add_definitions(-DBUILD_NUMBER="$ENV{BUILD_NUMBER}")
else()
add_definitions(-DBUILD_NUMBER="0")
endif()
include_directories(
${SOURCESDK}
${SOURCESDK}/thirdparty/protobuf-3.21.8/src
@@ -43,6 +54,7 @@ include_directories(
${SOURCESDK}/public/entity2
${SOURCESDK}/public/game/server
${SOURCESDK}/public/entity2
${SOURCESDK}/public/schemasystem
${METAMOD_DIR}/core
${METAMOD_DIR}/core/sourcehook
libraries/dyncall/dynload
@@ -55,4 +67,4 @@ include_directories(
libraries
)
include(${CMAKE_CURRENT_LIST_DIR}/metamod/configure_metamod.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/metamod/configure_metamod.cmake)

View File

@@ -6,6 +6,7 @@ add_definitions(
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819 /wd4828 /wd5033 /permissive- /utf-8 /wd4005 /MP")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /OPT:REF /OPT:ICF")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt")
set(COUNTER_STRIKE_SHARP_LINK_LIBRARIES
${SOURCESDK_LIB}/public/win64/tier0.lib
@@ -18,4 +19,4 @@ set(COUNTER_STRIKE_SHARP_LINK_LIBRARIES
distorm
funchook-static
dynohook
)
)

View File

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

View File

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

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -714,6 +714,37 @@ namespace CounterStrikeSharp.API.Core
}
}
public static void AcceptInput(IntPtr pthis, string inputname, IntPtr activator, IntPtr caller, string value, int outputid){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pthis);
ScriptContext.GlobalScriptContext.Push(inputname);
ScriptContext.GlobalScriptContext.Push(activator);
ScriptContext.GlobalScriptContext.Push(caller);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.Push(outputid);
ScriptContext.GlobalScriptContext.SetIdentifier(0x259E084C);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static void AddEntityIoEvent(IntPtr ptarget, string inputname, IntPtr activator, IntPtr caller, string value, float delay, int outputid){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(ptarget);
ScriptContext.GlobalScriptContext.Push(inputname);
ScriptContext.GlobalScriptContext.Push(activator);
ScriptContext.GlobalScriptContext.Push(caller);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.Push(delay);
ScriptContext.GlobalScriptContext.Push(outputid);
ScriptContext.GlobalScriptContext.SetIdentifier(0x4CFDE98A);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static void HookEvent(string name, InputArgument callback, bool ispost){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();

View File

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

View File

@@ -122,9 +122,6 @@ namespace CounterStrikeSharp.API.Core
public readonly Dictionary<Delegate, CallbackSubscriber> CommandListeners =
new Dictionary<Delegate, CallbackSubscriber>();
public readonly Dictionary<Delegate, CallbackSubscriber> ConvarChangeHandlers =
new Dictionary<Delegate, CallbackSubscriber>();
public readonly Dictionary<Delegate, CallbackSubscriber> Listeners =
new Dictionary<Delegate, CallbackSubscriber>();
@@ -159,7 +156,23 @@ namespace CounterStrikeSharp.API.Core
var name = typeof(T).GetCustomAttribute<EventNameAttribute>()?.Name;
RegisterEventHandlerInternal(name, handler, hookMode == HookMode.Post);
}
/// <summary>
/// De-registers a game event handler.
/// </summary>
/// <inheritdoc cref="RegisterEventHandler{T}"/>
public void DeregisterEventHandler<T>(GameEventHandler<T> handler, HookMode hookMode = HookMode.Post) where T : GameEvent
{
var name = typeof(T).GetCustomAttribute<EventNameAttribute>()!.Name;
if (!Handlers.TryGetValue(handler, out var subscriber)) return;
NativeAPI.UnhookEvent(name, subscriber.GetInputArgument(), hookMode == HookMode.Post);
FunctionReference.Remove(subscriber.GetReferenceIdentifier());
Handlers.Remove(handler);
}
[Obsolete("Use the generic version of this method")]
public void DeregisterEventHandler(string name, Delegate handler, bool post)
{
if (!Handlers.TryGetValue(handler, out var subscriber)) return;
@@ -187,6 +200,12 @@ namespace CounterStrikeSharp.API.Core
CommandManager.RegisterCommand(definition);
}
/// <summary>
/// Adds a command listener which will be called before or after the command is executed on the server by a player.
/// </summary>
/// <param name="name">Name of the command, e.g. `jointeam`</param>
/// <param name="handler">Code to run when command is executed. Return <see cref="HookResult.Handled"/> or higher to prevent command execution.</param>
/// <param name="mode">Whether to hook before or after the command is executed.</param>
public void AddCommandListener(string? name, CommandInfo.CommandListenerCallback handler, HookMode mode = HookMode.Pre)
{
var wrappedHandler = new Func<int, IntPtr, HookResult>((i, ptr) =>
@@ -202,6 +221,11 @@ namespace CounterStrikeSharp.API.Core
CommandListeners[handler] = subscriber;
}
/// <summary>
/// Removes a server command.
/// </summary>
/// <param name="name">The name of the command.</param>
/// <param name="handler">The callback function to be invoked when the command is executed.</param>
public void RemoveCommand(string name, CommandInfo.CommandCallback handler)
{
if (CommandHandlers.ContainsKey(handler))
@@ -215,6 +239,10 @@ namespace CounterStrikeSharp.API.Core
}
}
/// <summary>
/// Remove a command listener.
/// </summary>
/// <inheritdoc cref="AddCommandListener"/>
public void RemoveCommandListener(string name, CommandInfo.CommandListenerCallback handler, HookMode mode)
{
if (CommandListeners.ContainsKey(handler))
@@ -228,39 +256,24 @@ namespace CounterStrikeSharp.API.Core
}
}
/*
public void HookConVarChange(ConVar convar, ConVar.ConVarChangedCallback handler)
{
var wrappedHandler = new Action<IntPtr, string, string>((ptr, oldVal, newVal) =>
{
handler?.Invoke(new ConVar(ptr), oldVal, newVal);
});
var subscriber = new CallbackSubscriber(convar, handler, wrappedHandler);
NativeAPI.HookConvarChange(convar.Handle, subscriber.GetInputArgument());
ConvarChangeHandlers[handler] = subscriber;
}
public void UnhookConVarChange(ConVar convar, ConVar.ConVarChangedCallback handler)
{
if (ConvarChangeHandlers.ContainsKey(handler))
{
var subscriber = ConvarChangeHandlers[handler];
NativeAPI.UnhookConvarChange(convar.Handle, subscriber.GetInputArgument());
FunctionReference.Remove(subscriber.GetReferenceIdentifier());
CommandHandlers.Remove(handler);
}
}*/
// Adds global listener, e.g. OnTick, OnClientConnect
/// <summary>
/// Registers a global listener, e.g. <see cref="Listeners.OnTick"/>, <see cref="Listeners.OnClientConnect"/>.
/// </summary>
/// <param name="handler"></param>
/// <typeparam name="T">Listener delegate type</typeparam>
/// <exception cref="ArgumentException">Invalid listener <see cref="T"/> provided</exception>
/// <example>
/// <code lang="C#">
/// RegisterListener&lt;Listeners.OnTick&gt;(OnTick);
/// </code>
/// </example>
public void RegisterListener<T>(T handler) where T : Delegate
{
var listenerName = typeof(T).GetCustomAttribute<ListenerNameAttribute>()?.Name;
if (string.IsNullOrEmpty(listenerName))
{
throw new Exception("Listener of type T is invalid and does not have a name attribute");
throw new ArgumentException("Listener of type T is invalid and does not have a name attribute",
nameof(T));
}
var parameterTypes = typeof(T).GetMethod("Invoke").GetParameters().Select(p => p.ParameterType).ToArray();
@@ -291,6 +304,34 @@ namespace CounterStrikeSharp.API.Core
Listeners[handler] = subscriber;
}
/// <summary>
/// Removes a global listener.
/// </summary>
/// <param name="handler"></param>
/// <typeparam name="T"></typeparam>
/// <exception cref="ArgumentException">Invalid listener <see cref="T"/> provided</exception>
public void RemoveListener<T>(T handler) where T : Delegate
{
var listenerName = typeof(T).GetCustomAttribute<ListenerNameAttribute>()?.Name;
if (string.IsNullOrEmpty(listenerName))
{
throw new ArgumentException("Listener of type T is invalid and does not have a name attribute",
nameof(T));
}
if (!Listeners.TryGetValue(handler, out var subscriber)) return;
NativeAPI.RemoveListener(listenerName, subscriber.GetInputArgument());
FunctionReference.Remove(subscriber.GetReferenceIdentifier());
Listeners.Remove(handler);
}
/// <summary>
/// Removes a global listener.
/// </summary>
/// <param name="name"></param>
/// <param name="handler"></param>
[Obsolete("Use the generic version of this method")]
public void RemoveListener(string name, Delegate handler)
{
if (!Listeners.TryGetValue(handler, out var subscriber)) return;
@@ -300,6 +341,14 @@ namespace CounterStrikeSharp.API.Core
Listeners.Remove(handler);
}
/// <summary>
/// Adds a timer that will call the given callback after the specified amount of seconds.
/// By default will only run once unless the <see cref="TimerFlags.REPEAT"/> flag is set.
/// </summary>
/// <param name="interval">Interval/Delay in seconds</param>
/// <param name="callback">Code to run when timer elapses</param>
/// <param name="flags">Controls if the timer is a one-off, repeat or stops on map change etc.</param>
/// <returns>An instance of the <see cref="Timer"/></returns>
public Timer AddTimer(float interval, Action callback, TimerFlags? flags = null)
{
var timer = new Timer(interval, callback, flags ?? 0);
@@ -307,7 +356,11 @@ namespace CounterStrikeSharp.API.Core
return timer;
}
/// <summary>
/// Registers all attribute handlers on the given instance.
/// Can be used to register event handlers, console commands, entity outputs etc. from classes that are not derived from `BasePlugin`.
/// </summary>
/// <param name="instance"></param>
public void RegisterAllAttributes(object instance)
{
this.RegisterAttributeHandlers(instance);
@@ -342,7 +395,7 @@ namespace CounterStrikeSharp.API.Core
}
/// <summary>
/// Registers all game event handlers that are decorated with the `[GameEventHandler]` attribute.
/// Registers all game event handlers that are decorated with the <see cref="GameEventHandlerAttribute"/> attribute.
/// </summary>
/// <param name="instance">The instance of the object where the event handlers are defined.</param>
public void RegisterAttributeHandlers(object instance)
@@ -372,6 +425,10 @@ namespace CounterStrikeSharp.API.Core
}
}
/// <summary>
/// Registers all console command handlers that are decorated with the <see cref="ConsoleCommandAttribute"/> attribute.
/// </summary>
/// <param name="instance">The instance of the object where the console command handlers are defined.</param>
public void RegisterConsoleCommandAttributeHandlers(object instance)
{
var eventHandlers = instance.GetType()
@@ -399,6 +456,10 @@ namespace CounterStrikeSharp.API.Core
}
}
/// <summary>
/// Registers all entity output handlers that are decorated with the <see cref="EntityOutputHookAttribute"/> attribute.
/// </summary>
/// <param name="instance">The instance of the object where entity output hook handlers are defined.</param>
public void RegisterEntityOutputAttributeHandlers(object instance)
{
var handlers = instance.GetType()
@@ -453,6 +514,12 @@ namespace CounterStrikeSharp.API.Core
RegisterFakeConVars(instance.GetType(), instance);
}
/// <summary>
/// Hooks an <a href="https://developer.valvesoftware.com/wiki/Inputs_and_Outputs">entity output</a>.
/// </summary>
/// <param name="classname">Classname to hook, or `*` for wildcard</param>
/// <param name="outputName">Output name to hook, or `*` for wildcard</param>
/// <param name="handler">Handler to call</param>
public void HookEntityOutput(string classname, string outputName, EntityIO.EntityOutputHandler handler, HookMode mode = HookMode.Pre)
{
var subscriber = new CallbackSubscriber(handler, handler,
@@ -462,6 +529,10 @@ namespace CounterStrikeSharp.API.Core
EntityOutputHooks[handler] = subscriber;
}
/// <summary>
/// Unhooks an entity output.
/// </summary>
/// <inheritdoc cref="HookEntityOutput"/>
public void UnhookEntityOutput(string classname, string outputName, EntityIO.EntityOutputHandler handler, HookMode mode = HookMode.Pre)
{
if (!EntityOutputHooks.TryGetValue(handler, out var subscriber)) return;
@@ -471,6 +542,12 @@ namespace CounterStrikeSharp.API.Core
EntityOutputHooks.Remove(handler);
}
/// <summary>
/// Hooks an entity output for a single entity instance.
/// </summary>
/// <param name="entityInstance">Entity instance to hook</param>
/// <param name="outputName">Output name to hook, or `*` for wildcard</param>
/// <param name="handler">Handler to call</param>
public void HookSingleEntityOutput(CEntityInstance entityInstance, string outputName, EntityIO.EntityOutputHandler handler)
{
// since we wrap around the plugin handler we need to do this to ensure that the plugin callback is only called
@@ -494,6 +571,10 @@ namespace CounterStrikeSharp.API.Core
EntitySingleOutputHooks[handler] = new EntityIO.EntityOutputCallback(entityInstance.DesignerName, outputName, internalHandler);
}
/// <summary>
/// Unhooks an entity output for a single entity instance.
/// </summary>
/// <inheritdoc cref="HookSingleEntityOutput"/>
public void UnhookSingleEntityOutput(CEntityInstance entityInstance, string outputName, EntityIO.EntityOutputHandler handler)
{
UnhookSingleEntityOutputInternal(entityInstance.DesignerName, outputName, handler);
@@ -532,10 +613,6 @@ namespace CounterStrikeSharp.API.Core
subscriber.Dispose();
}
foreach (var kv in ConvarChangeHandlers)
{
}
foreach (var subscriber in Listeners.Values)
{
subscriber.Dispose();

File diff suppressed because it is too large Load Diff

View File

@@ -28,17 +28,23 @@ namespace CounterStrikeSharp.API.Core
public interface IPlugin : IDisposable
{
/// <summary>
/// Name of the plugin.
/// Name of the plugin as it will appear in the plugin list.
/// </summary>
string ModuleName { get; }
/// <summary>
/// Module version.
/// Module version as it will appear in the plugin list.
/// </summary>
string ModuleVersion { get; }
/// <summary>
/// Author of the plugin as it will appear in the plugin list.
/// </summary>
string ModuleAuthor { get; }
/// <summary>
/// Brief description of the plugin as it will appear in the plugin list.
/// </summary>
string ModuleDescription { get; }
/// <summary>
@@ -61,12 +67,15 @@ namespace CounterStrikeSharp.API.Core
/// <param name="hotReload"></param>
void OnAllPluginsLoaded(bool hotReload);
/// <summary>
/// The path to the plugin's DLL file.
/// </summary>
string ModulePath { get; internal set; }
ILogger Logger { get; set; }
IStringLocalizer Localizer { get; set; }
ICommandManager CommandManager { get; set; }
void RegisterAllAttributes(object instance);

View File

@@ -8,10 +8,14 @@ namespace CounterStrikeSharp.API.Core;
public partial class CBaseEntity
{
/// <exception cref="InvalidOperationException">Entity is not valid</exception>
public void Teleport(Vector position, QAngle angles, Vector velocity)
public void Teleport(Vector? position = null, QAngle? angles = null, Vector? velocity = null)
{
Guard.IsValidEntity(this);
position ??= AbsOrigin!;
angles ??= AbsRotation!;
velocity ??= AbsVelocity;
VirtualFunction.CreateVoid<IntPtr, IntPtr, IntPtr, IntPtr>(Handle, GameData.GetOffset("CBaseEntity_Teleport"))(
Handle, position.Handle, angles.Handle, velocity.Handle);
}
@@ -39,6 +43,6 @@ public partial class CBaseEntity
{
Guard.IsValidEntity(this);
return (T) Activator.CreateInstance(typeof(T), Marshal.ReadIntPtr(SubclassID.Handle + 4));
return (T)Activator.CreateInstance(typeof(T), Marshal.ReadIntPtr(SubclassID.Handle + 4));
}
}

View File

@@ -16,17 +16,17 @@ public partial class CCSPlayerController
/// <exception cref="InvalidOperationException">Entity is not valid</exception>
public IntPtr GiveNamedItem(string item)
{
Guard.IsValidEntity(this);
if (!PlayerPawn.IsValid) return 0;
if (PlayerPawn.Value == null) return 0;
if (!PlayerPawn.Value.IsValid) return 0;
if (PlayerPawn.Value.ItemServices == null) return 0;
return VirtualFunctions.GiveNamedItem(PlayerPawn.Value.ItemServices.Handle, item, 0, 0, 0, 0);
return GiveNamedItem<CEntityInstance>(item)?.Handle ?? IntPtr.Zero;
}
public IntPtr GiveNamedItem(CsItem item)
public T? GiveNamedItem<T>(string item) where T : CEntityInstance
{
Guard.IsValidEntity(this);
return PlayerPawn.Value?.ItemServices?.As<CCSPlayer_ItemServices>().GiveNamedItem<T>(item);
}
public IntPtr GiveNamedItem(CsItem item)
{
string? itemString = EnumUtils.GetEnumMemberAttributeValue(item);
if (string.IsNullOrWhiteSpace(itemString))
@@ -61,6 +61,14 @@ public partial class CCSPlayerController
VirtualFunctions.ClientPrint(Handle, HudDestination.Center, message, 0, 0, 0, 0);
}
/// <exception cref="InvalidOperationException">Entity is not valid</exception>
public void PrintToCenterAlert(string message)
{
Guard.IsValidEntity(this);
VirtualFunctions.ClientPrint(Handle, HudDestination.Alert, message, 0, 0, 0, 0);
}
public void PrintToCenterHtml(string message) => PrintToCenterHtml(message, 5);
/// <exception cref="InvalidOperationException">Entity is not valid</exception>
@@ -85,17 +93,13 @@ public partial class CCSPlayerController
public void DropActiveWeapon()
{
Guard.IsValidEntity(this);
if (!PlayerPawn.IsValid) return;
if (PlayerPawn.Value == null) return;
if (!PlayerPawn.Value.IsValid) return;
if (PlayerPawn.Value.ItemServices == null) return;
if (PlayerPawn.Value.WeaponServices == null) return;
if (!PlayerPawn.Value.WeaponServices.ActiveWeapon.IsValid) return;
CCSPlayer_ItemServices itemServices = new CCSPlayer_ItemServices(PlayerPawn.Value.ItemServices.Handle);
CCSPlayer_WeaponServices weaponServices = new CCSPlayer_WeaponServices(PlayerPawn.Value.WeaponServices.Handle);
itemServices.DropActivePlayerWeapon(weaponServices.ActiveWeapon.Value);
var itemServices = PlayerPawn.Value?.ItemServices?.As<CCSPlayer_ItemServices>();
var activeWeapon = PlayerPawn.Value?.WeaponServices?.ActiveWeapon.Value;
if (activeWeapon == null || itemServices == null) return;
itemServices.DropActivePlayerWeapon(activeWeapon);
}
/// <summary>
@@ -105,13 +109,8 @@ public partial class CCSPlayerController
public void RemoveWeapons()
{
Guard.IsValidEntity(this);
if (!PlayerPawn.IsValid) return;
if (PlayerPawn.Value == null) return;
if (!PlayerPawn.Value.IsValid) return;
if (PlayerPawn.Value.ItemServices == null) return;
CCSPlayer_ItemServices itemServices = new CCSPlayer_ItemServices(PlayerPawn.Value.ItemServices.Handle);
itemServices.RemoveWeapons();
PlayerPawn.Value?.ItemServices?.As<CCSPlayer_ItemServices>().RemoveWeapons();
}
/// <summary>
@@ -123,11 +122,8 @@ public partial class CCSPlayerController
public void CommitSuicide(bool explode, bool force)
{
Guard.IsValidEntity(this);
if (!PlayerPawn.IsValid) return;
if (PlayerPawn.Value == null) return;
if (!PlayerPawn.Value.IsValid) return;
PlayerPawn.Value.CommitSuicide(explode, force);
PlayerPawn.Value?.CommitSuicide(explode, force);
}
/// <summary>
@@ -137,9 +133,7 @@ public partial class CCSPlayerController
public void Respawn()
{
Guard.IsValidEntity(this);
if (!PlayerPawn.IsValid) return;
if (PlayerPawn.Value == null) return;
if (!PlayerPawn.Value.IsValid) return;
// The Call To Arms update appears to have invalidated the need for CCSPlayerPawn_Respawn.
SetPawn(PlayerPawn.Value);

View File

@@ -45,4 +45,13 @@ public partial class CCSPlayer_ItemServices
VirtualFunction.CreateVoid<nint>(Handle, GameData.GetOffset("CCSPlayer_ItemServices_RemoveWeapons"))(Handle);
}
}
public T? GiveNamedItem<T>(string item) where T : CEntityInstance
{
var pointer = VirtualFunction.Create<nint, string, nint>(Handle, GameData.GetOffset("CCSPlayer_ItemServices_GiveNamedItem"))(Handle, item);
if (pointer == IntPtr.Zero)
return null;
return (T)Activator.CreateInstance(typeof(T), pointer)!;
}
}

View File

@@ -65,7 +65,7 @@ public partial class CEntityInstance : IEquatable<CEntityInstance>
}
/// <summary>
/// Calls a named input method on an entity.
/// Calls a named input method on an entity, this will bypass the map IO event queue system.
/// <example>
/// <code>
/// entity.AcceptInput("Break");
@@ -82,7 +82,30 @@ public partial class CEntityInstance : IEquatable<CEntityInstance>
{
Guard.IsValidEntity(this);
VirtualFunctions.AcceptInput(Handle, inputName, activator?.Handle ?? IntPtr.Zero, caller?.Handle ?? IntPtr.Zero, value, 0);
NativeAPI.AcceptInput(Handle, inputName, activator?.Handle ?? IntPtr.Zero, caller?.Handle ?? IntPtr.Zero, value, outputId);
}
/// <summary>
/// Calls a named input method on an entity, conforming to the map IO event queue system.
/// <example>
/// <code>
/// entity.AddEntityIOEvent("Break");
/// </code>
/// </example>
/// </summary>
/// <param name="inputName">Input action name</param>
/// <param name="activator">Entity which initiated the action, <see langword="null"/> for no entity</param>
/// <param name="caller">Entity that is sending the event, <see langword="null"/> for no entity</param>
/// <param name="value">String variant value to send with the event</param>
/// <param name="delay">Delay in seconds before calling the input</param>
/// <param name="outputId">Unknown, defaults to 0</param>
/// <exception cref="InvalidOperationException">Entity is not valid</exception>
public void AddEntityIOEvent(string inputName, CEntityInstance? activator = null, CEntityInstance? caller = null, string value = "", float delay = 0, int outputId = 0)
{
Guard.IsValidEntity(this);
NativeAPI.AddEntityIoEvent(Handle, inputName, activator?.Handle ?? IntPtr.Zero, caller?.Handle ?? IntPtr.Zero, value, delay, outputId);
}
}
@@ -90,4 +113,4 @@ public partial class CEntityIdentity
{
public unsafe CEntityInstance EntityInstance => new(Unsafe.Read<IntPtr>((void*)Handle));
public unsafe CHandle<CEntityInstance> EntityHandle => new(this.Handle + 0x10);
}
}

View File

@@ -36,7 +36,7 @@ public class PluginManager : IPluginManager
config => { config.PreferSharedTypes = true; });
var assembly = loader.LoadDefaultAssembly();
_sharedAssemblies[assembly.GetName().FullName] = assembly;
_sharedAssemblies[assembly.GetName().Name] = assembly;
}
private void LoadSharedLibraries()
@@ -76,7 +76,7 @@ public class PluginManager : IPluginManager
_loadedSharedLibs = true;
}
if (!_sharedAssemblies.TryGetValue(name.FullName, out var assembly))
if (!_sharedAssemblies.TryGetValue(name.Name, out var assembly))
{
return null;
}
@@ -124,4 +124,4 @@ public class PluginManager : IPluginManager
_loadedPluginContexts.Add(plugin);
plugin.Load();
}
}
}

View File

@@ -54,6 +54,10 @@ public partial class CBaseCSGrenade : CCSWeaponBase
[SchemaMember("CBaseCSGrenade", "m_fDropTime")]
public ref float DropTime => ref Schema.GetRef<float>(this.Handle, "CBaseCSGrenade", "m_fDropTime");
// m_fPinPullTime
[SchemaMember("CBaseCSGrenade", "m_fPinPullTime")]
public ref float PinPullTime => ref Schema.GetRef<float>(this.Handle, "CBaseCSGrenade", "m_fPinPullTime");
// m_bJustPulledPin
[SchemaMember("CBaseCSGrenade", "m_bJustPulledPin")]
public ref bool JustPulledPin => ref Schema.GetRef<bool>(this.Handle, "CBaseCSGrenade", "m_bJustPulledPin");

View File

@@ -31,7 +31,7 @@ public partial class CBaseIssue : NativeObject
public string DetailsString
{
get { return Schema.GetString(this.Handle, "CBaseIssue", "m_szDetailsString"); }
set { Schema.SetStringBytes(this.Handle, "CBaseIssue", "m_szDetailsString", value, 260); }
set { Schema.SetStringBytes(this.Handle, "CBaseIssue", "m_szDetailsString", value, 4096); }
}
// m_iNumYesVotes

View File

@@ -62,8 +62,4 @@ public partial class CC4 : CCSWeaponBase
[SchemaMember("CC4", "m_bBombPlanted")]
public ref bool BombPlanted => ref Schema.GetRef<bool>(this.Handle, "CC4", "m_bBombPlanted");
// m_bDroppedFromDeath
[SchemaMember("CC4", "m_bDroppedFromDeath")]
public ref bool DroppedFromDeath => ref Schema.GetRef<bool>(this.Handle, "CC4", "m_bDroppedFromDeath");
}

View File

@@ -450,6 +450,10 @@ public partial class CCSGameRules : CTeamplayRules
[SchemaMember("CCSGameRules", "m_arrSelectedHostageSpawnIndices")]
public NetworkedVector<Int32> SelectedHostageSpawnIndices => Schema.GetDeclaredClass<NetworkedVector<Int32>>(this.Handle, "CCSGameRules", "m_arrSelectedHostageSpawnIndices");
// m_nSpawnPointsRandomSeed
[SchemaMember("CCSGameRules", "m_nSpawnPointsRandomSeed")]
public ref Int32 SpawnPointsRandomSeed => ref Schema.GetRef<Int32>(this.Handle, "CCSGameRules", "m_nSpawnPointsRandomSeed");
// m_bFirstConnected
[SchemaMember("CCSGameRules", "m_bFirstConnected")]
public ref bool FirstConnected => ref Schema.GetRef<bool>(this.Handle, "CCSGameRules", "m_bFirstConnected");
@@ -482,6 +486,10 @@ public partial class CCSGameRules : CTeamplayRules
[SchemaMember("CCSGameRules", "m_numQueuedMatchmakingAccounts")]
public ref UInt32 NumQueuedMatchmakingAccounts => ref Schema.GetRef<UInt32>(this.Handle, "CCSGameRules", "m_numQueuedMatchmakingAccounts");
// m_fAvgPlayerRank
[SchemaMember("CCSGameRules", "m_fAvgPlayerRank")]
public ref float AvgPlayerRank => ref Schema.GetRef<float>(this.Handle, "CCSGameRules", "m_fAvgPlayerRank");
// m_pQueuedMatchmakingReservationString
[SchemaMember("CCSGameRules", "m_pQueuedMatchmakingReservationString")]
public string QueuedMatchmakingReservationString
@@ -686,14 +694,26 @@ public partial class CCSGameRules : CTeamplayRules
[SchemaMember("CCSGameRules", "m_TerroristSpawnPointsMasterList")]
public NetworkedVector<SpawnPoint?> TerroristSpawnPointsMasterList => Schema.GetDeclaredClass<NetworkedVector<SpawnPoint?>>(this.Handle, "CCSGameRules", "m_TerroristSpawnPointsMasterList");
// m_bRespawningAllRespawnablePlayers
[SchemaMember("CCSGameRules", "m_bRespawningAllRespawnablePlayers")]
public ref bool RespawningAllRespawnablePlayers => ref Schema.GetRef<bool>(this.Handle, "CCSGameRules", "m_bRespawningAllRespawnablePlayers");
// m_iNextCTSpawnPoint
[SchemaMember("CCSGameRules", "m_iNextCTSpawnPoint")]
public ref Int32 NextCTSpawnPoint => ref Schema.GetRef<Int32>(this.Handle, "CCSGameRules", "m_iNextCTSpawnPoint");
// m_flCTSpawnPointUsedTime
[SchemaMember("CCSGameRules", "m_flCTSpawnPointUsedTime")]
public ref float CTSpawnPointUsedTime => ref Schema.GetRef<float>(this.Handle, "CCSGameRules", "m_flCTSpawnPointUsedTime");
// m_iNextTerroristSpawnPoint
[SchemaMember("CCSGameRules", "m_iNextTerroristSpawnPoint")]
public ref Int32 NextTerroristSpawnPoint => ref Schema.GetRef<Int32>(this.Handle, "CCSGameRules", "m_iNextTerroristSpawnPoint");
// m_flTerroristSpawnPointUsedTime
[SchemaMember("CCSGameRules", "m_flTerroristSpawnPointUsedTime")]
public ref float TerroristSpawnPointUsedTime => ref Schema.GetRef<float>(this.Handle, "CCSGameRules", "m_flTerroristSpawnPointUsedTime");
// m_CTSpawnPoints
[SchemaMember("CCSGameRules", "m_CTSpawnPoints")]
public NetworkedVector<SpawnPoint?> CTSpawnPoints => Schema.GetDeclaredClass<NetworkedVector<SpawnPoint?>>(this.Handle, "CCSGameRules", "m_CTSpawnPoints");
@@ -878,10 +898,6 @@ public partial class CCSGameRules : CTeamplayRules
[SchemaMember("CCSGameRules", "m_nRoundStartCount")]
public ref byte RoundStartCount => ref Schema.GetRef<byte>(this.Handle, "CCSGameRules", "m_nRoundStartCount");
// m_nRoundStartTicks
[SchemaMember("CCSGameRules", "m_nRoundStartTicks")]
public NetworkedVector<Int32> RoundStartTicks => Schema.GetDeclaredClass<NetworkedVector<Int32>>(this.Handle, "CCSGameRules", "m_nRoundStartTicks");
// m_flLastPerfSampleTime
[SchemaMember("CCSGameRules", "m_flLastPerfSampleTime")]
public ref double LastPerfSampleTime => ref Schema.GetRef<double>(this.Handle, "CCSGameRules", "m_flLastPerfSampleTime");

View File

@@ -294,6 +294,22 @@ public partial class CCSPlayerController : CBasePlayerController
[SchemaMember("CCSPlayerController", "m_vecKills")]
public NetworkedVector<EKillTypes_t> Kills => Schema.GetDeclaredClass<NetworkedVector<EKillTypes_t>>(this.Handle, "CCSPlayerController", "m_vecKills");
// m_bMvpNoMusic
[SchemaMember("CCSPlayerController", "m_bMvpNoMusic")]
public ref bool MvpNoMusic => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerController", "m_bMvpNoMusic");
// m_eMvpReason
[SchemaMember("CCSPlayerController", "m_eMvpReason")]
public ref Int32 MvpReason => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerController", "m_eMvpReason");
// m_iMusicKitID
[SchemaMember("CCSPlayerController", "m_iMusicKitID")]
public ref Int32 MusicKitID => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerController", "m_iMusicKitID");
// m_iMusicKitMVPs
[SchemaMember("CCSPlayerController", "m_iMusicKitMVPs")]
public ref Int32 MusicKitMVPs => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerController", "m_iMusicKitMVPs");
// m_iMVPs
[SchemaMember("CCSPlayerController", "m_iMVPs")]
public ref Int32 MVPs => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerController", "m_iMVPs");

View File

@@ -22,9 +22,9 @@ public partial class CCSPlayerController_InGameMoneyServices : CPlayerController
[SchemaMember("CCSPlayerController_InGameMoneyServices", "m_bReceivesMoneyNextRound")]
public ref bool ReceivesMoneyNextRound => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerController_InGameMoneyServices", "m_bReceivesMoneyNextRound");
// m_iAccountMoneyEarnedForNextRound
[SchemaMember("CCSPlayerController_InGameMoneyServices", "m_iAccountMoneyEarnedForNextRound")]
public ref Int32 AccountMoneyEarnedForNextRound => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerController_InGameMoneyServices", "m_iAccountMoneyEarnedForNextRound");
// m_iMoneyEarnedForNextRound
[SchemaMember("CCSPlayerController_InGameMoneyServices", "m_iMoneyEarnedForNextRound")]
public ref Int32 MoneyEarnedForNextRound => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerController_InGameMoneyServices", "m_iMoneyEarnedForNextRound");
// m_iAccount
[SchemaMember("CCSPlayerController_InGameMoneyServices", "m_iAccount")]

View File

@@ -46,10 +46,6 @@ public partial class CCSPlayerPawn : CCSPlayerPawnBase
[SchemaMember("CCSPlayerPawn", "m_nCharacterDefIndex")]
public ref UInt16 CharacterDefIndex => ref Schema.GetRef<UInt16>(this.Handle, "CCSPlayerPawn", "m_nCharacterDefIndex");
// m_hPreviousModel
[SchemaMember("CCSPlayerPawn", "m_hPreviousModel")]
public CStrongHandle<InfoForResourceTypeCModel> PreviousModel => Schema.GetDeclaredClass<CStrongHandle<InfoForResourceTypeCModel>>(this.Handle, "CCSPlayerPawn", "m_hPreviousModel");
// m_bHasFemaleVoice
[SchemaMember("CCSPlayerPawn", "m_bHasFemaleVoice")]
public ref bool HasFemaleVoice => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bHasFemaleVoice");
@@ -78,6 +74,10 @@ public partial class CCSPlayerPawn : CCSPlayerPawnBase
[SchemaMember("CCSPlayerPawn", "m_bInBuyZone")]
public ref bool InBuyZone => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bInBuyZone");
// m_TouchingBuyZones
[SchemaMember("CCSPlayerPawn", "m_TouchingBuyZones")]
public NetworkedVector<CHandle<CBaseEntity>> TouchingBuyZones => Schema.GetDeclaredClass<NetworkedVector<CHandle<CBaseEntity>>>(this.Handle, "CCSPlayerPawn", "m_TouchingBuyZones");
// m_bWasInBuyZone
[SchemaMember("CCSPlayerPawn", "m_bWasInBuyZone")]
public ref bool WasInBuyZone => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bWasInBuyZone");
@@ -122,9 +122,9 @@ public partial class CCSPlayerPawn : CCSPlayerPawnBase
[SchemaMember("CCSPlayerPawn", "m_flHealthShotBoostExpirationTime")]
public ref float HealthShotBoostExpirationTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flHealthShotBoostExpirationTime");
// m_flLandseconds
[SchemaMember("CCSPlayerPawn", "m_flLandseconds")]
public ref float Landseconds => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flLandseconds");
// m_flLandingTimeSeconds
[SchemaMember("CCSPlayerPawn", "m_flLandingTimeSeconds")]
public ref float LandingTimeSeconds => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flLandingTimeSeconds");
// m_aimPunchAngle
[SchemaMember("CCSPlayerPawn", "m_aimPunchAngle")]
@@ -226,4 +226,284 @@ public partial class CCSPlayerPawn : CCSPlayerPawnBase
[SchemaMember("CCSPlayerPawn", "m_bSkipOneHeadConstraintUpdate")]
public ref bool SkipOneHeadConstraintUpdate => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bSkipOneHeadConstraintUpdate");
// m_bLeftHanded
[SchemaMember("CCSPlayerPawn", "m_bLeftHanded")]
public ref bool LeftHanded => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bLeftHanded");
// m_fSwitchedHandednessTime
[SchemaMember("CCSPlayerPawn", "m_fSwitchedHandednessTime")]
public ref float SwitchedHandednessTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_fSwitchedHandednessTime");
// m_flViewmodelOffsetX
[SchemaMember("CCSPlayerPawn", "m_flViewmodelOffsetX")]
public ref float ViewmodelOffsetX => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flViewmodelOffsetX");
// m_flViewmodelOffsetY
[SchemaMember("CCSPlayerPawn", "m_flViewmodelOffsetY")]
public ref float ViewmodelOffsetY => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flViewmodelOffsetY");
// m_flViewmodelOffsetZ
[SchemaMember("CCSPlayerPawn", "m_flViewmodelOffsetZ")]
public ref float ViewmodelOffsetZ => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flViewmodelOffsetZ");
// m_flViewmodelFOV
[SchemaMember("CCSPlayerPawn", "m_flViewmodelFOV")]
public ref float ViewmodelFOV => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flViewmodelFOV");
// m_bIsWalking
[SchemaMember("CCSPlayerPawn", "m_bIsWalking")]
public ref bool IsWalking => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bIsWalking");
// m_fLastGivenDefuserTime
[SchemaMember("CCSPlayerPawn", "m_fLastGivenDefuserTime")]
public ref float LastGivenDefuserTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_fLastGivenDefuserTime");
// m_fLastGivenBombTime
[SchemaMember("CCSPlayerPawn", "m_fLastGivenBombTime")]
public ref float LastGivenBombTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_fLastGivenBombTime");
// m_flDealtDamageToEnemyMostRecentTimestamp
[SchemaMember("CCSPlayerPawn", "m_flDealtDamageToEnemyMostRecentTimestamp")]
public ref float DealtDamageToEnemyMostRecentTimestamp => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flDealtDamageToEnemyMostRecentTimestamp");
// m_iDisplayHistoryBits
[SchemaMember("CCSPlayerPawn", "m_iDisplayHistoryBits")]
public ref UInt32 DisplayHistoryBits => ref Schema.GetRef<UInt32>(this.Handle, "CCSPlayerPawn", "m_iDisplayHistoryBits");
// m_flLastAttackedTeammate
[SchemaMember("CCSPlayerPawn", "m_flLastAttackedTeammate")]
public ref float LastAttackedTeammate => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flLastAttackedTeammate");
// m_allowAutoFollowTime
[SchemaMember("CCSPlayerPawn", "m_allowAutoFollowTime")]
public ref float AllowAutoFollowTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_allowAutoFollowTime");
// m_bResetArmorNextSpawn
[SchemaMember("CCSPlayerPawn", "m_bResetArmorNextSpawn")]
public ref bool ResetArmorNextSpawn => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bResetArmorNextSpawn");
// m_nLastKillerIndex
[SchemaMember("CCSPlayerPawn", "m_nLastKillerIndex")]
public CEntityIndex LastKillerIndex => Schema.GetDeclaredClass<CEntityIndex>(this.Handle, "CCSPlayerPawn", "m_nLastKillerIndex");
// m_entitySpottedState
[SchemaMember("CCSPlayerPawn", "m_entitySpottedState")]
public EntitySpottedState_t EntitySpottedState => Schema.GetDeclaredClass<EntitySpottedState_t>(this.Handle, "CCSPlayerPawn", "m_entitySpottedState");
// m_nSpotRules
[SchemaMember("CCSPlayerPawn", "m_nSpotRules")]
public ref Int32 SpotRules => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_nSpotRules");
// m_bIsScoped
[SchemaMember("CCSPlayerPawn", "m_bIsScoped")]
public ref bool IsScoped => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bIsScoped");
// m_bResumeZoom
[SchemaMember("CCSPlayerPawn", "m_bResumeZoom")]
public ref bool ResumeZoom => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bResumeZoom");
// m_bIsDefusing
[SchemaMember("CCSPlayerPawn", "m_bIsDefusing")]
public ref bool IsDefusing => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bIsDefusing");
// m_bIsGrabbingHostage
[SchemaMember("CCSPlayerPawn", "m_bIsGrabbingHostage")]
public ref bool IsGrabbingHostage => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bIsGrabbingHostage");
// m_iBlockingUseActionInProgress
[SchemaMember("CCSPlayerPawn", "m_iBlockingUseActionInProgress")]
public ref CSPlayerBlockingUseAction_t BlockingUseActionInProgress => ref Schema.GetRef<CSPlayerBlockingUseAction_t>(this.Handle, "CCSPlayerPawn", "m_iBlockingUseActionInProgress");
// m_flEmitSoundTime
[SchemaMember("CCSPlayerPawn", "m_flEmitSoundTime")]
public ref float EmitSoundTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flEmitSoundTime");
// m_bInNoDefuseArea
[SchemaMember("CCSPlayerPawn", "m_bInNoDefuseArea")]
public ref bool InNoDefuseArea => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bInNoDefuseArea");
// m_iBombSiteIndex
[SchemaMember("CCSPlayerPawn", "m_iBombSiteIndex")]
public CEntityIndex BombSiteIndex => Schema.GetDeclaredClass<CEntityIndex>(this.Handle, "CCSPlayerPawn", "m_iBombSiteIndex");
// m_nWhichBombZone
[SchemaMember("CCSPlayerPawn", "m_nWhichBombZone")]
public ref Int32 WhichBombZone => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_nWhichBombZone");
// m_bInBombZoneTrigger
[SchemaMember("CCSPlayerPawn", "m_bInBombZoneTrigger")]
public ref bool InBombZoneTrigger => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bInBombZoneTrigger");
// m_bWasInBombZoneTrigger
[SchemaMember("CCSPlayerPawn", "m_bWasInBombZoneTrigger")]
public ref bool WasInBombZoneTrigger => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bWasInBombZoneTrigger");
// m_iShotsFired
[SchemaMember("CCSPlayerPawn", "m_iShotsFired")]
public ref Int32 ShotsFired => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_iShotsFired");
// m_flFlinchStack
[SchemaMember("CCSPlayerPawn", "m_flFlinchStack")]
public ref float FlinchStack => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flFlinchStack");
// m_flVelocityModifier
[SchemaMember("CCSPlayerPawn", "m_flVelocityModifier")]
public ref float VelocityModifier => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flVelocityModifier");
// m_flHitHeading
[SchemaMember("CCSPlayerPawn", "m_flHitHeading")]
public ref float HitHeading => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flHitHeading");
// m_nHitBodyPart
[SchemaMember("CCSPlayerPawn", "m_nHitBodyPart")]
public ref Int32 HitBodyPart => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_nHitBodyPart");
// m_vecTotalBulletForce
[SchemaMember("CCSPlayerPawn", "m_vecTotalBulletForce")]
public Vector TotalBulletForce => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawn", "m_vecTotalBulletForce");
// m_bWaitForNoAttack
[SchemaMember("CCSPlayerPawn", "m_bWaitForNoAttack")]
public ref bool WaitForNoAttack => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bWaitForNoAttack");
// m_ignoreLadderJumpTime
[SchemaMember("CCSPlayerPawn", "m_ignoreLadderJumpTime")]
public ref float IgnoreLadderJumpTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_ignoreLadderJumpTime");
// m_NumEnemiesKilledThisRound
[SchemaMember("CCSPlayerPawn", "m_NumEnemiesKilledThisRound")]
public ref Int32 NumEnemiesKilledThisRound => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_NumEnemiesKilledThisRound");
// m_bKilledByHeadshot
[SchemaMember("CCSPlayerPawn", "m_bKilledByHeadshot")]
public ref bool KilledByHeadshot => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bKilledByHeadshot");
// m_LastHitBox
[SchemaMember("CCSPlayerPawn", "m_LastHitBox")]
public ref Int32 LastHitBox => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_LastHitBox");
// m_LastHealth
[SchemaMember("CCSPlayerPawn", "m_LastHealth")]
public ref Int32 LastHealth => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_LastHealth");
// m_pBot
[SchemaMember("CCSPlayerPawn", "m_pBot")]
public CCSBot? Bot => Schema.GetPointer<CCSBot>(this.Handle, "CCSPlayerPawn", "m_pBot");
// m_bBotAllowActive
[SchemaMember("CCSPlayerPawn", "m_bBotAllowActive")]
public ref bool BotAllowActive => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bBotAllowActive");
// m_thirdPersonHeading
[SchemaMember("CCSPlayerPawn", "m_thirdPersonHeading")]
public QAngle ThirdPersonHeading => Schema.GetDeclaredClass<QAngle>(this.Handle, "CCSPlayerPawn", "m_thirdPersonHeading");
// m_flSlopeDropOffset
[SchemaMember("CCSPlayerPawn", "m_flSlopeDropOffset")]
public ref float SlopeDropOffset => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flSlopeDropOffset");
// m_flSlopeDropHeight
[SchemaMember("CCSPlayerPawn", "m_flSlopeDropHeight")]
public ref float SlopeDropHeight => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flSlopeDropHeight");
// m_vHeadConstraintOffset
[SchemaMember("CCSPlayerPawn", "m_vHeadConstraintOffset")]
public Vector HeadConstraintOffset => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawn", "m_vHeadConstraintOffset");
// m_nLastPickupPriority
[SchemaMember("CCSPlayerPawn", "m_nLastPickupPriority")]
public ref Int32 LastPickupPriority => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_nLastPickupPriority");
// m_flLastPickupPriorityTime
[SchemaMember("CCSPlayerPawn", "m_flLastPickupPriorityTime")]
public ref float LastPickupPriorityTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flLastPickupPriorityTime");
// m_ArmorValue
[SchemaMember("CCSPlayerPawn", "m_ArmorValue")]
public ref Int32 ArmorValue => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_ArmorValue");
// m_unCurrentEquipmentValue
[SchemaMember("CCSPlayerPawn", "m_unCurrentEquipmentValue")]
public ref UInt16 CurrentEquipmentValue => ref Schema.GetRef<UInt16>(this.Handle, "CCSPlayerPawn", "m_unCurrentEquipmentValue");
// m_unRoundStartEquipmentValue
[SchemaMember("CCSPlayerPawn", "m_unRoundStartEquipmentValue")]
public ref UInt16 RoundStartEquipmentValue => ref Schema.GetRef<UInt16>(this.Handle, "CCSPlayerPawn", "m_unRoundStartEquipmentValue");
// m_unFreezetimeEndEquipmentValue
[SchemaMember("CCSPlayerPawn", "m_unFreezetimeEndEquipmentValue")]
public ref UInt16 FreezetimeEndEquipmentValue => ref Schema.GetRef<UInt16>(this.Handle, "CCSPlayerPawn", "m_unFreezetimeEndEquipmentValue");
// m_iLastWeaponFireUsercmd
[SchemaMember("CCSPlayerPawn", "m_iLastWeaponFireUsercmd")]
public ref Int32 LastWeaponFireUsercmd => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_iLastWeaponFireUsercmd");
// m_flLastFriendlyFireDamageReductionRatio
[SchemaMember("CCSPlayerPawn", "m_flLastFriendlyFireDamageReductionRatio")]
public ref float LastFriendlyFireDamageReductionRatio => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flLastFriendlyFireDamageReductionRatio");
// m_bIsSpawning
[SchemaMember("CCSPlayerPawn", "m_bIsSpawning")]
public ref bool IsSpawning => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bIsSpawning");
// m_iDeathFlags
[SchemaMember("CCSPlayerPawn", "m_iDeathFlags")]
public ref Int32 DeathFlags => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_iDeathFlags");
// m_bHasDeathInfo
[SchemaMember("CCSPlayerPawn", "m_bHasDeathInfo")]
public ref bool HasDeathInfo => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bHasDeathInfo");
// m_flDeathInfoTime
[SchemaMember("CCSPlayerPawn", "m_flDeathInfoTime")]
public ref float DeathInfoTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_flDeathInfoTime");
// m_vecDeathInfoOrigin
[SchemaMember("CCSPlayerPawn", "m_vecDeathInfoOrigin")]
public Vector DeathInfoOrigin => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawn", "m_vecDeathInfoOrigin");
// m_vecPlayerPatchEconIndices
[SchemaMember("CCSPlayerPawn", "m_vecPlayerPatchEconIndices")]
public Span<UInt32> PlayerPatchEconIndices => Schema.GetFixedArray<UInt32>(this.Handle, "CCSPlayerPawn", "m_vecPlayerPatchEconIndices", 5);
// m_GunGameImmunityColor
[SchemaMember("CCSPlayerPawn", "m_GunGameImmunityColor")]
public Color GunGameImmunityColor
{
get { return Schema.GetCustomMarshalledType<Color>(this.Handle, "CCSPlayerPawn", "m_GunGameImmunityColor"); }
set { Schema.SetCustomMarshalledType<Color>(this.Handle, "CCSPlayerPawn", "m_GunGameImmunityColor", value); }
}
// m_grenadeParameterStashTime
[SchemaMember("CCSPlayerPawn", "m_grenadeParameterStashTime")]
public ref float GrenadeParameterStashTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_grenadeParameterStashTime");
// m_bGrenadeParametersStashed
[SchemaMember("CCSPlayerPawn", "m_bGrenadeParametersStashed")]
public ref bool GrenadeParametersStashed => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bGrenadeParametersStashed");
// m_angStashedShootAngles
[SchemaMember("CCSPlayerPawn", "m_angStashedShootAngles")]
public QAngle StashedShootAngles => Schema.GetDeclaredClass<QAngle>(this.Handle, "CCSPlayerPawn", "m_angStashedShootAngles");
// m_vecStashedGrenadeThrowPosition
[SchemaMember("CCSPlayerPawn", "m_vecStashedGrenadeThrowPosition")]
public Vector StashedGrenadeThrowPosition => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawn", "m_vecStashedGrenadeThrowPosition");
// m_vecStashedVelocity
[SchemaMember("CCSPlayerPawn", "m_vecStashedVelocity")]
public Vector StashedVelocity => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawn", "m_vecStashedVelocity");
// m_angShootAngleHistory
[SchemaMember("CCSPlayerPawn", "m_angShootAngleHistory")]
public Span<QAngle> ShootAngleHistory => Schema.GetFixedArray<QAngle>(this.Handle, "CCSPlayerPawn", "m_angShootAngleHistory", 2);
// m_vecThrowPositionHistory
[SchemaMember("CCSPlayerPawn", "m_vecThrowPositionHistory")]
public Span<Vector> ThrowPositionHistory => Schema.GetFixedArray<Vector>(this.Handle, "CCSPlayerPawn", "m_vecThrowPositionHistory", 2);
// m_vecVelocityHistory
[SchemaMember("CCSPlayerPawn", "m_vecVelocityHistory")]
public Span<Vector> VelocityHistory => Schema.GetFixedArray<Vector>(this.Handle, "CCSPlayerPawn", "m_vecVelocityHistory", 2);
}

View File

@@ -30,18 +30,6 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
[SchemaMember("CCSPlayerPawnBase", "m_pViewModelServices")]
public CPlayer_ViewModelServices? ViewModelServices => Schema.GetPointer<CPlayer_ViewModelServices>(this.Handle, "CCSPlayerPawnBase", "m_pViewModelServices");
// m_iDisplayHistoryBits
[SchemaMember("CCSPlayerPawnBase", "m_iDisplayHistoryBits")]
public ref UInt32 DisplayHistoryBits => ref Schema.GetRef<UInt32>(this.Handle, "CCSPlayerPawnBase", "m_iDisplayHistoryBits");
// m_flLastAttackedTeammate
[SchemaMember("CCSPlayerPawnBase", "m_flLastAttackedTeammate")]
public ref float LastAttackedTeammate => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastAttackedTeammate");
// m_hOriginalController
[SchemaMember("CCSPlayerPawnBase", "m_hOriginalController")]
public CHandle<CCSPlayerController> OriginalController => Schema.GetDeclaredClass<CHandle<CCSPlayerController>>(this.Handle, "CCSPlayerPawnBase", "m_hOriginalController");
// m_blindUntilTime
[SchemaMember("CCSPlayerPawnBase", "m_blindUntilTime")]
public ref float BlindUntilTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_blindUntilTime");
@@ -50,82 +38,14 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
[SchemaMember("CCSPlayerPawnBase", "m_blindStartTime")]
public ref float BlindStartTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_blindStartTime");
// m_allowAutoFollowTime
[SchemaMember("CCSPlayerPawnBase", "m_allowAutoFollowTime")]
public ref float AllowAutoFollowTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_allowAutoFollowTime");
// m_entitySpottedState
[SchemaMember("CCSPlayerPawnBase", "m_entitySpottedState")]
public EntitySpottedState_t EntitySpottedState => Schema.GetDeclaredClass<EntitySpottedState_t>(this.Handle, "CCSPlayerPawnBase", "m_entitySpottedState");
// m_nSpotRules
[SchemaMember("CCSPlayerPawnBase", "m_nSpotRules")]
public ref Int32 SpotRules => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nSpotRules");
// m_iPlayerState
[SchemaMember("CCSPlayerPawnBase", "m_iPlayerState")]
public ref CSPlayerState PlayerState => ref Schema.GetRef<CSPlayerState>(this.Handle, "CCSPlayerPawnBase", "m_iPlayerState");
// m_chickenIdleSoundTimer
[SchemaMember("CCSPlayerPawnBase", "m_chickenIdleSoundTimer")]
public CountdownTimer ChickenIdleSoundTimer => Schema.GetDeclaredClass<CountdownTimer>(this.Handle, "CCSPlayerPawnBase", "m_chickenIdleSoundTimer");
// m_chickenJumpSoundTimer
[SchemaMember("CCSPlayerPawnBase", "m_chickenJumpSoundTimer")]
public CountdownTimer ChickenJumpSoundTimer => Schema.GetDeclaredClass<CountdownTimer>(this.Handle, "CCSPlayerPawnBase", "m_chickenJumpSoundTimer");
// m_vecLastBookmarkedPosition
[SchemaMember("CCSPlayerPawnBase", "m_vecLastBookmarkedPosition")]
public Vector LastBookmarkedPosition => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vecLastBookmarkedPosition");
// m_flLastDistanceTraveledNotice
[SchemaMember("CCSPlayerPawnBase", "m_flLastDistanceTraveledNotice")]
public ref float LastDistanceTraveledNotice => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastDistanceTraveledNotice");
// m_flAccumulatedDistanceTraveled
[SchemaMember("CCSPlayerPawnBase", "m_flAccumulatedDistanceTraveled")]
public ref float AccumulatedDistanceTraveled => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flAccumulatedDistanceTraveled");
// m_flLastFriendlyFireDamageReductionRatio
[SchemaMember("CCSPlayerPawnBase", "m_flLastFriendlyFireDamageReductionRatio")]
public ref float LastFriendlyFireDamageReductionRatio => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastFriendlyFireDamageReductionRatio");
// m_bRespawning
[SchemaMember("CCSPlayerPawnBase", "m_bRespawning")]
public ref bool Respawning => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bRespawning");
// m_nLastPickupPriority
[SchemaMember("CCSPlayerPawnBase", "m_nLastPickupPriority")]
public ref Int32 LastPickupPriority => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nLastPickupPriority");
// m_flLastPickupPriorityTime
[SchemaMember("CCSPlayerPawnBase", "m_flLastPickupPriorityTime")]
public ref float LastPickupPriorityTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastPickupPriorityTime");
// m_bIsScoped
[SchemaMember("CCSPlayerPawnBase", "m_bIsScoped")]
public ref bool IsScoped => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bIsScoped");
// m_bIsWalking
[SchemaMember("CCSPlayerPawnBase", "m_bIsWalking")]
public ref bool IsWalking => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bIsWalking");
// m_bResumeZoom
[SchemaMember("CCSPlayerPawnBase", "m_bResumeZoom")]
public ref bool ResumeZoom => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bResumeZoom");
// m_bIsDefusing
[SchemaMember("CCSPlayerPawnBase", "m_bIsDefusing")]
public ref bool IsDefusing => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bIsDefusing");
// m_bIsGrabbingHostage
[SchemaMember("CCSPlayerPawnBase", "m_bIsGrabbingHostage")]
public ref bool IsGrabbingHostage => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bIsGrabbingHostage");
// m_iBlockingUseActionInProgress
[SchemaMember("CCSPlayerPawnBase", "m_iBlockingUseActionInProgress")]
public ref CSPlayerBlockingUseAction_t BlockingUseActionInProgress => ref Schema.GetRef<CSPlayerBlockingUseAction_t>(this.Handle, "CCSPlayerPawnBase", "m_iBlockingUseActionInProgress");
// m_fImmuneToGunGameDamageTime
[SchemaMember("CCSPlayerPawnBase", "m_fImmuneToGunGameDamageTime")]
public ref float ImmuneToGunGameDamageTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_fImmuneToGunGameDamageTime");
@@ -134,14 +54,6 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
[SchemaMember("CCSPlayerPawnBase", "m_bGunGameImmunity")]
public ref bool GunGameImmunity => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bGunGameImmunity");
// m_GunGameImmunityColor
[SchemaMember("CCSPlayerPawnBase", "m_GunGameImmunityColor")]
public Color GunGameImmunityColor
{
get { return Schema.GetCustomMarshalledType<Color>(this.Handle, "CCSPlayerPawnBase", "m_GunGameImmunityColor"); }
set { Schema.SetCustomMarshalledType<Color>(this.Handle, "CCSPlayerPawnBase", "m_GunGameImmunityColor", value); }
}
// m_fMolotovDamageTime
[SchemaMember("CCSPlayerPawnBase", "m_fMolotovDamageTime")]
public ref float MolotovDamageTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_fMolotovDamageTime");
@@ -150,210 +62,18 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
[SchemaMember("CCSPlayerPawnBase", "m_bHasMovedSinceSpawn")]
public ref bool HasMovedSinceSpawn => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bHasMovedSinceSpawn");
// m_bCanMoveDuringFreezePeriod
[SchemaMember("CCSPlayerPawnBase", "m_bCanMoveDuringFreezePeriod")]
public ref bool CanMoveDuringFreezePeriod => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bCanMoveDuringFreezePeriod");
// m_flGuardianTooFarDistFrac
[SchemaMember("CCSPlayerPawnBase", "m_flGuardianTooFarDistFrac")]
public ref float GuardianTooFarDistFrac => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flGuardianTooFarDistFrac");
// m_flNextGuardianTooFarHurtTime
[SchemaMember("CCSPlayerPawnBase", "m_flNextGuardianTooFarHurtTime")]
public ref float NextGuardianTooFarHurtTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flNextGuardianTooFarHurtTime");
// m_flDetectedByEnemySensorTime
[SchemaMember("CCSPlayerPawnBase", "m_flDetectedByEnemySensorTime")]
public ref float DetectedByEnemySensorTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flDetectedByEnemySensorTime");
// m_flDealtDamageToEnemyMostRecentTimestamp
[SchemaMember("CCSPlayerPawnBase", "m_flDealtDamageToEnemyMostRecentTimestamp")]
public ref float DealtDamageToEnemyMostRecentTimestamp => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flDealtDamageToEnemyMostRecentTimestamp");
// m_flLastEquippedHelmetTime
[SchemaMember("CCSPlayerPawnBase", "m_flLastEquippedHelmetTime")]
public ref float LastEquippedHelmetTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastEquippedHelmetTime");
// m_flLastEquippedArmorTime
[SchemaMember("CCSPlayerPawnBase", "m_flLastEquippedArmorTime")]
public ref float LastEquippedArmorTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastEquippedArmorTime");
// m_nHeavyAssaultSuitCooldownRemaining
[SchemaMember("CCSPlayerPawnBase", "m_nHeavyAssaultSuitCooldownRemaining")]
public ref Int32 HeavyAssaultSuitCooldownRemaining => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nHeavyAssaultSuitCooldownRemaining");
// m_bResetArmorNextSpawn
[SchemaMember("CCSPlayerPawnBase", "m_bResetArmorNextSpawn")]
public ref bool ResetArmorNextSpawn => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bResetArmorNextSpawn");
// m_flLastBumpMineBumpTime
[SchemaMember("CCSPlayerPawnBase", "m_flLastBumpMineBumpTime")]
public ref float LastBumpMineBumpTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastBumpMineBumpTime");
// m_flEmitSoundTime
[SchemaMember("CCSPlayerPawnBase", "m_flEmitSoundTime")]
public ref float EmitSoundTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flEmitSoundTime");
// m_iNumSpawns
[SchemaMember("CCSPlayerPawnBase", "m_iNumSpawns")]
public ref Int32 NumSpawns => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iNumSpawns");
// m_iShouldHaveCash
[SchemaMember("CCSPlayerPawnBase", "m_iShouldHaveCash")]
public ref Int32 ShouldHaveCash => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iShouldHaveCash");
// m_bInvalidSteamLogonDelayed
[SchemaMember("CCSPlayerPawnBase", "m_bInvalidSteamLogonDelayed")]
public ref bool InvalidSteamLogonDelayed => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bInvalidSteamLogonDelayed");
// m_flLastAction
[SchemaMember("CCSPlayerPawnBase", "m_flLastAction")]
public ref float LastAction => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastAction");
// m_flNameChangeHistory
[SchemaMember("CCSPlayerPawnBase", "m_flNameChangeHistory")]
public Span<float> NameChangeHistory => Schema.GetFixedArray<float>(this.Handle, "CCSPlayerPawnBase", "m_flNameChangeHistory", 5);
// m_fLastGivenDefuserTime
[SchemaMember("CCSPlayerPawnBase", "m_fLastGivenDefuserTime")]
public ref float LastGivenDefuserTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_fLastGivenDefuserTime");
// m_fLastGivenBombTime
[SchemaMember("CCSPlayerPawnBase", "m_fLastGivenBombTime")]
public ref float LastGivenBombTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_fLastGivenBombTime");
// m_bHasNightVision
[SchemaMember("CCSPlayerPawnBase", "m_bHasNightVision")]
public ref bool HasNightVision => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bHasNightVision");
// m_bNightVisionOn
[SchemaMember("CCSPlayerPawnBase", "m_bNightVisionOn")]
public ref bool NightVisionOn => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bNightVisionOn");
// m_flIdleTimeSinceLastAction
[SchemaMember("CCSPlayerPawnBase", "m_flIdleTimeSinceLastAction")]
public ref float IdleTimeSinceLastAction => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flIdleTimeSinceLastAction");
// m_fNextRadarUpdateTime
[SchemaMember("CCSPlayerPawnBase", "m_fNextRadarUpdateTime")]
public ref float NextRadarUpdateTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_fNextRadarUpdateTime");
// m_flLastMoneyUpdateTime
[SchemaMember("CCSPlayerPawnBase", "m_flLastMoneyUpdateTime")]
public ref float LastMoneyUpdateTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastMoneyUpdateTime");
// m_MenuStringBuffer
[SchemaMember("CCSPlayerPawnBase", "m_MenuStringBuffer")]
public string MenuStringBuffer
{
get { return Schema.GetString(this.Handle, "CCSPlayerPawnBase", "m_MenuStringBuffer"); }
set { Schema.SetStringBytes(this.Handle, "CCSPlayerPawnBase", "m_MenuStringBuffer", value, 1024); }
}
// m_fIntroCamTime
[SchemaMember("CCSPlayerPawnBase", "m_fIntroCamTime")]
public ref float IntroCamTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_fIntroCamTime");
// m_nMyCollisionGroup
[SchemaMember("CCSPlayerPawnBase", "m_nMyCollisionGroup")]
public ref Int32 MyCollisionGroup => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nMyCollisionGroup");
// m_bInNoDefuseArea
[SchemaMember("CCSPlayerPawnBase", "m_bInNoDefuseArea")]
public ref bool InNoDefuseArea => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bInNoDefuseArea");
// m_bKilledByTaser
[SchemaMember("CCSPlayerPawnBase", "m_bKilledByTaser")]
public ref bool KilledByTaser => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bKilledByTaser");
// m_iMoveState
[SchemaMember("CCSPlayerPawnBase", "m_iMoveState")]
public ref Int32 MoveState => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iMoveState");
// m_grenadeParameterStashTime
[SchemaMember("CCSPlayerPawnBase", "m_grenadeParameterStashTime")]
public ref float GrenadeParameterStashTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_grenadeParameterStashTime");
// m_bGrenadeParametersStashed
[SchemaMember("CCSPlayerPawnBase", "m_bGrenadeParametersStashed")]
public ref bool GrenadeParametersStashed => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bGrenadeParametersStashed");
// m_angStashedShootAngles
[SchemaMember("CCSPlayerPawnBase", "m_angStashedShootAngles")]
public QAngle StashedShootAngles => Schema.GetDeclaredClass<QAngle>(this.Handle, "CCSPlayerPawnBase", "m_angStashedShootAngles");
// m_vecStashedGrenadeThrowPosition
[SchemaMember("CCSPlayerPawnBase", "m_vecStashedGrenadeThrowPosition")]
public Vector StashedGrenadeThrowPosition => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vecStashedGrenadeThrowPosition");
// m_vecStashedVelocity
[SchemaMember("CCSPlayerPawnBase", "m_vecStashedVelocity")]
public Vector StashedVelocity => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vecStashedVelocity");
// m_angShootAngleHistory
[SchemaMember("CCSPlayerPawnBase", "m_angShootAngleHistory")]
public Span<QAngle> ShootAngleHistory => Schema.GetFixedArray<QAngle>(this.Handle, "CCSPlayerPawnBase", "m_angShootAngleHistory", 2);
// m_vecThrowPositionHistory
[SchemaMember("CCSPlayerPawnBase", "m_vecThrowPositionHistory")]
public Span<Vector> ThrowPositionHistory => Schema.GetFixedArray<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vecThrowPositionHistory", 2);
// m_vecVelocityHistory
[SchemaMember("CCSPlayerPawnBase", "m_vecVelocityHistory")]
public Span<Vector> VelocityHistory => Schema.GetFixedArray<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vecVelocityHistory", 2);
// m_bDiedAirborne
[SchemaMember("CCSPlayerPawnBase", "m_bDiedAirborne")]
public ref bool DiedAirborne => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bDiedAirborne");
// m_iBombSiteIndex
[SchemaMember("CCSPlayerPawnBase", "m_iBombSiteIndex")]
public CEntityIndex BombSiteIndex => Schema.GetDeclaredClass<CEntityIndex>(this.Handle, "CCSPlayerPawnBase", "m_iBombSiteIndex");
// m_nWhichBombZone
[SchemaMember("CCSPlayerPawnBase", "m_nWhichBombZone")]
public ref Int32 WhichBombZone => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nWhichBombZone");
// m_bInBombZoneTrigger
[SchemaMember("CCSPlayerPawnBase", "m_bInBombZoneTrigger")]
public ref bool InBombZoneTrigger => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bInBombZoneTrigger");
// m_bWasInBombZoneTrigger
[SchemaMember("CCSPlayerPawnBase", "m_bWasInBombZoneTrigger")]
public ref bool WasInBombZoneTrigger => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bWasInBombZoneTrigger");
// m_iDirection
[SchemaMember("CCSPlayerPawnBase", "m_iDirection")]
public ref Int32 Direction => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iDirection");
// m_iShotsFired
[SchemaMember("CCSPlayerPawnBase", "m_iShotsFired")]
public ref Int32 ShotsFired => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iShotsFired");
// m_ArmorValue
[SchemaMember("CCSPlayerPawnBase", "m_ArmorValue")]
public ref Int32 ArmorValue => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_ArmorValue");
// m_flFlinchStack
[SchemaMember("CCSPlayerPawnBase", "m_flFlinchStack")]
public ref float FlinchStack => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flFlinchStack");
// m_flVelocityModifier
[SchemaMember("CCSPlayerPawnBase", "m_flVelocityModifier")]
public ref float VelocityModifier => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flVelocityModifier");
// m_flHitHeading
[SchemaMember("CCSPlayerPawnBase", "m_flHitHeading")]
public ref float HitHeading => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flHitHeading");
// m_nHitBodyPart
[SchemaMember("CCSPlayerPawnBase", "m_nHitBodyPart")]
public ref Int32 HitBodyPart => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nHitBodyPart");
// m_iHostagesKilled
[SchemaMember("CCSPlayerPawnBase", "m_iHostagesKilled")]
public ref Int32 HostagesKilled => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iHostagesKilled");
// m_vecTotalBulletForce
[SchemaMember("CCSPlayerPawnBase", "m_vecTotalBulletForce")]
public Vector TotalBulletForce => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vecTotalBulletForce");
// m_flFlashDuration
[SchemaMember("CCSPlayerPawnBase", "m_flFlashDuration")]
public ref float FlashDuration => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flFlashDuration");
@@ -370,86 +90,10 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
[SchemaMember("CCSPlayerPawnBase", "m_iProgressBarDuration")]
public ref Int32 ProgressBarDuration => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iProgressBarDuration");
// m_bWaitForNoAttack
[SchemaMember("CCSPlayerPawnBase", "m_bWaitForNoAttack")]
public ref bool WaitForNoAttack => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bWaitForNoAttack");
// m_flLowerBodyYawTarget
[SchemaMember("CCSPlayerPawnBase", "m_flLowerBodyYawTarget")]
public ref float LowerBodyYawTarget => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLowerBodyYawTarget");
// m_bStrafing
[SchemaMember("CCSPlayerPawnBase", "m_bStrafing")]
public ref bool Strafing => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bStrafing");
// m_lastStandingPos
[SchemaMember("CCSPlayerPawnBase", "m_lastStandingPos")]
public Vector LastStandingPos => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_lastStandingPos");
// m_ignoreLadderJumpTime
[SchemaMember("CCSPlayerPawnBase", "m_ignoreLadderJumpTime")]
public ref float IgnoreLadderJumpTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_ignoreLadderJumpTime");
// m_ladderSurpressionTimer
[SchemaMember("CCSPlayerPawnBase", "m_ladderSurpressionTimer")]
public CountdownTimer LadderSurpressionTimer => Schema.GetDeclaredClass<CountdownTimer>(this.Handle, "CCSPlayerPawnBase", "m_ladderSurpressionTimer");
// m_lastLadderNormal
[SchemaMember("CCSPlayerPawnBase", "m_lastLadderNormal")]
public Vector LastLadderNormal => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_lastLadderNormal");
// m_lastLadderPos
[SchemaMember("CCSPlayerPawnBase", "m_lastLadderPos")]
public Vector LastLadderPos => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_lastLadderPos");
// m_thirdPersonHeading
[SchemaMember("CCSPlayerPawnBase", "m_thirdPersonHeading")]
public QAngle ThirdPersonHeading => Schema.GetDeclaredClass<QAngle>(this.Handle, "CCSPlayerPawnBase", "m_thirdPersonHeading");
// m_flSlopeDropOffset
[SchemaMember("CCSPlayerPawnBase", "m_flSlopeDropOffset")]
public ref float SlopeDropOffset => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flSlopeDropOffset");
// m_flSlopeDropHeight
[SchemaMember("CCSPlayerPawnBase", "m_flSlopeDropHeight")]
public ref float SlopeDropHeight => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flSlopeDropHeight");
// m_vHeadConstraintOffset
[SchemaMember("CCSPlayerPawnBase", "m_vHeadConstraintOffset")]
public Vector HeadConstraintOffset => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vHeadConstraintOffset");
// m_iLastWeaponFireUsercmd
[SchemaMember("CCSPlayerPawnBase", "m_iLastWeaponFireUsercmd")]
public ref Int32 LastWeaponFireUsercmd => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iLastWeaponFireUsercmd");
// m_angEyeAngles
[SchemaMember("CCSPlayerPawnBase", "m_angEyeAngles")]
public QAngle EyeAngles => Schema.GetDeclaredClass<QAngle>(this.Handle, "CCSPlayerPawnBase", "m_angEyeAngles");
// m_bVCollisionInitted
[SchemaMember("CCSPlayerPawnBase", "m_bVCollisionInitted")]
public ref bool VCollisionInitted => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bVCollisionInitted");
// m_storedSpawnPosition
[SchemaMember("CCSPlayerPawnBase", "m_storedSpawnPosition")]
public Vector StoredSpawnPosition => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_storedSpawnPosition");
// m_storedSpawnAngle
[SchemaMember("CCSPlayerPawnBase", "m_storedSpawnAngle")]
public QAngle StoredSpawnAngle => Schema.GetDeclaredClass<QAngle>(this.Handle, "CCSPlayerPawnBase", "m_storedSpawnAngle");
// m_bIsSpawning
[SchemaMember("CCSPlayerPawnBase", "m_bIsSpawning")]
public ref bool IsSpawning => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bIsSpawning");
// m_bHideTargetID
[SchemaMember("CCSPlayerPawnBase", "m_bHideTargetID")]
public ref bool HideTargetID => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bHideTargetID");
// m_nNumDangerZoneDamageHits
[SchemaMember("CCSPlayerPawnBase", "m_nNumDangerZoneDamageHits")]
public ref Int32 NumDangerZoneDamageHits => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nNumDangerZoneDamageHits");
// m_bHud_MiniScoreHidden
[SchemaMember("CCSPlayerPawnBase", "m_bHud_MiniScoreHidden")]
public ref bool Hud_MiniScoreHidden => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bHud_MiniScoreHidden");
@@ -458,42 +102,6 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
[SchemaMember("CCSPlayerPawnBase", "m_bHud_RadarHidden")]
public ref bool Hud_RadarHidden => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bHud_RadarHidden");
// m_nLastKillerIndex
[SchemaMember("CCSPlayerPawnBase", "m_nLastKillerIndex")]
public CEntityIndex LastKillerIndex => Schema.GetDeclaredClass<CEntityIndex>(this.Handle, "CCSPlayerPawnBase", "m_nLastKillerIndex");
// m_nLastConcurrentKilled
[SchemaMember("CCSPlayerPawnBase", "m_nLastConcurrentKilled")]
public ref Int32 LastConcurrentKilled => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nLastConcurrentKilled");
// m_nDeathCamMusic
[SchemaMember("CCSPlayerPawnBase", "m_nDeathCamMusic")]
public ref Int32 DeathCamMusic => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nDeathCamMusic");
// m_iAddonBits
[SchemaMember("CCSPlayerPawnBase", "m_iAddonBits")]
public ref Int32 AddonBits => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iAddonBits");
// m_iPrimaryAddon
[SchemaMember("CCSPlayerPawnBase", "m_iPrimaryAddon")]
public ref Int32 PrimaryAddon => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iPrimaryAddon");
// m_iSecondaryAddon
[SchemaMember("CCSPlayerPawnBase", "m_iSecondaryAddon")]
public ref Int32 SecondaryAddon => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iSecondaryAddon");
// m_currentDeafnessFilter
[SchemaMember("CCSPlayerPawnBase", "m_currentDeafnessFilter")]
public CUtlStringToken CurrentDeafnessFilter => Schema.GetDeclaredClass<CUtlStringToken>(this.Handle, "CCSPlayerPawnBase", "m_currentDeafnessFilter");
// m_NumEnemiesKilledThisSpawn
[SchemaMember("CCSPlayerPawnBase", "m_NumEnemiesKilledThisSpawn")]
public ref Int32 NumEnemiesKilledThisSpawn => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_NumEnemiesKilledThisSpawn");
// m_NumEnemiesKilledThisRound
[SchemaMember("CCSPlayerPawnBase", "m_NumEnemiesKilledThisRound")]
public ref Int32 NumEnemiesKilledThisRound => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_NumEnemiesKilledThisRound");
// m_NumEnemiesAtRoundStart
[SchemaMember("CCSPlayerPawnBase", "m_NumEnemiesAtRoundStart")]
public ref Int32 NumEnemiesAtRoundStart => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_NumEnemiesAtRoundStart");
@@ -502,76 +110,16 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
[SchemaMember("CCSPlayerPawnBase", "m_wasNotKilledNaturally")]
public ref bool WasNotKilledNaturally => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_wasNotKilledNaturally");
// m_vecPlayerPatchEconIndices
[SchemaMember("CCSPlayerPawnBase", "m_vecPlayerPatchEconIndices")]
public Span<UInt32> PlayerPatchEconIndices => Schema.GetFixedArray<UInt32>(this.Handle, "CCSPlayerPawnBase", "m_vecPlayerPatchEconIndices", 5);
// m_iDeathFlags
[SchemaMember("CCSPlayerPawnBase", "m_iDeathFlags")]
public ref Int32 DeathFlags => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_iDeathFlags");
// m_hPet
[SchemaMember("CCSPlayerPawnBase", "m_hPet")]
public CHandle<CChicken> Pet => Schema.GetDeclaredClass<CHandle<CChicken>>(this.Handle, "CCSPlayerPawnBase", "m_hPet");
// m_unCurrentEquipmentValue
[SchemaMember("CCSPlayerPawnBase", "m_unCurrentEquipmentValue")]
public ref UInt16 CurrentEquipmentValue => ref Schema.GetRef<UInt16>(this.Handle, "CCSPlayerPawnBase", "m_unCurrentEquipmentValue");
// m_unRoundStartEquipmentValue
[SchemaMember("CCSPlayerPawnBase", "m_unRoundStartEquipmentValue")]
public ref UInt16 RoundStartEquipmentValue => ref Schema.GetRef<UInt16>(this.Handle, "CCSPlayerPawnBase", "m_unRoundStartEquipmentValue");
// m_unFreezetimeEndEquipmentValue
[SchemaMember("CCSPlayerPawnBase", "m_unFreezetimeEndEquipmentValue")]
public ref UInt16 FreezetimeEndEquipmentValue => ref Schema.GetRef<UInt16>(this.Handle, "CCSPlayerPawnBase", "m_unFreezetimeEndEquipmentValue");
// m_nSurvivalTeamNumber
[SchemaMember("CCSPlayerPawnBase", "m_nSurvivalTeamNumber")]
public ref Int32 SurvivalTeamNumber => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_nSurvivalTeamNumber");
// m_bHasDeathInfo
[SchemaMember("CCSPlayerPawnBase", "m_bHasDeathInfo")]
public ref bool HasDeathInfo => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bHasDeathInfo");
// m_flDeathInfoTime
[SchemaMember("CCSPlayerPawnBase", "m_flDeathInfoTime")]
public ref float DeathInfoTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flDeathInfoTime");
// m_vecDeathInfoOrigin
[SchemaMember("CCSPlayerPawnBase", "m_vecDeathInfoOrigin")]
public Vector DeathInfoOrigin => Schema.GetDeclaredClass<Vector>(this.Handle, "CCSPlayerPawnBase", "m_vecDeathInfoOrigin");
// m_bKilledByHeadshot
[SchemaMember("CCSPlayerPawnBase", "m_bKilledByHeadshot")]
public ref bool KilledByHeadshot => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bKilledByHeadshot");
// m_LastHitBox
[SchemaMember("CCSPlayerPawnBase", "m_LastHitBox")]
public ref Int32 LastHitBox => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_LastHitBox");
// m_LastHealth
[SchemaMember("CCSPlayerPawnBase", "m_LastHealth")]
public ref Int32 LastHealth => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_LastHealth");
// m_flLastCollisionCeiling
[SchemaMember("CCSPlayerPawnBase", "m_flLastCollisionCeiling")]
public ref float LastCollisionCeiling => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastCollisionCeiling");
// m_flLastCollisionCeilingChangeTime
[SchemaMember("CCSPlayerPawnBase", "m_flLastCollisionCeilingChangeTime")]
public ref float LastCollisionCeilingChangeTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawnBase", "m_flLastCollisionCeilingChangeTime");
// m_pBot
[SchemaMember("CCSPlayerPawnBase", "m_pBot")]
public CCSBot? Bot => Schema.GetPointer<CCSBot>(this.Handle, "CCSPlayerPawnBase", "m_pBot");
// m_bBotAllowActive
[SchemaMember("CCSPlayerPawnBase", "m_bBotAllowActive")]
public ref bool BotAllowActive => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bBotAllowActive");
// m_bCommittingSuicideOnTeamChange
[SchemaMember("CCSPlayerPawnBase", "m_bCommittingSuicideOnTeamChange")]
public ref bool CommittingSuicideOnTeamChange => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_bCommittingSuicideOnTeamChange");
// m_hOriginalController
[SchemaMember("CCSPlayerPawnBase", "m_hOriginalController")]
public CHandle<CCSPlayerController> OriginalController => Schema.GetDeclaredClass<CHandle<CCSPlayerController>>(this.Handle, "CCSPlayerPawnBase", "m_hOriginalController");
}

View File

@@ -26,10 +26,6 @@ public partial class CCSPlayer_UseServices : CPlayer_UseServices
[SchemaMember("CCSPlayer_UseServices", "m_flLastUseTimeStamp")]
public ref float LastUseTimeStamp => ref Schema.GetRef<float>(this.Handle, "CCSPlayer_UseServices", "m_flLastUseTimeStamp");
// m_flTimeStartedHoldingUse
[SchemaMember("CCSPlayer_UseServices", "m_flTimeStartedHoldingUse")]
public ref float TimeStartedHoldingUse => ref Schema.GetRef<float>(this.Handle, "CCSPlayer_UseServices", "m_flTimeStartedHoldingUse");
// m_flTimeLastUsedWindow
[SchemaMember("CCSPlayer_UseServices", "m_flTimeLastUsedWindow")]
public ref float TimeLastUsedWindow => ref Schema.GetRef<float>(this.Handle, "CCSPlayer_UseServices", "m_flTimeLastUsedWindow");

View File

@@ -66,6 +66,10 @@ public partial class CCSPlayer_WeaponServices : CPlayer_WeaponServices
[SchemaMember("CCSPlayer_WeaponServices", "m_bDisableAutoDeploy")]
public ref bool DisableAutoDeploy => ref Schema.GetRef<bool>(this.Handle, "CCSPlayer_WeaponServices", "m_bDisableAutoDeploy");
// m_bIsPickingUpGroundWeapon
[SchemaMember("CCSPlayer_WeaponServices", "m_bIsPickingUpGroundWeapon")]
public ref bool IsPickingUpGroundWeapon => ref Schema.GetRef<bool>(this.Handle, "CCSPlayer_WeaponServices", "m_bIsPickingUpGroundWeapon");
// m_nOldShootPositionHistoryCount
[SchemaMember("CCSPlayer_WeaponServices", "m_nOldShootPositionHistoryCount")]
public ref UInt32 OldShootPositionHistoryCount => ref Schema.GetRef<UInt32>(this.Handle, "CCSPlayer_WeaponServices", "m_nOldShootPositionHistoryCount");

View File

@@ -194,6 +194,14 @@ public partial class CCSWeaponBase : CBasePlayerWeapon
[SchemaMember("CCSWeaponBase", "m_iOriginalTeamNumber")]
public ref Int32 OriginalTeamNumber => ref Schema.GetRef<Int32>(this.Handle, "CCSWeaponBase", "m_iOriginalTeamNumber");
// m_iMostRecentTeamNumber
[SchemaMember("CCSWeaponBase", "m_iMostRecentTeamNumber")]
public ref Int32 MostRecentTeamNumber => ref Schema.GetRef<Int32>(this.Handle, "CCSWeaponBase", "m_iMostRecentTeamNumber");
// m_bDroppedNearBuyZone
[SchemaMember("CCSWeaponBase", "m_bDroppedNearBuyZone")]
public ref bool DroppedNearBuyZone => ref Schema.GetRef<bool>(this.Handle, "CCSWeaponBase", "m_bDroppedNearBuyZone");
// m_flNextAttackRenderTimeOffset
[SchemaMember("CCSWeaponBase", "m_flNextAttackRenderTimeOffset")]
public ref float NextAttackRenderTimeOffset => ref Schema.GetRef<float>(this.Handle, "CCSWeaponBase", "m_flNextAttackRenderTimeOffset");

View File

@@ -20,11 +20,11 @@ public partial class CDamageRecord : NativeObject
// m_PlayerDamager
[SchemaMember("CDamageRecord", "m_PlayerDamager")]
public CHandle<CCSPlayerPawnBase> PlayerDamager => Schema.GetDeclaredClass<CHandle<CCSPlayerPawnBase>>(this.Handle, "CDamageRecord", "m_PlayerDamager");
public CHandle<CCSPlayerPawn> PlayerDamager => Schema.GetDeclaredClass<CHandle<CCSPlayerPawn>>(this.Handle, "CDamageRecord", "m_PlayerDamager");
// m_PlayerRecipient
[SchemaMember("CDamageRecord", "m_PlayerRecipient")]
public CHandle<CCSPlayerPawnBase> PlayerRecipient => Schema.GetDeclaredClass<CHandle<CCSPlayerPawnBase>>(this.Handle, "CDamageRecord", "m_PlayerRecipient");
public CHandle<CCSPlayerPawn> PlayerRecipient => Schema.GetDeclaredClass<CHandle<CCSPlayerPawn>>(this.Handle, "CDamageRecord", "m_PlayerRecipient");
// m_hPlayerControllerDamager
[SchemaMember("CDamageRecord", "m_hPlayerControllerDamager")]

View File

@@ -114,10 +114,6 @@ public partial class CPlantedC4 : CBaseAnimGraph
[SchemaMember("CPlantedC4", "m_flNextBotBeepTime")]
public ref float NextBotBeepTime => ref Schema.GetRef<float>(this.Handle, "CPlantedC4", "m_flNextBotBeepTime");
// m_bPlantedAfterPickup
[SchemaMember("CPlantedC4", "m_bPlantedAfterPickup")]
public ref bool PlantedAfterPickup => ref Schema.GetRef<bool>(this.Handle, "CPlantedC4", "m_bPlantedAfterPickup");
// m_angCatchUpToPlayerEye
[SchemaMember("CPlantedC4", "m_angCatchUpToPlayerEye")]
public QAngle CatchUpToPlayerEye => Schema.GetDeclaredClass<QAngle>(this.Handle, "CPlantedC4", "m_angCatchUpToPlayerEye");

View File

@@ -22,4 +22,8 @@ public partial class CWeaponTaser : CCSWeaponBaseGun
[SchemaMember("CWeaponTaser", "m_fFireTime")]
public ref float FireTime => ref Schema.GetRef<float>(this.Handle, "CWeaponTaser", "m_fFireTime");
// m_nLastAttackTick
[SchemaMember("CWeaponTaser", "m_nLastAttackTick")]
public ref Int32 LastAttackTick => ref Schema.GetRef<Int32>(this.Handle, "CWeaponTaser", "m_nLastAttackTick");
}

View File

@@ -25,5 +25,6 @@ public enum PulseValueType_t : uint
PVAL_CURSOR_FLOW = 0xD,
PVAL_ANY = 0xE,
PVAL_SCHEMA_ENUM = 0xF,
PVAL_COUNT = 0x10,
PVAL_PANORAMA_PANEL_HANDLE = 0x10,
PVAL_COUNT = 0x11,
}

View File

@@ -28,7 +28,7 @@ public enum SoundFlags_t : uint
SOUND_CONTEXT_DANGER_APPROACH = 0x2000000,
SOUND_CONTEXT_ALLIES_ONLY = 0x4000000,
SOUND_CONTEXT_PANIC_NPCS = 0x8000000,
ALL_CONTEXTS = 0xFFFFFFFF,
ALL_CONTEXTS = 0xFFF00000,
ALL_SCENTS = 0x0,
ALL_SOUNDS = 0xFFFFF,
}

View File

@@ -11,4 +11,5 @@ public enum WeaponSwitchReason_t : uint
eDrawn = 0x0,
eEquipped = 0x1,
eUserInitiatedSwitchToLast = 0x2,
eUserInitiatedSwitchHands = 0x3,
}

View File

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

View File

@@ -23,6 +23,10 @@ namespace CounterStrikeSharp.API.Modules.Commands
{
public delegate void CommandCallback(CCSPlayerController? player, CommandInfo commandInfo);
/// <summary>
/// Command listener callback.
/// <returns>If returning <see cref="HookResult.Handled"/> or higher, will prevent the command from executing.</returns>
/// </summary>
public delegate HookResult CommandListenerCallback(CCSPlayerController? player, CommandInfo commandInfo);
public CCSPlayerController? CallingPlayer { get; }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using CounterStrikeSharp.API.Modules.Entities;
@@ -12,7 +13,7 @@ public class Target
private string Raw { get; }
private string Slug { get; }
private static readonly Dictionary<string, TargetType> TargetTypeMap = new(StringComparer.OrdinalIgnoreCase)
public static readonly IReadOnlyDictionary<string, TargetType> TargetTypeMap = new Dictionary<string, TargetType>(StringComparer.OrdinalIgnoreCase)
{
{ "@all", TargetType.GroupAll },
{ "@bots", TargetType.GroupBots },
@@ -24,7 +25,7 @@ public class Target
{ "@ct", TargetType.TeamCt },
{ "@t", TargetType.TeamT },
{ "@spec", TargetType.TeamSpec }
};
}.ToFrozenDictionary();
private static bool ConstTargetType(string target, out TargetType targetType)

View File

@@ -34,16 +34,16 @@ namespace CounterStrikeSharp.API.Modules.Events
{
// Used to track freeable state for manually created events.
private bool _freeable = false;
public GameEvent(IntPtr pointer) : base(pointer)
{
}
public GameEvent(string name, bool force) : this(NativeAPI.CreateEvent(name, force))
{
_freeable = true;
}
public string EventName => NativeAPI.GetEventName(Handle);
public T Get<T>(string name)
@@ -58,7 +58,9 @@ namespace CounterStrikeSharp.API.Modules.Events
_ when type == typeof(bool) => GetBool(name),
_ when type == typeof(ulong) => GetUint64(name),
_ when type == typeof(long) => (long)GetUint64(name),
_ when type == typeof(CCSPlayerController) => GetPlayer(name),
// This is a special case for player controllers as this method previously did not allow for nullable returns.
// So we return an invalid player controller if the player is not found.
_ when type == typeof(CCSPlayerController) => GetPlayer(name) ?? new CCSPlayerController(0),
_ => throw new NotSupportedException(),
};
@@ -80,7 +82,7 @@ namespace CounterStrikeSharp.API.Modules.Events
SetInt(name, i);
break;
case var _ when value is CCSPlayerController player:
NativeAPI.SetEventPlayerController(Handle, name, player.Handle);
SetPlayer(name, player);
break;
case var _ when value is string s:
SetString(name, s);
@@ -104,9 +106,15 @@ namespace CounterStrikeSharp.API.Modules.Events
protected string GetString(string name) => NativeAPI.GetEventString(Handle, name);
protected int GetInt(string name) => NativeAPI.GetEventInt(Handle, name);
protected CCSPlayerController GetPlayer(string name)
protected CCSPlayerController? GetPlayer(string name)
{
return new CCSPlayerController(NativeAPI.GetEventPlayerController(Handle, name));
var ptr = NativeAPI.GetEventPlayerController(Handle, name);
if (ptr == IntPtr.Zero)
{
return null;
}
return new CCSPlayerController(ptr);
}
protected ulong GetUint64(string name) => NativeAPI.GetEventUint64(Handle, name);
@@ -125,6 +133,8 @@ namespace CounterStrikeSharp.API.Modules.Events
protected void SetEntityIndex(string name, int value) => NativeAPI.SetEventEntityIndex(Handle, name, value);
protected void SetPlayer(string name, CCSPlayerController? player) => NativeAPI.SetEventPlayerController(Handle, name, player?.Handle ?? IntPtr.Zero);
public void FireEvent(bool dontBroadcast)
{
NativeAPI.FireEvent(Handle, dontBroadcast);
@@ -132,7 +142,7 @@ namespace CounterStrikeSharp.API.Modules.Events
}
public void FireEventToClient(CCSPlayerController player) => NativeAPI.FireEventToClient(Handle, (int)player.Index);
/// <summary>
/// Used to manually free the event.
/// <remarks>If <see cref="FireEvent"/> is called, Free will be called automatically.</remarks>
@@ -143,10 +153,10 @@ namespace CounterStrikeSharp.API.Modules.Events
{
throw new InvalidOperationException("Event is not able to be freed.");
}
NativeAPI.FreeEvent(Handle);
_freeable = false;
}
}
}
}

View File

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

View File

@@ -81,15 +81,12 @@ public static class VirtualFunctions
public static MemoryFunctionVoid<IntPtr, IntPtr> RemovePlayerItemFunc =
new(GameData.GetSignature("CBasePlayerPawn_RemovePlayerItem"));
public static Action<IntPtr, IntPtr> RemovePlayerItemVirtual = RemovePlayerItemFunc.Invoke;
public static MemoryFunctionVoid<IntPtr, string, IntPtr, IntPtr, string, int> AcceptInputFunc = new(GameData.GetSignature("CEntityInstance_AcceptInput"));
public static Action<IntPtr, string, IntPtr, IntPtr, string, int> AcceptInput = AcceptInputFunc.Invoke;
public static MemoryFunctionVoid<IntPtr, IntPtr, int, short, short> StateChangedFunc =
new(GameData.GetSignature("StateChanged"));
public static Action<IntPtr, IntPtr, int, short, short> StateChanged = StateChangedFunc.Invoke;
public static MemoryFunctionVoid<IntPtr, int, long> NetworkStateChangedFunc = new("NetworkStateChanged");
public static MemoryFunctionVoid<IntPtr, int, long> NetworkStateChangedFunc = new(GameData.GetSignature("NetworkStateChanged"));
public static Action<IntPtr, int, long> NetworkStateChanged = NetworkStateChangedFunc.Invoke;
}
}

View File

@@ -28,23 +28,35 @@ public enum PostSelectAction
public abstract class BaseMenu : IMenu
{
public string Title { get; set; }
public List<ChatMenuOption> MenuOptions { get; } = new();
public PostSelectAction PostSelectAction { get; set; } = PostSelectAction.Reset;
public bool ExitButton { get; set; } = true;
protected BaseMenu(string title)
{
Title = title;
}
public virtual ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false)
public virtual ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect,
bool disabled = false)
{
var option = new ChatMenuOption(display, disabled, onSelect);
MenuOptions.Add(option);
return option;
}
public abstract void Open(CCSPlayerController player);
public void OpenToAll()
{
foreach (var player in Utilities.GetPlayers())
{
Open(player);
}
}
}
// This must be called ChatMenuOption to maintain backwards compatibility with the old API
public class ChatMenuOption
{
@@ -114,7 +126,7 @@ public abstract class BaseMenuInstance : IMenuInstance
if (menuItemIndex >= 0 && menuItemIndex < Menu.MenuOptions.Count)
{
var menuOption = Menu.MenuOptions[menuItemIndex];
if (!menuOption.Disabled)
{
menuOption.OnSelect(Player, menuOption);
@@ -142,7 +154,7 @@ public abstract class BaseMenuInstance : IMenuInstance
Page = 0;
PrevPageOffsets.Clear();
}
public virtual void Close()
{
MenuManager.CloseActiveMenu(Player);

View File

@@ -21,10 +21,35 @@ namespace CounterStrikeSharp.API.Modules.Menu;
public class CenterHtmlMenu : BaseMenu
{
private readonly BasePlugin? _plugin;
public string TitleColor { get; set; } = "yellow";
public string EnabledColor { get; set; } = "green";
public string DisabledColor { get; set; } = "grey";
public string PrevPageColor { get; set; } = "yellow";
public string NextPageColor { get; set; } = "yellow";
public string CloseColor { get; set; } = "red";
public CenterHtmlMenu(string title, BasePlugin plugin) : base(ModifyTitle(title))
{
_plugin = plugin;
}
[Obsolete("Use the constructor that takes a BasePlugin")]
public CenterHtmlMenu(string title) : base(ModifyTitle(title))
{
}
public override void Open(CCSPlayerController player)
{
if (_plugin == null)
{
throw new InvalidOperationException("This method is unsupported with the CenterHtmlMenu constructor used." +
"Please provide a BasePlugin in the constructor.");
};
MenuManager.OpenCenterHtmlMenu(_plugin, player, this);
}
public override ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect,
bool disabled = false)
{
@@ -77,35 +102,40 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
return;
}
if (Menu is not CenterHtmlMenu centerHtmlMenu)
{
return;
}
var builder = new StringBuilder();
builder.Append($"<b><font color='yellow'>{Menu.Title}</font></b>");
builder.Append($"<b><font color='{centerHtmlMenu.TitleColor}'>{centerHtmlMenu.Title}</font></b>");
builder.AppendLine("<br>");
var keyOffset = 1;
for (var i = CurrentOffset; i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count); i++)
for (var i = CurrentOffset; i < Math.Min(CurrentOffset + MenuItemsPerPage, centerHtmlMenu.MenuOptions.Count); i++)
{
var option = Menu.MenuOptions[i];
string color = option.Disabled ? "grey" : "green";
var option = centerHtmlMenu.MenuOptions[i];
string color = option.Disabled ? centerHtmlMenu.DisabledColor : centerHtmlMenu.EnabledColor;
builder.Append($"<font color='{color}'>!{keyOffset++}</font> {option.Text}");
builder.AppendLine("<br>");
}
if (HasPrevButton)
{
builder.AppendFormat("<font color='yellow'>!7</font> &#60;- Prev");
builder.AppendFormat($"<font color='{centerHtmlMenu.PrevPageColor}'>!7</font> &#60;- Prev");
builder.AppendLine("<br>");
}
if (HasNextButton)
{
builder.AppendFormat("<font color='yellow'>!8</font> -> Next");
builder.AppendFormat($"<font color='{centerHtmlMenu.NextPageColor}'>!8</font> -> Next");
builder.AppendLine("<br>");
}
if (Menu.ExitButton)
if (centerHtmlMenu.ExitButton)
{
builder.AppendFormat("<font color='red'>!9</font> -> Close");
builder.AppendFormat($"<font color='{centerHtmlMenu.CloseColor}'>!9</font> -> Close");
builder.AppendLine("<br>");
}

View File

@@ -20,10 +20,21 @@ namespace CounterStrikeSharp.API.Modules.Menu;
public class ChatMenu : BaseMenu
{
public char TitleColor { get; set; } = ChatColors.Yellow;
public char EnabledColor { get; set; } = ChatColors.Green;
public char DisabledColor { get; set; } = ChatColors.Grey;
public char PrevPageColor { get; set; } = ChatColors.Yellow;
public char NextPageColor { get; set; } = ChatColors.Yellow;
public char CloseColor { get; set; } = ChatColors.Red;
public ChatMenu(string title) : base(title)
{
ExitButton = false;
}
public override void Open(CCSPlayerController player)
{
MenuManager.OpenChatMenu(player, this);
}
}
public class ChatMenuInstance : BaseMenuInstance
@@ -34,30 +45,35 @@ public class ChatMenuInstance : BaseMenuInstance
public override void Display()
{
Player.PrintToChat(Menu.Title);
if (Menu is not ChatMenu chatMenu)
{
return;
}
Player.PrintToChat($" {chatMenu.TitleColor} {chatMenu.Title}");
Player.PrintToChat("---");
var keyOffset = 1;
for (var i = CurrentOffset; i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count); i++)
{
var option = Menu.MenuOptions[i];
Player.PrintToChat($" {(option.Disabled ? ChatColors.Grey : ChatColors.Green)} !{keyOffset++} {ChatColors.Default}{option.Text}");
char color = option.Disabled ? chatMenu.DisabledColor : chatMenu.EnabledColor;
Player.PrintToChat($" {color} !{keyOffset++} {ChatColors.Default}{option.Text}");
}
if (HasPrevButton)
{
Player.PrintToChat($" {ChatColors.Yellow}!7 {ChatColors.Default}-> Prev");
Player.PrintToChat($" {chatMenu.PrevPageColor}!7 {ChatColors.Default}-> Prev");
}
if (HasNextButton)
{
Player.PrintToChat($" {ChatColors.Yellow}!8 {ChatColors.Default}-> Next");
Player.PrintToChat($" {chatMenu.NextPageColor}!8 {ChatColors.Default}-> Next");
}
if (Menu.ExitButton)
{
Player.PrintToChat($" {ChatColors.Red}!9 {ChatColors.Default}-> Close");
Player.PrintToChat($" {chatMenu.CloseColor}!9 {ChatColors.Default}-> Close");
}
}
}

View File

@@ -21,6 +21,11 @@ public class ConsoleMenu : BaseMenu
public ConsoleMenu(string title) : base(title)
{
}
public override void Open(CCSPlayerController player)
{
MenuManager.OpenConsoleMenu(player, this);
}
}
public class ConsoleMenuInstance : BaseMenuInstance

View File

@@ -20,16 +20,18 @@ namespace CounterStrikeSharp.API.Modules.Menu;
public interface IMenu
{
public string Title { get; set; }
public List<ChatMenuOption> MenuOptions { get; }
public PostSelectAction PostSelectAction
string Title { get; set; }
List<ChatMenuOption> MenuOptions { get; }
PostSelectAction PostSelectAction
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public bool ExitButton { get; set; }
bool ExitButton { get; set; }
public ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false);
ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false);
void Open(CCSPlayerController player);
void OpenToAll();
}
public interface IMenuInstance

View File

@@ -41,7 +41,7 @@ public static class MenuManager
ActiveMenus.Remove(player.Handle);
}
public static void OpenChatMenu(CCSPlayerController player, ChatMenu menu)
{
CloseActiveMenu(player);
@@ -49,7 +49,7 @@ public static class MenuManager
ActiveMenus[player.Handle] = new ChatMenuInstance(player, menu);
ActiveMenus[player.Handle].Display();
}
public static void OpenCenterHtmlMenu(BasePlugin plugin, CCSPlayerController player, CenterHtmlMenu menu)
{
CloseActiveMenu(player);
@@ -57,7 +57,7 @@ public static class MenuManager
ActiveMenus[player.Handle] = new CenterHtmlMenuInstance(plugin, player, menu);
ActiveMenus[player.Handle].Display();
}
public static void OpenConsoleMenu(CCSPlayerController player, ConsoleMenu menu)
{
CloseActiveMenu(player);

View File

@@ -14,9 +14,6 @@
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using CounterStrikeSharp.API.Core;
namespace CounterStrikeSharp.API.Modules.Utils
{
/// <summary>
@@ -30,6 +27,8 @@ namespace CounterStrikeSharp.API.Modules.Utils
/// </summary>
public class Angle : NativeObject
{
public static readonly Angle Zero = new();
public Angle(IntPtr pointer) : base(pointer)
{
}
@@ -46,8 +45,6 @@ namespace CounterStrikeSharp.API.Modules.Utils
this.Y = y ?? 0;
this.Z = z ?? 0;
}
#region Accessors
@@ -366,15 +363,15 @@ namespace CounterStrikeSharp.API.Modules.Utils
return this.IsEqualTol(v, 0.01f);
}
public override string ToString()
{
return $"{X:n2} {Y:n2} {Z:n2}";
}
#endregion
protected override void OnDispose()
{
}*/
public override string ToString()
{
return $"{X:n2} {Y:n2} {Z:n2}";
}
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using Microsoft.Extensions.DependencyInjection;
namespace CounterStrikeSharp.API.Modules.Utils;
@@ -11,6 +11,12 @@ public readonly record struct CEntityIndex(uint Value)
public override string ToString() => $"Entity Index {Value}";
}
/// <summary>
/// CHandle is a class that represents a 32-bit ID (entindex + serial number) unique to every past and present entity in a game.
/// It is used to refer to entities where pointers and entity indexes are unsafe; mainly across the client/server divide.
/// <a href="https://developer.valvesoftware.com/wiki/CHandle">More info</a>
/// </summary>
/// <typeparam name="T">Type of entity this handle refers to</typeparam>
public class CHandle<T> : IEquatable<CHandle<T>> where T : NativeEntity
{
private uint _raw;
@@ -49,15 +55,35 @@ public class CHandle<T> : IEquatable<CHandle<T>> where T : NativeEntity
_pointer = raw;
}
public T? Value => (T)Activator.CreateInstance(typeof(T), EntitySystem.GetEntityByHandle(this));
/// <inheritdoc cref="Get"/>
public T? Value => Get();
/// <summary>
/// Retrieves the instance of the entity this handle refers to.
/// </summary>
public T? Get()
{
if (!IsValid)
return null;
var entity = EntitySystem.GetEntityByHandle(this);
if (entity == null)
return null;
return (T)Activator.CreateInstance(typeof(T), entity)!;
}
public override string ToString() => IsValid ? $"Index = {Index}, Serial = {SerialNum}" : "<invalid>";
/// <summary>
/// Checks that the handle is valid and points to an entity.
/// </summary>
public bool IsValid => Index != (Utilities.MaxEdicts - 1);
public uint Index => (uint)(Raw & (Utilities.MaxEdicts - 1));
public uint SerialNum => Raw >> Utilities.MaxEdictBits;
public static implicit operator uint(CHandle<T> handle) => handle.Raw;
public bool Equals(CHandle<T>? other)
@@ -81,8 +107,8 @@ public class CEntityHandle : CHandle<CEntityInstance>
public CEntityHandle(uint raw) : base(raw)
{
}
public CEntityHandle(IntPtr raw) : base (raw)
public CEntityHandle(IntPtr raw) : base(raw)
{
}
}
@@ -103,4 +129,4 @@ public class PointerTo<T> : NativeObject where T : NativeObject
}
}
}
}
}

View File

@@ -14,14 +14,14 @@
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using System.Runtime.CompilerServices;
using CounterStrikeSharp.API.Core;
namespace CounterStrikeSharp.API.Modules.Utils
{
public class QAngle : NativeObject
{
public static readonly QAngle Zero = new();
public QAngle(IntPtr pointer) : base(pointer)
{
}

View File

@@ -1,4 +1,4 @@
/*
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,11 +14,8 @@
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Utils
{
@@ -31,13 +28,18 @@ namespace CounterStrikeSharp.API.Modules.Utils
/// <item><term>Z</term><description>+up/-down</description></item>
/// </list>
/// </summary>
public class Vector : NativeObject
public class Vector : NativeObject,
IAdditionOperators<Vector, Vector, Vector>,
ISubtractionOperators<Vector, Vector, Vector>,
IMultiplyOperators<Vector, float, Vector>,
IDivisionOperators<Vector, float, Vector>
{
public static readonly Vector Zero = new();
public Vector(IntPtr pointer) : base(pointer)
{
}
public Vector(float? x = null, float? y = null, float? z = null) : this(NativeAPI.VectorNew())
{
this.X = x ?? 0;
@@ -48,7 +50,7 @@ namespace CounterStrikeSharp.API.Modules.Utils
public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle, 0);
public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle, 1);
public unsafe ref float Z => ref Unsafe.Add(ref *(float*)Handle, 2);
/// <summary>
/// Returns a copy of the vector with values replaced.
/// </summary>
@@ -75,10 +77,10 @@ namespace CounterStrikeSharp.API.Modules.Utils
{
this.X += vector.X;
this.Y += vector.Y;
this.Z = this.Z = vector.Z;
this.Z += vector.Z;
}
/// <summary>
/// Returns an angle that represents the normal of the vector.
/// </summary>
@@ -184,7 +186,7 @@ namespace CounterStrikeSharp.API.Modules.Utils
public bool IsZero() => NativeAPI.VectorIsZero(Handle);
/// <summary>
/// Returns the Euclidean length of the vector: √x² + y² + z²
/// Returns the Euclidean length of the vector: √x² + y² + z²
/// </summary>
/// <returns>Euclidean length of vector</returns>
public float Length() => NativeAPI.VectorLength(Handle);
@@ -238,7 +240,7 @@ namespace CounterStrikeSharp.API.Modules.Utils
var returnVal = new Vector();
NativePINVOKE.VectorRotate__SWIG_1(ptr, angle.Handle(), returnVal.Handle());
Set(returnVal);
}
}
/// <summary>
/// Copies X, Y and Z into this Vector
@@ -299,21 +301,23 @@ namespace CounterStrikeSharp.API.Modules.Utils
public float this[int i]
{
get {
get
{
switch (i)
{
case 0:
return this.X;
case 1:
return this.Y;
case 2:
return this.Z;
case 2:
return this.Z;
}
return 0;
}
set {
switch (i)
set
{
switch (i)
{
case 0:
this.X = value;
@@ -321,7 +325,7 @@ namespace CounterStrikeSharp.API.Modules.Utils
case 1:
this.Y = value;
break;
case 2:
case 2:
this.Z = value;
break;
}
@@ -371,8 +375,8 @@ namespace CounterStrikeSharp.API.Modules.Utils
return $"{X:n2} {Y:n2} {Z:n2}";
}
/*
/*
*/
}
}
}

View File

@@ -42,9 +42,15 @@ namespace CounterStrikeSharp.API
.Where(x => flags.HasFlag(x)).AsEnumerable();
}
public static T GetEntityFromIndex<T>(int index) where T : CEntityInstance
public static T? GetEntityFromIndex<T>(int index) where T : CEntityInstance
{
return (T)Activator.CreateInstance(typeof(T), NativeAPI.GetEntityFromIndex(index))!;
var entityPtr = EntitySystem.GetEntityByIndex((uint)index);
if (entityPtr is null || entityPtr == IntPtr.Zero)
{
return null;
}
return (T)Activator.CreateInstance(typeof(T), entityPtr)!;
}
public static T? CreateEntityByName<T>(string name) where T : CBaseEntity
@@ -52,19 +58,25 @@ namespace CounterStrikeSharp.API
return (T?)Activator.CreateInstance(typeof(T), VirtualFunctions.UTIL_CreateEntityByName(name, -1));
}
public static CCSPlayerController GetPlayerFromIndex(int index)
public static CCSPlayerController? GetPlayerFromIndex(int index)
{
return Utilities.GetEntityFromIndex<CCSPlayerController>(index);
var player = GetEntityFromIndex<CCSPlayerController>(index);
if (player == null || player.DesignerName != "cs_player_controller")
{
return null;
}
return player;
}
public static CCSPlayerController GetPlayerFromSlot(int slot)
public static CCSPlayerController? GetPlayerFromSlot(int slot)
{
return Utilities.GetEntityFromIndex<CCSPlayerController>(slot + 1);
return GetPlayerFromIndex(slot + 1);
}
public static CCSPlayerController GetPlayerFromUserid(int userid)
public static CCSPlayerController? GetPlayerFromUserid(int userid)
{
return Utilities.GetEntityFromIndex<CCSPlayerController>((userid & 0xFF) + 1);
return GetPlayerFromIndex((userid & 0xFF) + 1);
}
public static CCSPlayerController? GetPlayerFromSteamId(ulong steamId)
@@ -87,16 +99,16 @@ namespace CounterStrikeSharp.API
CHandle<CBasePlayerWeapon>? item = null;
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.WeaponServices == null) return false;
foreach(var weapon in player.PlayerPawn.Value.WeaponServices.MyWeapons)
foreach (var weapon in player.PlayerPawn.Value.WeaponServices.MyWeapons)
{
if (weapon is not { IsValid: true, Value.IsValid: true })
if (weapon is not { IsValid: true, Value.IsValid: true })
continue;
if (weapon.Value.DesignerName != designerName)
if (weapon.Value.DesignerName != designerName)
continue;
item = weapon;
}
if (item != null && item.Value != null)
{
player.PlayerPawn.Value.RemovePlayerItem(item.Value);
@@ -108,7 +120,7 @@ namespace CounterStrikeSharp.API
return true;
}
return false;
}
@@ -121,7 +133,7 @@ namespace CounterStrikeSharp.API
yield return new PointerTo<T>(pEntity.Handle).Value;
}
}
public static IEnumerable<CEntityInstance> GetAllEntities()
{
var pEntity = new CEntityIdentity(EntitySystem.FirstActiveEntity);
@@ -130,7 +142,7 @@ namespace CounterStrikeSharp.API
yield return new PointerTo<CEntityInstance>(pEntity.Handle).Value;
}
}
/// <summary>
/// Returns a list of <see cref="CCSPlayerController"/> that are valid and have a valid <see cref="CCSPlayerController.UserId"/> >= 0
/// </summary>
@@ -142,7 +154,7 @@ namespace CounterStrikeSharp.API
{
var controller = GetPlayerFromSlot(i);
if (!controller.IsValid || controller.UserId == -1)
if (controller == null || !controller.IsValid || controller.Connected != PlayerConnectedState.PlayerConnected)
continue;
players.Add(controller);
@@ -198,7 +210,7 @@ namespace CounterStrikeSharp.API
return (T)Activator.CreateInstance(typeof(T), pointerTo)!;
}
private static int FindSchemaChain(string className) => Schema.GetSchemaOffset(className, "__m_pChainEntity");
/// <summary>
@@ -216,10 +228,11 @@ namespace CounterStrikeSharp.API
if (!Schema.IsSchemaFieldNetworked(className, fieldName))
{
Application.Instance.Logger.LogWarning("Field {ClassName}:{FieldName} is not networked, but SetStateChanged was called on it.", className, fieldName);
Application.Instance.Logger.LogWarning(
"Field {ClassName}:{FieldName} is not networked, but SetStateChanged was called on it.", className, fieldName);
return;
}
int offset = Schema.GetSchemaOffset(className, fieldName);
int chainOffset = FindSchemaChain(className);
@@ -235,4 +248,4 @@ namespace CounterStrikeSharp.API
entity.IsSteadyState.Clear();
}
}
}
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -24,18 +24,14 @@ 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 CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Events;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Menu;
using CounterStrikeSharp.API.Modules.Utils;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using static CounterStrikeSharp.API.Core.Listeners;
namespace TestPlugin
{
@@ -56,7 +52,7 @@ namespace TestPlugin
public override string ModuleDescription => "A playground of features used for testing";
public SampleConfig Config { get; set; }
public SampleConfig Config { get; set; } = null!;
// This method is called right before `Load` is called
public void OnConfigParsed(SampleConfig config)
@@ -94,7 +90,6 @@ namespace TestPlugin
SetupGameEvents();
SetupListeners();
SetupCommands();
SetupMenus();
SetupEntityOutputHooks();
// ValveInterface provides pointers to loaded modules via Interface Name exposed from the engine (e.g. Source2Server001)
@@ -114,69 +109,10 @@ namespace TestPlugin
var virtualFunc = VirtualFunction.Create<IntPtr>(server.Pointer, 91);
var result = virtualFunc() - 8;
Logger.LogInformation("Result of virtual func call is {Pointer:X}", result);
_testInjectedClass.Hello();
VirtualFunctions.CBaseTrigger_StartTouchFunc.Hook(h =>
{
var trigger = h.GetParam<CBaseTrigger>(0);
var entity = h.GetParam<CBaseEntity>(1);
Logger.LogInformation("Trigger {Trigger} touched by {Entity}", trigger.DesignerName, entity.DesignerName);
return HookResult.Continue;
}, HookMode.Post);
VirtualFunctions.CBaseTrigger_EndTouchFunc.Hook(h =>
{
var trigger = h.GetParam<CBaseTrigger>(0);
var entity = h.GetParam<CBaseEntity>(1);
Logger.LogInformation("Trigger left {Trigger} by {Entity}", trigger.DesignerName, entity.DesignerName);
return HookResult.Continue;
}, HookMode.Post);
VirtualFunctions.UTIL_RemoveFunc.Hook(hook =>
{
var entityInstance = hook.GetParam<CEntityInstance>(0);
Logger.LogInformation("Removed entity {EntityIndex}", entityInstance.Index);
return HookResult.Continue;
}, HookMode.Post);
VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook((h =>
{
var victim = h.GetParam<CEntityInstance>(0);
var damageInfo = h.GetParam<CTakeDamageInfo>(1);
if (damageInfo.Inflictor.Value.DesignerName == "inferno")
{
var inferno = new CInferno(damageInfo.Inflictor.Value.Handle);
Logger.LogInformation("Owner of inferno is {Owner}", inferno.OwnerEntity);
if (victim == inferno.OwnerEntity.Value)
{
damageInfo.Damage = 0;
}
else
{
damageInfo.Damage = 150;
}
}
return HookResult.Continue;
}), HookMode.Pre);
// Precache resources
RegisterListener<Listeners.OnServerPrecacheResources>((manifest) =>
{
manifest.AddResource("path/to/model");
manifest.AddResource("path/to/material");
manifest.AddResource("path/to/particle");
});
}
public override void OnAllPluginsLoaded(bool hotReload)
{
Logger.LogInformation("All plugins loaded!");
@@ -186,8 +122,7 @@ namespace TestPlugin
{
RegisterListener<Listeners.OnMapStart>(name =>
{
var cheatsCvar = ConVar.Find("sv_cheats");
cheatsCvar.SetValue(true);
ConVar.Find("sv_cheats")?.SetValue(true);
var numericCvar = ConVar.Find("mp_warmuptime");
Logger.LogInformation("mp_warmuptime = {Value}", numericCvar?.GetPrimitiveValue<float>());
@@ -204,67 +139,73 @@ namespace TestPlugin
{
// Register Game Event Handlers
RegisterEventHandler<EventPlayerConnect>(GenericEventHandler, HookMode.Pre);
RegisterEventHandler<EventPlayerChat>(((@event, info) =>
{
var entity = new CCSPlayerController(NativeAPI.GetEntityFromIndex(@event.Userid));
if (!entity.IsValid)
{
Logger.LogInformation("invalid entity");
return HookResult.Continue;
}
RegisterEventHandler<EventPlayerBlind>(GenericEventHandler);
entity.PrintToChat($"You said {@event.Text}");
// Mirrors a chat message back to the player
RegisterEventHandler<EventPlayerChat>(((@event, _) =>
{
var player = Utilities.GetPlayerFromIndex(@event.Userid);
if (player == null) return HookResult.Continue;
player.PrintToChat($"You said {@event.Text}");
return HookResult.Continue;
}));
RegisterEventHandler<EventPlayerDeath>((@event, info) =>
{
// You can use `info.DontBroadcast` to set the dont broadcast flag on the event.
// You can use `info.DontBroadcast` to set the don't broadcast flag on the event.
if (new Random().NextSingle() > 0.5f)
{
@event.Attacker.PrintToChat($"Skipping player_death broadcast at {Server.CurrentTime}");
@event.Attacker?.PrintToChat($"Skipping player_death broadcast at {Server.CurrentTime}");
info.DontBroadcast = true;
}
return HookResult.Continue;
}, HookMode.Pre);
RegisterEventHandler<EventGrenadeBounce>((@event, info) =>
{
Logger.LogInformation("Player {Player} grenade bounce", @event.Userid.PlayerName);
Logger.LogInformation("Player \"{Player}\" grenade bounce", @event.Userid!.PlayerName);
return HookResult.Continue;
}, HookMode.Pre);
RegisterEventHandler<EventPlayerSpawn>((@event, info) =>
{
if (!@event.Userid.IsValid) return 0;
if (!@event.Userid.PlayerPawn.IsValid) return 0;
var player = @event.Userid;
var playerPawn = player?.PlayerPawn.Get();
if (player == null || playerPawn == null) return HookResult.Continue;
Logger.LogInformation("Player spawned with entity index: {EntityIndex} & User ID: {UserId}",
@event.Userid.Index, @event.Userid.UserId);
playerPawn.Index, player.UserId);
return HookResult.Continue;
});
RegisterEventHandler<EventPlayerBlind>(GenericEventHandler);
RegisterEventHandler<EventBulletImpact>((@event, info) =>
{
var player = @event.Userid;
var pawn = player.PlayerPawn.Value;
var activeWeapon = @event.Userid.PlayerPawn.Value.WeaponServices?.ActiveWeapon.Value;
var weapons = @event.Userid.PlayerPawn.Value.WeaponServices?.MyWeapons;
var pawn = player?.PlayerPawn.Get();
var activeWeapon = pawn?.WeaponServices?.ActiveWeapon.Get();
if (pawn == null) return HookResult.Continue;
Server.NextFrame(() =>
{
var weaponServices = player.PlayerPawn.Value.WeaponServices.As<CCSPlayer_WeaponServices>();
player.PrintToChat(weaponServices.ActiveWeapon.Value?.DesignerName);
player?.PrintToChat(activeWeapon?.DesignerName ?? "No Active Weapon");
});
// Set player to random colour
player.PlayerPawn.Value.Render = Color.FromArgb(Random.Shared.Next(0, 255),
Random.Shared.Next(0, 255), Random.Shared.Next(0, 255));
Utilities.SetStateChanged(player.PlayerPawn.Value, "CBaseModelEntity", "m_clrRender");
activeWeapon.ReserveAmmo[0] = 250;
activeWeapon.Clip1 = 250;
// Set player to random colour
pawn.Render = Color.FromArgb(Random.Shared.Next(0, 255),
Random.Shared.Next(0, 255), Random.Shared.Next(0, 255));
Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender");
// Give player 5 health and set their reserve ammo to 250
if (activeWeapon != null)
{
activeWeapon.ReserveAmmo[0] = 250;
activeWeapon.Clip1 = 250;
}
pawn.Health += 5;
Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth");
@@ -279,20 +220,19 @@ namespace TestPlugin
foreach (var player in playerEntities)
{
//var player = new CCSPlayerController(entInst.Handle);
if (player.InGameMoneyServices != null) player.InGameMoneyServices.Account = 1337;
player.InGameMoneyServices!.Account = 1337;
}
// Grab everything starting with cs_, but we'll only mainpulate cs_gamerules.
// Grab everything starting with cs_, but we'll only manipulate cs_gamerules.
// Note: this iterates through all entities, so is an expensive operation.
var csEntities = Utilities.FindAllEntitiesByDesignerName<CBaseEntity>("cs_");
Logger.LogInformation("Amount of cs_* entities: {Count}", csEntities.Count());
var csEntities = Utilities.FindAllEntitiesByDesignerName<CBaseEntity>("cs_").ToArray();
Logger.LogInformation("Amount of cs_* entities: {Count}", csEntities.Length);
foreach (var entity in csEntities)
foreach (var entity in csEntities.Where(x => x.DesignerName == "cs_gamerules"))
{
if (entity.DesignerName != "cs_gamerules") continue;
var gamerulesEnt = new CCSGameRules(entity.Handle);
gamerulesEnt.CTTimeOutActive = true;
// It's safe to cast to `CCSGameRules` here as we know the entity is a cs_gamerules entity.
var gameRules = entity.As<CCSGameRules>();
gameRules.CTTimeOutActive = true;
}
return HookResult.Continue;
@@ -301,26 +241,32 @@ namespace TestPlugin
private void SetupListeners()
{
// Precache resources
RegisterListener<Listeners.OnServerPrecacheResources>((manifest) =>
{
manifest.AddResource("path/to/model");
manifest.AddResource("path/to/material");
manifest.AddResource("path/to/particle");
});
// Hook global listeners defined by CounterStrikeSharp
RegisterListener<Listeners.OnMapStart>(mapName =>
{
Logger.LogInformation("Map {Map} has started!", mapName);
});
RegisterListener<Listeners.OnMapEnd>(() => { Logger.LogInformation($"Map has ended."); });
RegisterListener<Listeners.OnClientConnect>((index, name, ip) =>
RegisterListener<Listeners.OnClientConnect>((playerSlot, name, ip) =>
{
Logger.LogInformation("Client {Name} from {Ip} has connected!", name, ip);
});
RegisterListener<Listeners.OnClientAuthorized>((index, id) =>
RegisterListener<Listeners.OnClientAuthorized>((playerSlot, steamId) =>
{
Logger.LogInformation("Client {Index} with address {Id}", index, id);
Logger.LogInformation("Client {Index} with address {Id}", playerSlot, steamId);
});
RegisterListener<Listeners.OnEntitySpawned>(entity =>
{
var designerName = entity.DesignerName;
switch (designerName)
switch (entity.DesignerName)
{
case "smokegrenade_projectile":
var projectile = entity.As<CSmokeGrenadeProjectile>();
@@ -328,8 +274,8 @@ namespace TestPlugin
Server.NextFrame(() =>
{
projectile.SmokeColor.X = Random.Shared.NextSingle() * 255.0f;
projectile.SmokeColor.X = Random.Shared.NextSingle() * 255.0f;
projectile.SmokeColor.X = Random.Shared.NextSingle() * 255.0f;
projectile.SmokeColor.Y = Random.Shared.NextSingle() * 255.0f;
projectile.SmokeColor.Z = Random.Shared.NextSingle() * 255.0f;
Logger.LogInformation("Smoke grenade spawned with color {SmokeColor}",
projectile.SmokeColor);
});
@@ -343,58 +289,6 @@ namespace TestPlugin
});
}
private void SetupMenus()
{
// [Legacy] Chat Menu Example
var largeMenu = new ChatMenu("Test Menu");
for (int i = 1; i < 26; i++)
{
var i1 = i;
largeMenu.AddMenuOption(new Random().NextSingle().ToString(),
(player, option) => player.PrintToChat($"You just selected {option.Text}"), i1 % 5 == 0);
}
var giveItemMenu = new ChatMenu("Small Menu");
var handleGive = (CCSPlayerController player, ChatMenuOption option) =>
{
player.GiveNamedItem(option.Text);
};
giveItemMenu.AddMenuOption("weapon_ak47", handleGive);
giveItemMenu.AddMenuOption("weapon_p250", handleGive);
AddCommand("css_target", "Target Test", (player, info) =>
{
if (player == null) return;
var targetResult = info.GetArgTargetResult(1);
if (!targetResult.Any())
{
player.PrintToChat("No players found.");
return;
}
foreach (var result in targetResult.Players)
{
player.PrintToChat($"Target found: {result?.PlayerName}");
}
});
AddCommand("css_menu", "Opens example menu", (player, info) => { ChatMenus.OpenMenu(player, largeMenu); });
AddCommand("css_gunmenu", "Gun Menu", (player, info) => { ChatMenus.OpenMenu(player, giveItemMenu); });
for (int i = 1; i <= 9; i++)
{
AddCommand("css_" + i, "Command Key Handler", (player, info) =>
{
if (player == null) return;
var key = Convert.ToInt32(info.GetArg(0).Split("_")[1]);
ChatMenus.OnKeyPress(player, key);
});
}
}
private void SetupCommands()
{
// Adds a new server console command
@@ -407,24 +301,17 @@ namespace TestPlugin
((SteamID)player.SteamID).SteamId2, info.ArgString);
});
AddCommand("css_changeteam", "change team", (player, info) =>
AddCommand("css_changeteam", "change team", (player, _) =>
{
if (player?.IsValid != true) return;
if (player == null) return;
if ((CsTeam)player.TeamNum == CsTeam.Terrorist)
{
player.ChangeTeam(CsTeam.CounterTerrorist);
}
else
{
player.ChangeTeam(CsTeam.Terrorist);
}
player.ChangeTeam((CsTeam)player.TeamNum == CsTeam.Terrorist ? CsTeam.CounterTerrorist : CsTeam.Terrorist);
});
// Listens for any client use of the command `jointeam`.
AddCommandListener("jointeam", (player, info) =>
{
Logger.LogInformation("{PlayerName} just did a jointeam (pre) [{ArgString}]", player.PlayerName,
Logger.LogInformation("{PlayerName} just did a jointeam (pre) [{ArgString}]", player?.PlayerName,
info.ArgString);
return HookResult.Continue;
@@ -433,21 +320,21 @@ namespace TestPlugin
private void SetupEntityOutputHooks()
{
HookEntityOutput("weapon_knife", "OnPlayerPickup", (output, name, activator, caller, value, delay) =>
HookEntityOutput("weapon_knife", "OnPlayerPickup", (output, _, activator, caller, _, delay) =>
{
Logger.LogInformation("weapon_knife called OnPlayerPickup ({name}, {activator}, {caller}, {delay})", output.Description.Name, activator.DesignerName, caller.DesignerName, delay);
return HookResult.Continue;
});
HookEntityOutput("*", "*", (output, name, activator, caller, value, delay) =>
HookEntityOutput("*", "*", (output, _, activator, caller, _, delay) =>
{
Logger.LogInformation("All EntityOutput ({name}, {activator}, {caller}, {delay})", output.Description.Name, activator.DesignerName, caller.DesignerName, delay);
return HookResult.Continue;
});
HookEntityOutput("*", "OnStartTouch", (output, name, activator, caller, value, delay) =>
HookEntityOutput("*", "OnStartTouch", (_, name, activator, caller, _, delay) =>
{
Logger.LogInformation("OnStartTouch: ({name}, {activator}, {caller}, {delay})", name, activator.DesignerName, caller.DesignerName, delay);
return HookResult.Continue;
@@ -470,49 +357,59 @@ namespace TestPlugin
return HookResult.Continue;
}
[ConsoleCommand("css_testinput", "Test AcceptInput and AddEntityIOEvent")]
public void OnTestInput(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
var pawn = player.PlayerPawn.Get();
if (pawn == null) return;
pawn!.AcceptInput("SetHealth", null, null, "50");
pawn!.AddEntityIOEvent("SetHealth", null, null, "75", 5);
}
[ConsoleCommand("css_killmeplease", "Kills the player")]
[ConsoleCommand("css_killme", "Kills the player")]
public void OnKillme(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
if (!player.PlayerPawn.IsValid) return;
var pawn = player.PlayerPawn.Get();
if (pawn == null) return;
player.PlayerPawn.Value.CommitSuicide(true, true);
pawn.CommitSuicide(true, true);
}
[CommandHelper(minArgs: 1, usage: "[weaponName]")]
[ConsoleCommand("css_strip", "Removes weapon by name")]
public void OnStripActiveWeapon(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
if (!player.PlayerPawn.IsValid) return;
if (player == null || player.PlayerPawn.Get() == null) return;
player.RemoveItemByDesignerName(command.GetArg(1));
}
[ConsoleCommand("css_stripweapons", "Removes player weapons")]
public void OnStripWeapons(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
if (!player.PlayerPawn.IsValid) return;
if (player == null || player.PlayerPawn.Get() == null) return;
player.RemoveWeapons();
}
[ConsoleCommand("css_teleportup", "Teleports the player up")]
public void OnTeleport(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
if (!player.PlayerPawn.IsValid) return;
var pawn = player.PlayerPawn.Get();
if (pawn == null) return;
player.PlayerPawn.Value.Teleport(player.PlayerPawn.Value.AbsOrigin.With(z: player.PlayerPawn.Value.AbsOrigin.Z + 100), player.PlayerPawn.Value.AbsRotation, new Vector(IntPtr.Zero));
pawn.Teleport(pawn.AbsOrigin!.With(z: pawn.AbsOrigin.Z + 100), pawn.AbsRotation, new Vector(IntPtr.Zero));
}
[ConsoleCommand("css_respawn", "Respawns the player")]
public void OnRespawn(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
if (!player.PlayerPawn.IsValid) return;
if (player == null || player.PlayerPawn.Get() == null) return;
player.Respawn();
}
@@ -527,7 +424,7 @@ namespace TestPlugin
entity.AcceptInput("Break");
}
}
[ConsoleCommand("css_fov", "Sets the player's FOV")]
[CommandHelper(minArgs: 1, usage: "[fov]")]
public void OnFovCommand(CCSPlayerController? player, CommandInfo command)
@@ -557,7 +454,7 @@ namespace TestPlugin
}
else
{
player.PrintToChat($"Level \"{mapName}\" is invalid.");
command.ReplyToCommand($"Level \"{mapName}\" is invalid.");
}
}
@@ -565,15 +462,19 @@ namespace TestPlugin
public void OnCommandGuns(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
if (!player.PlayerPawn.IsValid) return;
var pawn = player.PlayerPawn.Get();
if (pawn == null) return;
foreach (var weapon in player.PlayerPawn.Value.WeaponServices.MyWeapons)
foreach (var weapon in pawn.WeaponServices!.MyWeapons)
{
var vData = weapon.Value.As<CCSWeaponBase>().VData;
command.ReplyToCommand(string.Format("{0}, {1}, {2}, {3}, {4}, {5}", vData.Name, vData.GearSlot, vData.Price, vData.WeaponCategory, vData.WeaponType, vData.KillAward));
var vData = weapon.Get()?.As<CCSWeaponBase>().VData;
if (vData == null) continue;
command.ReplyToCommand(
$"{vData.Name}, {vData.GearSlot}, {vData.Price}, {vData.WeaponCategory}, {vData.WeaponType}, {vData.KillAward}");
}
}
[ConsoleCommand("css_entities", "List entities")]
public void OnCommandEntities(CCSPlayerController? player, CommandInfo command)
{
@@ -581,13 +482,13 @@ namespace TestPlugin
{
command.ReplyToCommand($"{entity.Index}:{entity.DesignerName}");
}
foreach (var entity in Utilities.FindAllEntitiesByDesignerName<CBaseEntity>("cs_"))
{
command.ReplyToCommand($"{entity.Index}:{entity.DesignerName}");
}
}
[ConsoleCommand("css_colors", "List Chat Colors")]
public void OnCommandColors(CCSPlayerController? player, CommandInfo command)
{
@@ -599,14 +500,14 @@ namespace TestPlugin
command.ReplyToCommand($" {(char)i}Color 0x{i:x}");
}
}
[ConsoleCommand("css_localetest", "Test Translations")]
public void OnCommandLocaleTest(CCSPlayerController? player, CommandInfo command)
{
Logger.LogInformation("Current Culture is {Culture}", CultureInfo.CurrentCulture);
command.ReplyToCommand(Localizer["testPlugin.maxPlayersAnnouncement", Server.MaxPlayers]);
}
[ConsoleCommand("css_sound", "Play a sound to client")]
public void OnCommandSound(CCSPlayerController? player, CommandInfo command)
{

View File

@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj">
<Private>false</Private>
</ProjectReference>
</ProjectReference>
</ItemGroup>
<ItemGroup>

View File

@@ -1,130 +0,0 @@
#pragma once
#include <array>
#include <cstdint>
#include <vector>
using UtlTsHashHandleT = std::uint64_t;
class CUtlMemoryPool {
public:
// returns number of allocated blocks
int BlockSize() const {
return m_blocks_per_blob_;
}
int Count() const {
return m_block_allocated_size_;
}
int PeakCount() const {
return m_peak_alloc_;
}
private:
std::int32_t m_block_size_ = 0; // 0x0558
std::int32_t m_blocks_per_blob_ = 0; // 0x055C
std::int32_t m_grow_mode_ = 0; // 0x0560
std::int32_t m_blocks_allocated_ = 0; // 0x0564
std::int32_t m_block_allocated_size_ = 0; // 0x0568
std::int32_t m_peak_alloc_ = 0; // 0x056C
};
template <class T, class Keytype = std::uint64_t>
class CUtlTSHash {
public:
// Invalid handle.
static UtlTsHashHandleT InvalidHandle(void) {
return static_cast<UtlTsHashHandleT>(0);
}
// Returns the number of elements in the hash table
[[nodiscard]] int BlockSize() const {
return m_entry_memory_.BlockSize();
}
[[nodiscard]] int Count() const {
return m_entry_memory_.Count();
}
// Returns elements in the table
std::vector<T> GetElements(void);
public:
// Templatized for memory tracking purposes
template <typename DataT>
struct HashFixedDataInternalT {
Keytype m_ui_key;
HashFixedDataInternalT<DataT>* m_next;
DataT m_data;
};
using HashFixedDataT = HashFixedDataInternalT<T>;
// Templatized for memory tracking purposes
template <typename DataT>
struct HashFixedStructDataInternalT {
DataT m_data;
Keytype m_ui_key;
char pad_0x0020[0x8];
};
using HashFixedStructDataT = HashFixedStructDataInternalT<T>;
struct HashStructDataT {
char pad_0x0000[0x10]; // 0x0000
std::array<HashFixedStructDataT, 256> m_list;
};
struct HashAllocatedDataT {
public:
auto GetList() {
return m_list_;
}
private:
char pad_0x0000[0x18]; // 0x0000
std::array<HashFixedDataT, 128> m_list_;
};
// Templatized for memory tracking purposes
template <typename DataT>
struct HashBucketDataInternalT {
DataT m_data;
HashFixedDataInternalT<DataT>* m_next;
Keytype m_ui_key;
};
using HashBucketDataT = HashBucketDataInternalT<T>;
struct HashUnallocatedDataT {
HashUnallocatedDataT* m_next_ = nullptr; // 0x0000
Keytype m_6114; // 0x0008
Keytype m_ui_key; // 0x0010
Keytype m_i_unk_1; // 0x0018
std::array<HashBucketDataT, 256> m_current_block_list; // 0x0020
};
struct HashBucketT {
HashStructDataT* m_struct_data = nullptr;
void* m_mutex_list = nullptr;
HashAllocatedDataT* m_allocated_data = nullptr;
HashUnallocatedDataT* m_unallocated_data = nullptr;
};
CUtlMemoryPool m_entry_memory_;
HashBucketT m_buckets_;
bool m_needs_commit_ = false;
};
template <class T, class Keytype>
std::vector<T> CUtlTSHash<T, Keytype>::GetElements(void) {
std::vector<T> list;
const int n_count = Count();
auto n_index = 0;
auto& unallocated_data = m_buckets_.m_unallocated_data;
for (auto element = unallocated_data; element; element = element->m_next_) {
for (auto i = 0; i < BlockSize() && i != n_count; i++) {
list.emplace_back(element->m_current_block_list.at(i).m_data);
n_index++;
if (n_index >= n_count)
break;
}
}
return list;
}

View File

@@ -32,7 +32,5 @@ void interfaces::Initialize() {
g_pCVar = (ICvar*)modules::tier0->FindInterface(CVAR_INTERFACE_VERSION);
g_pSource2GameEntities = (ISource2GameEntities*)modules::server->FindInterface(
SOURCE2GAMEENTITIES_INTERFACE_VERSION);
pSchemaSystem =
(CSchemaSystem*)modules::schemasystem->FindInterface(SCHEMASYSTEM_INTERFACE_VERSION);
}
} // namespace counterstrikesharp

View File

@@ -20,13 +20,11 @@
#pragma once
#include "cgameresourceserviceserver.h"
#include "cschemasystem.h"
namespace counterstrikesharp {
namespace interfaces {
void Initialize();
inline CGameResourceService *pGameResourceServiceServer = nullptr;
inline CSchemaSystem *pSchemaSystem = nullptr;
} // namespace interfaces
} // namespace counterstrikesharp

View File

@@ -1,418 +0,0 @@
// Copyright (C) 2023 neverlosecc
// See end of file for extended copyright information.
/**
* =============================================================================
* Source2Gen
* Copyright (C) 2023 neverlose (https://github.com/neverlosecc/source2gen)
* =============================================================================
**/
#pragma once
#include <vector>
#include <utils/virtual.h>
#include <string_view>
#include <array>
#include "core/cs2_sdk/interfaces/CUtlTSHash.h"
#define CS2
#define CSCHEMATYPE_GETSIZES_INDEX 3
#define SCHEMASYSTEM_TYPE_SCOPES_OFFSET 0x190
#define SCHEMASYSTEMTYPESCOPE_OFF1 0x47E
#define SCHEMASYSTEMTYPESCOPE_OFF2 0x2808
#define SCHEMASYSTEM_FIND_DECLARED_CLASS_TYPE 2
class CSchemaClassInfo;
class CSchemaSystemTypeScope;
class CSchemaType;
struct SchemaMetadataEntryData_t;
struct SchemaMetadataSetData_t;
struct SchemaClassInfoData_t;
using SchemaString_t = const char*;
template <typename T> struct SchemaArray
{
public:
T* begin() const { return m_data; }
T* end() const { return m_data + m_size; }
T* m_data;
unsigned int m_size;
};
struct CSchemaNetworkValue
{
union
{
const char* m_sz_value;
int m_n_value;
float m_f_value;
std::uintptr_t m_p_value;
};
};
struct CSchemaClassBinding
{
CSchemaClassBinding* parent;
const char* m_binary_name; // ex: C_World
const char* m_module_name; // ex: libclient.so
const char* m_class_name; // ex: client
void* m_class_info_old_synthesized;
void* m_class_info;
void* m_this_module_binding_pointer;
CSchemaType* m_schema_type;
};
struct SchemaEnumeratorInfoData_t
{
SchemaString_t m_name;
union
{
unsigned char m_value_char;
unsigned short m_value_short;
unsigned int m_value_int;
unsigned long long m_value;
};
char pad_0x0010[0x10]; // 0x0010
};
class CSchemaEnumInfo
{
public:
SchemaEnumeratorInfoData_t m_field_;
};
class CSchemaEnumBinding
{
public:
virtual const char* GetBindingName() = 0;
virtual CSchemaClassBinding* AsClassBinding() = 0;
virtual CSchemaEnumBinding* AsEnumBinding() = 0;
virtual const char* GetBinaryName() = 0;
virtual const char* GetProjectName() = 0;
public:
char* m_binding_name_; // 0x0008
char* m_dll_name_; // 0x0010
std::int8_t m_align_; // 0x0018
char pad_0x0019[0x3]; // 0x0019
std::int16_t m_size_; // 0x001C
std::int16_t m_flags_; // 0x001E
SchemaEnumeratorInfoData_t* m_enum_info_;
char pad_0x0028[0x8]; // 0x0028
CSchemaSystemTypeScope* m_type_scope_; // 0x0030
char pad_0x0038[0x8]; // 0x0038
std::int32_t m_i_unk1_; // 0x0040
};
enum SchemaClassFlags_t
{
SCHEMA_CLASS_HAS_VIRTUAL_MEMBERS = 1,
SCHEMA_CLASS_IS_ABSTRACT = 2,
SCHEMA_CLASS_HAS_TRIVIAL_CONSTRUCTOR = 4,
SCHEMA_CLASS_HAS_TRIVIAL_DESTRUCTOR = 8,
SCHEMA_CLASS_TEMP_HACK_HAS_NOSCHEMA_MEMBERS = 16,
SCHEMA_CLASS_TEMP_HACK_HAS_CONSTRUCTOR_LIKE_METHODS = 32,
SCHEMA_CLASS_TEMP_HACK_HAS_DESTRUCTOR_LIKE_METHODS = 64,
SCHEMA_CLASS_IS_NOSCHEMA_CLASS = 128,
};
enum ETypeCategory
{
Schema_Builtin = 0,
Schema_Ptr = 1,
Schema_Bitfield = 2,
Schema_FixedArray = 3,
Schema_Atomic = 4,
Schema_DeclaredClass = 5,
Schema_DeclaredEnum = 6,
Schema_None = 7
};
enum EAtomicCategory
{
Atomic_Basic,
Atomic_T,
Atomic_CollectionOfT,
Atomic_TT,
Atomic_I,
Atomic_None
};
#define __thiscall
class CSchemaType
{
public:
bool GetSizes(int* out_size1, uint8_t* unk_probably_not_size)
{
return reinterpret_cast<int(__thiscall*)(void*, int*, uint8_t*)>(
_vtable[CSCHEMATYPE_GETSIZES_INDEX])(this, out_size1, unk_probably_not_size);
}
public:
bool GetSize(int* out_size)
{
uint8_t smh = 0;
return GetSizes(out_size, &smh);
}
public:
uintptr_t* _vtable; // 0x0000
const char* m_name_; // 0x0008
CSchemaSystemTypeScope* m_type_scope_; // 0x0010
uint8_t type_category; // ETypeCategory 0x0018
uint8_t atomic_category; // EAtomicCategory 0x0019
// find out to what class pointer points.
CSchemaType* GetRefClass()
{
if (type_category != Schema_Ptr)
return nullptr;
auto ptr = m_schema_type_;
while (ptr && ptr->type_category == ETypeCategory::Schema_Ptr)
ptr = ptr->m_schema_type_;
return ptr;
}
struct array_t
{
uint32_t array_size;
uint32_t unknown;
CSchemaType* element_type_;
};
struct generic_type_t
{
uint64_t unknown;
const char* m_name_; // 0x0008
};
struct atomic_t
{ // same goes for CollectionOfT
generic_type_t* generic_type;
uint64_t unknown;
CSchemaType* template_typename;
};
struct atomic_tt
{
uint64_t gap[2];
CSchemaType* templates[2];
};
struct atomic_i
{
uint64_t gap[2];
uint64_t integer;
};
// this union depends on CSchema implementation, all members above
// is from base class ( CSchemaType )
union // 0x020
{
CSchemaType* m_schema_type_;
CSchemaClassInfo* m_class_info;
CSchemaEnumBinding* m_enum_binding_;
array_t m_array_;
atomic_t m_atomic_t_;
atomic_tt m_atomic_tt_;
atomic_i m_atomic_i_;
};
};
static_assert(offsetof(CSchemaType, m_schema_type_) == 0x20);
struct SchemaMetadataEntryData_t
{
SchemaString_t m_name;
CSchemaNetworkValue* m_value;
// CSchemaType* m_pDataType;
// void* unaccounted;
};
struct SchemaMetadataSetData_t
{
SchemaMetadataEntryData_t m_static_entries;
};
struct SchemaClassFieldData_t
{
SchemaString_t m_name; // 0x0000
CSchemaType* m_type; // 0x0008
std::int32_t m_single_inheritance_offset; // 0x0010
std::int32_t m_metadata_size; // 0x0014
SchemaMetadataEntryData_t* m_metadata; // 0x0018
};
struct SchemaStaticFieldData_t
{
const char* name; // 0x0000
CSchemaType* m_type; // 0x0008
void* m_instance; // 0x0010
char pad_0x0018[0x10]; // 0x0018
};
struct SchemaBaseClassInfoData_t
{
unsigned int m_offset;
CSchemaClassInfo* m_class;
};
// Classes
struct SchemaClassInfoData_t
{
char pad_0x0000[0x8]; // 0x0000
const char* m_name; // 0x0008
char* m_module; // 0x0010
int m_size; // 0x0018
std::int16_t m_align; // 0x001C
std::int16_t m_static_size; // 0x001E
std::int16_t m_metadata_size; // 0x0020
std::int16_t m_i_unk1; // 0x0022
std::int16_t m_i_unk2; // 0x0024
std::int16_t m_i_unk3; // 0x0026
SchemaClassFieldData_t* m_fields; // 0x0028
SchemaStaticFieldData_t* m_static_fields; // 0x0030
SchemaBaseClassInfoData_t* m_schema_parent; // 0x0038
char pad_0x0038[0x10]; // 0x0038
SchemaMetadataSetData_t* m_metadata; // 0x0048
CSchemaSystemTypeScope* m_type_scope; // 0x0050
CSchemaType* m_shema_type; // 0x0058
SchemaClassFlags_t m_class_flags : 8; // 0x0060
};
class CSchemaClassInfo : public SchemaClassInfoData_t
{
public:
bool GetMetaStrings(const char* metaName, std::vector<const char**>& strings);
unsigned int CalculateInheritanceDataSize(bool ignoreVirtuals = false);
bool DependsOn(CSchemaClassInfo* other);
bool InheritsFrom(CSchemaClassInfo* other);
bool UsesClass(CSchemaClassInfo* other);
bool InheritsVirtuals();
void FillClassFieldsList(std::vector<SchemaClassFieldData_t*>& fields);
void FillInheritanceList(std::vector<const char*>& inheritance);
CSchemaClassInfo* GetParent()
{
if (!m_schema_parent)
return nullptr;
return m_schema_parent->m_class;
}
private:
};
class CSchemaSystemTypeScope
{
public:
CSchemaClassInfo* FindDeclaredClass(const char* class_name)
{
#ifdef _WIN32
CSchemaClassInfo* rv = nullptr;
CALL_VIRTUAL(void, 2, this, &rv, class_name);
return rv;
#else
return CALL_VIRTUAL(CSchemaClassInfo*, 2, this, class_name);
#endif
}
CSchemaEnumBinding* FindDeclaredEnum(const char* name)
{
#ifdef _WIN32
CSchemaEnumBinding* rv = nullptr;
CALL_VIRTUAL(void, 3, this, &rv, name);
return rv;
#else
return CALL_VIRTUAL(CSchemaEnumBinding*, 3, this, name);
#endif
}
CSchemaType* FindSchemaTypeByName(const char* name, std::uintptr_t* pSchema)
{
return CALL_VIRTUAL(CSchemaType*, 4, this, name, pSchema);
}
CSchemaType* FindTypeDeclaredClass(const char* name)
{
return CALL_VIRTUAL(CSchemaType*, 5, this, name);
}
CSchemaType* FindTypeDeclaredEnum(const char* name)
{
return CALL_VIRTUAL(CSchemaType*, 6, this, name);
}
CSchemaClassBinding* FindRawClassBinding(const char* name)
{
return CALL_VIRTUAL(CSchemaClassBinding*, 7, this, name);
}
CSchemaEnumBinding* FindRawEnumBinding(const char* name)
{
return CALL_VIRTUAL(CSchemaEnumBinding*, 8, this, name);
}
std::string_view GetScopeName() { return {m_name_.data()}; }
[[nodiscard]] CUtlTSHash<CSchemaClassBinding*> GetClasses() const { return m_classes_; }
[[nodiscard]] CUtlTSHash<CSchemaEnumBinding*> GetEnums() const { return m_enumes_; }
private:
char pad_0x0000[0x8]; // 0x0000
std::array<char, 256> m_name_ = {};
char pad_0x0108[SCHEMASYSTEMTYPESCOPE_OFF1]; // 0x0108
CUtlTSHash<CSchemaClassBinding*> m_classes_; // 0x0588
char pad_0x0594[SCHEMASYSTEMTYPESCOPE_OFF2]; // 0x05C8
CUtlTSHash<CSchemaEnumBinding*> m_enumes_; // 0x2DD0
private:
static constexpr unsigned int s_class_list = 0x580;
};
class CSchemaSystem
{
public:
CSchemaSystemTypeScope* GlobalTypeScope(void)
{
return CALL_VIRTUAL(CSchemaSystemTypeScope*, 11, this);
}
CSchemaSystemTypeScope* FindTypeScopeForModule(const char* m_module_name)
{
return CALL_VIRTUAL(CSchemaSystemTypeScope*, 13, this, m_module_name, nullptr);
}
};
// 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.

View File

@@ -25,6 +25,7 @@
#include "core/log.h"
#include "tier1/utlmap.h"
#include <schemasystem.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@@ -33,9 +34,9 @@ using SchemaKeyValueMap_t = CUtlMap<uint32_t, SchemaKey>;
using SchemaTableMap_t = CUtlMap<uint32_t, SchemaKeyValueMap_t*>;
bool IsFieldNetworked(SchemaClassFieldData_t& field) {
for (int i = 0; i < field.m_metadata_size; i++) {
for (int i = 0; i < field.m_nStaticMetadataCount; i++) {
static auto networkEnabled = hash_32_fnv1a_const("MNetworkEnable");
if (networkEnabled == hash_32_fnv1a_const(field.m_metadata[i].m_name)) return true;
if (networkEnabled == hash_32_fnv1a_const(field.m_pStaticMetadata[i].m_pszName)) return true;
}
return false;
@@ -44,12 +45,11 @@ bool IsFieldNetworked(SchemaClassFieldData_t& field) {
static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
const char* className,
uint32_t classKey) {
CSchemaSystemTypeScope* pType =
counterstrikesharp::interfaces::pSchemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
CSchemaSystemTypeScope* pType = counterstrikesharp::globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
if (!pType) return false;
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className);
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className).Get();
if (!pClassInfo) {
SchemaKeyValueMap_t* map = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
@@ -59,8 +59,8 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
return false;
}
short fieldsSize = pClassInfo->m_align;
SchemaClassFieldData_t* pFields = pClassInfo->m_fields;
short fieldsSize = pClassInfo->m_nFieldCount;
SchemaClassFieldData_t* pFields = pClassInfo->m_pFields;
SchemaKeyValueMap_t* keyValueMap = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
keyValueMap->EnsureCapacity(fieldsSize);
@@ -69,8 +69,8 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
for (int i = 0; i < fieldsSize; ++i) {
SchemaClassFieldData_t& field = pFields[i];
keyValueMap->Insert(hash_32_fnv1a_const(field.m_name),
{field.m_single_inheritance_offset, IsFieldNetworked(field)});
keyValueMap->Insert(hash_32_fnv1a_const(field.m_pszName),
{field.m_nSingleInheritanceOffset, IsFieldNetworked(field)});
}
return true;
@@ -78,23 +78,23 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
int16_t schema::FindChainOffset(const char* className) {
CSchemaSystemTypeScope* pType =
counterstrikesharp::interfaces::pSchemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
counterstrikesharp::globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
if (!pType) return false;
auto* pClassInfo = pType->FindDeclaredClass(className);
auto* pClassInfo = pType->FindDeclaredClass(className).Get();
do {
SchemaClassFieldData_t* pFields = pClassInfo->m_fields;
short fieldsSize = pClassInfo->m_align;
SchemaClassFieldData_t* pFields = pClassInfo->m_pFields;
short fieldsSize = pClassInfo->m_nFieldCount;
for (int i = 0; i < fieldsSize; ++i) {
SchemaClassFieldData_t& field = pFields[i];
if (V_strcmp(field.m_name, "__m_pChainEntity") == 0) {
return field.m_single_inheritance_offset;
if (V_strcmp(field.m_pszName, "__m_pChainEntity") == 0) {
return field.m_nSingleInheritanceOffset;
}
}
} while ((pClassInfo = pClassInfo->GetParent()) != nullptr);
} while ((pClassInfo = pClassInfo->m_pBaseClasses->m_pClass) != nullptr);
return 0;
}

View File

@@ -1,4 +1,5 @@
#include "core/gameconfig.h"
#include <fstream>
#include "log.h"
@@ -13,7 +14,8 @@ CGameConfig::~CGameConfig() = default;
bool CGameConfig::Init(char* conf_error, int conf_error_size)
{
std::ifstream ifs(m_sPath);
if (!ifs) {
if (!ifs)
{
V_snprintf(conf_error, conf_error_size, "Gamedata file not found.");
return false;
}
@@ -26,44 +28,53 @@ bool CGameConfig::Init(char* conf_error, int conf_error_size)
constexpr auto platform = "linux";
#endif
try {
for (auto& [k, v] : m_json.items()) {
if (v.contains("signatures")) {
if (auto library = v["signatures"]["library"]; library.is_string()) {
try
{
for (auto& [k, v] : m_json.items())
{
if (v.contains("signatures"))
{
if (auto library = v["signatures"]["library"]; library.is_string())
{
m_umLibraries[k] = library.get<std::string>();
}
if (auto signature = v["signatures"][platform]; signature.is_string()) {
if (auto signature = v["signatures"][platform]; signature.is_string())
{
m_umSignatures[k] = signature.get<std::string>();
}
}
if (v.contains("offsets")) {
if (auto offset = v["offsets"][platform]; offset.is_number_integer()) {
if (v.contains("offsets"))
{
if (auto offset = v["offsets"][platform]; offset.is_number_integer())
{
m_umOffsets[k] = offset.get<std::int64_t>();
}
}
if (v.contains("patches")) {
if (auto patch = v["patches"][platform]; patch.is_string()) {
if (v.contains("patches"))
{
if (auto patch = v["patches"][platform]; patch.is_string())
{
m_umPatches[k] = patch.get<std::string>();
}
}
}
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
V_snprintf(conf_error, conf_error_size, "Failed to parse gamedata file: %s", ex.what());
return false;
}
return true;
}
const std::string CGameConfig::GetPath()
{
return m_sPath;
}
const std::string CGameConfig::GetPath() { return m_sPath; }
const char* CGameConfig::GetLibrary(const std::string& name)
{
// My recommendation is switch to C++20.
auto it = m_umLibraries.find(name);
if (it == m_umLibraries.end()) {
if (it == m_umLibraries.end())
{
return nullptr;
}
return it->second.c_str();
@@ -72,7 +83,8 @@ const char* CGameConfig::GetLibrary(const std::string& name)
const char* CGameConfig::GetSignature(const std::string& name)
{
auto it = m_umSignatures.find(name);
if (it == m_umSignatures.end()) {
if (it == m_umSignatures.end())
{
return nullptr;
}
return it->second.c_str();
@@ -82,7 +94,8 @@ const char* CGameConfig::GetSymbol(const char* name)
{
const char* symbol = this->GetSignature(name);
if (!symbol || strlen(symbol) <= 1) {
if (!symbol || strlen(symbol) <= 1)
{
CSSHARP_CORE_ERROR("Missing symbol: {}\n", name);
return nullptr;
}
@@ -92,7 +105,8 @@ const char* CGameConfig::GetSymbol(const char* name)
const char* CGameConfig::GetPatch(const std::string& name)
{
auto it = m_umPatches.find(name);
if (it == m_umPatches.end()) {
if (it == m_umPatches.end())
{
return nullptr;
}
return it->second.c_str();
@@ -101,14 +115,14 @@ const char* CGameConfig::GetPatch(const std::string& name)
int CGameConfig::GetOffset(const std::string& name)
{
auto it = m_umOffsets.find(name);
if (it == m_umOffsets.end()) {
if (it == m_umOffsets.end())
{
return -1;
}
return it->second;
}
void* CGameConfig::GetAddress(const std::string& name, void* engine, void* server, char* error,
int maxlen)
void* CGameConfig::GetAddress(const std::string& name, void* engine, void* server, char* error, int maxlen)
{
CSSHARP_CORE_ERROR("Not implemented.");
return nullptr;
@@ -117,11 +131,9 @@ void* CGameConfig::GetAddress(const std::string& name, void* engine, void* serve
modules::CModule** CGameConfig::GetModule(const char* name)
{
const char* library = this->GetLibrary(name);
if (!library)
return nullptr;
if (!library) return nullptr;
if (strcmp(library, "engine") == 0)
return &modules::engine;
if (strcmp(library, "engine") == 0) return &modules::engine;
else if (strcmp(library, "server") == 0)
return &modules::server;
else if (strcmp(library, "vscript") == 0)
@@ -135,7 +147,8 @@ modules::CModule** CGameConfig::GetModule(const char* name)
bool CGameConfig::IsSymbol(const char* name)
{
const char* sigOrSymbol = this->GetSignature(name);
if (!sigOrSymbol || strlen(sigOrSymbol) <= 0) {
if (!sigOrSymbol || strlen(sigOrSymbol) <= 0)
{
CSSHARP_CORE_ERROR("Missing signature or symbol: {}\n", name);
return false;
}
@@ -145,34 +158,37 @@ bool CGameConfig::IsSymbol(const char* name)
void* CGameConfig::ResolveSignature(const char* name)
{
modules::CModule** module = this->GetModule(name);
if (!module || !(*module)) {
if (!module || !(*module))
{
CSSHARP_CORE_ERROR("Invalid Module {}\n", name);
return nullptr;
}
void* address = nullptr;
if (this->IsSymbol(name)) {
if (this->IsSymbol(name))
{
const char* symbol = this->GetSymbol(name);
if (!symbol) {
if (!symbol)
{
CSSHARP_CORE_ERROR("Invalid symbol for {}\n", name);
return nullptr;
}
address = dlsym((*module)->m_hModule, symbol);
} else {
address = (*module)->FindSymbol(symbol);
}
else
{
const char* signature = this->GetSignature(name);
if (!signature) {
if (!signature)
{
CSSHARP_CORE_ERROR("Failed to find signature for {}\n", name);
return nullptr;
}
size_t iLength = 0;
byte* pSignature = HexToByte(signature, iLength);
if (!pSignature) {
return nullptr;
}
address = (*module)->FindSignature(pSignature, iLength);
address = (*module)->FindSignature(signature);
}
if (!address) {
if (!address)
{
CSSHARP_CORE_ERROR("Failed to find address for {}\n", name);
return nullptr;
}
@@ -184,53 +200,74 @@ std::string CGameConfig::GetDirectoryName(const std::string& directoryPathInput)
std::string directoryPath = std::string(directoryPathInput);
size_t found = std::string(directoryPath).find_last_of("/\\");
if (found != std::string::npos) {
if (found != std::string::npos)
{
return std::string(directoryPath, found + 1);
}
return "";
}
int CGameConfig::HexStringToUint8Array(const char* hexString, uint8_t* byteArray, size_t maxBytes)
std::vector<int16_t> CGameConfig::HexToByte(std::string_view src)
{
if (!hexString) {
printf("Invalid hex string.\n");
if (src.empty())
{
return {};
}
auto hex_char_to_byte = [](char c) -> int16_t {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
// a valid hex char can never go up to 0xFF
return -1;
}
};
size_t hexStringLength = strlen(hexString);
size_t byteCount = hexStringLength / 4; // Each "\\x" represents one byte.
std::vector<int16_t> result{};
if (hexStringLength % 4 != 0 || byteCount == 0 || byteCount > maxBytes) {
printf("Invalid hex string format or byte count.\n");
return -1; // Return an error code.
}
const bool is_code_style = src[0] == '\\';
for (size_t i = 0; i < hexStringLength; i += 4) {
if (sscanf(hexString + i, "\\x%2hhX", &byteArray[i / 4]) != 1) {
printf("Failed to parse hex string at position %zu.\n", i);
return -1; // Return an error code.
const std::string_view pattern = is_code_style ? R"(\x)" : " ";
const std::string_view wildcard = is_code_style ? "2A" : "?";
std::string::size_type pos = 0;
while (pos < src.size())
{
std::string::size_type found = src.find(pattern, pos);
if (found == std::string::npos)
{
found = src.size();
}
std::string_view str = src.substr(pos, found - pos);
pos = found + pattern.size();
if (str.empty()) continue;
std::string byte(str.data(), str.size());
if (byte.substr(0, wildcard.size()) == wildcard)
{
result.emplace_back(-1);
continue;
}
if (byte.size() < 2)
{
return {};
}
const auto high = hex_char_to_byte(byte[0]);
const auto low = hex_char_to_byte(byte[1]);
if (high == 0xFF || low == 0xFF)
{
return {};
}
result.emplace_back((high << 4) | low);
}
byteArray[byteCount] = '\0'; // Add a null-terminating character.
return byteCount; // Return the number of bytes successfully converted.
return result;
}
byte* CGameConfig::HexToByte(const char* src, size_t& length)
{
if (!src || strlen(src) <= 0) {
CSSHARP_CORE_INFO("Invalid hex string\n");
return nullptr;
}
length = strlen(src) / 4;
uint8_t* dest = new uint8_t[length];
int byteCount = HexStringToUint8Array(src, dest, length);
if (byteCount <= 0) {
CSSHARP_CORE_INFO("Invalid hex format %s\n", src);
return nullptr;
}
return dest;
}
} // namespace counterstrikesharp
} // namespace counterstrikesharp

View File

@@ -33,8 +33,7 @@ class CGameConfig
void* ResolveSignature(const char* name);
static std::string GetDirectoryName(const std::string& directoryPathInput);
static int HexStringToUint8Array(const char* hexString, uint8_t* byteArray, size_t maxBytes);
static byte* HexToByte(const char* src, size_t& length);
static std::vector<int16_t> HexToByte(std::string_view src);
private:
std::string m_sPath;

View File

@@ -28,6 +28,7 @@
namespace counterstrikesharp {
namespace modules {
std::vector<std::unique_ptr<CModule>> moduleList{};
CModule* engine = nullptr;
CModule* tier0 = nullptr;
CModule* server = nullptr;
@@ -52,6 +53,7 @@ IFileSystem* fileSystem = nullptr;
IServerGameDLL* serverGameDll = nullptr;
IServerGameClients* serverGameClients = nullptr;
INetworkServerService* networkServerService = nullptr;
CSchemaSystem* schemaSystem = nullptr;
IServerTools* serverTools = nullptr;
IPhysics* physics = nullptr;
IPhysicsCollision* physicsCollision = nullptr;
@@ -91,11 +93,13 @@ const float engine_fixed_tick_interval = 0.015625f;
void Initialize()
{
modules::engine = new modules::CModule(ROOTBIN, "engine2");
modules::tier0 = new modules::CModule(ROOTBIN, "tier0");
modules::server = new modules::CModule(GAMEBIN, "server");
modules::schemasystem = new modules::CModule(ROOTBIN, "schemasystem");
modules::vscript = new modules::CModule(ROOTBIN, "vscript");
modules::Initialize();
modules::engine = modules::GetModuleByName(MODULE_PREFIX "engine2" MODULE_EXT);
modules::tier0 = modules::GetModuleByName(MODULE_PREFIX "tier0" MODULE_EXT);
modules::server = modules::GetModuleByName(MODULE_PREFIX "server" MODULE_EXT);
modules::schemasystem = modules::GetModuleByName(MODULE_PREFIX "schemasystem" MODULE_EXT);
modules::vscript = modules::GetModuleByName(MODULE_PREFIX "vscript" MODULE_EXT);
interfaces::Initialize();

View File

@@ -8,6 +8,8 @@
#include <thread>
#include <memory>
#include "ISmmAPI.h"
#include "eiface.h"
#include "iserver.h"
@@ -37,6 +39,7 @@ class IGameEventSystem;
class CounterStrikeSharpMMPlugin;
class CGameEntitySystem;
class IGameEventListener2;
class CSchemaSystem;
namespace counterstrikesharp {
class EntityListener;
@@ -75,6 +78,7 @@ extern IFileSystem *fileSystem;
extern IServerGameDLL *serverGameDll;
extern IServerGameClients *serverGameClients;
extern INetworkServerService *networkServerService;
extern CSchemaSystem *schemaSystem;
extern IServerTools *serverTools;
extern IPhysics *physics;
extern IPhysicsCollision *physicsCollision;
@@ -129,6 +133,11 @@ CGlobalVars *getGlobalVars();
namespace modules {
class CModule;
void Initialize();
CModule* GetModuleByName(std::string name);
extern std::vector<std::unique_ptr<CModule>> moduleList;
extern CModule *engine;
extern CModule *tier0;
extern CModule *server;
@@ -141,4 +150,4 @@ extern CModule *vscript;
#undef SH_GLOB_SHPTR
#define SH_GLOB_SHPTR counterstrikesharp::globals::source_hook
#undef SH_GLOB_PLUGPTR
#define SH_GLOB_PLUGPTR counterstrikesharp::globals::source_hook_pluginid
#define SH_GLOB_PLUGPTR counterstrikesharp::globals::source_hook_pluginid

View File

@@ -19,8 +19,8 @@ private:
} // namespace counterstrikesharp
#define CSSHARP_CORE_TRACE(...) ::counterstrikesharp::Log::GetCoreLogger()->trace(__VA_ARGS__)
#define CSSHARP_CORE_DEBUG(...) _ ::counterstrikesharp::Log::GetCoreLogger()->debug(__VA_ARGS__)
#define CSSHARP_CORE_DEBUG(...) ::counterstrikesharp::Log::GetCoreLogger()->debug(__VA_ARGS__)
#define CSSHARP_CORE_INFO(...) ::counterstrikesharp::Log::GetCoreLogger()->info(__VA_ARGS__)
#define CSSHARP_CORE_WARN(...) ::counterstrikesharp::Log::GetCoreLogger()->warn(__VA_ARGS__)
#define CSSHARP_CORE_ERROR(...) ::counterstrikesharp::Log::GetCoreLogger()->error(__VA_ARGS__)
#define CSSHARP_CORE_CRITICAL(...) ::counterstrikesharp::Log::GetCoreLogger()->critical(__VA_ARGS__)
#define CSSHARP_CORE_CRITICAL(...) ::counterstrikesharp::Log::GetCoreLogger()->critical(__VA_ARGS__)

View File

@@ -15,21 +15,19 @@
*/
#include "core/managers/chat_manager.h"
#include "core/managers/con_command_manager.h"
#include "scripting/callback_manager.h"
#include "characterset.h"
#include <igameevents.h>
#include <baseentity.h>
#include <public/eiface.h>
#include "core/memory.h"
#include "core/log.h"
#include "core/coreconfig.h"
#include "core/gameconfig.h"
#include <funchook.h>
#include <igameevents.h>
#include <public/eiface.h>
#include "characterset.h"
#include "core/coreconfig.h"
#include "core/gameconfig.h"
#include "core/log.h"
#include "core/managers/con_command_manager.h"
#include "core/memory.h"
#include "core/memory_module.h"
#include "scripting/callback_manager.h"
namespace counterstrikesharp {
@@ -39,10 +37,10 @@ ChatManager::~ChatManager() {}
void ChatManager::OnAllInitialized()
{
m_pHostSay = reinterpret_cast<HostSay>(
modules::server->FindSignature(globals::gameConfig->GetSignature("Host_Say")));
m_pHostSay = reinterpret_cast<HostSay>(modules::server->FindSignature(globals::gameConfig->GetSignature("Host_Say")));
if (m_pHostSay == nullptr) {
if (m_pHostSay == nullptr)
{
CSSHARP_CORE_ERROR("Failed to find signature for \'Host_Say\'");
return;
}
@@ -54,12 +52,13 @@ void ChatManager::OnAllInitialized()
void ChatManager::OnShutdown() {}
void DetourHostSay(CBaseEntity* pController, CCommand& args, bool teamonly, int unk1,
const char* unk2)
void DetourHostSay(CEntityInstance* pController, CCommand& args, bool teamonly, int unk1, const char* unk2)
{
if (pController) {
if (pController)
{
auto pEvent = globals::gameEventManager->CreateEvent("player_chat", true);
if (pEvent) {
if (pEvent)
{
pEvent->SetBool("teamonly", teamonly);
pEvent->SetInt("userid", pController->GetEntityIndex().Get() - 1);
pEvent->SetString("text", args[1]);
@@ -72,17 +71,17 @@ void DetourHostSay(CBaseEntity* pController, CCommand& args, bool teamonly, int
bool bSilent = globals::coreConfig->IsSilentChatTrigger(args[1], prefix);
bool bCommand = globals::coreConfig->IsPublicChatTrigger(args[1], prefix) || bSilent;
if (!bSilent) {
if (!bSilent)
{
m_pHostSay(pController, args, teamonly, unk1, unk2);
}
if (bCommand)
{
char *pszMessage = (char *)(args.ArgS() + prefix.length() + 1);
char* pszMessage = (char*)(args.ArgS() + prefix.length() + 1);
// Trailing slashes are only removed if Host_Say has been called.
if (bSilent)
pszMessage[V_strlen(pszMessage) - 1] = 0;
if (bSilent) pszMessage[V_strlen(pszMessage) - 1] = 0;
CCommand args;
args.Tokenize(pszMessage);
@@ -90,7 +89,8 @@ void DetourHostSay(CBaseEntity* pController, CCommand& args, bool teamonly, int
auto prefixedPhrase = std::string("css_") + args.Arg(0);
auto bValidWithPrefix = globals::conCommandManager.IsValidValveCommand(prefixedPhrase.c_str());
if (bValidWithPrefix) {
if (bValidWithPrefix)
{
// Re-tokenize with a `css_` prefix if we have found that its a valid command.
args.Tokenize(("css_" + std::string(pszMessage)).c_str());
}
@@ -99,30 +99,29 @@ void DetourHostSay(CBaseEntity* pController, CCommand& args, bool teamonly, int
}
}
bool ChatManager::OnSayCommandPre(CBaseEntity* pController, CCommand& command) { return false; }
bool ChatManager::OnSayCommandPre(CEntityInstance* pController, CCommand& command) { return false; }
void ChatManager::OnSayCommandPost(CBaseEntity* pController, CCommand& command)
void ChatManager::OnSayCommandPost(CEntityInstance* pController, CCommand& command)
{
auto commandStr = command.Arg(0);
return InternalDispatch(pController, commandStr, command);
}
void ChatManager::InternalDispatch(CBaseEntity* pPlayerController, const char* szTriggerPhase,
CCommand& fullCommand)
void ChatManager::InternalDispatch(CEntityInstance* pPlayerController, const char* szTriggerPhase, CCommand& fullCommand)
{
if (pPlayerController == nullptr) {
globals::conCommandManager.ExecuteCommandCallbacks(
fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(-1)),
fullCommand, HookMode::Pre, CommandCallingContext::Chat);
if (pPlayerController == nullptr)
{
globals::conCommandManager.ExecuteCommandCallbacks(fullCommand.Arg(0),
CCommandContext(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(-1)), fullCommand,
HookMode::Pre, CommandCallingContext::Chat);
return;
}
auto index = pPlayerController->GetEntityIndex().Get();
auto slot = CPlayerSlot(index - 1);
globals::conCommandManager.ExecuteCommandCallbacks(
fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), fullCommand,
HookMode::Pre, CommandCallingContext::Chat);
globals::conCommandManager.ExecuteCommandCallbacks(fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, slot),
fullCommand, HookMode::Pre, CommandCallingContext::Chat);
}
} // namespace counterstrikesharp
} // namespace counterstrikesharp

Some files were not shown because too many files have changed in this diff Show More