Compare commits

...

6 Commits
v18 ... v21

Author SHA1 Message Date
pedrotski
4430060efd Update README.md (#37)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
2023-11-10 19:07:45 +10:00
Roflmuffin
77ea6fd80d fix: prevent server crash on duplicate command registration, fixes #51 2023-11-10 19:06:40 +10:00
Roflmuffin
f18df3df2b docs: update console command expected usage docs 2023-11-10 19:02:46 +10:00
Roflmuffin
4ce1ec2cf5 feat: add disabled plugins folder, and source folder for source code 2023-11-10 18:56:37 +10:00
Roflmuffin
9005f3c29c fix: my bad merging skills 2023-11-10 18:52:20 +10:00
Roflmuffin
b7ace4256a feat: change permission helper attribute to RequiresPermissions 2023-11-10 18:45:04 +10:00
11 changed files with 80 additions and 16 deletions

View File

@@ -2,6 +2,8 @@
CounterStrikeSharp is a server side modding framework for Counter-Strike: Global Offensive. This project attempts to implement a .NET Core scripting layer on top of a Metamod Source Plugin, allowing developers to create plugins that interact with the game server in a modern language (C#) to facilitate the creation of maintainable and testable code.
[Come and join our Discord](https://discord.gg/X7r3PmuYKq)
## History
This project is an ongoing migration of a previous project (titled [VSP.NET](https://github.com/roflmuffin/vspdotnet)) whereby a scripting layer was added to a Valve Server Plugin for CSGO.
@@ -16,7 +18,7 @@ As a result, there are a few key philosophies and trade-offs that drive the proj
- Supporting both platforms is a lot of work for 1 person, so there are no real plans to support Windows.
## Install
Development builds are currently available through GitHub actions, you can download the latest build from [there](https://github.com/roflmuffin/CounterStrikeSharp/actions/workflows/cmake-single-platform.yml).
Download the latest build from [here](https://github.com/roflmuffin/CounterStrikeSharp/releases). (Download the with runtime version if this is your first time installing).
Detailed installation instructions can be found in the [docs](https://docs.cssharp.dev/guides/getting-started/).

View File

@@ -0,0 +1 @@
Place your source code for plugins here.

View File

@@ -24,10 +24,10 @@ You can also manually assign permissions to players in code with `AddPlayerPermi
## Assigning permissions to a Command
Assigning permissions to a Command is as easy as tagging the Command method (function callback) with a `PermissionHelper` attribute.
Assigning permissions to a Command is as easy as tagging the Command method (function callback) with a `RequiresPermissions` attribute.
```csharp
[PermissionHelper("can_execute_test_command", "other_permission")]
[RequiresPermissions("can_execute_test_command", "other_permission")]
public void OnMyCommand(CCSPlayerController? caller, CommandInfo info)
{
...

View File

@@ -64,3 +64,39 @@ Command String: custom_command "Test Quoted" 5 13
First Argument: custom_command
Second Argument: Test Quoted
```
## Helper Attribute
CounterStrikeSharp provides the `CommandHelper` attribute for Command methods (function callback) to simplify the process of checking for the correct amount of arguments and to restrict commands to being executed by the server console or by players (or both!).
```csharp
[ConsoleCommand("freeze", "Freezes a client.")]
[CommandHelper(minArgs: 1, usage: "[target]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnFreezeCommand(CCSPlayerController? caller, CommandInfo command)
{
...
}
```
If a client tries to execute the command without the `[target]` argument, it will print a message to them in chat:
```shell
[CSS] Expected usage: "!freeze [target]".
```
If a command is executed by the wrong user, it will print a message to them:
```shell
[CSS] This command can only be executed by clients.
```
Valid `CommandUsage` values:
```csharp
public enum CommandUsage
{
CLIENT_AND_SERVER = 0,
CLIENT_ONLY,
SERVER_ONLY
}
```

View File

@@ -184,7 +184,7 @@ namespace CounterStrikeSharp.API.Core
}
// Do not execute command if we do not have the correct permissions.
var permissions = methodInfo?.GetCustomAttribute<PermissionHelperAttribute>()?.RequiredPermissions;
var permissions = methodInfo?.GetCustomAttribute<RequiresPermissions>()?.RequiredPermissions;
if (permissions != null && !AdminManager.PlayerHasPermissions(caller, permissions))
{
command.ReplyToCommand("[CSS] You do not have the correct permissions to execute this command.");

View File

@@ -183,7 +183,7 @@ namespace CounterStrikeSharp.API.Core
return plugin;
}
[PermissionHelper("can_execute_css_commands")]
[RequiresPermissions("can_execute_css_commands")]
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private void OnCSSCommand(CCSPlayerController? caller, CommandInfo info)
{
@@ -196,7 +196,7 @@ namespace CounterStrikeSharp.API.Core
return;
}
[PermissionHelper("can_execute_css_commands")]
[RequiresPermissions("can_execute_css_commands")]
[CommandHelper(minArgs: 1,
usage: "[option]\n" +
" list - List all plugins currently loaded.\n" +

View File

@@ -29,7 +29,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
CommandUtils.AddStandaloneCommand("css_admins_list", "List admins and their flags.", ListAdminsCommand);
}
[PermissionHelper("can_reload_admins")]
[RequiresPermissions("can_reload_admins")]
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void ReloadAdminsCommand(CCSPlayerController? player, CommandInfo command)
{
@@ -38,7 +38,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
Load(Path.Combine(rootDir.FullName, "configs", "admins.json"));
}
[PermissionHelper("can_reload_admins")]
[RequiresPermissions("can_reload_admins")]
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
private static void ListAdminsCommand(CCSPlayerController? player, CommandInfo command)
{
@@ -131,8 +131,17 @@ namespace CounterStrikeSharp.API.Modules.Admin
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
var steamId = new SteamID(player.SteamID);
AddPlayerPermissions((SteamID)player.SteamID, flags);
}
/// <summary>
/// Temporarily adds a permission flag to the player. These flags are not saved to
/// "configs/admins.json".
/// </summary>
/// <param name="steamId">SteamID to add a flag to.</param>
/// <param name="flags">Flags to add for the player.</param>
public static void AddPlayerPermissions(SteamID steamId, params string[] flags)
{
var data = GetPlayerAdminData(steamId);
if (data == null)
{
@@ -151,19 +160,30 @@ namespace CounterStrikeSharp.API.Modules.Admin
data.Flags.Add(flag);
}
}
/// <summary>
/// Temporarily removes a permission flag to the player. These flags are not saved to
/// "configs/admins.json".
/// </summary>
/// <param name="player">Player controller to add a flag to.</param>
/// <param name="player">Player controller to remove flags from.</param>
/// <param name="flags">Flags to remove from the player.</param>
public static void RemovePlayerPermissions(CCSPlayerController? player, params string[] flags)
{
if (player == null) return;
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
var data = GetPlayerAdminData(new SteamID(player.SteamID));
RemovePlayerPermissions((SteamID)player.SteamID, flags);
}
/// <summary>
/// Temporarily removes a permission flag to the player. These flags are not saved to
/// "configs/admins.json".
/// </summary>
/// <param name="steamId">Steam ID to remove flags from.</param>
/// <param name="flags">Flags to remove from the player.</param>
public static void RemovePlayerPermissions(SteamID steamId, params string[] flags)
{
var data = GetPlayerAdminData(steamId);
if (data == null) return;
data.Flags.ExceptWith(flags);

View File

@@ -3,11 +3,11 @@
namespace CounterStrikeSharp.API.Modules.Admin
{
[AttributeUsage(AttributeTargets.Method)]
public class PermissionHelperAttribute : Attribute
public class RequiresPermissions : Attribute
{
public string[] RequiredPermissions { get; }
public PermissionHelperAttribute(params string[] permissions)
public RequiresPermissions(params string[] permissions)
{
RequiredPermissions = permissions;
}

View File

@@ -42,7 +42,7 @@ public class CommandUtils
}
// Do not execute command if we do not have the correct permissions.
var permissions = methodInfo?.GetCustomAttribute<PermissionHelperAttribute>()?.RequiredPermissions;
var permissions = methodInfo?.GetCustomAttribute<RequiresPermissions>()?.RequiredPermissions;
if (permissions != null && !AdminManager.PlayerHasPermissions(caller, permissions))
{
command.ReplyToCommand("[CSS] You do not have the correct permissions to execute this command.");

View File

@@ -37,6 +37,11 @@ static ConCommandInfo* AddCommand(ScriptContext& script_context)
CSSHARP_CORE_TRACE("Adding command {}, {}, {}, {}, {}", name, description, server_only, flags,
(void*)callback);
if (globals::conCommandManager.FindCommand(name)) {
script_context.ThrowNativeError("Failed to add command \"%s\", command already exists.", name);
return nullptr;
}
return globals::conCommandManager.AddCommand(name, description, server_only, flags, callback);
}