Compare commits

...

41 Commits
v124 ... v158

Author SHA1 Message Date
B3none
9071d51ecd Tidy CCSPlayerController (#287)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
2024-01-26 06:04:57 +00:00
Michael Wilson
0a32962f4a fix: move discord notify into release pipeline 2024-01-26 15:51:39 +10:00
Michael Wilson
271705b377 Update discord-notify.yml 2024-01-26 15:28:58 +10:00
Michael Wilson
cdcddbb5f3 Update discord-notify.yml 2024-01-25 16:47:53 +10:00
Michael Wilson
91f51d0c5c Update discord-notify.yml 2024-01-25 16:47:45 +10:00
Dliix66
e97f804294 HTML Menu improvements (#284)
Co-authored-by: B3none <24966460+B3none@users.noreply.github.com>
2024-01-23 11:15:18 +10:00
Dliix66
4f805b18e2 Added canUse virtual method (#282) 2024-01-22 10:23:02 +10:00
roflmuffin
e1f9b5635e chore: update API compatibility version to 151 2024-01-21 21:07:02 +10:00
Michael Wilson
59bff4f500 feat: add discord notify through GH actions 2024-01-21 12:35:49 +10:00
Daniel Wiesendorf
a2581d8e91 Log exception if plugin load fails using the load command (#265) 2024-01-21 12:01:27 +10:00
Ravid-A
e7d190a6f7 Change TerroristsPlanned to TerroristsPlanted in RoundEndReason (#216)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
Co-authored-by: B3none <24966460+B3none@users.noreply.github.com>
2024-01-21 12:01:27 +10:00
B3none
5513d5710a Menu system updates (#268)
Co-authored-by: Stimayk <51941742+Stimayk@users.noreply.github.com>
2024-01-21 12:01:27 +10:00
Michael Poutre
e5c223699c fix(Offsets/Win): CCSPlayer_ItemServices.RemoveWeapons() (#271) 2024-01-21 12:01:27 +10:00
ZoNiCaL
fa37c222d9 Admin manager improvements (#278)
Co-authored-by: B3none <24966460+B3none@users.noreply.github.com>
2024-01-21 12:01:27 +10:00
Michael Wilson
3b633fafc7 Create CODEOWNERS 2024-01-21 11:44:42 +10:00
Abner Santos
765c56a38a Fix css_plugins commands number of args check (#269) 2024-01-19 17:43:21 +00:00
B3none
204850fb55 Add casted property .Team to CCSPlayerController (#259)
Co-authored-by: Roflmuffin <shortguy014@gmail.com>
2024-01-15 15:49:05 +10:00
ZoNiCaL
bac31b9190 Purge disabled folder (#256) 2024-01-12 12:14:38 +10:00
B3none
289f95a6b7 Add DarkRed to ChatColors class to follow naming convention (#245) 2024-01-09 16:20:51 +10:00
roflmuffin
7b45a884d4 chore: remove schema::GetOffset warning message 2023-12-28 18:01:44 +10:00
Michael Wilson
6ea6d0a22d feat: add state changed and network state changed handler (#229) 2023-12-27 20:56:38 +10:00
roflmuffin
12523455c0 fix: bad max player count 2023-12-27 15:30:57 +10:00
Michael Wilson
db63fdc00c feat: add AcceptInput method to CEntityInstance (#228) 2023-12-27 14:32:37 +10:00
roflmuffin
57747f2e1c fix: update GetPlayers to use slot access 2023-12-27 14:00:11 +10:00
roflmuffin
66b5f77a2d feat: add GetMaxClients native, fixes #184 2023-12-27 13:40:06 +10:00
Michael Wilson
8dbcb6d531 chore: update hl2sdk (#227) 2023-12-27 13:26:59 +10:00
roflmuffin
2f0d34b271 chore: disable compat suppression file by default 2023-12-26 17:36:55 +10:00
roflmuffin
2a59544fbc feat: add ApiCompat checker to determine breaking API changes 2023-12-26 17:30:17 +10:00
pedrotski
f80f2ae949 Fix getting started image (#220) 2023-12-26 17:09:32 +10:00
roflmuffin
f68a0abc61 fix: ignore null designer names in FindAllEntitiesByDesignerName Fixes #212 2023-12-26 17:00:58 +10:00
Sürat ÜNLÜGÜN
a07dd9d7d4 Fix CanPlayerTarget Immu (#222) 2023-12-25 23:26:34 +10:00
B3none
d527038fba Added a parameter for people to optionally remove the entity when calling RemoveItemByDesignerName (#214) 2023-12-24 19:40:23 +10:00
pedrotski
ca85922270 Update Getting Started Guide (#217) 2023-12-24 10:02:41 +10:00
B3none
b837479f98 Added links to referenced projects in the credits for the README.md (#210) 2023-12-19 11:15:30 +10:00
Hackmastr
1e42f72655 Docs: Using DOTNET_SYSTEM_GLOBALIZATION_INVARIANT is no longer valid. (#209)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
2023-12-19 11:14:31 +10:00
Michael Wilson
1ad1828e30 feat: Add SchemaMember attribute to schema objects` (#208) 2023-12-17 13:12:26 +10:00
Charles_
563a5d7b3a feat: Added RemovePlayerItem() to CBasePlayerPawn. (#200)
Co-authored-by: roflmuffin <shortguy014@gmail.com>
2023-12-16 14:24:08 +10:00
Charlie Thomson
983b673b4c feat: Add OnClientVoice listener (#204)
Co-authored-by: roflmuffin <shortguy014@gmail.com>
2023-12-16 14:18:40 +10:00
Roflmuffin
74fd0e0832 fix: offsets for CBaseEntity derived classes
Also adds test commands to test plugin for future validation
2023-12-14 15:14:34 +10:00
Michael Wilson
44e3f2240c chore: license updates (#199) 2023-12-14 11:03:18 +10:00
BuSheeZy
8af219e7a8 CHANGE: visual adjustments (#198) 2023-12-14 10:44:48 +10:00
82 changed files with 10373 additions and 7009 deletions

View File

@@ -196,6 +196,7 @@ jobs:
(cd build/windows && zip -qq -r ../../counterstrikesharp-with-runtime-build-${{ needs.build_managed.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 }}
@@ -208,4 +209,11 @@ jobs:
- 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.build_managed.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 }}"

View File

@@ -22,6 +22,22 @@ saul/demofile-net, https://github.com/saul/demofile-net/blob/main/LICENSE:
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
neverlosecc/source2gen, https://github.com/neverlosecc/source2gen
source2gen - Source2 games SDK generator
Copyright 2023 neverlosecc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Source2ZE/CS2Fixes:
alliedmodders/sourcemod:
Source-Python-Dev-Team/Source.Python:

View File

@@ -18,6 +18,7 @@ SET(SOURCE_FILES
src/mm_plugin.h
libraries/hl2sdk-cs2/tier1/convar.cpp
libraries/hl2sdk-cs2/tier1/generichash.cpp
libraries/hl2sdk-cs2/entity2/entityidentity.cpp
libraries/hl2sdk-cs2/entity2/entitysystem.cpp
libraries/dotnet/hostfxr.h
libraries/dotnet/coreclr_delegates.h

1
CODEOWNERS Normal file
View File

@@ -0,0 +1 @@
* @roflmuffin

View File

@@ -43,7 +43,7 @@ These features are the core of the platform and work pretty well/have a low risk
- [Read the docs](https://docs.cssharp.dev/): Getting started guide, hello world plugin example
- [Issue tracker](https://github.com/roflmuffin/CounterStrikeSharp/issues): Raise any issues here
- [Builds](https://github.com/roflmuffin/CounterStrikeSharp/actions): Download latest unstable dev snapshot
- [Install Docs](https://docs.cssharp.dev/guides/getting-started/): Installation instructions
- [Install Docs](https://docs.cssharp.dev/docs/guides/getting-started.html): Installation instructions
- [Example Plugin](managed/TestPlugin/TestPlugin.cs): Test plugin with basic functionality
## Examples
@@ -91,8 +91,8 @@ public class HelloWorldPlugin : BasePlugin
## Credits
A lot of code has been borrowed from SourceMod as well as Source.Python, two pioneering source engine plugin frameworks which this project lends a lot of its credit to.
I've also used the scripting context & native system that is implemented in FiveM for GTA5. Also shoutout to the [CS2Fixes](https://github.com/Source2ZE/CS2Fixes) project for providing good reverse-engineering information so shortly after CS2 release.
A lot of code has been borrowed from [SourceMod](https://github.com/alliedmodders/sourcemod) as well as [Source.Python](https://github.com/Source-Python-Dev-Team/Source.Python), two pioneering source engine plugin frameworks which this project lends a lot of its credit to.
I've also used the scripting context & native system that is implemented in [FiveM](https://github.com/citizenfx/fivem) for GTA5. Also shoutout to the [CS2Fixes](https://github.com/Source2ZE/CS2Fixes) project for providing good reverse-engineering information so shortly after CS2 release.
## How to Build

View File

@@ -28,8 +28,8 @@
},
"CCSPlayerController_Respawn": {
"offsets": {
"windows": 241,
"linux": 243
"windows": 242,
"linux": 244
}
},
"CCSPlayerPawn_Respawn": {
@@ -74,6 +74,13 @@
"linux": "\\x55\\x48\\x89\\xF2\\x48\\x89\\xE5\\x41\\x54\\x49\\x89\\xFC\\x48\\x8D\\x2A\\x2A\\x48\\x83\\x2A\\x2A\\x2A\\x8D\\x05\\x2A\\x2A\\x2A\\x00\\x48\\x8B\\x30\\x48\\x8B\\x06\\xFF\\x2A\\x2A\\x48\\x8B\\x45\\x2A\\x48\\x8D\\x2A\\x2A\\x4C\\x89\\x2A\\x48\\x89\\x45\\x2A\\x2A\\x68\\xFC"
}
},
"CCSPlayer_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\\xA8\\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"
}
},
"CCSPlayer_ItemServices_DropActivePlayerWeapon": {
"offsets": {
"windows": 18,
@@ -82,7 +89,7 @@
},
"CCSPlayer_ItemServices_RemoveWeapons": {
"offsets": {
"windows": 21,
"windows": 19,
"linux": 20
}
},
@@ -113,6 +120,13 @@
"linux": "\\x48\\x85\\xFF\\x74\\x4B\\x55\\x48\\x89\\xE5\\x41\\x56"
}
},
"CEntityInstance_AcceptInput": {
"signatures": {
"library": "server",
"windows": "\\x48\\x89\\x5C\\x24\\x10\\x48\\x89\\x74\\x24\\x18\\x57\\x48\\x83\\xEC\\x40\\x49\\x8B\\xF0",
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x49\\x89\\xFF\\x41\\x56\\x48\\x8D\\x7D\\xC0"
}
},
"LegacyGameEventListener": {
"signatures": {
"library": "server",
@@ -122,14 +136,21 @@
},
"CBasePlayerPawn_CommitSuicide": {
"offsets": {
"windows": 356,
"linux": 356
"windows": 357,
"linux": 357
}
},
"CBasePlayerPawn_RemovePlayerItem": {
"signatures": {
"library": "server",
"linux": "\\x55\\x48\\x89\\x2A\\x41\\x2A\\x49\\x89\\x2A\\x41\\x2A\\x49\\x89\\x2A\\xE8\\x2A\\x2A\\x2A\\x2A\\x49\\x39",
"windows": "\\x48\\x85\\xD2\\x0F\\x84\\x2A\\x2A\\x2A\\x2A\\x48\\x89\\x5C\\x24\\x08\\x57\\x48\\x83\\xEC\\x30\\x48\\x8B\\xDA"
}
},
"CBaseEntity_Teleport": {
"offsets": {
"windows": 148,
"linux": 147
"windows": 149,
"linux": 148
}
},
"CBaseEntity_TakeDamageOld": {
@@ -153,6 +174,20 @@
"linux": "\\x55\\xBA\\xFF\\xFF\\xFF\\xFF\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x49"
}
},
"StateChanged": {
"signatures": {
"library": "server",
"windows": "\\x40\\x55\\x53\\x56\\x41\\x55\\x41\\x57\\x48\\x8D\\x6C\\x24\\xB0",
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x41\\x54\\x53\\x89\\xD3"
}
},
"NetworkStateChanged": {
"signatures": {
"library": "server",
"windows": "\\x4C\\x8B\\xC9\\x48\\x8B\\x09\\x48\\x85\\xC9\\x74\\x2A\\x48\\x8B\\x41\\x10",
"linux": "\\x4C\\x8B\\x07\\x4D\\x85\\xC0\\x74\\x2A\\x49\\x8B\\x40\\x10"
}
},
"GameEntitySystem": {
"offsets": {
"windows": 88,

View File

@@ -5,31 +5,52 @@ description: How to get started installing & using CounterStrikeSharp.
# Getting Started
How to get started installing & using CounterStrikeSharp.
In this guide you will learn how to install CounterStrikeSharp onto your vanilla Counter-Strike 2 server. `CounterStrikeSharp` uses `Metamod:Source` as its main way of communicating with the game server, so both frameworks will need to be installed.
If you're more of a visual person, here is a <a href="https://www.youtube.com/watch?v=FlsKzStHJuY" target="_blank">Youtube video</a> that covers everything.
## Prerequisites
- <a href="https://www.sourcemm.net/downloads.php/?branch=master" target="_blank">Metamod: Source 2.X Dev Build</a>
- <a href="https://github.com/roflmuffin/CounterStrikeSharp/releases" target="_blank">CounterStrikeSharp With Runtime</a>
## Installing Metamod
`CounterStrikeSharp` uses `Metamod:Source` as its main way of communicating with the game server. To install it, you can follow the detailed instructions found <a href="https://cs2.poggu.me/metamod/installation/" target="_blank">here</a>.
1. Extract Metamod and copy the `/addons/` directory to `/game/csgo/`.
2. Inside `/game/csgo/`, locate `gameinfo.gi`.
3. Create a new line underneath `Game_LowViolence csgo_lv` and add `Game csgo/addons/metamod`.
4. Restart your game server.
Your `gameinfo.gi` should look like <a href="../../images/gameinfogi-example.png" target="_blank">this</a>. Type `meta list` in your server console to see if Metamod is loaded.
## Installing CounterStrikeSharp
Download the latest release of CounterStrikeSharp from <a href="https://github.com/roflmuffin/CounterStrikeSharp/releases/latest" target="_blank">GitHub releases pages</a>.
1. Extract CounterStrikeSharp and copy the `/addons/` directory to `/game/csgo/`.
2. Restart your game server.
Running the command `meta list` in the console should show 1 plugin loaded 🎉
```shell
meta list
Listing 1 plugin:
[01] CounterStrikeSharp (0.1.0) by Roflmuffin
```
> [!CAUTION]
> If this is your first time installing, you will need to download the `with-runtime` version. This includes a copy of the .NET runtime, which is required to run the plugin.
> Depending on the os you might also either need to install `libicu` / `icu-libs` / `libicu-dev` using your package manager for .NET to run or setting `DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true` in your servers environment variables. You can find more infos about that <a href="https://github.com/dotnet/runtime/blob/main/docs/design/features/globalization-invariant-mode.md#enabling-the-invariant-mode" target="_blank">here</a>
>
> Subsequent upgrades will not require the runtime, unless a version bump of the .NET runtime is required (i.e. from 7.0.x to 8.0.x). We will inform you when this occurs.
> For Windows servers, you must have <a href="https://aka.ms/vs/17/release/vc_redist.x64.exe" target="_blank">Visual Studio Redistributables</a> installed otherwise CounterStrikeSharp will not work.
> [!CAUTION]
> For Windows users, you must ensure that you have installed **Visual Studio Redistributables**.
> If not, you can download it here: <a href="https://aka.ms/vs/17/release/vc_redist.x64.exe" target="_blank">Download</a>
> > This link will download VC Redistributable directly.
>
> You must install it before starting the server, otherwise CSS will not work!
## Upgrading CounterStrikeSharp
To upgrade CounterStrikeSharp you simply need to download the latest release and copy it to your server, the same as the original installation.
Extract the `addons` folder to the `/csgo/` directory of the dedicated server. The contents of your addons folder should contain both the `counterstrikesharp` folder and the `metamod` folder as seen below.
CounterStrikeSharp is designed in a way where your configuration files will not be overwritten if you do this. As CounterStrikeSharp is already installed, you may download the non `with-runtime` build, but you will need to ensure your .NET runtime is up-to-date yourself.
## Troubleshooting
- If this is your first time installing, you **MUST** download the `with-runtime` version. This includes a copy of the .NET runtime, which is required to run the plugin.
- Depending on your OS you might also either need to install `libicu` / `icu-libs` / `libicu-dev` using your package manager for .NET to run.
- If you get `Unknown Command` when typing `meta list` into your console, double-check the folders are copied over correctly and that your `gameinfo.gi` file is correctly modified.
Your folder structure should look like this:
```shell
<server_path>/game/csgo/addons > tree -L 2
@@ -49,15 +70,3 @@ addons
├── metamod.vdf
└── metamod_x64.vdf
```
## Start the Server
Launch your CS2 dedicated server as normal. If everything is working correctly, you should see a message in the console that says `CSSharp: CounterStrikeSharp.API Loaded Successfully.`.
Running the command `meta list` in the console should show 1 plugin loaded 🎉
```shell
meta list
Listing 1 plugin:
[01] CounterStrikeSharp (0.1.0) by Roflmuffin
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

View File

@@ -14,7 +14,7 @@ description: Write Counter-Strike 2 server plugins in C#.
<span>CounterStrikeSharp is a simpler way to write CS2 server plugins.</span>
<div>
<a href="docs/guides/getting-started.md" class="btn btn-primary btn-lg fw-bold my-5">Get Started <i class="bi bi-arrow-right"></a>
<a href="https://github.com/roflmuffin/CounterStrikeSharp/releases/latest" class="btn btn-primary btn-lg fw-bold my-5">Download <i class="bi bi-arrow-right"></a>
<a href="https://github.com/roflmuffin/CounterStrikeSharp/releases/latest" class="btn btn-secondary btn-lg fw-bold my-5">Download <i class="bi bi-download"></a>
</div>
</div>

View File

@@ -14,8 +14,11 @@ set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING
# TODO: Use C++20 instead.
set(CMAKE_CXX_STANDARD 17)
Set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
Set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
if (LINUX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
endif()
set(CMAKE_STATIC_LIBRARY_PREFIX "")
set(SOURCESDK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2)
@@ -51,8 +54,4 @@ include_directories(
libraries
)
include(${CMAKE_CURRENT_LIST_DIR}/metamod/configure_metamod.cmake)
if (LINUX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
include(${CMAKE_CURRENT_LIST_DIR}/metamod/configure_metamod.cmake)

View File

@@ -27,9 +27,9 @@ public class AdminTests
{
var adminData = AdminManager.GetPlayerAdminData((SteamID)76561197960265731);
Assert.NotNull(adminData);
Assert.Equal(125u, adminData.Immunity); // Group immunity is 125, Admin immunity is 100
Assert.Equal(125u, AdminManager.GetPlayerImmunity((SteamID)76561197960265731)); // Group immunity is 125, Admin immunity is 100
AdminManager.SetPlayerImmunity((SteamID)76561197960265731, 150u);
Assert.Equal(150u, adminData.Immunity); // Group immunity is 125, Admin immunity is 100
Assert.Equal(150u, AdminManager.GetPlayerImmunity((SteamID)76561197960265731)); // Group immunity is 125, Admin immunity is 100
}
[Fact]

Binary file not shown.

View File

@@ -312,6 +312,16 @@ namespace CounterStrikeSharp.API.Core
}
}
public static int GetMaxClients(){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.SetIdentifier(0x5DF2E20D);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int));
}
}
public static void IssueServerCommand(string command){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
@@ -1064,6 +1074,18 @@ namespace CounterStrikeSharp.API.Core
}
}
public static bool IsSchemaFieldNetworked(string classname, string propname){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(classname);
ScriptContext.GlobalScriptContext.Push(propname);
ScriptContext.GlobalScriptContext.SetIdentifier(0xFE413B0C);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (bool)ScriptContext.GlobalScriptContext.GetResult(typeof(bool));
}
}
public static T GetSchemaValueByName<T>(IntPtr instance, int returntype, string classname, string propname){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();

View File

@@ -85,11 +85,12 @@ namespace CounterStrikeSharp.API.Core
for (var i = 1; i <= 9; i++)
{
CommandUtils.AddStandaloneCommand("css_" + i, "Command Key Handler", (player, info) =>
CommandUtils.AddStandaloneCommand($"css_{i}", "Command Key Handler", (player, info) =>
{
if (player == null) return;
var key = Convert.ToInt32(info.GetArg(0).Split("_")[1]);
ChatMenus.OnKeyPress(player, key);
MenuManager.OnKeyPress(player, key);
});
}
@@ -104,7 +105,7 @@ namespace CounterStrikeSharp.API.Core
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 and CS2Fixes.\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, true);
return;
@@ -151,7 +152,7 @@ namespace CounterStrikeSharp.API.Core
case "start":
case "load":
{
if (info.ArgCount < 2)
if (info.ArgCount < 3)
{
info.ReplyToCommand(
"Valid usage: css_plugins start/load [relative plugin path || absolute plugin path] (e.g \"TestPlugin\", \"plugins/TestPlugin/TestPlugin.dll\")\n",
@@ -182,6 +183,7 @@ namespace CounterStrikeSharp.API.Core
catch (Exception e)
{
info.ReplyToCommand($"Could not load plugin \"{path}\")", true);
Logger.LogError(e, "Could not load plugin \"{Path}\"", path);
}
}
else
@@ -195,7 +197,7 @@ namespace CounterStrikeSharp.API.Core
case "stop":
case "unload":
{
if (info.ArgCount < 2)
if (info.ArgCount < 3)
{
info.ReplyToCommand(
"Valid usage: css_plugins stop/unload [plugin name || #plugin id] (e.g \"TestPlugin\", \"1\")\n",
@@ -218,7 +220,7 @@ namespace CounterStrikeSharp.API.Core
case "restart":
case "reload":
{
if (info.ArgCount < 2)
if (info.ArgCount < 3)
{
info.ReplyToCommand(
"Valid usage: css_plugins restart/reload [plugin name || #plugin id] (e.g \"TestPlugin\", \"#1\")\n",
@@ -288,7 +290,7 @@ namespace CounterStrikeSharp.API.Core
CommandUtils.AddStandaloneCommand("css", "Counter-Strike Sharp options.", OnCSSCommand);
CommandUtils.AddStandaloneCommand("css_plugins", "Counter-Strike Sharp plugin options.",
OnCSSPluginCommand);
CommandUtils.AddStandaloneCommand("css_lang", "Set Counter-Strike Sharp language", OnLangCommand);
CommandUtils.AddStandaloneCommand("css_lang", "Set Counter-Strike Sharp language.", OnLangCommand);
}
}
}

View File

@@ -0,0 +1,14 @@
namespace CounterStrikeSharp.API.Core.Attributes;
[AttributeUsage(AttributeTargets.Property)]
public class SchemaMemberAttribute : Attribute
{
public string ClassName { get; }
public string MemberName { get; }
public SchemaMemberAttribute(string className, string memberName)
{
ClassName = className;
MemberName = memberName;
}
}

View File

@@ -93,6 +93,13 @@ namespace CounterStrikeSharp.API.Core
[ListenerName("OnClientDisconnectPost")]
public delegate void OnClientDisconnectPost(int playerSlot);
/// <summary>
/// Called when a client transmits voice data
/// </summary>
/// <param name="playerSlot">The player slot of the client.</param>
[ListenerName("OnClientVoice")]
public delegate void OnClientVoice(int playerSlot);
/// <summary>
/// Called when a client has been authorized by Steam.
/// </summary>

View File

@@ -14,4 +14,13 @@ public partial class CBasePlayerPawn
{
VirtualFunction.CreateVoid<IntPtr, bool, bool>(Handle, GameData.GetOffset("CBasePlayerPawn_CommitSuicide"))(Handle, explode, force);
}
/// <summary>
/// Remove Player Item
/// </summary>
/// <param name="weapon"></param>
public void RemovePlayerItem(CBasePlayerWeapon weapon)
{
VirtualFunctions.RemovePlayerItemVirtual(Handle, weapon.Handle);
}
}

View File

@@ -10,17 +10,13 @@ namespace CounterStrikeSharp.API.Core;
public partial class CCSPlayerController
{
public int? UserId
{
get
{
return NativeAPI.GetUseridFromIndex((int)this.Index);
}
}
public int? UserId => NativeAPI.GetUseridFromIndex((int)Index);
public CsTeam Team => (CsTeam)TeamNum;
public IntPtr GiveNamedItem(string item)
{
if (!PlayerPawn.IsValid) return 0;
if (PlayerPawn.Value == null) return 0;
if (!PlayerPawn.Value.IsValid) return 0;
if (PlayerPawn.Value.ItemServices == null) return 0;
@@ -35,7 +31,7 @@ public partial class CCSPlayerController
return IntPtr.Zero;
}
return this.GiveNamedItem(itemString);
return GiveNamedItem(itemString);
}
public void PrintToConsole(string message)
@@ -45,12 +41,12 @@ public partial class CCSPlayerController
public void PrintToChat(string message)
{
VirtualFunctions.ClientPrint(this.Handle, HudDestination.Chat, message, 0, 0, 0, 0);
VirtualFunctions.ClientPrint(Handle, HudDestination.Chat, message, 0, 0, 0, 0);
}
public void PrintToCenter(string message)
{
VirtualFunctions.ClientPrint(this.Handle, HudDestination.Center, message, 0, 0, 0, 0);
VirtualFunctions.ClientPrint(Handle, HudDestination.Center, message, 0, 0, 0, 0);
}
public void PrintToCenterHtml(string message) => PrintToCenterHtml(message, 5);
@@ -72,14 +68,16 @@ public partial class CCSPlayerController
public void DropActiveWeapon()
{
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 weponServices = new CCSPlayer_WeaponServices(PlayerPawn.Value.WeaponServices.Handle);
itemServices.DropActivePlayerWeapon(weponServices.ActiveWeapon.Value);
CCSPlayer_WeaponServices weaponServices = new CCSPlayer_WeaponServices(PlayerPawn.Value.WeaponServices.Handle);
itemServices.DropActivePlayerWeapon(weaponServices.ActiveWeapon.Value);
}
/// <summary>
@@ -88,6 +86,7 @@ public partial class CCSPlayerController
public void RemoveWeapons()
{
if (!PlayerPawn.IsValid) return;
if (PlayerPawn.Value == null) return;
if (!PlayerPawn.Value.IsValid) return;
if (PlayerPawn.Value.ItemServices == null) return;
@@ -103,6 +102,7 @@ public partial class CCSPlayerController
public void CommitSuicide(bool explode, bool force)
{
if (!PlayerPawn.IsValid) return;
if (PlayerPawn.Value == null) return;
if (!PlayerPawn.Value.IsValid) return;
PlayerPawn.Value.CommitSuicide(explode, force);
@@ -114,6 +114,7 @@ public partial class CCSPlayerController
public void Respawn()
{
if (!PlayerPawn.IsValid) return;
if (PlayerPawn.Value == null) return;
if (!PlayerPawn.Value.IsValid) return;
VirtualFunctions.CCSPlayerPawn_Respawn(PlayerPawn.Value.Handle);
@@ -128,7 +129,7 @@ public partial class CCSPlayerController
/// <param name="team">The team to switch to</param>
public void SwitchTeam(CsTeam team)
{
VirtualFunctions.SwitchTeam(this.Handle, (byte)team);
VirtualFunctions.SwitchTeam(Handle, (byte)team);
}
/// <summary>
@@ -151,7 +152,7 @@ public partial class CCSPlayerController
/// <returns>ConVar string value</returns>
public string GetConVarValue(string conVar)
{
return NativeAPI.GetClientConvarValue(this.Slot, conVar);
return NativeAPI.GetClientConvarValue(Slot, conVar);
}
public string GetConVarValue(ConVar? conVar)
@@ -177,7 +178,7 @@ public partial class CCSPlayerController
throw new InvalidOperationException("'SetFakeClientConVar' can only be called for fake clients (bots)");
}
NativeAPI.SetFakeClientConvarValue(this.Slot, conVar, value);
NativeAPI.SetFakeClientConvarValue(Slot, conVar, value);
}
/// <summary>
@@ -226,8 +227,8 @@ public partial class CCSPlayerController
{
get
{
if (!this.IsValid) return null;
var authorizedSteamId = NativeAPI.GetPlayerAuthorizedSteamid(this.Slot);
if (!IsValid) return null;
var authorizedSteamId = NativeAPI.GetPlayerAuthorizedSteamid(Slot);
if ((long)authorizedSteamId == -1) return null;
return (SteamID)authorizedSteamId;
@@ -242,8 +243,8 @@ public partial class CCSPlayerController
{
get
{
if (!this.IsValid) return null;
var ipAddress = NativeAPI.GetPlayerIpAddress(this.Slot);
if (!IsValid) return null;
var ipAddress = NativeAPI.GetPlayerIpAddress(Slot);
if (string.IsNullOrWhiteSpace(ipAddress)) return null;
return ipAddress;
@@ -256,9 +257,6 @@ public partial class CCSPlayerController
public VoiceFlags VoiceFlags
{
get => (VoiceFlags)NativeAPI.GetClientVoiceFlags(Handle);
set
{
NativeAPI.SetClientVoiceFlags(Handle, (Byte)value);
}
set => NativeAPI.SetClientVoiceFlags(Handle, (Byte)value);
}
}
}

View File

@@ -58,6 +58,24 @@ public partial class CEntityInstance : IEquatable<CEntityInstance>
{
return !Equals(left, right);
}
/// <summary>
/// Calls a named input method on an entity.
/// <example>
/// <code>
/// entity.AcceptInput("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="outputId">Unknown, defaults to 0</param>
public void AcceptInput(string inputName, CEntityInstance? activator = null, CEntityInstance? caller = null, string value = "", int outputId = 0)
{
VirtualFunctions.AcceptInput(Handle, inputName, activator?.Handle ?? IntPtr.Zero, caller?.Handle ?? IntPtr.Zero, value, 0);
}
}
public partial class CEntityIdentity

File diff suppressed because it is too large Load Diff

View File

@@ -4,9 +4,8 @@
<EnableDynamicLoading>true</EnableDynamicLoading>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EnablePackageValidation>true</EnablePackageValidation>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<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>
@@ -16,6 +15,10 @@
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup>
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
<ApiCompatContractAssembly>.\ApiCompat\v151.dll</ApiCompatContractAssembly>
</PropertyGroup>
<ItemGroup>
<None Remove="Modules\Commands\CommandInfo" />
<None Remove="Modules\Disabled\**" />
@@ -23,6 +26,7 @@
<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" />

View File

@@ -95,7 +95,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
// This is here for cases where the server console is attempting to call commands.
// The server console should have access to all commands, regardless of groups.
if (player == null) return true;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return false; }
var playerData = GetPlayerAdminData(player.AuthorizedSteamID);
if (playerData == null) return false;
@@ -136,20 +136,20 @@ namespace CounterStrikeSharp.API.Modules.Admin
return playerData.Groups.IsSupersetOf(playerGroups);
}
/// <summary>
/// Adds a player to a group.
/// </summary>
/// <param name="player">Player controller.</param>
/// <param name="groups">Groups to add the player to.</param>
public static void AddPlayerToGroup(CCSPlayerController? player, params string[] groups)
/// <summary>
/// Adds a player to a group. This does NOT modify the immunity of the player (see SetPlayerImmunity).
/// </summary>
/// <param name="player">Player controller.</param>
/// <param name="groups">Groups to add the player to.</param>
public static void AddPlayerToGroup(CCSPlayerController? player, params string[] groups)
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return; }
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return; }
AddPlayerToGroup(player.AuthorizedSteamID, groups);
}
/// <summary>
/// Adds a player to a group.
/// Adds a player to a group. This does NOT modify the immunity of the player (see SetPlayerImmunity).
/// </summary>
/// <param name="steamId">SteamID of the player.</param>
/// <param name="groups">Groups to add the player to.</param>
@@ -187,7 +187,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
public static void RemovePlayerFromGroup(CCSPlayerController? player, bool removeInheritedFlags = true, params string[] groups)
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return; }
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return; }
RemovePlayerFromGroup(player.AuthorizedSteamID, true, groups);
}

View File

@@ -167,22 +167,43 @@ namespace CounterStrikeSharp.API.Modules.Admin
}
}
/// <summary>
/// Grabs the admin data for a player that was loaded from "configs/admins.json".
/// </summary>
/// <param name="steamId">SteamID object of the player.</param>
/// <returns>AdminData class if data found, null if not.</returns>
public static AdminData? GetPlayerAdminData(SteamID? steamId)
/// <summary>
/// Grabs the admin data for a player that was loaded from "configs/admins.json" and "configs/admins_groups.json".
/// </summary>
/// <param name="player">Player controller</param>
/// <returns>AdminData class if data found, null if not.</returns>
public static AdminData? GetPlayerAdminData(CCSPlayerController? player)
{
if (player == null) return null;
return GetPlayerAdminData(player.AuthorizedSteamID);
}
/// <summary>
/// Grabs the admin data for a player that was loaded from "configs/admins.json" and "configs/admins_groups.json".
/// </summary>
/// <param name="steamId">SteamID object of the player.</param>
/// <returns>AdminData class if data found, null if not.</returns>
public static AdminData? GetPlayerAdminData(SteamID? steamId)
{
if (steamId == null) return null;
return Admins.GetValueOrDefault(steamId);
}
/// <summary>
/// Removes a players admin data. This is not saved to "configs/admins.json"
/// </summary>
/// <param name="steamId">Steam ID remove admin data from.</param>
public static void RemovePlayerAdminData(SteamID? steamId)
/// <summary>
/// Removes a players admin data. This is not saved to "configs/admins.json"
/// </summary>
/// <param name="player">Player controller</param>
public static void RemovePlayerAdminData(CCSPlayerController? player)
{
if (player == null) return;
RemovePlayerAdminData(player.AuthorizedSteamID);
}
/// <summary>
/// Removes a players admin data. This is not saved to "configs/admins.json"
/// </summary>
/// <param name="steamId">Steam ID remove admin data from.</param>
public static void RemovePlayerAdminData(SteamID? steamId)
{
if (steamId == null) return;
Admins.Remove(steamId);
@@ -201,7 +222,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
// This is here for cases where the server console is attempting to call commands.
// The server console should have access to all commands, regardless of permissions.
if (player == null) return true;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return false; }
return PlayerHasPermissions(player.AuthorizedSteamID, flags);
}
@@ -260,7 +281,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
// This is here for cases where the server console is attempting to call commands.
// The server console should have access to all commands, regardless of permissions.
if (player == null) return true;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return false; }
var playerData = GetPlayerAdminData(player.AuthorizedSteamID);
return playerData?.CommandOverrides.ContainsKey(command) ?? false;
}
@@ -290,7 +311,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
// This is here for cases where the server console is attempting to call commands.
// The server console should have access to all commands, regardless of permissions.
if (player == null) return true;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return false; }
var playerData = GetPlayerAdminData(player.AuthorizedSteamID);
return playerData?.CommandOverrides.GetValueOrDefault(command) ?? false;
}
@@ -319,7 +340,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
// This is here for cases where the server console is attempting to call commands.
// The server console should have access to all commands, regardless of permissions.
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return; }
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return; }
SetPlayerCommandOverride(player.AuthorizedSteamID, command, state);
}
@@ -362,7 +383,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
public static void AddPlayerPermissions(CCSPlayerController? player, params string[] flags)
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) return;
AddPlayerPermissions(player.AuthorizedSteamID, flags);
}
@@ -400,7 +421,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
public static void RemovePlayerPermissions(CCSPlayerController? player, params string[] flags)
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) return;
RemovePlayerPermissions(player.AuthorizedSteamID, flags);
}
@@ -427,7 +448,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
public static void ClearPlayerPermissions(CCSPlayerController? player)
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) return;
ClearPlayerPermissions(player.AuthorizedSteamID);
}
@@ -457,7 +478,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
public static void SetPlayerImmunity(CCSPlayerController? player, uint value)
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) return;
SetPlayerImmunity(player.AuthorizedSteamID, value);
}
@@ -477,13 +498,44 @@ namespace CounterStrikeSharp.API.Modules.Admin
Admins[steamId] = data;
}
/// <summary>
/// Checks to see if a player can target another player based on their immunity value.
/// </summary>
/// <param name="caller">Caller of the command.</param>
/// <param name="target">Target of the command.</param>
/// <returns></returns>
public static bool CanPlayerTarget(CCSPlayerController? caller, CCSPlayerController? target)
/// <summary>
/// Returns the immunity value for a player.
/// </summary>
/// <param name="player">Player controller.</param>
/// <returns> If an immunity value is present in "configs/admins_groups.json"
/// and in "configs/admins.json", the returned value will be the greater of the two.
/// If the value is overriden with SetPlayerImmunity, that value is returned instead.</returns>
public static uint GetPlayerImmunity(CCSPlayerController? player)
{
if (player == null) return 0;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) return 0;
return GetPlayerImmunity(player.AuthorizedSteamID);
}
/// <summary>
/// Returns the immunity value for a player.
/// </summary>
/// <param name="steamId">Steam ID of the player.</param>
/// <returns> If an immunity value is present in "configs/admins_groups.json"
/// and in "configs/admins.json", the returned value will be the greater of the two.
/// If the value is overriden with SetPlayerImmunity, that value is returned instead.</returns>
public static uint GetPlayerImmunity(SteamID? steamId)
{
if (steamId == null) return 0;
var data = GetPlayerAdminData(steamId);
if (data == null) return 0;
return data.Immunity;
}
/// <summary>
/// Checks to see if a player can target another player based on their immunity value.
/// </summary>
/// <param name="caller">Caller of the command.</param>
/// <param name="target">Target of the command.</param>
/// <returns></returns>
public static bool CanPlayerTarget(CCSPlayerController? caller, CCSPlayerController? target)
{
// The server console should be able to target everyone.
if (caller == null) return true;
@@ -494,7 +546,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
var callerData = GetPlayerAdminData(caller.AuthorizedSteamID);
if (callerData == null) return false;
var targetData = GetPlayerAdminData(caller.AuthorizedSteamID);
var targetData = GetPlayerAdminData(target.AuthorizedSteamID);
if (targetData == null) return true;
return callerData.Immunity >= targetData.Immunity;
@@ -514,7 +566,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
var callerData = GetPlayerAdminData(caller);
if (callerData == null) return false;
var targetData = GetPlayerAdminData(caller);
var targetData = GetPlayerAdminData(target);
if (targetData == null) return true;
return callerData.Immunity >= targetData.Immunity;

View File

@@ -90,11 +90,11 @@ public class Target
case TargetType.TeamSpec:
return player.TeamNum == (byte)CsTeam.Spectator;
case TargetType.GroupAll:
return true;
return !player.IsHLTV;
case TargetType.GroupBots:
return player.IsBot;
case TargetType.GroupHumans:
return !player.IsBot;
return !player.IsBot && !player.IsHLTV;
case TargetType.GroupAlive:
return player.PlayerPawn is { IsValid: true, Value.LifeState: (byte)LifeState_t.LIFE_ALIVE };
case TargetType.GroupDead:

View File

@@ -1,110 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Listeners;
namespace CounterStrikeSharp.API.Modules.Cvars
{
public class ConVar
{
public delegate void ConVarChangedCallback(ConVar convar, string oldValue, string newValue);
public IntPtr Handle { get; private set; }
internal ConVar(IntPtr handle)
{
Handle = handle;
}
public ConVar(string name, string value, string description, ConVarFlags flags, bool hasMinValue, float minValue, bool hasMaxValue, float maxValue) :
this(NativeAPI.CreateConvar(name, value, description, (int)flags, hasMinValue, minValue, hasMaxValue, maxValue))
{
}
public ConVar(string name, string value, string description = null, ConVarFlags flags = ConVarFlags.None, float? minValue = null, float? maxValue = null) :
this(name, value, description, flags, minValue.HasValue, minValue?? 0, maxValue.HasValue, maxValue?? 0)
{
}
public string Name => NativeAPI.ConvarGetName(Handle);
public string StringValue
{
get { return NativeAPI.ConvarGetStringValue(Handle); }
set { NativeAPI.ConvarSetStringValue(Handle, value); }
}
public float FloatValue
{
get { return Convert.ToSingle(NativeAPI.ConvarGetStringValue(Handle)); }
set { NativeAPI.ConvarSetStringValue(Handle, value.ToString("n2")); }
}
public int IntValue
{
get { return Convert.ToInt32(NativeAPI.ConvarGetStringValue(Handle)); }
set { NativeAPI.ConvarSetStringValue(Handle, value.ToString()); }
}
public bool BoolValue
{
get { return NativeAPI.ConvarGetStringValue(Handle) == "1"; }
set { NativeAPI.ConvarSetStringValue(Handle, value ? "1" : "0"); }
}
public ConVarFlags Flags
{
get { return (ConVarFlags) NativeAPI.ConvarGetFlags(Handle); }
set { NativeAPI.ConvarSetFlags(Handle, (int)value); }
}
public bool Public
{
get { return Flags.HasFlag(ConVarFlags.Notify); }
set
{
if (value)
{
Flags |= ConVarFlags.Notify;
}
else
{
Flags &= ~ConVarFlags.Notify;
}
}
}
public static ConVar Find(string name)
{
var ptr = NativeAPI.FindConvar(name);
if (ptr == IntPtr.Zero) return null;
return new ConVar(ptr);
}
public void Unregister()
{
NativeAPI.ConvarUnregister(Handle);
}
}
}

View File

@@ -1,22 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Engine.Trace
{
public enum ContentMasks
{
}
}

View File

@@ -1,24 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Engine.Trace
{
public enum RayType
{
EndPoint,
Infinite
}
}

View File

@@ -1,166 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using System.Runtime.InteropServices;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Listeners;
namespace CounterStrikeSharp.API.Modules.Engine.Trace
{
public class SimpleTraceFilter : NativeObject
{
public SimpleTraceFilter(IntPtr cPtr) : base(cPtr)
{
}
public SimpleTraceFilter(int indexToIgnore) : base(NativeAPI.NewSimpleTraceFilter(indexToIgnore))
{
}
}
public class TraceFilterProxy : NativeObject
{
private ITraceFilter _filter;
private FunctionReference.CallbackDelegate getTypeCallback;
private FunctionReference.CallbackDelegate shouldHitCallback;
public TraceFilterProxy(IntPtr cPtr) : base(cPtr)
{
}
public TraceFilterProxy(ITraceFilter filter) : base(NativeAPI.NewTraceFilterProxy())
{
_filter = filter;
/*
getTypeCallback = Utilities.SafeExecute(intPtr =>
{
var marshal = new CMarshalObject();
marshal.PushInt((int) _filter.GetTraceType());
return marshal.GetPointer();
});
*/
/*shouldHitCallback = Utilities.SafeExecute(ptr =>
{
var marshal = new CMarshalObject(ptr, true);
var entity = marshal.GetValue<BaseEntity>();
var contentMask = marshal.GetInt();
var isValidEntity = _filter.ShouldHitEntity(entity, contentMask);
var response = new CMarshalObject();
response.PushInt(isValidEntity ? 1 : 0);
return response.GetPointer();
});*/
unsafe
{
getTypeCallback = (fxScriptContext* context) =>
{
var scriptContext = new ScriptContext(context);
scriptContext.Push(_filter.GetTraceType());
};
shouldHitCallback = (fxScriptContext* context) =>
{
var scriptContext = new ScriptContext(context);
var entity = new BaseEntity(scriptContext.GetArgument<int>(0));
var contentMask = scriptContext.GetArgument<int>(1);
var isValidEntity = _filter.ShouldHitEntity(entity, contentMask);
Console.WriteLine($"Returning {isValidEntity} to `ShouldHitEntity`");
scriptContext.SetResult(isValidEntity, context);
};
}
NativeAPI.TraceFilterProxySetTraceTypeCallback(Handle, Marshal.GetFunctionPointerForDelegate(getTypeCallback));
NativeAPI.TraceFilterProxySetShouldHitEntityCallback(Handle, Marshal.GetFunctionPointerForDelegate(shouldHitCallback));
/*NativeAPI.TraceFilterProxySetTraceTypeCallback(Handle, getTypeCallback);
NativePINVOKE.TraceFilterProxy_SetGetTraceTypeCallback(ptr, getTypeCallback.ToHandle());
NativePINVOKE.TraceFilterProxy_SetShouldHitEntityCallback(ptr, shouldHitCallback.ToHandle());*/
}
}
public enum TraceType
{
Everything = 0,
WorldOnly, // NOTE: This does *not* test static props!!!
EntitiesOnly, // NOTE: This version will *not* test static props
EverythingFilterProps, // NOTE: This version will pass the IHandleEntity for props through the filter, unlike all other filters
};
public class CustomTraceFilter : TraceFilter
{
private Func<BaseEntity, bool> _filter;
public CustomTraceFilter(Func<BaseEntity, bool> filter)
{
_filter = filter;
}
public override bool ShouldHitEntity(BaseEntity entity, int contentMask)
{
return _filter.Invoke(entity);
}
public override TraceType GetTraceType()
{
return TraceType.Everything;
}
}
public class ExclusionTraceFilter : TraceFilter
{
private int _indexToExclude;
public ExclusionTraceFilter(int indexToExclude)
{
this._indexToExclude = indexToExclude;
}
public override bool ShouldHitEntity(BaseEntity entity, int contentMask)
{
if (entity.Index == _indexToExclude) return false;
return true;
}
public override TraceType GetTraceType()
{
return TraceType.Everything;
}
}
public abstract class TraceFilter : ITraceFilter
{
public abstract bool ShouldHitEntity(BaseEntity entity, int contentMask);
public abstract TraceType GetTraceType();
}
public interface ITraceFilter
{
bool ShouldHitEntity(BaseEntity entity, int contentMask);
TraceType GetTraceType();
}
}

View File

@@ -1,43 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Engine.Trace
{
public class TraceEngine
{
public static IntPtr CreateRay(RayType rayType, Vector vec1, Vector vec2)
{
return NativeAPI.CreateRay1((int) rayType, vec1.Handle, vec2.Handle);
}
public static IntPtr CreateRay(Vector vec1, Vector vec2, Vector vec3, Vector vec4)
{
return NativeAPI.CreateRay2(vec1.Handle, vec2.Handle, vec3.Handle, vec4.Handle);
}
public static TraceResult TraceRay(IntPtr ray, uint mask, ITraceFilter filter)
{
var tr = new TraceResult();
var proxy = new TraceFilterProxy(filter);
NativeAPI.TraceRay(ray, tr.Handle, proxy.Handle, mask);
return tr;
}
}
}

View File

@@ -1,63 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Engine.Trace
{
public class TraceResult : NativeObject
{
public TraceResult(IntPtr cPtr) : base(cPtr)
{
}
public TraceResult() : base(NativeAPI.NewTraceResult())
{
}
public bool DidHit()
{
// return NativeAPI.TraceDidHit(Handle);
return false;
}
public BaseEntity Entity
{
get
{
var entity = new BaseEntity(NativeAPI.TraceResultEntity(Handle));
if (entity?.IsNetworked == true)
{
return entity;
}
return null;
}
}
/*public TraceSurface Surface => NativePINVOKE.CGameTrace_surface_get(ptr).ToObject<TraceSurface>();
public int Hitbox => NativePINVOKE.CGameTrace_hitbox_get(ptr);
public int Hitgroup => NativePINVOKE.CGameTrace_hitgroup_get(ptr);
public float FractionLeftSolid => NativePINVOKE.CGameTrace_fractionleftsolid_get(ptr);
public int PhysicsBone => NativePINVOKE.CGameTrace_physicsbone_get(ptr);*/
/*public Vector StartPosition => NativePINVOKE.CBaseTrace_startpos_get(ptr).ToObject<Vector>();
public Vector EndPosition => NativePINVOKE.CBaseTrace_endpos_get(ptr).ToObject<Vector>();*/
}
}

View File

@@ -1,449 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using System.Drawing;
using System.Linq;
using System.Numerics;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace CounterStrikeSharp.API.Modules.Entities
{
public class BaseEntity : NativeObject
{
public BaseEntity(int index) : base(NativeAPI.BaseentityFromIndex(index))
{
_index = index;
}
public BaseEntity(IntPtr pointer) : base(pointer)
{
_index = NativeAPI.IndexFromBaseentity(pointer);
}
public override string ToString()
{
return string.Format("{0}", Index);
}
#region Props
public int GetProp(PropType type, string name) => NativeAPI.EntityGetPropInt(Index, (int) type, name);
public T GetProp<T>(PropType type, string name) => (T) (NativeAPI.EntityGetPropInt(Index, (int) type, name) as object);
public void SetProp(PropType type, string name, int value) => NativeAPI.EntitySetPropInt(Index, (int)type, name, value);
public void SetProp<T>(PropType type, string name, T value) => NativeAPI.EntitySetPropInt(Index, (int)type, name, (int)(object)value);
public bool GetPropBool(PropType type, string name) => GetProp(type, name) == 1;
public void SetPropBool(PropType type, string name, bool value) => SetProp(type, name, value ? 1 : 0);
public float GetPropFloat(PropType type, string name) => NativeAPI.EntityGetPropFloat(Index, (int) type, name);
public void SetPropFloat(PropType type, string name, float value) => NativeAPI.EntitySetPropFloat(Index, (int)type, name, value);
public Vector GetPropVector(PropType type, string name) => new(NativeAPI.EntityGetPropVector(Index, (int) type, name));
public void SetPropVector(PropType type, string name, Vector vector) => NativeAPI.EntitySetPropVector(Index, (int) type, name, vector.Handle);
public string GetPropString(PropType type, string name) => NativeAPI.EntityGetPropString(Index, (int)type, name);
public void SetPropString(PropType type, string name, string value) => NativeAPI.EntitySetPropString(Index, (int)type, name, value);
public BaseEntity GetPropEnt(PropType type, string name)
{
var returnVal = NativeAPI.EntityGetPropEnt(Index, (int) type, name);
if (returnVal < 0) return null;
return BaseEntity.FromIndex(returnVal);
}
public BaseEntity GetPropEntByOffset(int offset)
{
var returnVal = NativeAPI.EntityGetPropEntByOffset(Index, offset);
if (returnVal < 0) return null;
return BaseEntity.FromIndex(returnVal);
}
public void SetPropEnt(PropType type, string name, int index) => NativeAPI.EntitySetPropEnt(Index, (int) type, name, index);
#endregion
#region KeyValues
public string GetKeyValue(string name) => NativeAPI.EntityGetKeyvalue(Index, name);
public Vector GetKeyValueVector(string name)
{
var values = GetKeyValue(name).Split(new []{" "}, StringSplitOptions.None).Select(float.Parse).ToArray();
return new Vector(values[0], values[1], values[2]);
}
public float GetKeyValueFloat(string name)
{
return Convert.ToSingle(GetKeyValue(name));
}
public void SetKeyValue(string name, string value) => NativeAPI.EntitySetKeyvalue(Index, name, value);
public void SetKeyValueFloat(string name, float value) => SetKeyValue(name, value.ToString());
public void SetKeyValueVector(string name, Vector vec)
{
string strValue = $"{vec.X} {vec.Y} {vec.Z}";
NativeAPI.EntitySetKeyvalue(Index, name, strValue);
}
#endregion
public bool IsPlayer => NativeAPI.EntityIsPlayer(Index);
public bool IsWeapon => NativeAPI.EntityIsWeapon(Index);
public bool IsNetworked => NativeAPI.EntityIsNetworked(Index);
public bool IsValid => NativeAPI.EntityIsValid(Index);
/*public bool IsPlayer => NativePINVOKE.CBaseEntityWrapper_IsPlayer(ptr);
public bool IsWeapon => NativePINVOKE.CBaseEntityWrapper_IsWeapon(ptr);
public bool IsMoving => NativePINVOKE.CBaseEntityWrapper_IsMoving(ptr);*/
public Vector Origin
{
get => GetKeyValueVector("origin");
set => SetKeyValueVector("origin", value);
}
public Vector Maxs
{
get => GetPropVector(PropType.Send, "m_Collision.m_vecMaxs");
set => SetPropVector(PropType.Send, "m_Collision.m_vecMaxs", value);
}
public Vector Mins
{
get => GetPropVector(PropType.Send, "m_Collision.m_vecMins");
set => SetPropVector(PropType.Send, "m_Collision.m_vecMins", value);
}
public int EntityFlags
{
get => GetProp(PropType.Data, "m_iEFlags");
set => SetProp(PropType.Data, "m_iEFlags", value);
}
public SolidType SolidType
{
get => (SolidType)GetProp(PropType.Send, "m_Collision.m_nSolidType");
set => SetProp(PropType.Send, "m_Collision.m_nSolidType", (int)value);
}
public SolidFlags SolidFlags
{
get => GetProp<SolidFlags>(PropType.Send, "m_Collision.m_usSolidFlags");
set => SetProp(PropType.Send, "m_Collision.m_usSolidFlags", value);
}
public CollisionGroup CollisionGroup
{
get => GetProp<CollisionGroup>(PropType.Send, "m_CollisionGroup");
set => SetProp(PropType.Send, "m_CollisionGroup", value);
}
// TODO: ENTITY RENDER COLOR
public Color Color
{
get
{
int offset = NativeAPI.FindDatamapInfo(Index, "m_clrRender");
int r = NativeAPI.EntityGetProp(Index, offset + 0, 8);
int g = NativeAPI.EntityGetProp(Index, offset + 1, 8);
int b = NativeAPI.EntityGetProp(Index, offset + 2, 8);
int a = NativeAPI.EntityGetProp(Index, offset + 3, 8);
return Color.FromArgb(a, r, g, b);
}
set
{
int offset = NativeAPI.FindDatamapInfo(Index, "m_clrRender");
NativeAPI.EntitySetProp(Index, offset + 0, 8, value.R);
NativeAPI.EntitySetProp(Index, offset + 1, 8, value.G);
NativeAPI.EntitySetProp(Index, offset + 2, 8, value.B);
NativeAPI.EntitySetProp(Index, offset + 3, 8, value.A);
}
}
public float Elasticity
{
get => GetPropFloat(PropType.Send, "m_flElasticity");
set => SetPropFloat(PropType.Send, "m_flElasticity", value);
}
public BaseEntity GroundEntity
{
get => GetPropEnt(PropType.Data, "m_hGroundEntity");
set => SetPropEnt(PropType.Data, "m_hGroundEntity", value.Index);
}
public Team Team
{
get => GetProp<Team>(PropType.Send, "m_iTeamNum");
set => SetProp(PropType.Send, "m_iTeamNum", value);
}
public RenderFx RenderFx
{
get => (RenderFx)GetProp(PropType.Send, "m_nRenderFX");
set => SetProp(PropType.Send, "m_nRenderFX", (int)value);
}
public RenderMode RenderMode
{
get => (RenderMode)GetProp(PropType.Send, "m_nRenderMode");
set => SetProp(PropType.Send, "m_nRenderMode", (int)value);
}
public MoveType MoveType
{
get => (MoveType)GetProp(PropType.Send, "movetype");
set => SetProp(PropType.Send, "movetype", (int)value);
}
public new IntPtr Handle => NativeAPI.BaseentityFromIndex(Index);
public int ParentHandle
{
get
{
try
{
return GetProp(PropType.Data, "m_pParent");
}
catch (Exception)
{
return -1;
}
}
set => SetProp(PropType.Data, "m_pParent", value);
}
public Vector Angles
{
get => GetKeyValueVector("angles");
set => SetKeyValueVector("angles", value);
}
public string TargetName
{
get => GetKeyValue("targetname");
set => SetKeyValue("targetname", value);
}
// TODO: Entity Owner Handle
public Vector AngVelocity
{
get => GetPropVector(PropType.Data, "m_vecAngVelocity");
set => SetPropVector(PropType.Data, "m_vecAngVelocity", value);
}
public Vector BaseVelocity
{
get => GetPropVector(PropType.Data, "m_vecBaseVelocity");
set => SetPropVector(PropType.Data, "m_vecBaseVelocity", value);
}
public string DamageFilter
{
get => GetKeyValue("damagefilter");
set => SetKeyValue("damagefilter", value);
}
public int Effects
{
get => GetProp(PropType.Data, "m_fEffects");
set => SetProp(PropType.Data, "m_fEffects", value);
}
public float Friction
{
get => GetPropFloat(PropType.Data, "m_flFriction");
set => SetPropFloat(PropType.Data, "m_flFriction", value);
}
public string GlobalName
{
get => GetKeyValue("globalname");
set => SetKeyValue("globalname", value);
}
public float Gravity
{
get => GetPropFloat(PropType.Data, "m_flGravity");
set => SetPropFloat(PropType.Data, "m_flGravity", value);
}
public int HammerId
{
get => GetProp(PropType.Data, "m_iHammerID");
set => SetProp(PropType.Data, "m_iHammerID", value);
}
public int Health
{
get => GetProp(PropType.Data, "m_iHealth");
set => SetProp(PropType.Data, "m_iHealth", value);
}
public float LocalTime
{
get => GetPropFloat(PropType.Data, "m_flLocalTime");
set => SetPropFloat(PropType.Data, "m_flLocalTime", value);
}
public int MaxHealth
{
get => GetProp(PropType.Data, "m_iMaxHealth");
set => SetProp(PropType.Data, "m_iMaxHealth", value);
}
public string ParentName
{
get => GetKeyValue("parentname");
set => SetKeyValue("parentname", value);
}
public float ShadowCastDistance
{
get => GetPropFloat(PropType.Send, "m_flShadowCastDistance");
set => SetPropFloat(PropType.Send, "m_flShadowCastDistance", value);
}
public int SpawnFlags
{
get => GetProp(PropType.Data, "m_spawnflags");
set => SetProp(PropType.Data, "m_spawnflags", value);
}
public float Speed
{
get
{
try
{
return GetPropFloat(PropType.Data, "m_flLaggedMovementValue");
}
catch (Exception)
{
return GetKeyValueFloat("speed");
}
}
set
{
try
{
SetPropFloat(PropType.Data, "m_flLaggedMovementValue", value);
}
catch (Exception)
{
SetKeyValueFloat("speed", value);
}
}
}
public string Target
{
get => GetKeyValue("target");
set => SetKeyValue("target", value);
}
public Vector Velocity
{
get => GetPropVector(PropType.Data, "m_vecVelocity");
set => SetPropVector(PropType.Data, "m_vecVelocity", value);
}
public int WaterLevel
{
get => GetProp(PropType.Data, "m_nWaterLevel");
set => SetProp(PropType.Data, "m_nWaterLevel", value);
}
public Vector Rotation
{
get => GetPropVector(PropType.Data, "m_angRotation");
set => SetPropVector(PropType.Data, "m_angRotation", value);
}
private int? _index;
public int Index
{
get
{
return _index.Value;
}
}
public string ClassName => NativeAPI.EntityGetClassname(Index);
public Vector AbsVelocity
{
get => GetPropVector(PropType.Data, "m_vecAbsVelocity");
set => SetPropVector(PropType.Data, "m_vecAbsVelocity", value);
}
public Vector AbsOrigin
{
get => GetPropVector(PropType.Data, "m_vecAbsOrigin");
set => SetPropVector(PropType.Data, "m_vecAbsOrigin", value);
}
public void Spawn() => NativeAPI.EntitySpawn(Index);
public void AcceptInput(string name) => NativeAPI.AcceptInput(Index, name);
public static BaseEntity Create(string className)
{
var index = NativeAPI.EntityCreateByClassname(className);
if (index < 0) return null;
return new BaseEntity(index);
}
public static BaseEntity FromIndex(int index)
{
if (index < 0) return null;
var entity = new BaseEntity(index);
if (!entity.IsValid) return null;
return entity;
}
public static BaseEntity FindByClassname(int startIndex, string className)
{
var index = NativeAPI.EntityFindByClassname(startIndex, className);
if (index < 0) return null;
return new BaseEntity(index);
}
public static BaseEntity FindByNetClass(int startIndex, string className)
{
var index = NativeAPI.EntityFindByNetclass(startIndex, className);
if (index < 0) return null;
return new BaseEntity(index);
}
}
}

View File

@@ -1,60 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum DamageType
{
DMG_GENERIC = 0, // generic damage was done
DMG_CRUSH = (1 << 0), // crushed by falling or moving object.
// = NOTE: It's assumed crush damage is occurring as a result of physics collision, so no extra physics force is generated by crush damage.
DMG_BULLET = (1 << 1), // shot
DMG_SLASH = (1 << 2), // cut, clawed, stabbed
DMG_BURN = (1 << 3), // heat burned
DMG_VEHICLE = (1 << 4), // hit by a vehicle
DMG_FALL = (1 << 5), // fell too far
DMG_BLAST = (1 << 6), // explosive blast damage
DMG_CLUB = (1 << 7), // crowbar, punch, headbutt
DMG_SHOCK = (1 << 8), // electric shock
DMG_SONIC = (1 << 9), // sound pulse shockwave
DMG_ENERGYBEAM = (1 << 10), // laser or other high energy beam
DMG_PREVENT_PHYSICS_FORCE = (1 << 11), // Prevent a physics force
DMG_NEVERGIB = (1 << 12), // with this bit OR'd in, no damage type will be able to gib victims upon death
DMG_ALWAYSGIB = (1 << 13), // with this bit OR'd in, any damage type can be made to gib victims upon death.
DMG_DROWN = (1 << 14), // Drowning
DMG_PARALYZE = (1 << 15), // slows affected creature down
DMG_NERVEGAS = (1 << 16), // nerve toxins, very bad
DMG_POISON = (1 << 17), // blood poisoning - heals over time like drowning damage
DMG_RADIATION = (1 << 18), // radiation exposure
DMG_DROWNRECOVER = (1 << 19), // drowning recovery
DMG_ACID = (1 << 20), // toxic chemicals or acid burns
DMG_SLOWBURN = (1 << 21), // in an oven
DMG_REMOVENORAGDOLL = (1 << 22), // with this bit OR'd in, no ragdoll will be created, and the target will be quietly removed.
// = use this to kill an entity that you've already got a server-side ragdoll for
DMG_PHYSGUN = (1 << 23), // Hit by manipulator. Usually doesn't do any damage.
DMG_PLASMA = (1 << 24), // Shot by Cremator
DMG_AIRBOAT = (1 << 25), // Hit by the airboat's gun
DMG_DISSOLVE = (1 << 26), // Dissolving!
DMG_BLAST_SURFACE = (1 << 27), // A blast on the surface of water that cannot harm things underwater
DMG_DIRECT = (1 << 28),
DMG_BUCKSHOT = (1 << 29), // not quite a bullet. Little, rounder, different.
DMG_HEADSHOT = (1 << 30)
}
}

