From c8de71854b70af0abcd2ce876b71d83595f5d431 Mon Sep 17 00:00:00 2001 From: Noi Date: Sat, 14 Jan 2023 21:54:23 -0800 Subject: [PATCH] Remove custom precondition; use Discord permissions --- Commands/CommandsBase.cs | 7 ---- Commands/ConfigCommands.cs | 37 ++++++++++++++---- Commands/RequireGuildContextAttribute.cs | 14 ------- Commands/UserCommands.cs | 48 +++--------------------- WorldTime.cs | 19 +++------- 5 files changed, 40 insertions(+), 85 deletions(-) delete mode 100644 Commands/RequireGuildContextAttribute.cs diff --git a/Commands/CommandsBase.cs b/Commands/CommandsBase.cs index 3dfc7e9..cc25cf8 100644 --- a/Commands/CommandsBase.cs +++ b/Commands/CommandsBase.cs @@ -73,13 +73,6 @@ public class CommandsBase : InteractionModuleBase { return $"**{username}**#{user.Discriminator}"; } - /// - /// Checks if the given user can be considered a guild admin ('Manage Server' is set). - /// - // TODO replace this with a precondition, or there's also a new permission scheme going around? - protected static bool IsUserAdmin(SocketGuildUser user) - => user.GuildPermissions.Administrator || user.GuildPermissions.ManageGuild; - /// /// Checks if the member cache for the specified guild needs to be filled, and sends a request if needed. /// diff --git a/Commands/ConfigCommands.cs b/Commands/ConfigCommands.cs index 43c3d74..8c81f8e 100644 --- a/Commands/ConfigCommands.cs +++ b/Commands/ConfigCommands.cs @@ -1,19 +1,16 @@ using Discord.Interactions; namespace WorldTime.Commands; -[Group("config", HelpSettings)] +[Group("config", "Configuration commands for World Time.")] +[DefaultMemberPermissions(GuildPermission.ManageGuild)] +[EnabledInDm(false)] public class ConfigCommands : CommandsBase { - internal const string HelpSettings = "Configuration commands for World Time."; internal const string HelpUse12 = "Sets whether to use the 12-hour (AM/PM) format in time zone listings."; + internal const string HelpSetFor = "Sets/updates time zone for a given user."; + internal const string HelpRemoveFor = "Removes time zone for a given user."; - [RequireGuildContext] [SlashCommand("use-12hour", HelpUse12)] public async Task Cmd12Hour([Summary(description: "True to enable, False to disable.")] bool setting) { - if (!IsUserAdmin((SocketGuildUser)Context.User)) { - await RespondAsync(ErrNotAllowed, ephemeral: true); - return; - } - using var db = DbContext; var gs = db.GuildSettings.Where(r => r.GuildId == Context.Guild.Id).SingleOrDefault(); if (gs == null) { @@ -25,4 +22,28 @@ public class ConfigCommands : CommandsBase { await db.SaveChangesAsync(); await RespondAsync($":white_check_mark: Time listing set to **{(setting ? "AM/PM" : "24 hour")}** format."); } + + [SlashCommand("set-for", HelpSetFor)] + public async Task CmdSetFor([Summary(description: "The user whose time zone to modify.")] SocketGuildUser user, + [Summary(description: "The new time zone to set.")] string zone) { + // Extract parameters + var newtz = ParseTimeZone(zone); + if (newtz == null) { + await RespondAsync(ErrInvalidZone); + return; + } + + using var db = DbContext; + db.UpdateUser(user, newtz); + await RespondAsync($":white_check_mark: Time zone for **{user}** set to **{newtz}**."); + } + + [SlashCommand("remove-for", HelpRemoveFor)] + public async Task CmdRemoveFor([Summary(description: "The user whose time zone to remove.")] SocketGuildUser user) { + using var db = DbContext; + if (db.DeleteUser(user)) + await RespondAsync($":white_check_mark: Removed zone information for {user}."); + else + await RespondAsync($":white_check_mark: No time zone is set for {user}."); + } } \ No newline at end of file diff --git a/Commands/RequireGuildContextAttribute.cs b/Commands/RequireGuildContextAttribute.cs deleted file mode 100644 index 5994111..0000000 --- a/Commands/RequireGuildContextAttribute.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Discord.Interactions; - -namespace WorldTime.Commands; -/// -/// Implements the included precondition from Discord.Net, requiring a guild context while using our custom error message. -/// -class RequireGuildContextAttribute : RequireContextAttribute { - public const string Error = "Command not received within a guild context."; - public const string Reply = ":x: This command is only available within a server."; - - public override string ErrorMessage => Error; - - public RequireGuildContextAttribute() : base(ContextType.Guild) { } -} diff --git a/Commands/UserCommands.cs b/Commands/UserCommands.cs index d8a237e..8e0345a 100644 --- a/Commands/UserCommands.cs +++ b/Commands/UserCommands.cs @@ -10,16 +10,15 @@ public class UserCommands : CommandsBase { + $"`/remove` - {HelpRemove}"; const string EmbedHelpField2 = $"`/config use-12hour` - {ConfigCommands.HelpUse12}\n" - + $"`/set-for` - {HelpSetFor}\n" - + $"`/remove-for` - {HelpRemoveFor}"; + + $"`/set-for` - {ConfigCommands.HelpSetFor}\n" + + $"`/remove-for` - {ConfigCommands.HelpRemoveFor}"; #region Help strings const string HelpHelp = "Displays a list of available bot commands."; const string HelpList = "Shows the current time for all recently active known users."; const string HelpSet = "Adds or updates your time zone to the bot."; - const string HelpSetFor = "Sets/updates time zone for a given user."; const string HelpRemove = "Removes your time zone information from this bot."; - const string HelpRemoveFor = "Removes time zone for a given user."; + #endregion [SlashCommand("help", HelpHelp)] @@ -46,8 +45,8 @@ public class UserCommands : CommandsBase { ).Build()); } - [RequireGuildContext] [SlashCommand("list", HelpList)] + [EnabledInDm(false)] public async Task CmdList([Summary(description: "A specific user whose time to look up.")]SocketGuildUser? user = null) { if (!await AreUsersDownloadedAsync(Context.Guild)) { await RespondAsync(ErrNoUserCache, ephemeral: true); @@ -149,6 +148,7 @@ public class UserCommands : CommandsBase { } [SlashCommand("set", HelpSet)] + [EnabledInDm(false)] public async Task CmdSet([Summary(description: "The new time zone to set.")]string zone) { var parsedzone = ParseTimeZone(zone); if (parsedzone == null) { @@ -160,48 +160,12 @@ public class UserCommands : CommandsBase { await RespondAsync($":white_check_mark: Your time zone has been set to **{parsedzone}**."); } - [RequireGuildContext] - [SlashCommand("set-for", HelpSetFor)] - public async Task CmdSetFor([Summary(description: "The user whose time zone to modify.")] SocketGuildUser user, - [Summary(description: "The new time zone to set.")] string zone) { - if (!IsUserAdmin((SocketGuildUser)Context.User)) { - await RespondAsync(ErrNotAllowed, ephemeral: true).ConfigureAwait(false); - return; - } - - // Extract parameters - var newtz = ParseTimeZone(zone); - if (newtz == null) { - await RespondAsync(ErrInvalidZone); - return; - } - - using var db = DbContext; - db.UpdateUser(user, newtz); - await RespondAsync($":white_check_mark: Time zone for **{user}** set to **{newtz}**."); - } - - [RequireGuildContext] [SlashCommand("remove", HelpRemove)] + [EnabledInDm(false)] public async Task CmdRemove() { using var db = DbContext; var success = db.DeleteUser((SocketGuildUser)Context.User); if (success) await RespondAsync(":white_check_mark: Your zone has been removed."); else await RespondAsync(":x: You don't have a time zone set."); } - - [RequireGuildContext] - [SlashCommand("remove-for", HelpRemoveFor)] - public async Task CmdRemoveFor([Summary(description: "The user whose time zone to remove.")] SocketGuildUser user) { - if (!IsUserAdmin((SocketGuildUser)Context.User)) { - await RespondAsync(ErrNotAllowed, ephemeral: true).ConfigureAwait(false); - return; - } - - using var db = DbContext; - if (db.DeleteUser(user)) - await RespondAsync($":white_check_mark: Removed zone information for {user}."); - else - await RespondAsync($":white_check_mark: No time zone is set for {user}."); - } } diff --git a/WorldTime.cs b/WorldTime.cs index 07185a0..074cd70 100644 --- a/WorldTime.cs +++ b/WorldTime.cs @@ -199,20 +199,11 @@ internal class WorldTime : IDisposable { // Additional log information with error detail logresult += " " + Enum.GetName(typeof(InteractionCommandError), result.Error) + ": " + result.ErrorReason; - // Specific responses to errors, if necessary - if (result.Error == InteractionCommandError.UnmetPrecondition) { - string errReply = result.ErrorReason switch { - Commands.RequireGuildContextAttribute.Error => Commands.RequireGuildContextAttribute.Reply, - _ => result.ErrorReason - }; - await context.Interaction.RespondAsync(errReply, ephemeral: true); - } else { - // Generic error response - // TODO when implementing proper application error logging, see here - var ia = context.Interaction; - if (ia.HasResponded) await ia.ModifyOriginalResponseAsync(p => p.Content = InternalError); - else await ia.RespondAsync(InternalError); - } + // Generic error response + // TODO when implementing proper application error logging, see here + var ia = context.Interaction; + if (ia.HasResponded) await ia.ModifyOriginalResponseAsync(p => p.Content = InternalError); + else await ia.RespondAsync(InternalError); } Program.Log("Command", logresult);