bulking out the dispatch fn

This commit is contained in:
jude 2020-08-07 01:02:01 +01:00
parent 7dac9f7895
commit c2c5e79940
4 changed files with 94 additions and 7 deletions

1
Cargo.lock generated
View File

@ -1072,6 +1072,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"dotenv", "dotenv",
"log",
"regex", "regex",
"regex_command_attr", "regex_command_attr",
"reqwest", "reqwest",

View File

@ -12,6 +12,7 @@ reqwest = "0.10.6"
sqlx = {version = "0.3.5", default-features = false, features = ["runtime-tokio", "macros", "mysql", "bigdecimal"]} sqlx = {version = "0.3.5", default-features = false, features = ["runtime-tokio", "macros", "mysql", "bigdecimal"]}
regex = "1.3.9" regex = "1.3.9"
async-trait = "0.1.36" async-trait = "0.1.36"
log = "0.4.11"
[dependencies.regex_command_attr] [dependencies.regex_command_attr]
path = "./regex_command_attr" path = "./regex_command_attr"

View File

@ -3,9 +3,21 @@ use async_trait::async_trait;
use serenity::{ use serenity::{
client::Context, client::Context,
framework::Framework, framework::Framework,
model::channel::Message, model::{
guild::Guild,
channel::{
Channel, GuildChannel, Message,
}
},
}; };
use log::{
warn,
error,
};
use regex::Regex;
use std::{ use std::{
collections::HashMap, collections::HashMap,
fmt, fmt,
@ -42,17 +54,19 @@ impl fmt::Debug for Command {
// create event handler for bot // create event handler for bot
pub struct RegexFramework { pub struct RegexFramework {
commands: HashMap<String, &'static Command>, commands: HashMap<String, &'static Command>,
command_names: String, regex_matcher: Regex,
default_prefix: String, default_prefix: String,
client_id: u64,
ignore_bots: bool, ignore_bots: bool,
} }
impl RegexFramework { impl RegexFramework {
pub fn new() -> Self { pub fn new(client_id: u64) -> Self {
Self { Self {
commands: HashMap::new(), commands: HashMap::new(),
command_names: String::new(), regex_matcher: Regex::new(r#"^$"#).unwrap(),
default_prefix: String::from("$"), default_prefix: String::from("$"),
client_id,
ignore_bots: true, ignore_bots: true,
} }
} }
@ -76,19 +90,90 @@ impl RegexFramework {
} }
pub fn build(mut self) -> Self { pub fn build(mut self) -> Self {
self.command_names = self.commands let command_names = self.commands
.keys() .keys()
.map(|k| &k[..]) .map(|k| &k[..])
.collect::<Vec<&str>>() .collect::<Vec<&str>>()
.join("|"); .join("|");
let match_string = r#"^(?:(?:<@ID>\s+)|(?:<@!ID>\s+)|(?P<prefix>\S{1,5}?))(?P<cmd>COMMANDS)(?:$|\s+(?P<args>.*))$"#
.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 self
} }
} }
enum PermissionCheck {
None, // No permissions
Basic, // Send + Embed permissions (sufficient to reply)
All, // Above + Manage Webhooks (sufficient to operate)
}
#[async_trait] #[async_trait]
impl Framework for RegexFramework { impl Framework for RegexFramework {
async fn dispatch(&self, ctx: Context, msg: Message) { 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<PermissionCheck, Box<dyn std::error::Error>> {
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 {
}
} }
} }

View File

@ -54,7 +54,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("{:?}", HELP_COMMAND); 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) .ignore_bots(true)
.default_prefix("$") .default_prefix("$")
.add_command("help".to_string(), &HELP_COMMAND) .add_command("help".to_string(), &HELP_COMMAND)