From c2c5e79940e75a74b83185de60b4e8cf6edde95d Mon Sep 17 00:00:00 2001 From: jude Date: Fri, 7 Aug 2020 01:02:01 +0100 Subject: [PATCH] bulking out the dispatch fn --- Cargo.lock | 1 + Cargo.toml | 1 + src/framework.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++--- src/main.rs | 2 +- 4 files changed, 94 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8f888b..ad3b2c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1072,6 +1072,7 @@ version = "0.1.0" dependencies = [ "async-trait", "dotenv", + "log", "regex", "regex_command_attr", "reqwest", diff --git a/Cargo.toml b/Cargo.toml index 1df279e..63ec92c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ reqwest = "0.10.6" sqlx = {version = "0.3.5", default-features = false, features = ["runtime-tokio", "macros", "mysql", "bigdecimal"]} regex = "1.3.9" async-trait = "0.1.36" +log = "0.4.11" [dependencies.regex_command_attr] path = "./regex_command_attr" diff --git a/src/framework.rs b/src/framework.rs index 10e6aaf..328d528 100644 --- a/src/framework.rs +++ b/src/framework.rs @@ -3,9 +3,21 @@ use async_trait::async_trait; use serenity::{ client::Context, framework::Framework, - model::channel::Message, + model::{ + guild::Guild, + channel::{ + Channel, GuildChannel, Message, + } + }, }; +use log::{ + warn, + error, +}; + +use regex::Regex; + use std::{ collections::HashMap, fmt, @@ -42,17 +54,19 @@ impl fmt::Debug for Command { // create event handler for bot pub struct RegexFramework { commands: HashMap, - command_names: String, + regex_matcher: Regex, default_prefix: String, + client_id: u64, ignore_bots: bool, } impl RegexFramework { - pub fn new() -> Self { + pub fn new(client_id: u64) -> Self { Self { commands: HashMap::new(), - command_names: String::new(), + regex_matcher: Regex::new(r#"^$"#).unwrap(), default_prefix: String::from("$"), + client_id, ignore_bots: true, } } @@ -76,19 +90,90 @@ impl RegexFramework { } pub fn build(mut self) -> Self { - self.command_names = self.commands + let command_names = self.commands .keys() .map(|k| &k[..]) .collect::>() .join("|"); + let match_string = r#"^(?:(?:<@ID>\s+)|(?:<@!ID>\s+)|(?P\S{1,5}?))(?PCOMMANDS)(?:$|\s+(?P.*))$"# + .replace("COMMANDS", command_names.as_str()) + .replace("ID", self.client_id.to_string().as_str()); + + self.regex_matcher = Regex::new(match_string.as_str()).unwrap(); + self } } +enum PermissionCheck { + None, // No permissions + Basic, // Send + Embed permissions (sufficient to reply) + All, // Above + Manage Webhooks (sufficient to operate) +} + #[async_trait] impl Framework for RegexFramework { async fn dispatch(&self, ctx: Context, msg: Message) { - println!("Message received! command_names=={}", self.command_names); + + async fn check_self_permissions(ctx: &Context, guild: &Guild, channel: &GuildChannel) -> Result> { + let user_id = ctx.cache.current_user_id().await; + + let guild_perms = guild.member_permissions(user_id); + let perms = channel.permissions_for_user(ctx, user_id).await?; + + let basic_perms = perms.send_messages() && perms.embed_links(); + + Ok(if basic_perms && guild_perms.manage_webhooks() { + PermissionCheck::All + } + else if basic_perms { + PermissionCheck::Basic + } + else { + PermissionCheck::None + }) + } + + // gate to prevent analysing messages unnecessarily + if (msg.author.bot && self.ignore_bots) || + msg.tts || + msg.content.len() == 0 || + msg.attachments.len() > 0 + { + return + } + + // Guild Command + else if let (Some(guild), Some(Channel::Guild(channel))) = (msg.guild(&ctx).await, msg.channel(&ctx).await) { + + if let Some(full_match) = self.regex_matcher.captures(msg.content.as_str()) { + + match check_self_permissions(&ctx, &guild, &channel).await { + Ok(perms) => match perms { + PermissionCheck::All => { + + } + + PermissionCheck::Basic => { + + } + + PermissionCheck::None => { + warn!("Missing enough permissions for guild {}", guild.id); + } + } + + Err(e) => { + error!("Error occurred getting permissions in guild {}: {:?}", guild.id, e); + } + } + } + } + + // DM Command + else { + + } } } diff --git a/src/main.rs b/src/main.rs index 7acdde2..dc4b7d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,7 @@ async fn main() -> Result<(), Box> { println!("{:?}", HELP_COMMAND); - let framework = RegexFramework::new() + let framework = RegexFramework::new(env::var("CLIENT_ID").expect("Missing CLIENT_ID from environment").parse()?) .ignore_bots(true) .default_prefix("$") .add_command("help".to_string(), &HELP_COMMAND)