aboutsummaryrefslogtreecommitdiff
path: root/src/ext/framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/framework')
-rw-r--r--src/ext/framework/command.rs13
-rw-r--r--src/ext/framework/configuration.rs24
-rw-r--r--src/ext/framework/create_command.rs49
-rw-r--r--src/ext/framework/mod.rs73
4 files changed, 157 insertions, 2 deletions
diff --git a/src/ext/framework/command.rs b/src/ext/framework/command.rs
index b7d5bb8..204c90c 100644
--- a/src/ext/framework/command.rs
+++ b/src/ext/framework/command.rs
@@ -2,6 +2,7 @@ use std::sync::Arc;
use super::Configuration;
use ::client::Context;
use ::model::Message;
+use ::model::Permissions;
use std::collections::HashMap;
pub type Check = Fn(&Context, &Message) -> bool + Send + Sync + 'static;
@@ -33,6 +34,18 @@ pub struct Command {
pub usage: Option<String>,
/// Whether arguments should be parsed using quote parser or not.
pub use_quotes: bool,
+ /// Minumum amount of arguments that should be passed.
+ pub min_args: Option<i32>,
+ /// Maximum amount of arguments that can be passed.
+ pub max_args: Option<i32>,
+ /// Permissions required to use this command.
+ pub required_permissions: Permissions,
+ /// Whether command should be displayed in help list or not, used by other commands.
+ pub help_available: bool,
+ /// Whether command can be used only privately or not.
+ pub dm_only: bool,
+ /// Whether command can be used only in guilds or not.
+ pub guild_only: bool,
}
pub fn positions(ctx: &Context, content: &str, conf: &Configuration) -> Option<Vec<usize>> {
diff --git a/src/ext/framework/configuration.rs b/src/ext/framework/configuration.rs
index 9caa48b..e95faea 100644
--- a/src/ext/framework/configuration.rs
+++ b/src/ext/framework/configuration.rs
@@ -3,6 +3,18 @@ use super::command::PrefixCheck;
use ::client::rest;
use ::client::Context;
+/// Account type used for configuration.
+pub enum AccountType {
+ /// Connected client will only listen to itself.
+ Selfbot,
+ /// Connected client will ignore all bot accounts.
+ Bot,
+ /// Connected client will listen to everyone.
+ Any,
+ #[doc(hidden)]
+ Automatic
+}
+
/// The configuration to use for a [`Framework`] associated with a [`Client`]
/// instance.
///
@@ -36,6 +48,8 @@ pub struct Configuration {
pub prefixes: Vec<String>,
#[doc(hidden)]
pub dynamic_prefix: Option<Box<PrefixCheck>>,
+ #[doc(hidden)]
+ pub account_type: AccountType
}
impl Configuration {
@@ -136,6 +150,13 @@ impl Configuration {
self
}
+ /// Allows you to change what accounts to ignore.
+ pub fn account_type(mut self, account_type: AccountType) -> Self {
+ self.account_type = account_type;
+
+ self
+ }
+
/// Sets the prefix to respond to. This can either be a single-char or
/// multi-char string.
pub fn dynamic_prefix<F>(mut self, dynamic_prefix: F) -> Self
@@ -159,7 +180,8 @@ impl Default for Configuration {
on_mention: None,
allow_whitespace: false,
prefixes: vec![],
- dynamic_prefix: None
+ dynamic_prefix: None,
+ account_type: AccountType::Automatic
}
}
}
diff --git a/src/ext/framework/create_command.rs b/src/ext/framework/create_command.rs
index 824c3dd..6d40592 100644
--- a/src/ext/framework/create_command.rs
+++ b/src/ext/framework/create_command.rs
@@ -5,6 +5,7 @@ use std::default::Default;
use std::sync::Arc;
use ::client::Context;
use ::model::Message;
+use ::model::Permissions;
pub struct CreateCommand(pub Command);
@@ -54,6 +55,48 @@ impl CreateCommand {
self
}
+ /// Whether command should be displayed in help list or not, used by other commands.
+ pub fn help_available(mut self, help_available: bool) -> Self {
+ self.0.help_available = help_available;
+
+ self
+ }
+
+ /// Whether command can be used only privately or not.
+ pub fn dm_only(mut self, dm_only: bool) -> Self {
+ self.0.dm_only = dm_only;
+
+ self
+ }
+
+ /// Whether command can be used only in guilds or not.
+ pub fn guild_only(mut self, guild_only: bool) -> Self {
+ self.0.guild_only = guild_only;
+
+ self
+ }
+
+ /// Minumum amount of arguments that should be passed.
+ pub fn min_args(mut self, min_args: i32) -> Self {
+ self.0.min_args = Some(min_args);
+
+ self
+ }
+
+ /// Maximum amount of arguments that can be passed.
+ pub fn max_args(mut self, max_args: i32) -> Self {
+ self.0.max_args = Some(max_args);
+
+ self
+ }
+
+ /// Maximum amount of arguments that can be passed.
+ pub fn required_permissions(mut self, required_permissions: Permissions) -> Self {
+ self.0.required_permissions = required_permissions;
+
+ self
+ }
+
/// A function that can be called when a command is received.
///
/// See [`exec_str`] if you _only_ need to return a string on command use.
@@ -126,6 +169,12 @@ impl Default for Command {
desc: None,
usage: None,
use_quotes: true,
+ min_args: None,
+ max_args: None,
+ required_permissions: Permissions::empty(),
+ dm_only: false,
+ guild_only: false,
+ help_available: true
}
}
}
diff --git a/src/ext/framework/mod.rs b/src/ext/framework/mod.rs
index 077f767..fa7fdac 100644
--- a/src/ext/framework/mod.rs
+++ b/src/ext/framework/mod.rs
@@ -58,7 +58,7 @@ mod configuration;
mod create_command;
pub use self::command::{Command, CommandType};
-pub use self::configuration::Configuration;
+pub use self::configuration::{AccountType, Configuration};
pub use self::create_command::CreateCommand;
use self::command::{Hook, InternalCommand};
@@ -68,6 +68,8 @@ use std::thread;
use ::client::Context;
use ::model::Message;
use ::utils;
+use ::client::CACHE;
+use ::model::Permissions;
/// A macro to generate "named parameters". This is useful to avoid manually
/// using the "arguments" parameter and manually parsing types.
@@ -194,6 +196,29 @@ impl Framework {
#[doc(hidden)]
pub fn dispatch(&mut self, context: Context, message: Message) {
+ match self.configuration.account_type {
+ AccountType::Selfbot => {
+ if message.author.id != CACHE.read().unwrap().user.id {
+ return;
+ }
+ },
+ AccountType::Bot => {
+ if message.author.bot {
+ return;
+ }
+ },
+ AccountType::Automatic => {
+ let cache = CACHE.read().unwrap();
+ if cache.user.bot {
+ if message.author.bot {
+ return;
+ }
+ } else if message.author.id != cache.user.id {
+ return;
+ }
+ },
+ AccountType::Any => {}
+ }
let res = command::positions(&context, &message.content, &self.configuration);
let positions = match res {
@@ -230,6 +255,14 @@ impl Framework {
});
if let Some(command) = self.commands.get(&built) {
+ if message.is_private() {
+ if command.guild_only {
+ return;
+ }
+ } else if command.dm_only {
+ return;
+ }
+
for check in &command.checks {
if !(check)(&context, &message) {
continue 'outer;
@@ -255,6 +288,38 @@ impl Framework {
.collect::<Vec<String>>()
};
+ if let Some(x) = command.min_args {
+ if args.len() < x as usize {
+ return;
+ }
+ }
+
+ if let Some(x) = command.max_args {
+ if args.len() > x as usize {
+ return;
+ }
+ }
+
+ if !command.required_permissions.is_empty() {
+ let mut permissions_fulfilled = false;
+
+ if let Some(member) = message.get_member() {
+ let cache = CACHE.read().unwrap();
+
+ if let Ok(guild_id) = member.find_guild() {
+ if let Some(guild) = cache.get_guild(guild_id) {
+ let perms = guild.permissions_for(message.channel_id, message.author.id);
+
+ permissions_fulfilled = perms.contains(command.required_permissions);
+ }
+ }
+ }
+
+ if !permissions_fulfilled {
+ return;
+ }
+ }
+
match command.exec {
CommandType::StringResponse(ref x) => {
let _ = &context.say(x);
@@ -302,6 +367,12 @@ impl Framework {
desc: None,
usage: None,
use_quotes: false,
+ dm_only: false,
+ guild_only: false,
+ help_available: true,
+ min_args: None,
+ max_args: None,
+ required_permissions: Permissions::empty()
}));
self.initialized = true;