View File

@@ -1,56 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
[Flags]
public enum EntityFlags
{
Onground = (1 << 0), // At rest / on the ground
Ducking = (1 << 1), // Player flag -- Player is fully crouched
Waterjump = (1 << 3), // player jumping out of water
Ontrain = (1 << 4), // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
Inrain = (1 << 5), // Indicates the entity is standing in rain
Frozen = (1 << 6), // Player is frozen for 3rd person camera
Atcontrols = (1 << 7), // Player can't move, but keeps key inputs for controlling another entity
Client = (1 << 8), // Is a player
Fakeclient = (1 << 9), // Fake client, simulated server side; don't send network messages to them
Inwater = (1 << 10), // In water
Fly = (1 << 11), // Changes the SV_Movestep() behavior to not need to be on ground
Swim = (1 << 12), // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
Conveyor = (1 << 13),
Npc = (1 << 14),
Godmode = (1 << 15),
Notarget = (1 << 16),
Aimtarget = (1 << 17), // set if the crosshair needs to aim onto the entity
Partialground = (1 << 18), // not all corners are valid
Staticprop = (1 << 19), // Eetsa static prop!
Graphed = (1 << 20), // worldgraph has this ent listed as something that blocks a connection
Grenade = (1 << 21),
Stepmovement = (1 << 22), // Changes the SV_Movestep() behavior to not do any processing
Donttouch = (1 << 23), // Doesn't generate touch functions, generates Untouch() for anything it was touching when this flag was set
Basevelocity = (1 << 24), // Base velocity has been applied this frame (used to convert base velocity into momentum)
Worldbrush = (1 << 25), // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
Object = (1 << 26), // Terrible name. This is an object that NPCs should see. Missiles, for example.
Killme = (1 << 27), // This entity is marked for death -- will be freed by game DLL
Onfire = (1 << 28), // You know...
Dissolving = (1 << 29), // We're dissolving!
Transragdoll = (1 << 30), // In the process of turning into a client side ragdoll.
UnblockableByPlayer = (1 << 31) // pusher that can't be blocked by the player
}
}

