diff --git a/src/commands/moderation.rs b/src/commands/moderation.rs index a5e0fc5..771308e 100644 --- a/src/commands/moderation.rs +++ b/src/commands/moderation.rs @@ -2,23 +2,14 @@ use bson::{doc, Document}; use chrono::{Duration, Utc}; use mongodb::options::{UpdateModifications, UpdateOptions}; use poise::serenity_prelude::{ - self as serenity, - Member, - PermissionOverwrite, - Permissions, - RoleId, - User, Mentionable, + self as serenity, Member, Mentionable, PermissionOverwrite, Permissions, RoleId, User, }; use tracing::log::error; -use tracing::{debug, warn, trace}; +use tracing::{debug, trace, warn}; use crate::db::model::{LockedChannel, Muted}; use crate::utils::moderation::{ - ban_moderation, - queue_unmute_member, - respond_moderation, - BanKind, - ModerationKind, + ban_moderation, queue_unmute_member, respond_moderation, BanKind, ModerationKind, }; use crate::{Context, Error}; @@ -97,11 +88,14 @@ pub async fn lock(ctx: Context<'_>) -> Result<(), Error> { let permission = Permissions::SEND_MESSAGES & Permissions::ADD_REACTIONS; if let Err(err) = channel - .create_permission(http, &PermissionOverwrite { - allow: permission_overwrite.allow & !permission, - deny: permission_overwrite.deny | permission, - kind: permission_overwrite.kind, - }) + .create_permission( + http, + &PermissionOverwrite { + allow: permission_overwrite.allow & !permission, + deny: permission_overwrite.deny | permission, + kind: permission_overwrite.kind, + }, + ) .await { error!("Failed to create the new permission: {:?}", err); @@ -143,7 +137,7 @@ pub async fn unlock(ctx: Context<'_>) -> Result<(), Error> { let channel = cache.guild_channel(channel_id).unwrap(); let author = ctx.author(); - + let mut error = None; if let Ok(Some(locked_channel)) = delete_result { for overwrite in &locked_channel.overwrites.unwrap() { @@ -236,7 +230,11 @@ pub async fn mute( .unwrap(); } - let unmute_time = now + mute_duration; + let unmute_time = if !mute_duration.is_zero() { + Some((now + mute_duration).timestamp() as u64) + } else { + None + }; let data = &mut *ctx.data().write().await; let configuration = &data.configuration; @@ -272,7 +270,7 @@ pub async fn mute( // Roles which were removed from the user let updated: Document = Muted { guild_id: Some(member.guild_id.0.to_string()), - expires: Some(unmute_time.timestamp() as u64), + expires: unmute_time, reason: Some(reason.clone()), taken_roles: if is_currently_muted { // Prevent the bot from overriding the "take" field. @@ -301,6 +299,20 @@ pub async fn mute( .await { Some(database_update_result) + } else if unmute_time.is_none() { + data.database + .update::( + "muted", + Muted { + user_id: Some(member.user.id.0.to_string()), + ..Default::default() + } + .into(), + UpdateModifications::Document(doc! { "$unset": { "expires": "" } }), + None, + ) + .await + .err() } else { None } @@ -312,16 +324,18 @@ pub async fn mute( pending_unmute.abort(); } - data.pending_unmutes.insert( - member.user.id.0, - queue_unmute_member( - &ctx.discord().http, - &data.database, - &member, - mute_role_id, - mute_duration.num_seconds() as u64, - ), - ); + if let Some(mute_duration) = unmute_time { + data.pending_unmutes.insert( + member.user.id.0, + queue_unmute_member( + &ctx.discord().http, + &data.database, + &member, + mute_role_id, + mute_duration, + ), + ); + } if result.is_none() { if let Err(e) = member.disconnect_from_voice(&ctx.discord().http).await { @@ -329,15 +343,11 @@ pub async fn mute( } } + let duration = unmute_time.map(|time| format!("", time)); + respond_moderation( &ctx, - &ModerationKind::Mute( - member.user, - author.clone(), - reason, - format!("", unmute_time.timestamp()), - result, - ), + &ModerationKind::Mute(member.user, author.clone(), reason, duration, result), configuration, ) .await @@ -450,10 +460,9 @@ pub async fn purge( .color(embed_color) .thumbnail(&image) .footer(|f| { - f.text("ReVanced"); - f.icon_url(image) - } - ) + f.text("ReVanced"); + f.icon_url(image) + }) .clone(), ) }) @@ -496,4 +505,4 @@ async fn handle_ban(ctx: &Context<'_>, kind: &BanKind) -> Result<(), Error> { &data.configuration, ) .await -} \ No newline at end of file +} diff --git a/src/events/ready.rs b/src/events/ready.rs index 47d8019..0e7de57 100644 --- a/src/events/ready.rs +++ b/src/events/ready.rs @@ -28,13 +28,13 @@ pub async fn load_muted_members(ctx: &serenity::Context, _: &serenity::Ready) { while cursor.advance().await.unwrap() { let current: Muted = cursor.deserialize_current().unwrap(); + let Some(expires) = current.expires else { continue }; let guild_id = current.guild_id.unwrap().parse::().unwrap(); let member_id = current.user_id.unwrap().parse::().unwrap(); if let Ok(guild) = http_ref.get_guild(guild_id).await { if let Ok(member) = guild.member(http_ref, member_id).await { - let amount_left = - std::cmp::max(current.expires.unwrap() as i64 - Utc::now().timestamp(), 0); + let amount_left = std::cmp::max(expires as i64 - Utc::now().timestamp(), 0); data.pending_unmutes.insert( member.user.id.0, diff --git a/src/utils/moderation.rs b/src/utils/moderation.rs index b171580..c61dc4f 100644 --- a/src/utils/moderation.rs +++ b/src/utils/moderation.rs @@ -15,12 +15,12 @@ use crate::serenity::SerenityError; use crate::{Context, Error}; pub enum ModerationKind { - Mute(User, User, String, String, Option), // User, Command author, Reason, Expires, Error - Unmute(User, User, Option), // User, Command author, Error - Ban(User, User, Option, Option), // User, Command author, Reason, Error - Unban(User, User, Option), // User, Command author, Error - Lock(GuildChannel, User, Option), // Channel name, Command author, Error - Unlock(GuildChannel, User, Option), // Channel name, Command author, Error + Mute(User, User, String, Option, Option), // User, Command author, Reason, Expires, Error + Unmute(User, User, Option), // User, Command author, Error + Ban(User, User, Option, Option), // User, Command author, Reason, Error + Unban(User, User, Option), // User, Command author, Error + Lock(GuildChannel, User, Option), // Channel name, Command author, Error + Unlock(GuildChannel, User, Option), // Channel name, Command author, Error } pub enum BanKind { Ban(User, Option, Option), // User, Amount of days to delete messages, Reason @@ -134,7 +134,7 @@ pub async fn respond_moderation<'a>( ModerationKind::Mute(user, author, reason, expires, error) => { moderated_user = Some(user); - match error { + let embed = match error { Some(err) => f .title(format!("Failed to mute {}", user.tag())) .field("Exception", err.to_string(), false) @@ -147,16 +147,19 @@ pub async fn respond_moderation<'a>( ), false, ), - None => f - .title(format!("Muted {}", user.tag())) - .field( - "Action", - format!("{} was muted by {}", user.mention(), author.mention()), - false, - ), + None => f.title(format!("Muted {}", user.tag())).field( + "Action", + format!("{} was muted by {}", user.mention(), author.mention()), + false, + ), + } + .field("Reason", reason, true); + + // add expiration date to embed if mute has a duration + if let Some(expire) = expires { + embed.field("Expires", expire, true); } - .field("Reason", reason, true) - .field("Expires", expires, true) + embed }, ModerationKind::Unmute(user, author, error) => { moderated_user = Some(user); @@ -173,13 +176,11 @@ pub async fn respond_moderation<'a>( ), false, ), - None => f - .title(format!("Unmuted {}", user.tag())) - .field( - "Action", - format!("{} was unmuted by {}", user.mention(), author.mention()), - false, - ), + None => f.title(format!("Unmuted {}", user.tag())).field( + "Action", + format!("{} was unmuted by {}", user.mention(), author.mention()), + false, + ), } }, ModerationKind::Ban(user, author, reason, error) => { @@ -197,13 +198,11 @@ pub async fn respond_moderation<'a>( ), false, ), - None => f - .title(format!("Banned {}", user.tag())) - .field( - "Action", - format!("{} was banned by {}", user.mention(), author.mention()), - false, - ), + None => f.title(format!("Banned {}", user.tag())).field( + "Action", + format!("{} was banned by {}", user.mention(), author.mention()), + false, + ), }; if let Some(reason) = reason { f.field("Reason", reason, true) @@ -226,13 +225,11 @@ pub async fn respond_moderation<'a>( ), false, ), - None => f - .title(format!("Unbanned {}", user.tag())) - .field( - "Action", - format!("{} was unbanned by {}", user.mention(), author.mention()), - false, - ), + None => f.title(format!("Unbanned {}", user.tag())).field( + "Action", + format!("{} was unbanned by {}", user.mention(), author.mention()), + false, + ), } }, ModerationKind::Lock(channel, author, error) => match error { @@ -241,7 +238,11 @@ pub async fn respond_moderation<'a>( .field("Exception", err.to_string(), false) .field( "Action", - format!("{} was locked by {} but failed", channel.mention(), author.mention()), + format!( + "{} was locked by {} but failed", + channel.mention(), + author.mention() + ), false, ), None => f