From d82a4d2e5e380e67dbb9212a9edcc654727454ec Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Mon, 5 Dec 2022 01:43:40 +0000 Subject: [PATCH] Add pre-execution checks --- .../PreExecutionCheckAttribute.cs | 13 ++++++++ .../RequireAvatarNameAttribute.cs | 31 +++++++++++++++++++ .../ExecutionChecks/RequireBotAttribute.cs | 14 +++++++++ .../ExecutionChecks/RequireHumanAttribute.cs | 14 +++++++++ .../ExecutionChecks/RequireUserIdAttribute.cs | 31 +++++++++++++++++++ .../RequireUserNameAttribute.cs | 31 +++++++++++++++++++ VpSharp.Commands/CommandsExtension.cs | 11 ++++++- 7 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 VpSharp.Commands/Attributes/ExecutionChecks/PreExecutionCheckAttribute.cs create mode 100644 VpSharp.Commands/Attributes/ExecutionChecks/RequireAvatarNameAttribute.cs create mode 100644 VpSharp.Commands/Attributes/ExecutionChecks/RequireBotAttribute.cs create mode 100644 VpSharp.Commands/Attributes/ExecutionChecks/RequireHumanAttribute.cs create mode 100644 VpSharp.Commands/Attributes/ExecutionChecks/RequireUserIdAttribute.cs create mode 100644 VpSharp.Commands/Attributes/ExecutionChecks/RequireUserNameAttribute.cs diff --git a/VpSharp.Commands/Attributes/ExecutionChecks/PreExecutionCheckAttribute.cs b/VpSharp.Commands/Attributes/ExecutionChecks/PreExecutionCheckAttribute.cs new file mode 100644 index 0000000..26edd99 --- /dev/null +++ b/VpSharp.Commands/Attributes/ExecutionChecks/PreExecutionCheckAttribute.cs @@ -0,0 +1,13 @@ +namespace VpSharp.Commands.Attributes.ExecutionChecks; + +/// +/// Represents the base class for all execution check attributes. +/// +public abstract class PreExecutionCheckAttribute : Attribute +{ + /// + /// Performs the execution check. + /// + /// if the execution check has passed; otherwise, . + protected internal abstract Task PerformAsync(CommandContext context); +} diff --git a/VpSharp.Commands/Attributes/ExecutionChecks/RequireAvatarNameAttribute.cs b/VpSharp.Commands/Attributes/ExecutionChecks/RequireAvatarNameAttribute.cs new file mode 100644 index 0000000..5b851a6 --- /dev/null +++ b/VpSharp.Commands/Attributes/ExecutionChecks/RequireAvatarNameAttribute.cs @@ -0,0 +1,31 @@ +namespace VpSharp.Commands.Attributes.ExecutionChecks; + +/// +/// Specifies that this command can only be run by bots. +/// +public sealed class RequireAvatarNameAttribute : PreExecutionCheckAttribute +{ + /// + /// Initializes a new instance of the class. + /// + /// An array of allowed user names. + /// is . + public RequireAvatarNameAttribute(params string[] names) + { + ArgumentNullException.ThrowIfNull(names); + Names = names[..]; + } + + /// + /// Gets a read-only view of the user names allowed to run this command. + /// + /// A of representing the allowed user names. + public IReadOnlyList Names { get; } + + /// + protected internal override Task PerformAsync(CommandContext context) + { + ArgumentNullException.ThrowIfNull(context); + return Task.FromResult(Names.Contains(context.Avatar.Name)); + } +} diff --git a/VpSharp.Commands/Attributes/ExecutionChecks/RequireBotAttribute.cs b/VpSharp.Commands/Attributes/ExecutionChecks/RequireBotAttribute.cs new file mode 100644 index 0000000..3afce7c --- /dev/null +++ b/VpSharp.Commands/Attributes/ExecutionChecks/RequireBotAttribute.cs @@ -0,0 +1,14 @@ +namespace VpSharp.Commands.Attributes.ExecutionChecks; + +/// +/// Specifies that this command can only be run by bots. +/// +public sealed class RequireBotAttribute : PreExecutionCheckAttribute +{ + /// + protected internal override Task PerformAsync(CommandContext context) + { + ArgumentNullException.ThrowIfNull(context); + return Task.FromResult(context.Avatar.IsBot); + } +} diff --git a/VpSharp.Commands/Attributes/ExecutionChecks/RequireHumanAttribute.cs b/VpSharp.Commands/Attributes/ExecutionChecks/RequireHumanAttribute.cs new file mode 100644 index 0000000..83332a9 --- /dev/null +++ b/VpSharp.Commands/Attributes/ExecutionChecks/RequireHumanAttribute.cs @@ -0,0 +1,14 @@ +namespace VpSharp.Commands.Attributes.ExecutionChecks; + +/// +/// Specifies that this command cannot be run by bots. +/// +public sealed class RequireHumanAttribute : PreExecutionCheckAttribute +{ + /// + protected internal override Task PerformAsync(CommandContext context) + { + ArgumentNullException.ThrowIfNull(context); + return Task.FromResult(!context.Avatar.IsBot); + } +} diff --git a/VpSharp.Commands/Attributes/ExecutionChecks/RequireUserIdAttribute.cs b/VpSharp.Commands/Attributes/ExecutionChecks/RequireUserIdAttribute.cs new file mode 100644 index 0000000..57541b1 --- /dev/null +++ b/VpSharp.Commands/Attributes/ExecutionChecks/RequireUserIdAttribute.cs @@ -0,0 +1,31 @@ +namespace VpSharp.Commands.Attributes.ExecutionChecks; + +/// +/// Specifies that this command can only be run by bots. +/// +public sealed class RequireUserIdAttribute : PreExecutionCheckAttribute +{ + /// + /// Initializes a new instance of the class. + /// + /// An array of allowed user IDs. + /// is . + public RequireUserIdAttribute(params int[] userIds) + { + ArgumentNullException.ThrowIfNull(userIds); + UserIds = userIds[..]; + } + + /// + /// Gets a read-only view of the user IDs allowed to run this command. + /// + /// A of representing the allowed user IDs. + public IReadOnlyList UserIds { get; } + + /// + protected internal override Task PerformAsync(CommandContext context) + { + ArgumentNullException.ThrowIfNull(context); + return Task.FromResult(UserIds.Contains(context.Avatar.User.Id)); + } +} diff --git a/VpSharp.Commands/Attributes/ExecutionChecks/RequireUserNameAttribute.cs b/VpSharp.Commands/Attributes/ExecutionChecks/RequireUserNameAttribute.cs new file mode 100644 index 0000000..5ccb619 --- /dev/null +++ b/VpSharp.Commands/Attributes/ExecutionChecks/RequireUserNameAttribute.cs @@ -0,0 +1,31 @@ +namespace VpSharp.Commands.Attributes.ExecutionChecks; + +/// +/// Specifies that this command can only be run by bots. +/// +public sealed class RequireUserNameAttribute : PreExecutionCheckAttribute +{ + /// + /// Initializes a new instance of the class. + /// + /// An array of allowed user names. + /// is . + public RequireUserNameAttribute(params string[] names) + { + ArgumentNullException.ThrowIfNull(names); + Names = names[..]; + } + + /// + /// Gets a read-only view of the user names allowed to run this command. + /// + /// A of representing the allowed user names. + public IReadOnlyList Names { get; } + + /// + protected internal override Task PerformAsync(CommandContext context) + { + ArgumentNullException.ThrowIfNull(context); + return Task.FromResult(Names.Contains(context.Avatar.User.Name)); + } +} diff --git a/VpSharp.Commands/CommandsExtension.cs b/VpSharp.Commands/CommandsExtension.cs index 105e73f..fedfe32 100644 --- a/VpSharp.Commands/CommandsExtension.cs +++ b/VpSharp.Commands/CommandsExtension.cs @@ -2,6 +2,7 @@ using System.Reflection; using Microsoft.Extensions.DependencyInjection; using VpSharp.ClientExtensions; using VpSharp.Commands.Attributes; +using VpSharp.Commands.Attributes.ExecutionChecks; using VpSharp.Entities; using VpSharp.EventData; @@ -218,8 +219,16 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension } var context = new CommandContext(Client, message.Author, command.Name, commandNameString, rawArguments.ToString()); - object?[] arguments = {context}; + foreach (var attribute in command.Method.GetCustomAttributes()) + { + if (!attribute.PerformAsync(context).ConfigureAwait(false).GetAwaiter().GetResult()) + { + return base.OnMessageReceived(args); + } + } + + object?[] arguments = {context}; if (rawArguments.Length > 0) { spaceIndex = rawArguments.IndexOf(' ');