View File

@@ -1,31 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum HitGroup
{
HITGROUP_GENERIC = 0,
HITGROUP_HEAD = 1,
HITGROUP_CHEST = 2,
HITGROUP_STOMACH = 3,
HITGROUP_LEFTARM = 4,
HITGROUP_RIGHTARM = 5,
HITGROUP_LEFTLEG = 6,
HITGROUP_RIGHTLEG = 7,
HITGROUP_GEAR = 10,
}
}

View File

@@ -1,27 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum LifeState
{
LIFE_ALIVE = 0, // alive
LIFE_DYING, // playing death animation or still falling off of a ledge waiting to hit ground
LIFE_DEAD, // dead. lying still.
LIFE_RESPAWNABLE,
LIFE_DISCARDBODY,
}
}

View File

@@ -1,39 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum MoveType
{
MOVETYPE_NONE = 0, // never moves
MOVETYPE_ISOMETRIC, // For players -- in TF2 commander view, etc.
MOVETYPE_WALK, // Player only - moving on the ground
MOVETYPE_STEP, // gravity, special edge handling -- monsters use this
MOVETYPE_FLY, // No gravity, but still collides with stuff
MOVETYPE_FLYGRAVITY, // flies through the air + is affected by gravity
MOVETYPE_VPHYSICS, // uses VPHYSICS for simulation
MOVETYPE_PUSH, // no clip to world, push and crush
MOVETYPE_NOCLIP, // No gravity, no collisions, still do velocity/avelocity
MOVETYPE_LADDER, // Used by players only when going onto a ladder
MOVETYPE_OBSERVER, // Observer movement, depends on player's observer mode
MOVETYPE_CUSTOM, // Allows the entity to describe its own physics
// should always be defined as the last item in the list
MOVETYPE_LAST = MOVETYPE_CUSTOM,
MOVETYPE_MAX_BITS = 4
}
}

