From 042fc8c4666fd96baf85dca8df6385e7b2f37cc3 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 25 Aug 2022 23:15:09 +0200 Subject: [PATCH] feat: handle mute when rejoining the server --- src/commands/moderation.rs | 7 +++-- src/events/guild_member_addition.rs | 5 +++- src/events/message_create.rs | 19 +++++++------ src/events/mod.rs | 4 +-- src/utils/moderation.rs | 43 +++++++++++++++++++++++++++++ src/utils/ocr.rs | 2 +- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/commands/moderation.rs b/src/commands/moderation.rs index d96daae..7905b01 100644 --- a/src/commands/moderation.rs +++ b/src/commands/moderation.rs @@ -98,21 +98,22 @@ pub async fn mute( if let Err(add_role_result) = member.add_role(&ctx.discord().http, mute_role_id).await { Some(Error::from(add_role_result)) } else { + // accumulate all roles to take from the member let removed_roles = member .roles .iter() .filter(|r| take.contains(&r.0)) .map(|r| r.to_string()) .collect::>(); - - let removed = member + // take them from the member, get remaining roles + let remaining_roles = member .remove_roles( &ctx.discord().http, &take.iter().map(|&r| RoleId::from(r)).collect::>(), ) .await; - if let Err(remove_role_result) = removed { + if let Err(remove_role_result) = remaining_roles { Some(Error::from(remove_role_result)) } else { // Roles which were removed from the user diff --git a/src/events/guild_member_addition.rs b/src/events/guild_member_addition.rs index dde9d78..5f3ba0e 100644 --- a/src/events/guild_member_addition.rs +++ b/src/events/guild_member_addition.rs @@ -1,6 +1,9 @@ use super::*; use crate::utils::decancer::cure; +use crate::utils::moderation::mute_on_join; + +pub async fn guild_member_addition(ctx: &serenity::Context, new_member: &mut serenity::Member) { + mute_on_join(ctx, new_member).await; -pub async fn guild_member_addition(ctx: &serenity::Context, new_member: &serenity::Member) { cure(ctx, &None, new_member).await; } diff --git a/src/events/message_create.rs b/src/events/message_create.rs index 6d95ee3..25526ec 100644 --- a/src/events/message_create.rs +++ b/src/events/message_create.rs @@ -7,11 +7,11 @@ use super::*; use crate::utils::bot::get_data_lock; use crate::utils::ocr; -fn contains_match(regex: &Vec, text: &str) -> bool { +fn contains_match(regex: &[Regex], text: &str) -> bool { regex.iter().any(|r| r.is_match(text)) } -async fn attachments_contains(attachments: &Vec, regex: &Vec) -> bool { +async fn attachments_contains(attachments: &[Attachment], regex: &[Regex]) -> bool { for attachment in attachments { debug!("Checking attachment {}", &attachment.url); @@ -31,7 +31,7 @@ async fn attachments_contains(attachments: &Vec, regex: &Vec) pub async fn message_create(ctx: &serenity::Context, new_message: &serenity::Message) { debug!("Received message: {}", new_message.content); - + if new_message.guild_id.is_none() || new_message.author.bot { return; } @@ -64,18 +64,19 @@ pub async fn message_create(ctx: &serenity::Context, new_message: &serenity::Mes let contains_attachments = !new_message.attachments.is_empty(); // check if the message does not match any of the excludes - if contains_match(&excludes.match_field.text, &message) { + if contains_match(&excludes.match_field.text, message) { continue; } - if contains_attachments && !excludes.match_field.ocr.is_empty() { - if attachments_contains(&new_message.attachments, &excludes.match_field.ocr).await { - continue; - } + if contains_attachments + && !excludes.match_field.ocr.is_empty() + && attachments_contains(&new_message.attachments, &excludes.match_field.ocr).await + { + continue; } // check if the message does match any of the includes - if !(contains_match(&response.includes.match_field.text, &message) + if !(contains_match(&response.includes.match_field.text, message) || (contains_attachments && !response.includes.match_field.ocr.is_empty() && attachments_contains( diff --git a/src/events/mod.rs b/src/events/mod.rs index c9c7e65..461661e 100644 --- a/src/events/mod.rs +++ b/src/events/mod.rs @@ -87,8 +87,8 @@ impl serenity::EventHandler for Handler>> { thread_create::thread_create(&ctx, &thread).await; } - async fn guild_member_addition(&self, ctx: serenity::Context, new_member: serenity::Member) { - guild_member_addition::guild_member_addition(&ctx, &new_member).await; + async fn guild_member_addition(&self, ctx: serenity::Context, mut new_member: serenity::Member) { + guild_member_addition::guild_member_addition(&ctx, &mut new_member).await; } async fn guild_member_update( diff --git a/src/utils/moderation.rs b/src/utils/moderation.rs index 7147542..ba1e5c5 100644 --- a/src/utils/moderation.rs +++ b/src/utils/moderation.rs @@ -1,8 +1,11 @@ use std::sync::Arc; +use mongodb::options::FindOptions; use poise::serenity_prelude::Http; use tokio::task::JoinHandle; +use tracing::{debug, error, trace}; +use super::bot::get_data_lock; use super::*; use crate::db::database::Database; use crate::db::model::Muted; @@ -13,6 +16,46 @@ pub enum ModerationKind { Unmute(Option), // Error } +pub async fn mute_on_join(ctx: &serenity::Context, new_member: &mut serenity::Member) { + let data = get_data_lock(ctx).await; + let data = data.read().await; + + if let Ok(mut cursor) = data + .database + .find::( + "muted", + Muted { + user_id: Some(new_member.user.id.to_string()), + ..Default::default() + } + .into(), + Some(FindOptions::builder().limit(1).build()), + ) + .await + { + if cursor.advance().await.is_ok() { + trace!("Muted member {} rejoined the server", new_member.user.tag()); + if new_member + .add_role(&ctx.http, RoleId(data.configuration.general.mute.role)) + .await + .is_ok() + { + debug!( + "Muted member {} was successfully muted", + new_member.user.tag() + ); + } else { + error!( + "Failed to mute member {} after rejoining the server", + new_member.user.tag() + ); + } + } + } else { + error!("Failed to query database for muted users"); + } +} + pub fn queue_unmute_member( http: &Arc, database: &Arc, diff --git a/src/utils/ocr.rs b/src/utils/ocr.rs index 3b81544..521b6ab 100644 --- a/src/utils/ocr.rs +++ b/src/utils/ocr.rs @@ -5,7 +5,7 @@ pub async fn get_text_from_image_url(url: &str) -> Result { let image = &reqwest::get(url).await?.bytes().await.unwrap().to_vec(); Ok(Tesseract::new(None, None) .unwrap() - .set_image_from_mem(&image) + .set_image_from_mem(image) .unwrap() .get_text() .unwrap())