Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

feat: permanently mute when no duration is specified #44

Merged
merged 4 commits into from Dec 19, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 37 additions & 42 deletions src/commands/moderation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -236,7 +230,11 @@ pub async fn mute(
.unwrap();
}

This conversation was marked as resolved.
Show resolved Hide resolved
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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -312,32 +310,30 @@ 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 {
warn!("Could not disconnect member from voice channel: {}", e);
}
}

let duration = unmute_time.map(|time| format!("<t:{}:F>", time));

respond_moderation(
&ctx,
&ModerationKind::Mute(
member.user,
author.clone(),
reason,
format!("<t:{}:F>", unmute_time.timestamp()),
result,
),
&ModerationKind::Mute(member.user, author.clone(), reason, duration, result),
configuration,
)
.await
Expand Down Expand Up @@ -450,10 +446,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(),
)
})
Expand Down Expand Up @@ -496,4 +491,4 @@ async fn handle_ban(ctx: &Context<'_>, kind: &BanKind) -> Result<(), Error> {
&data.configuration,
)
.await
}
}
4 changes: 2 additions & 2 deletions src/events/ready.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<u64>().unwrap();
let member_id = current.user_id.unwrap().parse::<u64>().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,
Expand Down
77 changes: 39 additions & 38 deletions src/utils/moderation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ use crate::serenity::SerenityError;
use crate::{Context, Error};

pub enum ModerationKind {
Mute(User, User, String, String, Option<Error>), // User, Command author, Reason, Expires, Error
Unmute(User, User, Option<Error>), // User, Command author, Error
Ban(User, User, Option<String>, Option<SerenityError>), // User, Command author, Reason, Error
Unban(User, User, Option<SerenityError>), // User, Command author, Error
Lock(GuildChannel, User, Option<Error>), // Channel name, Command author, Error
Unlock(GuildChannel, User, Option<Error>), // Channel name, Command author, Error
Mute(User, User, String, Option<String>, Option<Error>), // User, Command author, Reason, Expires, Error
Unmute(User, User, Option<Error>), // User, Command author, Error
Ban(User, User, Option<String>, Option<SerenityError>), // User, Command author, Reason, Error
Unban(User, User, Option<SerenityError>), // User, Command author, Error
Lock(GuildChannel, User, Option<Error>), // Channel name, Command author, Error
Unlock(GuildChannel, User, Option<Error>), // Channel name, Command author, Error
}
pub enum BanKind {
Ban(User, Option<u8>, Option<String>), // User, Amount of days to delete messages, Reason
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand All @@ -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) => {
Expand All @@ -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)
Expand All @@ -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 {
Expand All @@ -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
Expand Down