View File

@@ -1,31 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum ObserverMode
{
OBS_MODE_NONE = 0, // not in spectator mode
OBS_MODE_DEATHCAM, // special mode for death cam animation
OBS_MODE_FREEZECAM, // zooms to a target, and freeze-frames on them
OBS_MODE_FIXED, // view from a fixed camera position
OBS_MODE_IN_EYE, // follow a player in first person view
OBS_MODE_CHASE, // follow a player in third person view
OBS_MODE_ROAMING, // free roaming
NUM_OBSERVER_MODES,
}
}

View File

@@ -1,34 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
enum PLAYER_ANIM
{
PLAYER_IDLE,
PLAYER_WALK,
PLAYER_JUMP,
PLAYER_SUPERJUMP,
PLAYER_DIE,
PLAYER_ATTACK1,
PLAYER_IN_VEHICLE,
// TF Player animations
PLAYER_RELOAD,
PLAYER_START_AIMING,
PLAYER_LEAVE_AIMING,
};
}

View File

@@ -1,33 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
/// <summary>
/// Property types for entity
/// </summary>
public enum PropType
{
/// <summary>
/// Property is networked
/// </summary>
Send,
/// <summary>
/// Property is a save data field
/// </summary>
Data
}
}

View File

@@ -1,48 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum RenderFx
{
RENDERFX_NONE = 0,
RENDERFX_PULSE_SLOW,
RENDERFX_PULSE_FAST,
RENDERFX_PULSE_SLOW_WIDE,
RENDERFX_PULSE_FAST_WIDE,
RENDERFX_FADE_SLOW,
RENDERFX_FADE_FAST,
RENDERFX_SOLID_SLOW,
RENDERFX_SOLID_FAST,
RENDERFX_STROBE_SLOW,
RENDERFX_STROBE_FAST,
RENDERFX_STROBE_FASTER,
RENDERFX_FLICKER_SLOW,
RENDERFX_FLICKER_FAST,
RENDERFX_NO_DISSIPATION,
RENDERFX_DISTORT, /**< Distort/scale/translate flicker */
RENDERFX_HOLOGRAM, /**< kRenderFxDistort + distance fade */
RENDERFX_EXPLODE, /**< Scale up really big! */
RENDERFX_GLOWSHELL, /**< Glowing Shell */
RENDERFX_CLAMP_MIN_SCALE, /**< Keep this sprite from getting very small (SPRITES only!) */
RENDERFX_ENV_RAIN, /**< for environmental rendermode, make rain */
RENDERFX_ENV_SNOW, /**< " " " , make snow */
RENDERFX_SPOTLIGHT, /**< TEST CODE for experimental spotlight */
RENDERFX_RAGDOLL, /**< HACKHACK: TEST CODE for signalling death of a ragdoll character */
RENDERFX_PULSE_FAST_WIDER,
RENDERFX_MAX
};
}

