diff options
| author | Lakelezz <[email protected]> | 2018-07-15 16:48:06 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2018-07-15 16:48:06 +0200 |
| commit | 29480e5eeccc12afc0e9020373647786736aabc7 (patch) | |
| tree | 347ade11861894d95de87274e5c534d6795b282b | |
| parent | typos (diff) | |
| download | serenity-29480e5eeccc12afc0e9020373647786736aabc7.tar.xz serenity-29480e5eeccc12afc0e9020373647786736aabc7.zip | |
Add checks for groups (#349)
| -rw-r--r-- | examples/05_command_framework/src/main.rs | 33 | ||||
| -rw-r--r-- | src/framework/standard/command.rs | 5 | ||||
| -rw-r--r-- | src/framework/standard/create_command.rs | 2 | ||||
| -rw-r--r-- | src/framework/standard/create_group.rs | 17 | ||||
| -rw-r--r-- | src/framework/standard/mod.rs | 15 |
5 files changed, 65 insertions, 7 deletions
diff --git a/examples/05_command_framework/src/main.rs b/examples/05_command_framework/src/main.rs index ca16f23..afec234 100644 --- a/examples/05_command_framework/src/main.rs +++ b/examples/05_command_framework/src/main.rs @@ -186,13 +186,21 @@ fn main() { .command("latency", |c| c .cmd(latency)) .command("ping", |c| c - .check(owner_check) + .check(owner_check) // User needs to pass this test to run command .cmd(ping)) .command("role", |c| c .cmd(about_role) // Limits the usage of this command to roles named: .allowed_roles(vec!["mods", "ultimate neko"])) - .command("some long command", |c| c.cmd(some_long_command)), + .command("some long command", |c| c.cmd(some_long_command)) + .group("Owner", |g| g + // This check applies to every command on this group. + // User needs to pass the test for the command to execute. + .check(admin_check) + .command("am i admin", |c| c + .cmd(am_i_admin)) + .guild_only(true) + ), ); if let Err(why) = client.start() { @@ -231,6 +239,21 @@ fn owner_check(_: &mut Context, msg: &Message, _: &mut Args, _: &CommandOptions) msg.author.id == 7 } +// A function which acts as a "check", to determine whether to call a command. +// +// This check analyses whether a guild member permissions has +// administrator-permissions. +fn admin_check(_: &mut Context, msg: &Message, _: &mut Args, _: &CommandOptions) -> bool { + if let Some(member) = msg.member() { + + if let Ok(permissions) = member.permissions() { + return permissions.administrator(); + } + } + + false +} + command!(some_long_command(_ctx, msg, args) { if let Err(why) = msg.channel_id.say(&format!("Arguments: {:?}", args)) { println!("Error sending message: {:?}", why); @@ -333,6 +356,12 @@ command!(ping(_ctx, msg, _args) { } }); +command!(am_i_admin(_ctx, msg, _args) { + if let Err(why) = msg.channel_id.say("Yes you are.") { + println!("Error sending message: {:?}", why); + } +}); + command!(dog(_ctx, msg, _args) { if let Err(why) = msg.channel_id.say(":dog:") { println!("Error sending message: {:?}", why); diff --git a/src/framework/standard/command.rs b/src/framework/standard/command.rs index f4f455e..23f2f0c 100644 --- a/src/framework/standard/command.rs +++ b/src/framework/standard/command.rs @@ -101,6 +101,9 @@ pub struct CommandGroup { pub guild_only: bool, pub owners_only: bool, pub help: Option<Arc<Help>>, + /// A set of checks to be called prior to executing the command-group. The checks + /// will short-circuit on the first check that returns `false`. + pub checks: Vec<Check>, } impl Default for CommandGroup { @@ -116,6 +119,7 @@ impl Default for CommandGroup { owners_only: false, allowed_roles: Vec::new(), help: None, + checks: Vec::new(), } } } @@ -256,7 +260,6 @@ impl Default for HelpOptions { } } - lazy_static! { static ref DEFAULT_OPTIONS: Arc<CommandOptions> = Arc::new(CommandOptions::default()); } diff --git a/src/framework/standard/create_command.rs b/src/framework/standard/create_command.rs index 9c5e81c..a769d4c 100644 --- a/src/framework/standard/create_command.rs +++ b/src/framework/standard/create_command.rs @@ -60,7 +60,7 @@ impl CreateCommand { /// Adds a "check" to a command, which checks whether or not the command's /// function should be called. /// - /// These checks are bypassed for commands sent by the application owner. + /// **Note**: These checks are bypassed for commands sent by the application owner. /// /// # Examples /// diff --git a/src/framework/standard/create_group.rs b/src/framework/standard/create_group.rs index 18f6402..c99b829 100644 --- a/src/framework/standard/create_group.rs +++ b/src/framework/standard/create_group.rs @@ -8,7 +8,8 @@ pub(crate) use super::command::CommandOrAlias; pub use super::{ create_help_command::CreateHelpCommand, create_command::{CreateCommand, FnOrCommand}, - Args + Args, + Check, }; use client::Context; @@ -161,4 +162,18 @@ impl CreateGroup { self } + + /// Adds a "check" to a group, which checks whether or not the groups's + /// commands should be called. + /// + /// **Note**: These checks are bypassed for commands sent by the application owner. + pub fn check<F>(mut self, check: F) -> Self + where F: Fn(&mut Context, &Message, &mut Args, &CommandOptions) -> bool + + Send + + Sync + + 'static { + self.0.checks.push(Check::new(check)); + + self + } } diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs index 435069e..6eaa83e 100644 --- a/src/framework/standard/mod.rs +++ b/src/framework/standard/mod.rs @@ -488,6 +488,7 @@ impl StandardFramework { mut context: &mut Context, message: &Message, command: &Arc<CommandOptions>, + group: &Arc<CommandGroup>, args: &mut Args, to_check: &str, built: &str) @@ -600,12 +601,21 @@ impl StandardFramework { } } - let all_passed = command + let all_group_checks_passed = group .checks .iter() .all(|check| (check.0)(&mut context, message, args, command)); - if all_passed { + if !all_group_checks_passed { + return Some(DispatchError::CheckFailed); + } + + let all_command_checks_passed = command + .checks + .iter() + .all(|check| (check.0)(&mut context, message, args, command)); + + if all_command_checks_passed { None } else { Some(DispatchError::CheckFailed) @@ -1061,6 +1071,7 @@ impl Framework for StandardFramework { &mut context, &message, &command.options(), + &group, &mut args, &to_check, &built, |