mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-06 16:06:37 -08:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12523455c0 | ||
|
|
db63fdc00c | ||
|
|
57747f2e1c | ||
|
|
66b5f77a2d | ||
|
|
8dbcb6d531 | ||
|
|
2f0d34b271 | ||
|
|
2a59544fbc | ||
|
|
f80f2ae949 | ||
|
|
f68a0abc61 | ||
|
|
a07dd9d7d4 | ||
|
|
d527038fba | ||
|
|
ca85922270 | ||
|
|
b837479f98 | ||
|
|
1e42f72655 | ||
|
|
1ad1828e30 | ||
|
|
563a5d7b3a | ||
|
|
983b673b4c | ||
|
|
74fd0e0832 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
},
|
||||
"CCSPlayerController_Respawn": {
|
||||
"offsets": {
|
||||
"windows": 241,
|
||||
"linux": 243
|
||||
"windows": 242,
|
||||
"linux": 244
|
||||
}
|
||||
},
|
||||
"CCSPlayerPawn_Respawn": {
|
||||
@@ -113,6 +113,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 +129,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": {
|
||||
|
||||
@@ -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
|
||||
```
|
||||
BIN
docfx/images/gameinfogi-example.png
Normal file
BIN
docfx/images/gameinfogi-example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 275 KiB |
Submodule libraries/hl2sdk-cs2 updated: 9363452257...2f9dd2e61a
@@ -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)
|
||||
BIN
managed/CounterStrikeSharp.API/ApiCompat/v133.dll
Normal file
BIN
managed/CounterStrikeSharp.API/ApiCompat/v133.dll
Normal file
Binary file not shown.
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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\v133.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" />
|
||||
|
||||
@@ -494,7 +494,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 +514,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -76,4 +76,11 @@ 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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -75,12 +75,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 +136,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;
|
||||
|
||||
@@ -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);";
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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}[]",
|
||||
|
||||
@@ -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");
|
||||
@@ -465,6 +463,54 @@ 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("cssharp_attribute", "This is a custom attribute event")]
|
||||
public void OnCommand(CCSPlayerController? player, CommandInfo command)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user