View File

@@ -1,33 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum RenderMode
{
RENDER_NORMAL, /**< src */
RENDER_TRANSCOLOR, /**< c*a+dest*(1-a) */
RENDER_TRANSTEXTURE, /**< src*a+dest*(1-a) */
RENDER_GLOW, /**< src*a+dest -- No Z buffer checks -- Fixed size in screen space */
RENDER_TRANSALPHA, /**< src*srca+dest*(1-srca) */
RENDER_TRANSADD, /**< src*a+dest */
RENDER_ENVIRONMENTAL, /**< not drawn, used for environmental effects */
RENDER_TRANSADDFRAMEBLEND, /**< use a fractional frame value to blend between animation frames */
RENDER_TRANSALPHAADD, /**< src + dest*(1-a) */
RENDER_WORLDGLOW, /**< Same as kRenderGlow but not fixed size in screen space */
RENDER_NONE /**< Don't render. */
};
}

View File

@@ -1,40 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
[Flags]
public enum SolidFlags
{
FSOLID_CUSTOMRAYTEST = 0x0001, // Ignore solid type + always call into the entity for ray tests
FSOLID_CUSTOMBOXTEST = 0x0002, // Ignore solid type + always call into the entity for swept box tests
FSOLID_NOT_SOLID = 0x0004, // Are we currently not solid?
FSOLID_TRIGGER = 0x0008, // This is something may be collideable but fires touch functions
// even when it's not collideable (when the FSOLID_NOT_SOLID flag is set)
FSOLID_NOT_STANDABLE = 0x0010, // You can't stand on this
FSOLID_VOLUME_CONTENTS = 0x0020, // Contains volumetric contents (like water)
FSOLID_FORCE_WORLD_ALIGNED = 0x0040, // Forces the collision rep to be world-aligned even if it's SOLID_BSP or SOLID_VPHYSICS
FSOLID_USE_TRIGGER_BOUNDS = 0x0080, // Uses a special trigger bounds separate from the normal OBB
FSOLID_ROOT_PARENT_ALIGNED = 0x0100, // Collisions are defined in root parent's local coordinate space
FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200, // This trigger will touch debris objects
FSOLID_TRIGGER_TOUCH_PLAYER = 0x0400, // This trigger will touch only players
FSOLID_NOT_MOVEABLE = 0x0800, // Assume this object will not move
FSOLID_MAX_BITS = 12
}
}

View File

@@ -1,30 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum SolidType
{
SOLID_NONE = 0, // no solid model
SOLID_BSP = 1, // a BSP tree
SOLID_BBOX = 2, // an AABB
SOLID_OBB = 3, // an OBB (not implemented yet)
SOLID_OBB_YAW = 4, // an OBB, constrained so that it can only yaw
SOLID_CUSTOM = 5, // Always call into the entity for tests
SOLID_VPHYSICS = 6, // solid vphysics object, get vcollide from the model and collide with that
SOLID_LAST,
}
}

View File

@@ -1,29 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum Team
{
TEAM_ANY = -1,
TEAM_INVALID = 1,
TEAM_UNASSIGNED = 0,
TEAM_SPECTATOR = 1,
TEAM_TERRORIST = 2,
TEAM_CT = 3,
TEAM_MAXCOUNT = 4,
}
}

View File

@@ -1,24 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Players.Constants
{
public enum NetFlow
{
FLOW_OUTGOING=0,
FLOW_INCOMING=1
}
}

View File

@@ -1,150 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Players
{
public class Player : BaseEntity
{
public Player(IntPtr pointer) : base(pointer)
{
}
public new static Player FromIndex(int index)
{
var playerBaseEntity = BaseEntity.FromIndex(index);
if (playerBaseEntity != null && !NativeAPI.ClientIsInGame(index)) return null;
if (playerBaseEntity == null) return null;
return new Player(playerBaseEntity.Handle);
}
private PlayerInfo _playerInfo;
public PlayerInfo PlayerInfo => _playerInfo ??= new PlayerInfo(NativeAPI.PlayerinfoFromIndex(Index));
public bool IsAlive => LifeState == (int)Entities.Constants.LifeState.LIFE_ALIVE;
public ObserverMode ObserverMode
{
get => (ObserverMode)GetProp(PropType.Send, "m_iObserverMode");
set => SetProp(PropType.Send, "m_iObserverMode", (int)value);
}
public PlayerButtons Buttons => (PlayerButtons)GetProp(PropType.Data, "m_nButtons");
public IEnumerable<PlayerButtons> SelectedButtons => Buttons.FlagsToList();
public string Name
{
get => PlayerInfo.Name;
}
public Player ObserverTarget
{
get
{
var targetIndex= GetPropEnt(PropType.Send, "m_hObserverTarget")?.Index;
return targetIndex != null ? Player.FromIndex(targetIndex.Value) : null;
}
}
public bool IsScoped
{
get => GetPropBool(PropType.Send, "m_bIsScoped");
set => SetPropBool(PropType.Send, "m_bIsScoped", value);
}
public EntityFlags Flags
{
get => (EntityFlags)GetProp(PropType.Data, "m_fFlags");
set => SetProp(PropType.Data, "m_fFlags", (int)value);
}
public int LifeState
{
get => GetProp(PropType.Send, "m_lifeState");
set => SetProp(PropType.Send, "m_lifeState", value);
}
public Vector ViewOffset
{
get => GetPropVector(PropType.Data, "m_vecViewOffset");
set => SetPropVector(PropType.Data, "m_vecViewOffset", value);
}
public Vector EyeLocation => Origin + ViewOffset;
public Angle EyeAngle
{
get
{
try
{
var x = GetPropFloat(PropType.Send, "m_angEyeAngles[0]");
var y = GetPropFloat(PropType.Send, "m_angEyeAngles[1]");
return new Angle(x, y, 0);
}
catch (Exception e)
{
Server.PrintToConsole($"Error when retrieving eye angles: {e.Message}, {e.StackTrace}");
return new Angle();
}
}
}
public Vector ViewVector
{
get
{
double yaw = (Math.PI / 180) * EyeAngle.Y;
double pitch = (Math.PI / 180) * EyeAngle.X;
var sy = Math.Sin(yaw);
var cy = Math.Cos(yaw);
var sp = Math.Sin(pitch);
var cp = Math.Cos(pitch);
return new Vector((float)(cp * cy), (float)(cp * sy), (float)-sp);
}
}
public bool IsFakeClient => NativeAPI.IsFakeClient(Index);
public BaseEntity ActiveWeapon
{
get => GetPropEnt(PropType.Data, "m_hActiveWeapon");
set => SetPropEnt(PropType.Data, "m_hActiveWeapon", value.Index);
}
public static Player FromUserId(int userid)
{
var index = NativeAPI.IndexFromUserid(userid);
if (index <= 0) return null;
return FromIndex(index);
}
public void PrintToChat(string message) => NativeAPI.PrintToChat(Index, message);
public void PrintToHint(string message) => NativeAPI.PrintToHint(Index, message);
public void PrintToCenter(string message) => NativeAPI.PrintToCenter(Index, message);
}
}

View File

@@ -1,63 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Players
{
public class PlayerInfo : NativeObject
{
internal PlayerInfo(IntPtr cHandle) : base(cHandle)
{
}
public string Name => NativeAPI.PlayerinfoGetName(Handle);
public int UserId => NativeAPI.PlayerinfoGetUserid(Handle);
public string SteamId => NativeAPI.PlayerinfoGetSteamid(Handle);
public Team Team
{
get => (Team)NativeAPI.PlayerinfoGetTeam(Handle);
set => NativeAPI.PlayerinfoSetTeam(Handle, (int) value);
}
public int Kills => NativeAPI.PlayerinfoGetKills(Handle);
public int Deaths => NativeAPI.PlayerinfoGetKills(Handle);
public bool IsConnected => NativeAPI.PlayerinfoIsConnected(Handle);
public int Armor => NativeAPI.PlayerinfoGetArmor(Handle);
public bool IsHLTV => NativeAPI.PlayerinfoIsHltv(Handle);
public bool IsPlayer => NativeAPI.PlayerinfoIsPlayer(Handle);
public bool IsFakeClient => NativeAPI.PlayerinfoIsFakeclient(Handle);
public bool IsDead => NativeAPI.PlayerinfoIsDead(Handle);
public bool IsInAVehicle => NativeAPI.PlayerinfoIsInVehicle(Handle);
public bool IsObserver => NativeAPI.PlayerinfoIsObserver(Handle);
/*public Angle Origin => NativePINVOKE.IPlayerInfo_GetAbsOrigin(Handle).ToObject<Angle>();
public Angle Angles => NativePINVOKE.IPlayerInfo_GetAbsAngles(Handle).ToObject<Angle>();
public Angle MinSize => NativePINVOKE.IPlayerInfo_GetPlayerMins(Handle).ToObject<Angle>();
public Angle MaxSize => NativePINVOKE.IPlayerInfo_GetPlayerMaxs(Handle).ToObject<Angle>();*/
public string WeaponName => NativeAPI.PlayerinfoGetWeaponName(Handle);
public string ModelName => NativeAPI.PlayerinfoGetModelName(Handle);
public int Health => NativeAPI.PlayerinfoGetHealth(Handle);
public int MaxHealth => NativeAPI.PlayerinfoGetMaxHealth(Handle);
//public CBotCmd LastUserCommand => NativePINVOKE.IPlayerInfo_GetLastUserCommand(Handle);
}
}

View File

@@ -1,28 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Sound.Constants
{
public static class SoundAttenuation
{
public const float ATTN_NONE = 0.0f;
public const float ATTN_NORM = 0.8f;
public const float ATTN_IDLE = 2.0f;
public const float ATTN_STATIC = 1.25f;
public const float ATTN_RICOCHET = 1.5f;
public const float ATTN_GUNFIRE = 0.27f;
}
}

View File

@@ -1,32 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Sound.Constants
{
public enum SoundChannel
{
CHAN_REPLACE = -1,
CHAN_AUTO = 0,
CHAN_WEAPON = 1,
CHAN_VOICE = 2,
CHAN_ITEM = 3,
CHAN_BODY = 4,
CHAN_STREAM = 5, // allocate stream channel from the static or dynamic area
CHAN_STATIC = 6, // allocate channel from the static area
CHAN_VOICE_BASE = 7, // allocate channel for network voice data
CHAN_USER_BASE = 135
}
}

View File

@@ -1,42 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
namespace CounterStrikeSharp.API.Modules.Sound.Constants
{
[Flags]
public enum SoundFlags
{
SND_NOFLAGS = 0, // to keep the compiler happy
SND_CHANGE_VOL = (1<<0), // change sound vol
SND_CHANGE_PITCH = (1<<1), // change sound pitch
SND_STOP = (1<<2), // stop the sound
SND_SPAWNING = (1<<3), // we're spawning, used in some cases for ambients
// not sent over net, only a param between dll and server.
SND_DELAY = (1<<4), // sound has an initial delay
SND_STOP_LOOPING = (1<<5), // stop all looping sounds on the entity.
SND_SPEAKER = (1<<6), // being played again by a microphone through a speaker
SND_SHOULDPAUSE = (1<<7), // this sound should be paused if the game is paused
SND_IGNORE_PHONEMES = (1<<8),
SND_IGNORE_NAME = (1<<9), // used to change all sounds emitted by an entity, regardless of scriptname
SND_IS_SCRIPTHANDLE = (1<<10), // server has passed the actual SoundEntry instead of wave filename
SND_UPDATE_DELAY_FOR_CHOREO = (1<<11), // True if we have to update snd_delay_for_choreo with the IO latency.
SND_GENERATE_GUID = (1<<12),
}
}

View File

@@ -1,62 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Sound.Constants
{
public enum SoundLevel
{
SNDLVL_NONE = 0,
SNDLVL_20dB = 20, // rustling leaves
SNDLVL_25dB = 25, // whispering
SNDLVL_30dB = 30, // library
SNDLVL_35dB = 35,
SNDLVL_40dB = 40,
SNDLVL_45dB = 45, // refrigerator
SNDLVL_50dB = 50, // 3.9 // average home
SNDLVL_55dB = 55, // 3.0
SNDLVL_IDLE = 60, // 2.0
SNDLVL_60dB = 60, // 2.0 // normal conversation, clothes dryer
SNDLVL_65dB = 65, // 1.5 // washing machine, dishwasher
SNDLVL_STATIC = 66, // 1.25
SNDLVL_70dB = 70, // 1.0 // car, vacuum cleaner, mixer, electric sewing machine
SNDLVL_NORM = 75,
SNDLVL_75dB = 75, // 0.8 // busy traffic
SNDLVL_80dB = 80, // 0.7 // mini-bike, alarm clock, noisy restaurant, office tabulator, outboard motor, passing snowmobile
SNDLVL_TALKING = 80, // 0.7
SNDLVL_85dB = 85, // 0.6 // average factory, electric shaver
SNDLVL_90dB = 90, // 0.5 // screaming child, passing motorcycle, convertible ride on frw
SNDLVL_95dB = 95,
SNDLVL_100dB = 100, // 0.4 // subway train, diesel truck, woodworking shop, pneumatic drill, boiler shop, jackhammer
SNDLVL_105dB = 105, // helicopter, power mower
SNDLVL_110dB = 110, // snowmobile drvrs seat, inboard motorboat, sandblasting
SNDLVL_120dB = 120, // auto horn, propeller aircraft
SNDLVL_130dB = 130, // air raid siren
SNDLVL_GUNFIRE = 140, // 0.27 // THRESHOLD OF PAIN, gunshot, jet engine
SNDLVL_140dB = 140, // 0.2
SNDLVL_150dB = 150, // 0.2
SNDLVL_180dB = 180, // rocket launching
}
}

View File

@@ -1,25 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Sound.Constants
{
public static class SoundPitch
{
public const int PITCH_NORM = 100;
public const int PITCH_LOW = 95;
public const int PITCH_HIGH = 120;
}
}

View File

@@ -1,25 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Sound.Constants
{
public static class SoundSource
{
public const int SOUND_FROM_PLAYER = -2;
public const int SOUND_FROM_LOCAL_PLAYER = -1;
public const int SOUND_FROM_WORLD = 0;
}
}

View File

