diff --git a/Cargo.lock b/Cargo.lock index 59a8936..35c6678 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,8 +217,9 @@ dependencies = [ [[package]] name = "command_attr" -version = "0.2.0" -source = "git+https://github.com/acdenisSK/serenity?branch=await_next#91c30f43274481c7dfa57850cbe9c3ab18cd708f" +version = "0.3.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093ee06b40fcba41b22ddf85de7ed33728fe2e246fcdbc1b1d3ab26f87fabf3b" dependencies = [ "proc-macro2", "quote", @@ -1180,19 +1181,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "rustls" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" -dependencies = [ - "base64 0.11.0", - "log", - "ring", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.18.0" @@ -1300,8 +1288,9 @@ dependencies = [ [[package]] name = "serenity" -version = "0.8.6" -source = "git+https://github.com/acdenisSK/serenity?branch=await_next#91c30f43274481c7dfa57850cbe9c3ab18cd708f" +version = "0.9.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f2b6557e836289a35b45ecc9da78b464de79cec3aa9b7cfd07f654cbc478c00" dependencies = [ "async-tls", "async-trait", @@ -1315,7 +1304,7 @@ dependencies = [ "futures", "log", "reqwest", - "rustls 0.17.0", + "rustls 0.18.0", "serde", "serde_json", "static_assertions", diff --git a/Cargo.toml b/Cargo.toml index 777b9a5..54ec5e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["jellywx "] edition = "2018" [dependencies] -serenity = {git = "https://github.com/acdenisSK/serenity", branch = "await_next"} +serenity = "0.9.0-rc.0" dotenv = "0.15" tokio = {version = "0.2.19", features = ["fs", "sync", "process", "io-util"]} reqwest = "0.10.6" diff --git a/src/commands/moderation_cmds.rs b/src/commands/moderation_cmds.rs index 3972bf8..3e5341c 100644 --- a/src/commands/moderation_cmds.rs +++ b/src/commands/moderation_cmds.rs @@ -26,8 +26,12 @@ use crate::{ lazy_static! { static ref REGEX_CHANNEL: Regex = Regex::new(r#"^\s*<#(\d+)>\s*$"#).unwrap(); + static ref REGEX_ROLE: Regex = Regex::new(r#"<@&([0-9]+)>"#).unwrap(); + static ref REGEX_COMMANDS: Regex = Regex::new(r#"([a-z]+)"#).unwrap(); + + static ref REGEX_ALIAS: Regex = Regex::new(r#"(?P[\S]{1,12})(?:(?: (?P.*)$)|$)"#).unwrap(); } #[command] @@ -231,3 +235,100 @@ WHERE Ok(()) } + +#[command] +#[supports_dm(false)] +#[permission_level(Managed)] +async fn alias(ctx: &Context, msg: &Message, args: String) -> CommandResult { + let pool = ctx.data.read().await + .get::().cloned().expect("Could not get SQLPool from data"); + + let user_data = UserData::from_id(&msg.author, &ctx, &pool).await.unwrap(); + + let guild_id = msg.guild_id.unwrap().as_u64().to_owned(); + + let matches_opt = REGEX_ALIAS.captures(&args); + + if let Some(matches) = matches_opt { + let name = matches.name("name").unwrap().as_str(); + let command_opt = matches.name("cmd").map(|m| m.as_str()); + + match name { + "list" => { + let aliases = sqlx::query!( + " +SELECT name, command FROM command_aliases WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) + ", guild_id) + .fetch_all(&pool) + .await + .unwrap(); + + let content = aliases.iter().map(|row| format!("**{}**: {}", row.name, row.command)).collect::>().join("\n"); + + let _ = msg.channel_id.say(&ctx, format!("Aliases: \n{}", content)).await; + }, + + "remove" => { + if let Some(command) = command_opt { + sqlx::query!( + " +DELETE FROM command_aliases WHERE name = ? AND guild_id = (SELECT id FROM guilds WHERE guild = ?) + ", command, guild_id) + .execute(&pool) + .await + .unwrap(); + + let _ = msg.channel_id.say(&ctx, user_data.response(&pool, "alias/removed").await).await; + } + else { + let _ = msg.channel_id.say(&ctx, user_data.response(&pool, "alias/help").await).await; + } + }, + + name => { + if let Some(command) = command_opt { + let res = sqlx::query!( + " +INSERT INTO command_aliases (guild_id, name, command) VALUES ((SELECT id FROM guilds WHERE guild = ?), ?, ?) + ", guild_id, name, command) + .execute(&pool) + .await; + + if res.is_err() { + sqlx::query!( + " +UPDATE command_aliases SET command = ? WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ? + ", command, guild_id, name) + .execute(&pool) + .await + .unwrap(); + } + + let _ = msg.channel_id.say(&ctx, user_data.response(&pool, "alias/created").await).await; + } + else { + match sqlx::query!( + " +SELECT command FROM command_aliases WHERE guild_id = ? AND name = ? + ", guild_id, name) + .fetch_one(&pool) + .await { + + Ok(row) => { + // run aliased command content + }, + + Err(_) => { + let _ = msg.channel_id.say(&ctx, user_data.response(&pool, "alias/not_found").await).await; + }, + } + } + } + } + } + else { + let _ = msg.channel_id.say(&ctx, user_data.response(&pool, "alias/help").await).await; + } + + Ok(()) +} diff --git a/src/framework.rs b/src/framework.rs index 4e6705b..3023b42 100644 --- a/src/framework.rs +++ b/src/framework.rs @@ -134,7 +134,7 @@ impl fmt::Debug for Command { // create event handler for bot pub struct RegexFramework { commands: HashMap, - regex_matcher: Regex, + command_matcher: Regex, dm_regex_matcher: Regex, default_prefix: String, client_id: u64, @@ -145,7 +145,7 @@ impl RegexFramework { pub fn new(client_id: u64) -> Self { Self { commands: HashMap::new(), - regex_matcher: Regex::new(r#"^$"#).unwrap(), + command_matcher: Regex::new(r#"^$"#).unwrap(), dm_regex_matcher: Regex::new(r#"^$"#).unwrap(), default_prefix: String::from("$"), client_id, @@ -193,7 +193,7 @@ impl RegexFramework { .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.command_matcher = Regex::new(match_string.as_str()).unwrap(); } } @@ -305,7 +305,7 @@ impl Framework for RegexFramework { let member = guild.member(&ctx, &msg.author).await.unwrap(); - if let Some(full_match) = self.regex_matcher.captures(&msg.content[..]) { + if let Some(full_match) = self.command_matcher.captures(&msg.content[..]) { if check_prefix(&ctx, &guild, full_match.name("prefix")).await { diff --git a/src/main.rs b/src/main.rs index 2c1de97..028be6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use serenity::{ bridge::gateway::GatewayIntents, Client, }, + framework::Framework, prelude::TypeMapKey, }; @@ -49,6 +50,12 @@ impl TypeMapKey for ReqwestClient { type Value = Arc; } +struct FrameworkCtx; + +impl TypeMapKey for FrameworkCtx { + type Value = Arc>; +} + static THEME_COLOR: u32 = 0x8fb677; #[tokio::main] @@ -81,9 +88,11 @@ async fn main() -> Result<(), Box> { .build(); + let framework_arc = Arc::new(Box::new(framework) as Box); + let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment")) .intents(GatewayIntents::GUILD_MESSAGES | GatewayIntents::GUILDS | GatewayIntents::DIRECT_MESSAGES) - .framework(framework) + .framework_arc(framework_arc.clone()) .await.expect("Error occurred creating client"); { @@ -93,6 +102,7 @@ async fn main() -> Result<(), Box> { data.insert::(pool); data.insert::(Arc::new(reqwest::Client::new())); + data.insert::(framework_arc); } client.start_autosharded().await?;