From 7f93980c2ac641d1ddaa27b0378f5f94fbb54bdd Mon Sep 17 00:00:00 2001 From: Ambr0se Date: Wed, 8 Oct 2025 00:07:06 +0800 Subject: [PATCH 1/4] feat: Implement permission requirements for commands --- .../CommandAttributeParser.cs | 3 ++- .../Modules/Commands/CommandCallback.cs | 19 ++++++++++++++++--- .../Modules/Commands/CommandService.cs | 17 ++++++++++------- .../Commands/Attributes/CommandAttribute.cs | 5 ++++- .../Modules/Commands/ICommandService.cs | 3 ++- managed/src/TestPlugin/TestPlugin.cs | 12 +++++++++++- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs b/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs index 3345e6837..dc97a1d37 100644 --- a/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs +++ b/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs @@ -19,7 +19,8 @@ public static void ParseFromObject(this ICommandService self, object instance) { var commandName = commandAttribute.Name; var commandAlias = commandAliasAttributes.Select(a => a.Alias).ToArray(); var registerRaw = commandAttribute.RegisterRaw; - self.RegisterCommand(commandName, method.CreateDelegate(instance), registerRaw); + var permissions = commandAttribute.Permissions; + self.RegisterCommand(commandName, method.CreateDelegate(instance), registerRaw, permissions); foreach (var alias in commandAlias) { self.RegisterCommandAlias(commandName, alias, registerRaw); diff --git a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs index ca6746eca..8246a58c1 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs @@ -1,9 +1,13 @@ using System.Runtime.InteropServices; using SwiftlyS2.Core.Natives; +using SwiftlyS2.Core.Services; using SwiftlyS2.Shared.Misc; using SwiftlyS2.Shared.Commands; +using SwiftlyS2.Shared.Permissions; +using SwiftlyS2.Shared.Services; using Microsoft.Extensions.Logging; using SwiftlyS2.Shared.Profiler; +using SwiftlyS2.Shared; namespace SwiftlyS2.Core.Commands; @@ -40,17 +44,22 @@ internal class CommandCallback : CommandCallbackBase { private nint _unmanagedCallbackPtr; private ulong _nativeListenerId; + private string _permissions; private ILogger _logger; + private readonly IPlayerManagerService _playerManagerService; + private readonly IPermissionManager _permissionManager; - public CommandCallback(string commandName, bool registerRaw, ICommandService.CommandListener handler, ILoggerFactory loggerFactory, IContextedProfilerService profiler) + public CommandCallback(string commandName, bool registerRaw, ICommandService.CommandListener handler, string permissions, IPlayerManagerService playerManagerService, IPermissionManager permissionManager, ILoggerFactory loggerFactory, IContextedProfilerService profiler) : base(loggerFactory, profiler) { _logger = LoggerFactory.CreateLogger(); + _playerManagerService = playerManagerService; + _permissionManager = permissionManager; Guid = Guid.NewGuid(); CommandName = commandName; - + _permissions = permissions; _handler = handler; _unmanagedCallback = (playerId, argsPtr, commandNamePtr, prefixPtr, slient) => { @@ -63,7 +72,11 @@ public CommandCallback(string commandName, bool registerRaw, ICommandService.Com var args = argsString.Split('\x01'); var context = new CommandContext(playerId, args, commandNameString, prefixString, slient); - _handler(context); + if (string.IsNullOrWhiteSpace(_permissions) || _permissionManager.PlayerHasPermission(_playerManagerService.GetPlayer(playerId).SteamID, _permissions)) { + _handler(context); + } else { + context.Reply("You do not have permission to use this command."); + } Profiler.StopRecording(category); } catch (Exception e) { _logger.LogError(e, "Failed to handle command {0}.", commandName); diff --git a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs index ac582c38f..de1090056 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs @@ -4,6 +4,8 @@ using SwiftlyS2.Shared.Commands; using SwiftlyS2.Shared.Plugins; using SwiftlyS2.Shared.Profiler; +using SwiftlyS2.Shared.Services; +using SwiftlyS2.Shared.Permissions; namespace SwiftlyS2.Core.Commands; @@ -14,21 +16,22 @@ internal class CommandService : ICommandService, IDisposable private ILogger _Logger { get; init; } private ILoggerFactory _LoggerFactory { get; init; } private IContextedProfilerService _Profiler { get; init; } + private IPlayerManagerService _PlayerManagerService { get; init; } + private IPermissionManager _PermissionManager { get; init; } private object _lock = new(); - public CommandService(ILogger logger, ILoggerFactory loggerFactory, IContextedProfilerService profiler) - { + public CommandService(ILogger logger, ILoggerFactory loggerFactory, IContextedProfilerService profiler, IPlayerManagerService playerManagerService, IPermissionManager permissionManager) { _Logger = logger; _LoggerFactory = loggerFactory; _Profiler = profiler; + _PlayerManagerService = playerManagerService; + _PermissionManager = permissionManager; } - public Guid RegisterCommand(string commandName, ICommandService.CommandListener handler, bool registerRaw = false) - { - var callback = new CommandCallback(commandName, registerRaw, handler, _LoggerFactory, _Profiler); - lock (_lock) - { + public Guid RegisterCommand(string commandName, ICommandService.CommandListener handler, bool registerRaw = false, string permissions = "") { + var callback = new CommandCallback(commandName, registerRaw, handler, permissions, _PlayerManagerService, _PermissionManager, _LoggerFactory, _Profiler); + lock (_lock) { _callbacks.Add(callback); } diff --git a/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs b/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs index cf42cf934..633f123fd 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs @@ -6,8 +6,11 @@ public class Command : Attribute { public bool RegisterRaw { get; set; } = false; - public Command(string name, bool registerRaw = false) { + public string Permissions { get; set; } = ""; + + public Command(string name, bool registerRaw = false, string permissions = "") { Name = name; RegisterRaw = registerRaw; + Permissions = permissions; } } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs b/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs index 7082ba90f..9de64cba2 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs @@ -37,8 +37,9 @@ public interface ICommandService /// The command name. /// The handler callback for the command. /// If set to false, the command will not starts with a `sw_` prefix. + /// The permissions required to use the command. /// The guid of the command. - Guid RegisterCommand(string commandName, CommandListener handler, bool registerRaw = false); + Guid RegisterCommand(string commandName, CommandListener handler, bool registerRaw = false, string permissions = ""); /// /// Registers a command alias. diff --git a/managed/src/TestPlugin/TestPlugin.cs b/managed/src/TestPlugin/TestPlugin.cs index 18361a1cd..f5d37671b 100644 --- a/managed/src/TestPlugin/TestPlugin.cs +++ b/managed/src/TestPlugin/TestPlugin.cs @@ -264,7 +264,7 @@ public void TestCommand2(ICommandContext context) [EventListener] public void OnEntityCreated(IOnEntityCreatedEvent @event) { - @event.Entity.Entity.DesignerName = "abc"; + // @event.Entity.Entity.DesignerName = "abc"; Console.WriteLine("TestPlugin OnEntityCreated222 " + @event.Entity.Entity?.DesignerName); } @@ -292,6 +292,16 @@ public void TestCommand4(ICommandContext context) { Console.WriteLine(Core.Permission.PlayerHasPermission(7656, context.Args[0])); } + [Command("tt5")] + public void TestCommand5(ICommandContext context) { + Console.WriteLine("TestPlugin TestCommand5"); + } + + [Command("tt6", permissions: "tt6")] + public void TestCommand6(ICommandContext context) { + Console.WriteLine("TestPlugin TestCommand6"); + } + [GameEventHandler(HookMode.Pre)] public HookResult TestGameEventHandler(EventPlayerJump @e) { Console.WriteLine(@e.UserIdController.PlayerName); From 0fa14ac100a2e9f0ed22c7c1002066d7f3672d83 Mon Sep 17 00:00:00 2001 From: samyyc Date: Mon, 6 Oct 2025 03:22:03 +0800 Subject: [PATCH 2/4] [no ci] ci: skip release for other branch +semver: skip --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbca98222..81b9959d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -201,7 +201,7 @@ jobs: ${{ env.WINDOWS_FOLDER }}-with-runtimes.zip releasing: - if: ${{ github.event_name == 'push' }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/beta') }} needs: [versioning, packaging] runs-on: ubuntu-latest env: From cfd9277cfacb4c272d367235ace74878295e4493 Mon Sep 17 00:00:00 2001 From: Ambr0se Date: Wed, 8 Oct 2025 01:06:52 +0800 Subject: [PATCH 3/4] style: Rename permissions to permission for consistency --- .../AttributeParsers/CommandAttributeParser.cs | 4 ++-- .../src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs | 4 ++-- .../src/SwiftlyS2.Core/Modules/Commands/CommandService.cs | 4 ++-- .../Modules/Commands/Attributes/CommandAttribute.cs | 6 +++--- .../SwiftlyS2.Shared/Modules/Commands/ICommandService.cs | 4 ++-- managed/src/TestPlugin/TestPlugin.cs | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs b/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs index dc97a1d37..6b6fb343a 100644 --- a/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs +++ b/managed/src/SwiftlyS2.Core/AttributeParsers/CommandAttributeParser.cs @@ -19,8 +19,8 @@ public static void ParseFromObject(this ICommandService self, object instance) { var commandName = commandAttribute.Name; var commandAlias = commandAliasAttributes.Select(a => a.Alias).ToArray(); var registerRaw = commandAttribute.RegisterRaw; - var permissions = commandAttribute.Permissions; - self.RegisterCommand(commandName, method.CreateDelegate(instance), registerRaw, permissions); + var permission = commandAttribute.Permission; + self.RegisterCommand(commandName, method.CreateDelegate(instance), registerRaw, permission); foreach (var alias in commandAlias) { self.RegisterCommandAlias(commandName, alias, registerRaw); diff --git a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs index 8246a58c1..326f775af 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs @@ -50,7 +50,7 @@ internal class CommandCallback : CommandCallbackBase { private readonly IPlayerManagerService _playerManagerService; private readonly IPermissionManager _permissionManager; - public CommandCallback(string commandName, bool registerRaw, ICommandService.CommandListener handler, string permissions, IPlayerManagerService playerManagerService, IPermissionManager permissionManager, ILoggerFactory loggerFactory, IContextedProfilerService profiler) + public CommandCallback(string commandName, bool registerRaw, ICommandService.CommandListener handler, string permission, IPlayerManagerService playerManagerService, IPermissionManager permissionManager, ILoggerFactory loggerFactory, IContextedProfilerService profiler) : base(loggerFactory, profiler) { _logger = LoggerFactory.CreateLogger(); @@ -59,7 +59,7 @@ public CommandCallback(string commandName, bool registerRaw, ICommandService.Com Guid = Guid.NewGuid(); CommandName = commandName; - _permissions = permissions; + _permissions = permission; _handler = handler; _unmanagedCallback = (playerId, argsPtr, commandNamePtr, prefixPtr, slient) => { diff --git a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs index de1090056..f110ac22d 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs @@ -29,8 +29,8 @@ public CommandService(ILogger logger, ILoggerFactory loggerFacto _PermissionManager = permissionManager; } - public Guid RegisterCommand(string commandName, ICommandService.CommandListener handler, bool registerRaw = false, string permissions = "") { - var callback = new CommandCallback(commandName, registerRaw, handler, permissions, _PlayerManagerService, _PermissionManager, _LoggerFactory, _Profiler); + public Guid RegisterCommand(string commandName, ICommandService.CommandListener handler, bool registerRaw = false, string permission = "") { + var callback = new CommandCallback(commandName, registerRaw, handler, permission, _PlayerManagerService, _PermissionManager, _LoggerFactory, _Profiler); lock (_lock) { _callbacks.Add(callback); } diff --git a/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs b/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs index 633f123fd..e5c64f1d4 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Commands/Attributes/CommandAttribute.cs @@ -6,11 +6,11 @@ public class Command : Attribute { public bool RegisterRaw { get; set; } = false; - public string Permissions { get; set; } = ""; + public string Permission { get; set; } = ""; - public Command(string name, bool registerRaw = false, string permissions = "") { + public Command(string name, bool registerRaw = false, string permission = "") { Name = name; RegisterRaw = registerRaw; - Permissions = permissions; + Permission = permission; } } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs b/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs index 9de64cba2..95d1e2f3f 100644 --- a/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs +++ b/managed/src/SwiftlyS2.Shared/Modules/Commands/ICommandService.cs @@ -37,9 +37,9 @@ public interface ICommandService /// The command name. /// The handler callback for the command. /// If set to false, the command will not starts with a `sw_` prefix. - /// The permissions required to use the command. + /// The permission required to use the command. /// The guid of the command. - Guid RegisterCommand(string commandName, CommandListener handler, bool registerRaw = false, string permissions = ""); + Guid RegisterCommand(string commandName, CommandListener handler, bool registerRaw = false, string permission = ""); /// /// Registers a command alias. diff --git a/managed/src/TestPlugin/TestPlugin.cs b/managed/src/TestPlugin/TestPlugin.cs index f5d37671b..94c890607 100644 --- a/managed/src/TestPlugin/TestPlugin.cs +++ b/managed/src/TestPlugin/TestPlugin.cs @@ -297,7 +297,7 @@ public void TestCommand5(ICommandContext context) { Console.WriteLine("TestPlugin TestCommand5"); } - [Command("tt6", permissions: "tt6")] + [Command("tt6", permission: "tt6")] public void TestCommand6(ICommandContext context) { Console.WriteLine("TestPlugin TestCommand6"); } From 5ae3ad87c4023aa2545b5c9c51951fd511c14557 Mon Sep 17 00:00:00 2001 From: Ambr0se Date: Wed, 8 Oct 2025 01:14:37 +0800 Subject: [PATCH 4/4] fix: Change to correct namespace --- managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs | 2 +- managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs index 326f775af..7f8d72f86 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandCallback.cs @@ -4,7 +4,7 @@ using SwiftlyS2.Shared.Misc; using SwiftlyS2.Shared.Commands; using SwiftlyS2.Shared.Permissions; -using SwiftlyS2.Shared.Services; +using SwiftlyS2.Shared.Players; using Microsoft.Extensions.Logging; using SwiftlyS2.Shared.Profiler; using SwiftlyS2.Shared; diff --git a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs index f110ac22d..936708704 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Commands/CommandService.cs @@ -4,7 +4,7 @@ using SwiftlyS2.Shared.Commands; using SwiftlyS2.Shared.Plugins; using SwiftlyS2.Shared.Profiler; -using SwiftlyS2.Shared.Services; +using SwiftlyS2.Shared.Players; using SwiftlyS2.Shared.Permissions; namespace SwiftlyS2.Core.Commands;