@@ -1,72 +0,0 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System;
using System.Runtime.InteropServices;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Players;
using CounterStrikeSharp.API.Modules.Sound.Constants;
using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Sound
{
public static class Sound
{
public static bool PrecacheSound(string sound) => NativeAPI.PrecacheSound(sound, true);
public static bool IsSoundPrecached(string sound) => NativeAPI.IsSoundPrecached(sound);
public static float GetSoundDuration(string sound) => NativeAPI.GetSoundDuration(sound);
public static void EmitSound(int client,
string sound,
int entity = SoundSource.SOUND_FROM_PLAYER,
SoundChannel channel = SoundChannel.CHAN_AUTO,
SoundLevel level = SoundLevel.SNDLVL_NORM,
float attenuation = SoundAttenuation.ATTN_NORM,
SoundFlags flags = SoundFlags.SND_NOFLAGS,
float volume = 1.0f,
int pitch = SoundPitch.PITCH_NORM,
Vector origin = null,
Vector direction = null)
{
NativeAPI.EmitSound(client, entity, (int) channel, sound, volume, attenuation, (int) flags,
pitch, origin?.Handle ?? IntPtr.Zero, direction?.Handle ?? IntPtr.Zero);
}
public static void EmitSoundToAll(string sound,
int entity = SoundSource.SOUND_FROM_PLAYER,
SoundChannel channel = SoundChannel.CHAN_AUTO,
SoundLevel level = SoundLevel.SNDLVL_NORM,
float attenuation = SoundAttenuation.ATTN_NORM,
SoundFlags flags = SoundFlags.SND_NOFLAGS,
float volume = 1.0f,
int pitch = SoundPitch.PITCH_NORM,
Vector origin = null,
Vector direction = null)
{
for (int i = 1; i < 65; i++)
{
var client = Player.FromIndex(i);
if (client?.IsValid == true)
{
Sound.EmitSound(i, sound, entity, channel, level, attenuation, flags, volume, pitch, origin,
direction);
}
}
}
}
}

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
@@ -36,9 +36,12 @@ namespace CounterStrikeSharp.API.Modules.Entities.Constants
TerroristsSurrender = 0x11u, // this also triggers match cancelled
CTsSurrender = 0x12u, // this also triggers match cancelled
TerroristsPlanned = 0x13u,
TerroristsPlanted = 0x13u,
CTsReachedHostage = 0x14u,
SurvivalWin = 0x15u,
SurvivalDraw = 0x16u
SurvivalDraw = 0x16u,
[Obsolete("Use RoundEndReason.TerroristsPlanted instead.")]
TerroristsPlanned = 0x13u
}
}
}

View File

@@ -76,8 +76,7 @@ namespace CounterStrikeSharp.API.Modules.Events
SetInt(name, i);
break;
case var _ when value is CCSPlayerController player:
// When I was testing this, the code seems to expect a slot, even though it is called index
SetEntityIndex(name, (int)player.Index - 1);
NativeAPI.SetEventPlayerController(Handle, name, player.Handle);
break;
case var _ when value is string s:
SetString(name, s);

View File

@@ -69,6 +69,11 @@ public class Schema
return offset;
}
public static bool IsSchemaFieldNetworked(string className, string propertyName)
{
return NativeAPI.IsSchemaFieldNetworked(className, propertyName);
}
public static T GetSchemaValue<T>(IntPtr handle, string className, string propertyName)
{

View File

@@ -68,6 +68,9 @@ public static class VirtualFunctions
public static MemoryFunctionVoid<CEntityInstance, CTakeDamageInfo> CBaseEntity_TakeDamageOldFunc = new (GameData.GetSignature("CBaseEntity_TakeDamageOld"));
public static Action<CEntityInstance, CTakeDamageInfo> CBaseEntity_TakeDamageOld = CBaseEntity_TakeDamageOldFunc.Invoke;
public static MemoryFunctionWithReturn<CCSPlayer_WeaponServices, CBasePlayerWeapon, bool> CCSPlayer_WeaponServices_CanUseFunc = new(GameData.GetSignature("CCSPlayer_WeaponServices_CanUse"));
public static Func<CCSPlayer_WeaponServices, CBasePlayerWeapon, bool> CCSPlayer_WeaponServices_CanUse = CCSPlayer_WeaponServices_CanUseFunc.Invoke;
public static MemoryFunctionVoid<CCSPlayerPawnBase> CCSPlayerPawnBase_PostThinkFunc = new (GameData.GetSignature("CCSPlayerPawnBase_PostThink"));
public static Action<CCSPlayerPawnBase> CCSPlayerPawnBase_PostThink = CCSPlayerPawnBase_PostThinkFunc.Invoke;
@@ -76,4 +79,19 @@ public static class VirtualFunctions
public static MemoryFunctionVoid<CBaseTrigger, CBaseEntity> CBaseTrigger_EndTouchFunc = new (GameData.GetSignature("CBaseTrigger_EndTouch"));
public static Action<CBaseTrigger, CBaseEntity> CBaseTrigger_EndTouch = CBaseTrigger_EndTouchFunc.Invoke;
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 Action<IntPtr, int, long> NetworkStateChanged = NetworkStateChangedFunc.Invoke;
}

View File

@@ -0,0 +1,139 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System.Collections.Generic;
namespace CounterStrikeSharp.API.Modules.Menu
{
public abstract class BaseMenu : IMenu
{
public string Title { get; set; }
public List<ChatMenuOption> MenuOptions { get; } = new();
protected BaseMenu(string title)
{
Title = title;
}
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;
}
}
// This must be called ChatMenuOption to maintain backwards compatibility with the old API
public class ChatMenuOption
{
public string Text { get; set; }
public bool Disabled { get; set; }
public Action<CCSPlayerController, ChatMenuOption> OnSelect { get; set; }
public ChatMenuOption(string display, bool disabled, Action<CCSPlayerController, ChatMenuOption> onSelect)
{
Text = display;
Disabled = disabled;
OnSelect = onSelect;
}
}
public abstract class BaseMenuInstance : IMenuInstance
{
public virtual int NumPerPage => 6;
public Stack<int> PrevPageOffsets { get; } = new();
public IMenu Menu { get; }
public CCSPlayerController Player { get; }
public int Page { get; set; }
public int CurrentOffset { get; set; }
protected BaseMenuInstance(CCSPlayerController player, IMenu menu)
{
Menu = menu;
Player = player;
}
protected bool HasPrevButton => Page > 0;
protected bool HasNextButton => CurrentOffset + NumPerPage < Menu.MenuOptions.Count;
protected int MenuItemsPerPage => NumPerPage + 2 - (HasNextButton ? 1 : 0) - (HasPrevButton ? 1 : 0);
public virtual void Display()
{
throw new NotImplementedException();
}
public void OnKeyPress(CCSPlayerController player, int key)
{
if (player.Handle != Player.Handle) return;
if (key == 8 && HasNextButton)
{
NextPage();
return;
}
if (key == 7 && HasPrevButton)
{
PrevPage();
return;
}
if (key == 9)
{
Reset();
return;
}
var desiredValue = key;
var menuItemIndex = CurrentOffset + desiredValue - 1;
if (menuItemIndex >= 0 && menuItemIndex < Menu.MenuOptions.Count)
{
var menuOption = Menu.MenuOptions[menuItemIndex];
if (!menuOption.Disabled)
{
menuOption.OnSelect(Player, menuOption);
Reset();
}
}
}
public virtual void Reset()
{
CurrentOffset = 0;
Page = 0;
PrevPageOffsets.Clear();
}
public void NextPage()
{
PrevPageOffsets.Push(CurrentOffset);
CurrentOffset += MenuItemsPerPage;
Page++;
Display();
}
public void PrevPage()
{
Page--;
CurrentOffset = PrevPageOffsets.Pop();
Display();
}
}
}

View File

@@ -0,0 +1,126 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System.Text;
using Microsoft.Extensions.Logging;
namespace CounterStrikeSharp.API.Modules.Menu
{
public class CenterHtmlMenu : BaseMenu
{
public CenterHtmlMenu(string title) : base(ModifyTitle(title))
{
}
public override ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false)
{
var option = new ChatMenuOption(ModifyOptionDisplay(display), disabled, onSelect);
MenuOptions.Add(option);
return option;
}
private static string ModifyTitle(string title)
{
if (title.Length > 32)
{
Application.Instance.Logger.LogWarning("Title should not be longer than 32 characters for a CenterHtmlMenu");
return title[..32];
}
return title;
}
private static string ModifyOptionDisplay(string display)
{
if (display.Length > 26)
{
Application.Instance.Logger.LogWarning("Display should not be longer than 26 characters for a CenterHtmlMenu item");
return display[..26];
}
return display;
}
}
public class CenterHtmlMenuInstance : BaseMenuInstance
{
private readonly BasePlugin _plugin;
public override int NumPerPage => 5; // one less than the actual number of items per page to avoid truncated options
public CenterHtmlMenuInstance(BasePlugin plugin, CCSPlayerController player, IMenu menu) : base(player, menu)
{
_plugin = plugin;
RemoveOnTickListener();
plugin.RegisterListener<Core.Listeners.OnTick>(Display);
}
public override void Display()
{
if (MenuManager.GetActiveMenu(Player) != this)
{
Reset();
return;
}
var builder = new StringBuilder();
builder.Append($"<b><font color='yellow'>{Menu.Title}</font></b>");
builder.AppendLine("<br>");
var keyOffset = 1;
for (var i = CurrentOffset; i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count); i++)
{
var option = Menu.MenuOptions[i];
string color = option.Disabled ? "grey" : "green";
builder.Append($"<font color='{color}'>!{keyOffset++}</font> {option.Text}");
builder.AppendLine("<br>");
}
if (HasPrevButton)
{
builder.AppendFormat("<font color='yellow'>!7</font> &#60;- Prev");
builder.AppendLine("<br>");
}
if (HasNextButton)
{
builder.AppendFormat("<font color='yellow'>!8</font> -> Next");
builder.AppendLine("<br>");
}
builder.AppendFormat("<font color='red'>!9</font> -> Close");
builder.AppendLine("<br>");
var currentPageText = builder.ToString();
Player.PrintToCenterHtml(currentPageText);
}
public override void Reset()
{
base.Reset();
RemoveOnTickListener();
// Send a blank message to clear the menu
Player.PrintToCenterHtml(" ");
}
private void RemoveOnTickListener()
{
var onTick = new Core.Listeners.OnTick(Display);
_plugin.RemoveListener("OnTick", onTick);
}
}
}

View File

@@ -1,164 +1,77 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Menu;
public class ChatMenuOption
namespace CounterStrikeSharp.API.Modules.Menu
{
public ChatMenuOption(string text, bool disabled, Action<CCSPlayerController, ChatMenuOption> onSelect)
public class ChatMenu: BaseMenu
{
Text = text;
Disabled = disabled;
OnSelect = onSelect;
public ChatMenu(string title) : base(title)
{
}
}
public Action<CCSPlayerController, ChatMenuOption> OnSelect { get; set; }
public string Text { get; set; }
public bool Disabled { get; set; }
}
public class ChatMenu
{
public string Title { get; set; }
public List<ChatMenuOption> MenuOptions { get; } = new();
public ChatMenu(string title)
public class ChatMenuInstance : BaseMenuInstance
{
Title = title;
public ChatMenuInstance(CCSPlayerController player, ChatMenu menu) : base(player, menu)
{
}
public override void Display()
{
Player.PrintToChat(Menu.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}");
}
if (HasPrevButton)
{
Player.PrintToChat($" {ChatColors.Yellow}!7 {ChatColors.Default}-> Prev");
}
if (HasNextButton)
{
Player.PrintToChat($" {ChatColors.Yellow}!8 {ChatColors.Default}-> Next");
}
}
}
public ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false)
public static class ChatMenus
{
var option = new ChatMenuOption(display, disabled, onSelect);
MenuOptions.Add(option);
return option;
[Obsolete("Use MenuManager.OpenChatMenu instead")]
public static void OpenMenu(CCSPlayerController player, ChatMenu menu)
{
MenuManager.OpenChatMenu(player, menu);
}
[Obsolete("Use MenuManager.OnKeyPress instead")]
public static void OnKeyPress(CCSPlayerController player, int key)
{
MenuManager.OnKeyPress(player, key);
}
}
}
public class ChatMenuInstance
{
// Six items seems to be able to fit all options in the chat bot without having to open it
readonly int _numPerPage = 6;
private readonly Stack<int> _prevPageOffsets = new();
private readonly ChatMenu _menu;
int _page = 0;
int _currentOffset = 0;
private CCSPlayerController _player;
public ChatMenuInstance(CCSPlayerController player, ChatMenu menu)
{
_menu = menu;
_player = player;
}
private bool HasPrevButton => _page > 0;
private bool HasNextButton => (_currentOffset + _numPerPage) < _menu.MenuOptions.Count;
private int MenuItemsPerPage => _numPerPage + 2 - (HasNextButton ? 1 : 0) - (HasPrevButton ? 1 : 0);
public void Display()
{
_player.PrintToChat(_menu.Title);
_player.PrintToChat("---");
int keyOffset = 1;
if (HasPrevButton)
{
_player.PrintToChat($" {ChatColors.Yellow}[!1] {ChatColors.Default}-> Prev");
keyOffset++;
}
for (int 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}");
}
if (HasNextButton)
{
_player.PrintToChat($" {ChatColors.Yellow}[!8] {ChatColors.Default}-> Next");
}
}
internal void OnKeyPress(CCSPlayerController player, int key)
{
if (_player == null || player.Handle != _player.Handle) return;
if (key == 8 && HasNextButton)
{
NextPage();
return;
}
if (key == 1 && HasPrevButton)
{
PrevPage();
return;
}
var desiredValue = key;
if (HasPrevButton) desiredValue = key - 1;
var menuItemIndex = _currentOffset + desiredValue - 1;
var menuOption = _menu.MenuOptions[menuItemIndex];
if (!menuOption.Disabled)
{
menuOption.OnSelect(_player, menuOption);
Reset();
}
}
public void Reset()
{
_currentOffset = 0;
_page = 0;
_prevPageOffsets.Clear();
_player = null;
}
public void NextPage()
{
_prevPageOffsets.Push(_currentOffset);
_currentOffset += MenuItemsPerPage;
_page++;
Display();
}
public void PrevPage()
{
_page--;
_currentOffset = _prevPageOffsets.Pop();
Display();
}
}
public static class ChatMenus
{
private static readonly Dictionary<IntPtr, ChatMenuInstance> ActiveMenus = new();
public static void OpenMenu(CCSPlayerController player, ChatMenu menu)
{
ActiveMenus[player.Handle] = new ChatMenuInstance(player, menu);
ActiveMenus[player.Handle].Display();
}
public static void OnKeyPress(CCSPlayerController player, int key)
{
if (!ActiveMenus.ContainsKey(player.Handle)) return;
ActiveMenus[player.Handle].OnKeyPress(player, key);
}
}

View File

@@ -0,0 +1,60 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
namespace CounterStrikeSharp.API.Modules.Menu
{
public class ConsoleMenu : BaseMenu
{
public ConsoleMenu(string title) : base(title)
{
}
}
public class ConsoleMenuInstance : BaseMenuInstance
{
public ConsoleMenuInstance(CCSPlayerController player, IMenu menu) : base(player, menu)
{
}
public override void Display()
{
Player.PrintToConsole(Menu.Title);
Player.PrintToConsole("---");
var keyOffset = 1;
for (var i = CurrentOffset;
i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count);
i++)
{
var option = Menu.MenuOptions[i];
Player.PrintToConsole(
$" {(option.Disabled ? "[Enabled]" : "[Disabled] - ")} !{keyOffset++} {option.Text}");
}
if (HasPrevButton)
{
Player.PrintToConsole($"!7 -> Prev");
}
if (HasNextButton)
{
Player.PrintToConsole($"!8 -> Next");
}
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System.Collections.Generic;
namespace CounterStrikeSharp.API.Modules.Menu
{
public interface IMenu
{
public string Title { get; set; }
public List<ChatMenuOption> MenuOptions { get; }
public ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false);
}
public interface IMenuInstance
{
protected IMenu Menu { get; }
protected CCSPlayerController? Player { get; }
protected int Page { get; }
protected int CurrentOffset { get; }
protected int NumPerPage { get; }
protected Stack<int> PrevPageOffsets { get; }
public void NextPage();
public void PrevPage();
public void Reset();
public void Display();
public void OnKeyPress(CCSPlayerController player, int key);
}
}

View File

@@ -0,0 +1,76 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
using System.Collections.Generic;
namespace CounterStrikeSharp.API.Modules.Menu;
public static class MenuManager
{
private static readonly Dictionary<IntPtr, IMenuInstance> ActiveMenus = new();
public static Dictionary<IntPtr, IMenuInstance> GetActiveMenus()
{
return ActiveMenus;
}
public static IMenuInstance? GetActiveMenu(CCSPlayerController player)
{
return !ActiveMenus.TryGetValue(player.Handle, out var value) ? null : value;
}
private static void ResetMenus(CCSPlayerController player)
{
if (ActiveMenus.TryGetValue(player.Handle, out var activeMenu))
{
activeMenu.Reset();
}
ActiveMenus.Remove(player.Handle);
}
public static void OpenChatMenu(CCSPlayerController player, ChatMenu menu)
{
ResetMenus(player);
ActiveMenus[player.Handle] = new ChatMenuInstance(player, menu);
ActiveMenus[player.Handle].Display();
}
public static void OpenCenterHtmlMenu(BasePlugin plugin, CCSPlayerController player, CenterHtmlMenu menu)
{
ResetMenus(player);
ActiveMenus[player.Handle] = new CenterHtmlMenuInstance(plugin, player, menu);
ActiveMenus[player.Handle].Display();
}
public static void OpenConsoleMenu(CCSPlayerController player, ConsoleMenu menu)
{
ResetMenus(player);
ActiveMenus[player.Handle] = new ConsoleMenuInstance(player, menu);
ActiveMenus[player.Handle].Display();
}
public static void OnKeyPress(CCSPlayerController player, int key)
{
if (ActiveMenus.TryGetValue(player.Handle, out var activeMenu))
{
activeMenu.OnKeyPress(player, key);
}
}
}

View File

@@ -20,7 +20,7 @@ public class ChatColors
{
public static char Default = '\x01';
public static char White = '\x01';
public static char Darkred = '\x02';
public static char DarkRed = '\x02';
public static char Green = '\x04';
public static char LightYellow = '\x09';
public static char LightBlue = '\x0B';
@@ -39,4 +39,7 @@ public class ChatColors
public static char Magenta = '\x0E';
public static char LightRed = '\x0F';
public static char Orange = '\x10';
}
[Obsolete("Use ChatColors.DarkRed instead.")]
public static char Darkred = '\x02';
}

