ratelimit commands
This commit is contained in:
		@@ -21,7 +21,8 @@ use std::{collections::HashMap, fmt};
 | 
			
		||||
 | 
			
		||||
use crate::language_manager::LanguageManager;
 | 
			
		||||
use crate::models::{CtxGuildData, GuildData, UserData};
 | 
			
		||||
use crate::{models::ChannelData, SQLPool};
 | 
			
		||||
use crate::{models::ChannelData, CurrentlyExecuting, SQLPool};
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
 | 
			
		||||
type CommandFn = for<'fut> fn(&'fut Context, &'fut Message, String) -> BoxFuture<'fut, ()>;
 | 
			
		||||
 | 
			
		||||
@@ -345,9 +346,27 @@ impl Framework for RegexFramework {
 | 
			
		||||
 | 
			
		||||
        // gate to prevent analysing messages unnecessarily
 | 
			
		||||
        if (msg.author.bot && self.ignore_bots) || msg.content.is_empty() {
 | 
			
		||||
        } else {
 | 
			
		||||
            let currently_executing = ctx
 | 
			
		||||
                .data
 | 
			
		||||
                .read()
 | 
			
		||||
                .await
 | 
			
		||||
                .get::<CurrentlyExecuting>()
 | 
			
		||||
                .cloned()
 | 
			
		||||
                .unwrap();
 | 
			
		||||
 | 
			
		||||
            let user_is_executing;
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
                let mut lock = currently_executing.lock().unwrap();
 | 
			
		||||
 | 
			
		||||
                user_is_executing = lock.contains(&msg.author.id);
 | 
			
		||||
                lock.insert(msg.author.id);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if !user_is_executing {
 | 
			
		||||
                // Guild Command
 | 
			
		||||
        else if let (Some(guild), Some(Channel::Guild(channel))) =
 | 
			
		||||
                if let (Some(guild), Some(Channel::Guild(channel))) =
 | 
			
		||||
                    (msg.guild(&ctx).await, msg.channel(&ctx).await)
 | 
			
		||||
                {
 | 
			
		||||
                    let data = ctx.data.read().await;
 | 
			
		||||
@@ -368,7 +387,13 @@ impl Framework for RegexFramework {
 | 
			
		||||
                                    PermissionCheck::All => {
 | 
			
		||||
                                        let command = self
 | 
			
		||||
                                            .commands
 | 
			
		||||
                                    .get(&full_match.name("cmd").unwrap().as_str().to_lowercase())
 | 
			
		||||
                                            .get(
 | 
			
		||||
                                                &full_match
 | 
			
		||||
                                                    .name("cmd")
 | 
			
		||||
                                                    .unwrap()
 | 
			
		||||
                                                    .as_str()
 | 
			
		||||
                                                    .to_lowercase(),
 | 
			
		||||
                                            )
 | 
			
		||||
                                            .unwrap();
 | 
			
		||||
 | 
			
		||||
                                        let channel_data = ChannelData::from_channel(
 | 
			
		||||
@@ -385,33 +410,43 @@ impl Framework for RegexFramework {
 | 
			
		||||
                                                .unwrap_or("")
 | 
			
		||||
                                                .to_string();
 | 
			
		||||
 | 
			
		||||
                                    let member = guild.member(&ctx, &msg.author).await.unwrap();
 | 
			
		||||
                                            let member =
 | 
			
		||||
                                                guild.member(&ctx, &msg.author).await.unwrap();
 | 
			
		||||
 | 
			
		||||
                                    if command.check_permissions(&ctx, &guild, &member).await {
 | 
			
		||||
                                            if command
 | 
			
		||||
                                                .check_permissions(&ctx, &guild, &member)
 | 
			
		||||
                                                .await
 | 
			
		||||
                                            {
 | 
			
		||||
                                                dbg!(command.name);
 | 
			
		||||
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    let guild_id = guild.id.as_u64().to_owned();
 | 
			
		||||
 | 
			
		||||
                                            GuildData::from_guild(guild, &pool).await.expect(
 | 
			
		||||
                                                &format!(
 | 
			
		||||
                                                    GuildData::from_guild(guild, &pool)
 | 
			
		||||
                                                        .await
 | 
			
		||||
                                                        .expect(&format!(
 | 
			
		||||
                                                        "Failed to create new guild object for {}",
 | 
			
		||||
                                                        guild_id
 | 
			
		||||
                                                ),
 | 
			
		||||
                                            );
 | 
			
		||||
                                                    ));
 | 
			
		||||
                                                }
 | 
			
		||||
 | 
			
		||||
                                                (command.func)(&ctx, &msg, args).await;
 | 
			
		||||
                                    } else if command.required_perms == PermissionLevel::Restricted
 | 
			
		||||
                                            } else if command.required_perms
 | 
			
		||||
                                                == PermissionLevel::Restricted
 | 
			
		||||
                                            {
 | 
			
		||||
                                                let _ = msg
 | 
			
		||||
                                                    .channel_id
 | 
			
		||||
                                                    .say(
 | 
			
		||||
                                                        &ctx,
 | 
			
		||||
                                                lm.get(&language.await, "no_perms_restricted"),
 | 
			
		||||
                                                        lm.get(
 | 
			
		||||
                                                            &language.await,
 | 
			
		||||
                                                            "no_perms_restricted",
 | 
			
		||||
                                                        ),
 | 
			
		||||
                                                    )
 | 
			
		||||
                                                    .await;
 | 
			
		||||
                                    } else if command.required_perms == PermissionLevel::Managed {
 | 
			
		||||
                                            } else if command.required_perms
 | 
			
		||||
                                                == PermissionLevel::Managed
 | 
			
		||||
                                            {
 | 
			
		||||
                                                let _ = msg
 | 
			
		||||
                                                    .channel_id
 | 
			
		||||
                                                    .say(
 | 
			
		||||
@@ -439,7 +474,10 @@ impl Framework for RegexFramework {
 | 
			
		||||
                                                "{manage_webhooks}",
 | 
			
		||||
                                                if manage_webhooks { "✅" } else { "❌" },
 | 
			
		||||
                                            )
 | 
			
		||||
                                    .replace("{embed_links}", if embed_links { "✅" } else { "❌" })
 | 
			
		||||
                                            .replace(
 | 
			
		||||
                                                "{embed_links}",
 | 
			
		||||
                                                if embed_links { "✅" } else { "❌" },
 | 
			
		||||
                                            )
 | 
			
		||||
                                            .replace(
 | 
			
		||||
                                                "{add_reactions}",
 | 
			
		||||
                                                if add_reactions { "✅" } else { "❌" },
 | 
			
		||||
@@ -485,5 +523,15 @@ impl Framework for RegexFramework {
 | 
			
		||||
                        (command.func)(&ctx, &msg, args).await;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                {
 | 
			
		||||
                    // wait 500 ms before allowing the user to execute a command again
 | 
			
		||||
                    tokio::time::sleep(Duration::from_millis(500)).await;
 | 
			
		||||
 | 
			
		||||
                    let mut lock = currently_executing.lock().unwrap();
 | 
			
		||||
                    lock.remove(&msg.author.id);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -47,6 +47,8 @@ use dashmap::DashMap;
 | 
			
		||||
use tokio::sync::RwLock;
 | 
			
		||||
 | 
			
		||||
use chrono_tz::Tz;
 | 
			
		||||
use std::collections::HashSet;
 | 
			
		||||
use std::sync::Mutex;
 | 
			
		||||
 | 
			
		||||
struct GuildDataCache;
 | 
			
		||||
 | 
			
		||||
@@ -78,6 +80,12 @@ impl TypeMapKey for PopularTimezones {
 | 
			
		||||
    type Value = Arc<Vec<Tz>>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct CurrentlyExecuting;
 | 
			
		||||
 | 
			
		||||
impl TypeMapKey for CurrentlyExecuting {
 | 
			
		||||
    type Value = Arc<Mutex<HashSet<UserId>>>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Handler;
 | 
			
		||||
 | 
			
		||||
#[async_trait]
 | 
			
		||||
@@ -309,7 +317,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
 | 
			
		||||
        let mut data = client.data.write().await;
 | 
			
		||||
 | 
			
		||||
        data.insert::<GuildDataCache>(Arc::new(guild_data_cache));
 | 
			
		||||
 | 
			
		||||
        data.insert::<CurrentlyExecuting>(Arc::new(Mutex::new(HashSet::new())));
 | 
			
		||||
        data.insert::<SQLPool>(pool);
 | 
			
		||||
        data.insert::<PopularTimezones>(Arc::new(popular_timezones));
 | 
			
		||||
        data.insert::<ReqwestClient>(Arc::new(reqwest::Client::new()));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user