View File

@@ -75,7 +75,7 @@ namespace CounterStrikeSharp.API
public static string GameDirectory => NativeAPI.GetGameDirectory();
public static int MaxPlayers => NativeAPI.GetCommandParamValue("-maxplayers", DataType.DATA_TYPE_INT, 64);
public static int MaxPlayers => NativeAPI.GetMaxClients();
public static bool IsMapValid(string mapName) => NativeAPI.IsMapValid(mapName);

View File

@@ -21,8 +21,10 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using CounterStrikeSharp.API.Core.Logging;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Entities;
using Microsoft.Extensions.Logging;
namespace CounterStrikeSharp.API
{
@@ -75,12 +77,47 @@ namespace CounterStrikeSharp.API
return new Target(pattern).GetTarget(player);
}
public static bool RemoveItemByDesignerName(this CCSPlayerController player, string designerName)
{
return RemoveItemByDesignerName(player, designerName, false);
}
public static bool RemoveItemByDesignerName(this CCSPlayerController player, string designerName, bool shouldRemoveEntity)
{
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)
{
if (weapon is not { IsValid: true, Value.IsValid: true })
continue;
if (weapon.Value.DesignerName != designerName)
continue;
item = weapon;
}
if (item != null && item.Value != null)
{
player.PlayerPawn.Value.RemovePlayerItem(item.Value);
if (shouldRemoveEntity)
{
item.Value.Remove();
}
return true;
}
return false;
}
public static IEnumerable<T> FindAllEntitiesByDesignerName<T>(string designerName) where T : CEntityInstance
{
var pEntity = new CEntityIdentity(EntitySystem.FirstActiveEntity);
for (; pEntity != null && pEntity.Handle != IntPtr.Zero; pEntity = pEntity.Next)
{
if (!pEntity.DesignerName.Contains(designerName)) continue;
if (pEntity.DesignerName == null || !pEntity.DesignerName.Contains(designerName)) continue;
yield return new PointerTo<T>(pEntity.Handle).Value;
}
}
@@ -101,9 +138,9 @@ namespace CounterStrikeSharp.API
{
List<CCSPlayerController> players = new();
for (int i = 1; i <= Server.MaxPlayers; i++)
for (int i = 0; i < Server.MaxPlayers; i++)
{
var controller = GetPlayerFromIndex(i);
var controller = GetPlayerFromSlot(i);
if (!controller.IsValid || controller.UserId == -1)
continue;
@@ -161,5 +198,38 @@ namespace CounterStrikeSharp.API
return (T)Activator.CreateInstance(typeof(T), pointerTo)!;
}
private static int FindSchemaChain(string className) => Schema.GetSchemaOffset(className, "__m_pChainEntity");
/// <summary>
/// Marks a field as changed for network transmission.
/// Not all schema fields are network enabled, so please check the schema before using this.
/// </summary>
/// <param name="entity">Entity to update</param>
/// <param name="className" example="CBaseEntity">Schema field class name</param>
/// <param name="fieldName" example="m_iHealth">Schema field name</param>
/// <param name="extraOffset">Any additional offset to the schema field</param>
public static void SetStateChanged(CBaseEntity entity, string className, string fieldName, int extraOffset = 0)
{
if (!Schema.IsSchemaFieldNetworked(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);
if (chainOffset != 0)
{
VirtualFunctions.NetworkStateChanged(entity.Handle + chainOffset, offset + extraOffset, 0xFFFFFFFF);
return;
}
VirtualFunctions.StateChanged(entity.NetworkTransmitComponent.Handle, entity.Handle, offset + extraOffset, -1, -1);
entity.LastNetworkChange = Server.CurrentTime;
entity.IsSteadyState.Clear();
}
}
}

View File

@@ -233,7 +233,9 @@ internal static partial class Program
continue;
// Putting these in the too hard basket for now.
if (field.Name == "m_VoteOptions" || field.Name == "m_aShootSounds") continue;
if (field.Name == "m_VoteOptions" || field.Name == "m_aShootSounds" || field.Name == "m_pVecRelationships") continue;
if (IgnoreClasses.Contains(field.Type.Name)) continue;
if (field.Type.Category == SchemaTypeCategory.Bitfield) continue;
if (field.Type is { Category: SchemaTypeCategory.Atomic, Atomic: SchemaAtomicCategory.Collection })
{
@@ -242,9 +244,10 @@ internal static partial class Program
var handleParams = $"this.Handle, \"{schemaClassName}\", \"{field.Name}\"";
builder.AppendLine($" // {field.Name}");
builder.AppendLine($"\t// {field.Name}");
builder.AppendLine($"\t[SchemaMember(\"{schemaClassName}\", \"{field.Name}\")]");
if (field.Type is { Category: SchemaTypeCategory.FixedArray, CsTypeName: "string" })
if (field.Type is { Category: SchemaTypeCategory.FixedArray, CsTypeName: "string" } or { Category: SchemaTypeCategory.Ptr, CsTypeName: "string" })
{
var getter = $"return Schema.GetString({handleParams});";
var setter = $"Schema.SetString({handleParams}, value);";

View File

@@ -4816,10 +4816,10 @@
}
},
{
"name": "m_eThrowStatus",
"name": "m_bThrowAnimating",
"type": {
"category": 6,
"name": "EGrenadeThrowState"
"category": 0,
"name": "bool"
}
},
{
@@ -4849,6 +4849,40 @@
"category": 5,
"name": "GameTime_t"
}
},
{
"name": "m_bJustPulledPin",
"type": {
"category": 0,
"name": "bool"
}
},
{
"name": "m_nNextHoldTick",
"type": {
"category": 5,
"name": "GameTick_t"
}
},
{
"name": "m_flNextHoldFrac",
"type": {
"category": 0,
"name": "float32"
}
},
{
"name": "m_hSwitchToWeaponAfterThrow",
"type": {
"atomic": 1,
"category": 4,
"inner": {
"category": 5,
"name": "CCSWeaponBase"
},
"name": "CHandle< CCSWeaponBase >",
"outer": "CHandle"
}
}
],
"parent": "CCSWeaponBase"
@@ -6312,7 +6346,7 @@
"category": 0,
"name": "char"
},
"name": "char[4096]"
"name": "char[260]"
}
},
{
@@ -6842,6 +6876,13 @@
"name": "int64"
}
},
{
"name": "m_nLastRealCommandNumberExecuted",
"type": {
"category": 0,
"name": "int32"
}
},
{
"name": "m_iIgnoreGlobalChat",
"type": {
@@ -16738,10 +16779,17 @@
}
},
{
"name": "m_bPlayerFireEventIsPrimary",
"name": "m_ePlayerFireEvent",
"type": {
"category": 0,
"name": "bool"
"category": 6,
"name": "PlayerAnimEvent_t"
}
},
{
"name": "m_ePlayerFireEventAttackType",
"type": {
"category": 6,
"name": "WeaponAttackType_t"
}
},
{
@@ -16799,7 +16847,7 @@
"category": 5,
"name": "HSequence"
},
"name": "HSequence[6]"
"name": "HSequence[7]"
}
},
{
@@ -16951,10 +16999,17 @@
}
},
{
"name": "m_flPostponeFireReadyTime",
"name": "m_nPostponeFireReadyTicks",
"type": {
"category": 5,
"name": "GameTime_t"
"name": "GameTick_t"
}
},
{
"name": "m_flPostponeFireReadyFrac",
"type": {
"category": 0,
"name": "float32"
}
},
{
@@ -32791,40 +32846,6 @@
],
"parent": "CLogicalEntity"
},
"CLogicEventListener": {
"fields": [
{
"name": "m_strEventName",
"type": {
"atomic": 0,
"category": 4,
"name": "CUtlString"
}
},
{
"name": "m_bIsEnabled",
"type": {
"category": 0,
"name": "bool"
}
},
{
"name": "m_nTeam",
"type": {
"category": 0,
"name": "int32"
}
},
{
"name": "m_OnEventFired",
"type": {
"category": 5,
"name": "CEntityIOOutput"
}
}
],
"parent": "CLogicalEntity"
},
"CLogicGameEvent": {
"fields": [
{
@@ -34452,35 +34473,7 @@
"parent": "CLogicalEntity"
},
"CMelee": {
"fields": [
{
"name": "m_flThrowAt",
"type": {
"category": 5,
"name": "GameTime_t"
}
},
{
"name": "m_hThrower",
"type": {
"atomic": 1,
"category": 4,
"inner": {
"category": 5,
"name": "CBaseEntity"
},
"name": "CHandle< CBaseEntity >",
"outer": "CHandle"
}
},
{
"name": "m_bDidThrowDamage",
"type": {
"category": 0,
"name": "bool"
}
}
],
"fields": [],
"parent": "CCSWeaponBase"
},
"CMeshletDescriptor": {
@@ -54566,10 +54559,6 @@
"fields": [],
"parent": "CBaseTrigger"
},
"CTriggerHostageReset": {
"fields": [],
"parent": "CBaseTrigger"
},
"CTriggerHurt": {
"fields": [
{
@@ -70344,7 +70333,7 @@
"category": 0,
"name": "char"
},
"name": "char[4096]"
"name": "char[260]"
}
},
{
@@ -76074,6 +76063,20 @@
"category": 0,
"name": "float32"
}
},
{
"name": "m_flTickInterval",
"type": {
"category": 0,
"name": "float32"
}
},
{
"name": "m_flTickStartTime",
"type": {
"category": 0,
"name": "float64"
}
}
]
},
@@ -90386,23 +90389,6 @@
}
]
},
"C4LightEffect_t": {
"align": 4,
"items": [
{
"name": "eLightEffectNone",
"value": 0
},
{
"name": "eLightEffectDropped",
"value": 1
},
{
"name": "eLightEffectThirdPersonHeld",
"value": 2
}
]
},
"CAnimationGraphVisualizerPrimitiveType": {
"align": 4,
"items": [
@@ -91374,23 +91360,6 @@
}
]
},
"EGrenadeThrowState": {
"align": 4,
"items": [
{
"name": "NotThrowing",
"value": 0
},
{
"name": "Throwing",
"value": 1
},
{
"name": "ThrowComplete",
"value": 2
}
]
},
"EInButtonState": {
"align": 4,
"items": [
@@ -96428,7 +96397,7 @@
},
{
"name": "ALL_CONTEXTS",
"value": 4293918720
"value": 18446744073708503040
},
{
"name": "ALL_SCENTS",

View File

@@ -40,7 +40,7 @@ public record SchemaFieldType
}
public bool IsString =>
Category == SchemaTypeCategory.FixedArray
(Category == SchemaTypeCategory.FixedArray || Category == SchemaTypeCategory.Ptr)
&& Inner!.Category == SchemaTypeCategory.Builtin
&& Inner.Name == "char";
@@ -98,7 +98,8 @@ public record SchemaFieldType
public string CsTypeName => Category switch
{
SchemaTypeCategory.Builtin => BuiltinToCsKeyword(Name),
SchemaTypeCategory.Ptr => $"{Inner!.CsTypeName}?",
SchemaTypeCategory.Ptr => IsString
? "string" : $"{Inner!.CsTypeName}?",
SchemaTypeCategory.FixedArray => IsString
? "string"
: $"{Inner!.CsTypeName}[]",

View File

@@ -83,8 +83,6 @@ namespace TestPlugin
Logger.LogInformation(
$"Test Plugin has been loaded, and the hot reload flag was {hotReload}, path is {ModulePath}");
Logger.LogWarning($"Max Players: {Server.MaxPlayers}");
VirtualFunctions.SwitchTeamFunc.Hook(hook =>
{
Logger.LogInformation("Switch team func called");
@@ -249,11 +247,13 @@ namespace TestPlugin
// 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;
pawn.Health += 5;
Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth");
return HookResult.Continue;
});
@@ -331,7 +331,7 @@ namespace TestPlugin
private void SetupMenus()
{
// Chat Menu Example
// [Legacy] Chat Menu Example
var largeMenu = new ChatMenu("Test Menu");
for (int i = 1; i < 26; i++)
{
@@ -465,6 +465,67 @@ namespace TestPlugin
player.PlayerPawn.Value.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;
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;
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;
player.PlayerPawn.Value.Teleport(player.PlayerPawn.Value.AbsOrigin.With(z: player.PlayerPawn.Value.AbsOrigin.Z + 100), player.PlayerPawn.Value.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;
player.Respawn();
}
[ConsoleCommand("css_break", "Breaks the breakable entities")]
public void OnBreakCommand(CCSPlayerController? player, CommandInfo command)
{
var entities = Utilities.FindAllEntitiesByDesignerName<CBreakable>("prop_dynamic")
.Concat(Utilities.FindAllEntitiesByDesignerName<CBreakable>("func_breakable"));
foreach (var entity in entities)
{
entity.AcceptInput("Break");
}
}
[ConsoleCommand("css_fov", "Sets the player's FOV")]
[CommandHelper(minArgs: 1, usage: "[fov]")]
public void OnFovCommand(CCSPlayerController? player, CommandInfo command)
{
if (player == null) return;
if (!player.PlayerPawn.IsValid) return;
if (!Int32.TryParse(command.GetArg(1), out var desiredFov)) return;
player.DesiredFOV = (uint)desiredFov;
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
}
[ConsoleCommand("cssharp_attribute", "This is a custom attribute event")]
public void OnCommand(CCSPlayerController? player, CommandInfo command)

View File

@@ -1,3 +1,12 @@
// 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>
@@ -392,3 +401,18 @@ class CSchemaSystem
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

@@ -115,7 +115,6 @@ SchemaKey schema::GetOffset(const char* className,
SchemaKeyValueMap_t* tableMap = schemaTableMap[tableMapIndex];
int16_t memberIndex = tableMap->Find(memberKey);
if (!tableMap->IsValidIndex(memberIndex)) {
Warning("schema::GetOffset(): '%s' was not found in '%s'!\n", memberName, className);
return {0, 0};
}

View File

@@ -25,9 +25,6 @@
#include "entitysystem.h"
#include "scripting/callback_manager.h"
// variant.h depends on ivscript.h, lets not include the whole thing
DECLARE_POINTER_HANDLE(HSCRIPT);
#include <variant.h>
namespace counterstrikesharp {

View File

@@ -46,8 +46,10 @@
SH_DECL_HOOK4_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, CPlayerSlot, bool, const char*,
uint64);
SH_DECL_HOOK5_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, CPlayerSlot, ENetworkDisconnectionReason,
const char*, uint64, const char*);
SH_DECL_HOOK5_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, CPlayerSlot,
ENetworkDisconnectionReason, const char*, uint64, const char*);
SH_DECL_HOOK1_void(IServerGameClients, ClientVoice, SH_NOATTRIB, 0, CPlayerSlot);
SH_DECL_HOOK4_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, CPlayerSlot, char const*,
int, uint64);
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, CPlayerSlot);
@@ -76,6 +78,8 @@ void PlayerManager::OnAllInitialized()
SH_MEMBER(this, &PlayerManager::OnClientDisconnect_Post), true);
SH_ADD_HOOK(IServerGameClients, ClientCommand, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
SH_ADD_HOOK(IServerGameClients, ClientVoice, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientVoice), true);
m_on_client_connect_callback = globals::callbackManager.CreateCallback("OnClientConnect");
m_on_client_connected_callback = globals::callbackManager.CreateCallback("OnClientConnected");
@@ -84,6 +88,7 @@ void PlayerManager::OnAllInitialized()
m_on_client_disconnect_callback = globals::callbackManager.CreateCallback("OnClientDisconnect");
m_on_client_disconnect_post_callback =
globals::callbackManager.CreateCallback("OnClientDisconnectPost");
m_on_client_voice_callback = globals::callbackManager.CreateCallback("OnClientVoice");
m_on_client_authorized_callback = globals::callbackManager.CreateCallback("OnClientAuthorized");
}
@@ -101,6 +106,8 @@ void PlayerManager::OnShutdown()
SH_MEMBER(this, &PlayerManager::OnClientDisconnect_Post), true);
SH_REMOVE_HOOK(IServerGameClients, ClientCommand, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
SH_REMOVE_HOOK(IServerGameClients, ClientVoice, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientVoice), true);
globals::callbackManager.ReleaseCallback(m_on_client_connect_callback);
globals::callbackManager.ReleaseCallback(m_on_client_connected_callback);
@@ -108,6 +115,7 @@ void PlayerManager::OnShutdown()
globals::callbackManager.ReleaseCallback(m_on_client_disconnect_callback);
globals::callbackManager.ReleaseCallback(m_on_client_disconnect_post_callback);
globals::callbackManager.ReleaseCallback(m_on_client_authorized_callback);
globals::callbackManager.ReleaseCallback(m_on_client_voice_callback);
}
bool PlayerManager::OnClientConnect(CPlayerSlot slot, const char* pszName, uint64 xuid,
@@ -121,8 +129,10 @@ bool PlayerManager::OnClientConnect(CPlayerSlot slot, const char* pszName, uint6
CPlayer* pPlayer = &m_players[client];
if (pPlayer->IsConnected()) {
OnClientDisconnect(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, pszName, xuid, pszNetworkID);
OnClientDisconnect_Post(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, pszName, xuid, pszNetworkID);
OnClientDisconnect(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, pszName,
xuid, pszNetworkID);
OnClientDisconnect_Post(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID,
pszName, xuid, pszNetworkID);
}
pPlayer->Initialize(pszName, pszNetworkID, slot);
@@ -223,8 +233,7 @@ void PlayerManager::OnClientPutInServer(CPlayerSlot slot, char const* pszName, i
m_on_client_put_in_server_callback->Execute();
}
void PlayerManager::OnClientDisconnect(CPlayerSlot slot,
ENetworkDisconnectionReason reason,
void PlayerManager::OnClientDisconnect(CPlayerSlot slot, ENetworkDisconnectionReason reason,
const char* pszName, uint64 xuid, const char* pszNetworkID)
{
CSSHARP_CORE_TRACE("[PlayerManager][OnClientDisconnect] - {}, {}, {}", slot.Get(), pszName,
@@ -247,8 +256,7 @@ void PlayerManager::OnClientDisconnect(CPlayerSlot slot,
// globals::entityListener.HandleEntityDeleted(pPlayer->GetBaseEntity(), client);
}
void PlayerManager::OnClientDisconnect_Post(CPlayerSlot slot,
ENetworkDisconnectionReason reason,
void PlayerManager::OnClientDisconnect_Post(CPlayerSlot slot, ENetworkDisconnectionReason reason,
const char* pszName, uint64 xuid,
const char* pszNetworkID) const
{
@@ -270,16 +278,27 @@ void PlayerManager::OnClientDisconnect_Post(CPlayerSlot slot,
m_on_client_disconnect_post_callback->Execute();
}
void PlayerManager::OnClientVoice(CPlayerSlot slot) const
{
CSSHARP_CORE_TRACE("[PlayerManager][OnClientVoice] - {}", slot.Get());
m_on_client_voice_callback->ScriptContext().Reset();
m_on_client_voice_callback->ScriptContext().Push(slot.Get());
m_on_client_voice_callback->Execute();
}
void PlayerManager::OnLevelEnd()
{
CSSHARP_CORE_TRACE("[PlayerManager][OnLevelEnd]");
for (int i = 0; i <= MaxClients(); i++) {
if (m_players[i].IsConnected()) {
OnClientDisconnect(m_players[i].m_slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, m_players[i].GetName(), 0,
m_players[i].GetIpAddress());
OnClientDisconnect_Post(m_players[i].m_slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, m_players[i].GetName(), 0,
m_players[i].GetIpAddress());
OnClientDisconnect(m_players[i].m_slot,
ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID,
m_players[i].GetName(), 0, m_players[i].GetIpAddress());
OnClientDisconnect_Post(m_players[i].m_slot,
ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID,
m_players[i].GetName(), 0, m_players[i].GetIpAddress());
}
}
m_player_count = 0;
@@ -287,7 +306,8 @@ void PlayerManager::OnLevelEnd()
void PlayerManager::OnClientCommand(CPlayerSlot slot, const CCommand& args) const
{
CSSHARP_CORE_TRACE("[PlayerManager][OnClientCommand] - {}, {}, {}", slot.Get(), args.Arg(0), (void*)&args);
CSSHARP_CORE_TRACE("[PlayerManager][OnClientCommand] - {}, {}, {}", slot.Get(), args.Arg(0),
(void*)&args);
const char* cmd = args.Arg(0);
@@ -539,17 +559,11 @@ void CPlayer::SetListen(CPlayerSlot slot, ListenOverride listen)
m_listenMap[slot.Get()] = listen;
}
void CPlayer::SetVoiceFlags(VoiceFlag_t flags)
{
m_voiceFlag = flags;
}
void CPlayer::SetVoiceFlags(VoiceFlag_t flags) { m_voiceFlag = flags; }
VoiceFlag_t CPlayer::GetVoiceFlags() { return m_voiceFlag; }
ListenOverride CPlayer::GetListen(CPlayerSlot slot) const
{
return m_listenMap[slot.Get()];
}
ListenOverride CPlayer::GetListen(CPlayerSlot slot) const { return m_listenMap[slot.Get()]; }
void CPlayer::Connect()
{

View File

@@ -64,30 +64,31 @@ enum VoiceFlagValue
typedef uint8_t VoiceFlag_t;
class CPlayer {
class CPlayer
{
friend class PlayerManager;
public:
public:
CPlayer();
public:
void Initialize(const char *name, const char *ip, CPlayerSlot slot);
public:
void Initialize(const char* name, const char* ip, CPlayerSlot slot);
void Connect();
void Disconnect();
IPlayerInfo *GetPlayerInfo() const;
IPlayerInfo* GetPlayerInfo() const;
bool WasCountedAsInGame() const;
int GetUserId();
bool IsAuthStringValidated() const;
void Authorize();
public:
const char *GetName() const;
const CSteamID *GetSteamId();
void SetSteamId(const CSteamID *steam_id);
public:
const char* GetName() const;
const CSteamID* GetSteamId();
void SetSteamId(const CSteamID* steam_id);
bool IsConnected() const;
bool IsFakeClient() const;
bool IsAuthorized() const;
void PrintToConsole(const char *message) const;
void PrintToConsole(const char* message) const;
// void PrintToChat(const char *message);
// void PrintToHint(const char *message);
// void PrintToCenter(const char *message);
@@ -95,19 +96,19 @@ public:
Vector GetAbsOrigin() const;
bool IsAlive() const;
bool IsInGame() const;
void Kick(const char *kickReason);
const char *GetWeaponName() const;
void Kick(const char* kickReason);
const char* GetWeaponName() const;
void ChangeTeam(int team) const;
int GetTeam() const;
int GetArmor() const;
int GetFrags() const;
int GetDeaths() const;
const char *GetKeyValue(const char *key) const;
const char* GetKeyValue(const char* key) const;
Vector GetMaxSize() const;
Vector GetMinSize() const;
int GetMaxHealth() const;
const char *GetIpAddress() const;
const char *GetModelName() const;
const char* GetIpAddress() const;
const char* GetModelName() const;
int GetUserId() const;
float GetTimeConnected() const;
float GetLatency() const;
@@ -116,9 +117,9 @@ public:
VoiceFlag_t GetVoiceFlags();
ListenOverride GetListen(CPlayerSlot slot) const;
public:
public:
std::string m_name;
IPlayerInfo *m_info = nullptr;
IPlayerInfo* m_info = nullptr;
std::string m_auth_id;
bool m_is_connected = false;
bool m_is_fake_client = false;
@@ -131,72 +132,61 @@ public:
ListenOverride m_listenMap[66] = {};
VoiceFlag_t m_voiceFlag = 0;
CPlayerBitVec m_selfMutes[64] = {};
void SetName(const char *name);
INetChannelInfo *GetNetInfo() const;
void SetName(const char* name);
INetChannelInfo* GetNetInfo() const;
};
class PlayerManager : public GlobalClass {
class PlayerManager : public GlobalClass
{
friend class CPlayer;
public:
public:
PlayerManager();
void OnStartup() override;
void OnAllInitialized() override;
bool OnClientConnect(CPlayerSlot slot,
const char *pszName,
uint64 xuid,
const char *pszNetworkID,
bool unk1,
CBufferString *pRejectReason);
bool OnClientConnect_Post(CPlayerSlot slot,
const char *pszName,
uint64 xuid,
const char *pszNetworkID,
bool unk1,
CBufferString *pRejectReason);
void OnClientPutInServer(CPlayerSlot slot, char const *pszName, int type, uint64 xuid);
void OnClientDisconnect(CPlayerSlot slot,
ENetworkDisconnectionReason reason,
const char *pszName,
uint64 xuid,
const char *pszNetworkID);
void OnClientDisconnect_Post(CPlayerSlot slot,
ENetworkDisconnectionReason reason,
const char *pszName,
uint64 xuid,
const char *pszNetworkID) const;
bool OnClientConnect(CPlayerSlot slot, const char* pszName, uint64 xuid,
const char* pszNetworkID, bool unk1, CBufferString* pRejectReason);
bool OnClientConnect_Post(CPlayerSlot slot, const char* pszName, uint64 xuid,
const char* pszNetworkID, bool unk1, CBufferString* pRejectReason);
void OnClientPutInServer(CPlayerSlot slot, char const* pszName, int type, uint64 xuid);
void OnClientDisconnect(CPlayerSlot slot, ENetworkDisconnectionReason reason,
const char* pszName, uint64 xuid, const char* pszNetworkID);
void OnClientDisconnect_Post(CPlayerSlot slot, ENetworkDisconnectionReason reason,
const char* pszName, uint64 xuid, const char* pszNetworkID) const;
void OnClientVoice(CPlayerSlot slot) const;
void OnAuthorized(CPlayer* player) const;
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax) const;
void OnServerActivate(edict_t* pEdictList, int edictCount, int clientMax) const;
void OnThink(bool last_tick) const;
void OnShutdown() override;
void OnLevelEnd() override;
void OnClientCommand(CPlayerSlot slot, const CCommand &args) const;
void OnClientCommand(CPlayerSlot slot, const CCommand& args) const;
int ListenClient() const;
void RunAuthChecks();
public:
public:
int NumPlayers() const;
int MaxClients() const;
CPlayer *GetPlayerBySlot(int client) const;
CPlayer *GetClientOfUserId(int user_id) const;
CPlayer* GetPlayerBySlot(int client) const;
CPlayer* GetClientOfUserId(int user_id) const;
private:
void InvalidatePlayer(CPlayer *pPlayer) const;
private:
void InvalidatePlayer(CPlayer* pPlayer) const;
CPlayer *m_players;
CPlayer* m_players;
int m_max_clients = 0;
int m_player_count = 0;
int *m_user_id_lookup;
int* m_user_id_lookup;
int m_listen_client;
bool m_is_listen_server;
float m_last_auth_check_time = 0;
ScriptCallback *m_on_client_connect_callback;
ScriptCallback *m_on_client_put_in_server_callback;
ScriptCallback *m_on_client_connected_callback;
ScriptCallback *m_on_client_disconnect_callback;
ScriptCallback *m_on_client_disconnect_post_callback;
ScriptCallback *m_on_client_authorized_callback;
ScriptCallback* m_on_client_connect_callback;
ScriptCallback* m_on_client_put_in_server_callback;
ScriptCallback* m_on_client_connected_callback;
ScriptCallback* m_on_client_disconnect_callback;
ScriptCallback* m_on_client_disconnect_post_callback;
ScriptCallback* m_on_client_voice_callback;
ScriptCallback* m_on_client_authorized_callback;
};
} // namespace counterstrikesharp
} // namespace counterstrikesharp

View File

@@ -31,9 +31,13 @@
#include "entity2/entitysystem.h"
#include "interfaces/cs2_interfaces.h"
counterstrikesharp::GlobalClass* counterstrikesharp::GlobalClass::head = nullptr;
CGameEntitySystem *GameEntitySystem()
{
return counterstrikesharp::globals::entitySystem;
}
// TODO: Workaround for windows, we __MUST__ have COUNTERSTRIKESHARP_API to handle it.
// like on windows it should be `extern "C" __declspec(dllexport)`, on linux it should be anything else.
DLL_EXPORT void InvokeNative(counterstrikesharp::fxNativeContext& context)

View File

@@ -30,6 +30,7 @@
#include "core/memory.h"
#include "core/log.h"
#include "core/function.h"
#include "core/managers/player_manager.h"
#include "core/managers/server_manager.h"
// clang-format on
@@ -74,6 +75,17 @@ float GetGameFrameTime(ScriptContext& script_context)
double GetEngineTime(ScriptContext& script_context) { return Plat_FloatTime(); }
int GetMaxClients(ScriptContext& script_context)
{
auto globalVars = globals::getGlobalVars();
if (globalVars == nullptr) {
script_context.ThrowNativeError("Global Variables not initialized yet.");
return -1;
}
return globalVars->maxClients;
}
void ServerCommand(ScriptContext& script_context)
{
auto command = script_context.GetArgument<const char*>(0);
@@ -294,6 +306,7 @@ REGISTER_NATIVES(engine, {
ScriptEngine::RegisterNativeHandler("GET_CURRENT_TIME", GetCurrentTime);
ScriptEngine::RegisterNativeHandler("GET_GAMEFRAME_TIME", GetGameFrameTime);
ScriptEngine::RegisterNativeHandler("GET_ENGINE_TIME", GetEngineTime);
ScriptEngine::RegisterNativeHandler("GET_MAX_CLIENTS", GetMaxClients);
ScriptEngine::RegisterNativeHandler("ISSUE_SERVER_COMMAND", ServerCommand);
ScriptEngine::RegisterNativeHandler("PRECACHE_MODEL", PrecacheModel);
ScriptEngine::RegisterNativeHandler("PRECACHE_SOUND", PrecacheSound);

View File

@@ -6,6 +6,7 @@ GET_CURRENT_TIME: -> float
GET_TICK_COUNT: -> int
GET_GAME_FRAME_TIME: -> float
GET_ENGINE_TIME: -> double
GET_MAX_CLIENTS: -> int
ISSUE_SERVER_COMMAND: command:string -> void
PRECACHE_MODEL: name:string -> void
PRECACHE_SOUND: name:string, preload:bool -> bool

View File

@@ -42,6 +42,18 @@ int16 GetSchemaOffset(ScriptContext& script_context)
return m_key.offset;
}
bool IsSchemaFieldNetworked(ScriptContext& script_context)
{
auto className = script_context.GetArgument<const char*>(0);
auto memberName = script_context.GetArgument<const char*>(1);
auto classKey = hash_32_fnv1a_const(className);
auto memberKey = hash_32_fnv1a_const(memberName);
const auto m_key = schema::GetOffset(className, classKey, memberName, memberKey);
return m_key.networked;
}
int GetSchemaClassSize(ScriptContext& script_context)
{
auto className = script_context.GetArgument<const char*>(0);
@@ -150,19 +162,6 @@ void SetSchemaValueByName(ScriptContext& script_context)
auto memberKey = hash_32_fnv1a_const(memberName);
const auto m_key = schema::GetOffset(className, classKey, memberName, memberKey);
const auto m_chain = schema::FindChainOffset(className);
// todo network updates
// if (m_chain != 0 && m_key.networked) {
// addresses::NetworkStateChanged((uintptr_t)(instancePointer) + m_chain, m_key.offset,
// 0xFFFFFFFF);
// } else if (m_key.networked) { /* WIP: Works fine for most props, but inlined classes in
// the
// middle of a class will need to have their this pointer
// corrected by the offset .*/
// CALL_VIRTUAL(void, 1, instancePointer, m_key.offset, 0xFFFFFFFF, 0xFFFF);
// }
switch (dataType) {
case DATA_TYPE_BOOL:
@@ -239,6 +238,7 @@ void SetSchemaValueByName(ScriptContext& script_context)
REGISTER_NATIVES(schema, {
ScriptEngine::RegisterNativeHandler("GET_SCHEMA_OFFSET", GetSchemaOffset);
ScriptEngine::RegisterNativeHandler("IS_SCHEMA_FIELD_NETWORKED", IsSchemaFieldNetworked);
ScriptEngine::RegisterNativeHandler("GET_SCHEMA_VALUE_BY_NAME", GetSchemaValueByName);
ScriptEngine::RegisterNativeHandler("SET_SCHEMA_VALUE_BY_NAME", SetSchemaValueByName);
ScriptEngine::RegisterNativeHandler("GET_SCHEMA_CLASS_SIZE", GetSchemaClassSize);

View File

@@ -1,4 +1,5 @@
GET_SCHEMA_OFFSET: className:string, propName:string -> short
IS_SCHEMA_FIELD_NETWORKED: className:string, propName:string -> bool
GET_SCHEMA_VALUE_BY_NAME: instance:pointer, returnType:int, className:string, propName:string -> any
SET_SCHEMA_VALUE_BY_NAME: instance:pointer, returnType:int, className:string, propName:string, value:any -> void
GET_SCHEMA_CLASS_SIZE: className:string -> int