mirror of
https://github.com/arthur-pbty/shadowbot.git
synced 2026-06-05 08:11:44 +02:00
modify commands categories
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{add_sanction, parse_targets};
|
||||
|
||||
pub async fn handle_ban(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let reason = if args.len() > 1 {
|
||||
args[1..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
let mut done = 0usize;
|
||||
for uid in &targets {
|
||||
if guild_id
|
||||
.ban_with_reason(&ctx.http, *uid, 0, &reason)
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
done += 1;
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"ban",
|
||||
&reason,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Ban")
|
||||
.description(format!("{} membre(s) banni(s).", done))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct BanCommand;
|
||||
pub static COMMAND_DESCRIPTOR: BanCommand = BanCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for BanCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "ban",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> [raison]",
|
||||
summary: "Bannit un membre",
|
||||
description: "Ban un ou plusieurs membres.",
|
||||
examples: &["+ban @User"],
|
||||
default_aliases: &["b"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
|
||||
pub async fn handle_banlist(ctx: &Context, msg: &Message) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
let bans = guild_id
|
||||
.bans(&ctx.http, None, None)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
let desc = if bans.is_empty() {
|
||||
"Aucun ban en cours.".to_string()
|
||||
} else {
|
||||
bans.into_iter()
|
||||
.map(|ban| format!("- <@{}> ({})", ban.user.id.get(), ban.user.tag()))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
};
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("BanList")
|
||||
.description(desc)
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct BanlistCommand;
|
||||
pub static COMMAND_DESCRIPTOR: BanlistCommand = BanlistCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for BanlistCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "banlist",
|
||||
category: "moderation",
|
||||
params: "aucun",
|
||||
summary: "Liste les bans",
|
||||
description: "Affiche la liste des bannissements en cours.",
|
||||
examples: &["+banlist"],
|
||||
default_aliases: &["bls"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{parse_channel_id, send_embed, theme_color};
|
||||
|
||||
pub async fn handle_cleanup(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(channel_raw) = args.first() else {
|
||||
return;
|
||||
};
|
||||
let Some(channel_id) = parse_channel_id(channel_raw) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let user_ids = {
|
||||
let Some(guild) = guild_id.to_guild_cached(&ctx.cache) else {
|
||||
return;
|
||||
};
|
||||
|
||||
guild
|
||||
.voice_states
|
||||
.iter()
|
||||
.filter_map(|(uid, state)| {
|
||||
if state.channel_id == Some(channel_id) {
|
||||
Some(*uid)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
let mut kicked = 0usize;
|
||||
for user_id in user_ids {
|
||||
if guild_id.disconnect_member(&ctx.http, user_id).await.is_ok() {
|
||||
kicked += 1;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Cleanup")
|
||||
.description(format!("{} utilisateurs déconnectés.", kicked))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct CleanupCommand;
|
||||
pub static COMMAND_DESCRIPTOR: CleanupCommand = CleanupCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for CleanupCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "cleanup",
|
||||
category: "moderation",
|
||||
params: "<salon_vocal>",
|
||||
summary: "Vide un salon vocal",
|
||||
description: "Deconnecte tous les utilisateurs presents dans un salon vocal cible.",
|
||||
examples: &["+cleanup #General"],
|
||||
default_aliases: &["vclean", "vcleanup"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::db::DbPoolKey;
|
||||
|
||||
pub async fn handle_clear_all_sanctions(ctx: &Context, msg: &Message) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
let pool = {
|
||||
let data = ctx.data.read().await;
|
||||
data.get::<DbPoolKey>().cloned()
|
||||
};
|
||||
let Some(pool) = pool else {
|
||||
return;
|
||||
};
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
|
||||
let removed = sqlx::query(
|
||||
r#"
|
||||
DELETE FROM bot_sanctions
|
||||
WHERE bot_id = $1 AND guild_id = $2;
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.execute(&pool)
|
||||
.await
|
||||
.ok()
|
||||
.map(|r| r.rows_affected())
|
||||
.unwrap_or(0);
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Sanctions")
|
||||
.description(format!(
|
||||
"{} sanction(s) supprimée(s) sur le serveur.",
|
||||
removed
|
||||
))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct ClearAllSanctionsCommand;
|
||||
pub static COMMAND_DESCRIPTOR: ClearAllSanctionsCommand = ClearAllSanctionsCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for ClearAllSanctionsCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "clear_all_sanctions",
|
||||
category: "moderation",
|
||||
params: "aucun",
|
||||
summary: "Supprime toutes les sanctions du serveur",
|
||||
description: "Efface toutes les sanctions de tous les membres du serveur.",
|
||||
examples: &["+clear all sanctions"],
|
||||
default_aliases: &["casanctions"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
use serenity::builder::{CreateEmbed, GetMessages};
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::admin_common::parse_user_id;
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
|
||||
pub async fn handle_clear_messages(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Ok(mut amount) = args.first().unwrap_or(&"0").parse::<u64>() else {
|
||||
return;
|
||||
};
|
||||
if amount == 0 {
|
||||
return;
|
||||
}
|
||||
amount = amount.clamp(1, 100);
|
||||
|
||||
let filter_user = args.get(1).and_then(|raw| parse_user_id(raw));
|
||||
|
||||
let mut deleted = 0usize;
|
||||
if let Ok(messages) = msg
|
||||
.channel_id
|
||||
.messages(&ctx.http, GetMessages::new().limit(amount as u8 + 1))
|
||||
.await
|
||||
{
|
||||
for m in messages {
|
||||
if m.id == msg.id {
|
||||
continue;
|
||||
}
|
||||
if let Some(user_id) = filter_user {
|
||||
if m.author.id != user_id {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if msg.channel_id.delete_message(&ctx.http, m.id).await.is_ok() {
|
||||
deleted += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Clear")
|
||||
.description(format!("{} message(s) supprime(s).", deleted))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct ClearMessagesCommand;
|
||||
pub static COMMAND_DESCRIPTOR: ClearMessagesCommand = ClearMessagesCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for ClearMessagesCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "clear_messages",
|
||||
category: "moderation",
|
||||
params: "<nombre> [@membre/ID]",
|
||||
summary: "Supprime des messages dans le salon",
|
||||
description: "Supprime un nombre de messages, optionnellement filtres par membre.",
|
||||
examples: &["+clear 20", "+clear 20 @User"],
|
||||
default_aliases: &["purge"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::admin_common::parse_user_id;
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::db::DbPoolKey;
|
||||
|
||||
pub async fn handle_clear_sanctions(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.len() < 2 {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(target) = parse_user_id(args[1]) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let pool = {
|
||||
let data = ctx.data.read().await;
|
||||
data.get::<DbPoolKey>().cloned()
|
||||
};
|
||||
let Some(pool) = pool else {
|
||||
return;
|
||||
};
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
|
||||
let removed = sqlx::query(
|
||||
r#"
|
||||
DELETE FROM bot_sanctions
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND user_id = $3;
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.bind(target.get() as i64)
|
||||
.execute(&pool)
|
||||
.await
|
||||
.ok()
|
||||
.map(|r| r.rows_affected())
|
||||
.unwrap_or(0);
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Sanctions")
|
||||
.description(format!(
|
||||
"{} sanction(s) supprimée(s) pour <@{}>.",
|
||||
removed,
|
||||
target.get()
|
||||
))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct ClearSanctionsCommand;
|
||||
pub static COMMAND_DESCRIPTOR: ClearSanctionsCommand = ClearSanctionsCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for ClearSanctionsCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "clear_sanctions",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID>",
|
||||
summary: "Supprime toutes les sanctions d un membre",
|
||||
description: "Efface completement les sanctions d un membre cible.",
|
||||
examples: &["+clear sanctions @User"],
|
||||
default_aliases: &["csanctions"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{
|
||||
add_sanction, channel_mute_users, parse_targets,
|
||||
};
|
||||
|
||||
pub async fn handle_cmute(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let reason = if args.len() > 1 {
|
||||
args[1..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
let affected = channel_mute_users(ctx, msg.channel_id, &targets, true).await;
|
||||
|
||||
for uid in &targets {
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"cmute",
|
||||
&reason,
|
||||
Some(msg.channel_id),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("CMute")
|
||||
.description(format!("{} membre(s) cmute.", affected))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct CmuteCommand;
|
||||
pub static COMMAND_DESCRIPTOR: CmuteCommand = CmuteCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for CmuteCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "cmute",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> [raison]",
|
||||
summary: "Mute salon",
|
||||
description: "Mute un membre sur le salon courant.",
|
||||
examples: &["+cmute @User"],
|
||||
default_aliases: &["cm"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::admin_common::parse_user_id;
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::db::DbPoolKey;
|
||||
|
||||
pub async fn handle_del_sanction(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.len() < 3 {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(target) = parse_user_id(args[1]) else {
|
||||
return;
|
||||
};
|
||||
let Ok(index) = args[2].parse::<usize>() else {
|
||||
return;
|
||||
};
|
||||
if index == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let pool = {
|
||||
let data = ctx.data.read().await;
|
||||
data.get::<DbPoolKey>().cloned()
|
||||
};
|
||||
let Some(pool) = pool else {
|
||||
return;
|
||||
};
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
|
||||
let rows = sqlx::query_as::<_, (i64,)>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM bot_sanctions
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND user_id = $3
|
||||
ORDER BY created_at DESC;
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.bind(target.get() as i64)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
let Some((sanction_id,)) = rows.get(index - 1).copied() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let _ = sqlx::query(
|
||||
r#"
|
||||
DELETE FROM bot_sanctions
|
||||
WHERE id = $1 AND bot_id = $2 AND guild_id = $3;
|
||||
"#,
|
||||
)
|
||||
.bind(sanction_id)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.execute(&pool)
|
||||
.await;
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Sanctions")
|
||||
.description(format!(
|
||||
"Sanction #{} supprimée pour <@{}>.",
|
||||
sanction_id,
|
||||
target.get()
|
||||
))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct DelSanctionCommand;
|
||||
pub static COMMAND_DESCRIPTOR: DelSanctionCommand = DelSanctionCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for DelSanctionCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "del_sanction",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID> <nombre>",
|
||||
summary: "Supprime une sanction d un membre",
|
||||
description: "Supprime une sanction specifique dans l historique d un membre.",
|
||||
examples: &["+del sanction @User 1"],
|
||||
default_aliases: &["delsanction"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{add_sanction, parse_targets};
|
||||
|
||||
pub async fn handle_kick(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let reason = if args.len() > 1 {
|
||||
args[1..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
let mut done = 0usize;
|
||||
for uid in &targets {
|
||||
if guild_id
|
||||
.kick_with_reason(&ctx.http, *uid, &reason)
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
done += 1;
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"kick",
|
||||
&reason,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Kick")
|
||||
.description(format!("{} membre(s) expulse(s).", done))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct KickCommand;
|
||||
pub static COMMAND_DESCRIPTOR: KickCommand = KickCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for KickCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "kick",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> [raison]",
|
||||
summary: "Expulse un membre",
|
||||
description: "Kick un ou plusieurs membres.",
|
||||
examples: &["+kick @User"],
|
||||
default_aliases: &["k"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
use chrono::Utc;
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{add_sanction, handle_timeout, parse_targets};
|
||||
|
||||
pub async fn handle_mute(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let expires_at = Some(Utc::now() + chrono::Duration::seconds(28 * 24 * 3600));
|
||||
let reason = if args.len() > 1 {
|
||||
args[1..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
let affected = handle_timeout(ctx, guild_id, &targets, expires_at).await;
|
||||
|
||||
for uid in &targets {
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"mute",
|
||||
&reason,
|
||||
None,
|
||||
expires_at,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Mute")
|
||||
.description(format!("{} membre(s) mute.", affected))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct MuteCommand;
|
||||
pub static COMMAND_DESCRIPTOR: MuteCommand = MuteCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for MuteCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "mute",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> [raison]",
|
||||
summary: "Mute un membre",
|
||||
description: "Applique un mute a un ou plusieurs membres.",
|
||||
examples: &["+mute @User abus"],
|
||||
default_aliases: &["tmute"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
use chrono::Utc;
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::pool;
|
||||
|
||||
pub async fn handle_mutelist(ctx: &Context, msg: &Message) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
let Some(pool) = pool(ctx).await else {
|
||||
return;
|
||||
};
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
|
||||
let rows = sqlx::query_as::<_, (i64, String, Option<i64>, Option<chrono::DateTime<Utc>>)>(
|
||||
r#"
|
||||
SELECT user_id, kind, channel_id, expires_at
|
||||
FROM bot_sanctions
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND active = TRUE AND kind IN ('mute','tempmute','cmute','tempcmute')
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 60;
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
let desc = if rows.is_empty() {
|
||||
"Aucun mute en cours.".to_string()
|
||||
} else {
|
||||
rows.into_iter()
|
||||
.map(|(uid, kind, channel_id, exp)| {
|
||||
let channel = channel_id
|
||||
.map(|c| format!(" dans <#{}>", c))
|
||||
.unwrap_or_default();
|
||||
let until = exp
|
||||
.map(|d| format!(" jusqu'a <t:{}:R>", d.timestamp()))
|
||||
.unwrap_or_default();
|
||||
format!("- <@{}> `{}`{}{}", uid, kind, channel, until)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
};
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("MuteList")
|
||||
.description(desc)
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct MutelistCommand;
|
||||
pub static COMMAND_DESCRIPTOR: MutelistCommand = MutelistCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for MutelistCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "mutelist",
|
||||
category: "moderation",
|
||||
params: "aucun",
|
||||
summary: "Liste les mutes",
|
||||
description: "Affiche tous les mutes en cours.",
|
||||
examples: &["+mutelist"],
|
||||
default_aliases: &["ml"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
use serenity::builder::CreateChannel;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::parse_channel_id;
|
||||
|
||||
pub async fn handle_renew(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
let channel_id = args
|
||||
.first()
|
||||
.and_then(|raw| parse_channel_id(raw))
|
||||
.unwrap_or(msg.channel_id);
|
||||
|
||||
let Ok(channel) = channel_id.to_channel(&ctx.http).await else {
|
||||
return;
|
||||
};
|
||||
let Channel::Guild(text_channel) = channel else {
|
||||
return;
|
||||
};
|
||||
|
||||
if text_channel.kind != ChannelType::Text && text_channel.kind != ChannelType::News {
|
||||
return;
|
||||
}
|
||||
|
||||
let parent_id = text_channel.parent_id;
|
||||
let topic = text_channel.topic.clone();
|
||||
let nsfw = text_channel.nsfw;
|
||||
let slowmode = text_channel.rate_limit_per_user;
|
||||
let name = text_channel.name.clone();
|
||||
|
||||
let _ = text_channel.delete(&ctx.http).await;
|
||||
|
||||
let mut builder = CreateChannel::new(name)
|
||||
.kind(ChannelType::Text)
|
||||
.nsfw(nsfw)
|
||||
.rate_limit_per_user(slowmode.unwrap_or(0));
|
||||
|
||||
if let Some(parent) = parent_id {
|
||||
builder = builder.category(parent);
|
||||
}
|
||||
if let Some(topic) = topic {
|
||||
builder = builder.topic(topic);
|
||||
}
|
||||
|
||||
let _ = guild_id.create_channel(&ctx.http, builder).await;
|
||||
}
|
||||
|
||||
pub struct RenewCommand;
|
||||
pub static COMMAND_DESCRIPTOR: RenewCommand = RenewCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for RenewCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "renew",
|
||||
category: "moderation",
|
||||
params: "[salon]",
|
||||
summary: "Recree un salon textuel",
|
||||
description: "Supprime puis recree un salon textuel en conservant les options principales.",
|
||||
examples: &["+renew", "+renew #general"],
|
||||
default_aliases: &["nuke", "rebuildch"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
use chrono::Utc;
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::admin_common::parse_user_id;
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::db::DbPoolKey;
|
||||
|
||||
pub async fn handle_sanctions(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
let Some(target_raw) = args.first() else {
|
||||
let _ = send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Sanctions")
|
||||
.description("Usage: +sanctions <membre>")
|
||||
.color(0xED4245),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
};
|
||||
let Some(target) = parse_user_id(target_raw) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let pool = {
|
||||
let data = ctx.data.read().await;
|
||||
data.get::<DbPoolKey>().cloned()
|
||||
};
|
||||
let Some(pool) = pool else {
|
||||
return;
|
||||
};
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
|
||||
let rows = sqlx::query_as::<
|
||||
_,
|
||||
(
|
||||
i64,
|
||||
String,
|
||||
String,
|
||||
chrono::DateTime<Utc>,
|
||||
Option<chrono::DateTime<Utc>>,
|
||||
bool,
|
||||
),
|
||||
>(
|
||||
r#"
|
||||
SELECT id, kind, reason, created_at, expires_at, active
|
||||
FROM bot_sanctions
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND user_id = $3
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 30;
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.bind(target.get() as i64)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
let desc = if rows.is_empty() {
|
||||
"Aucune sanction.".to_string()
|
||||
} else {
|
||||
rows.into_iter()
|
||||
.map(|(id, kind, reason, created_at, expires_at, active)| {
|
||||
let until = expires_at
|
||||
.map(|d| format!(" · jusqu'à <t:{}:R>", d.timestamp()))
|
||||
.unwrap_or_default();
|
||||
format!(
|
||||
"`#{}` `{}` {} · <t:{}:R>{} · {}",
|
||||
id,
|
||||
kind,
|
||||
if active { "(active)" } else { "(inactive)" },
|
||||
created_at.timestamp(),
|
||||
until,
|
||||
reason
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
};
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title(format!("Sanctions de <@{}>", target.get()))
|
||||
.description(desc)
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct SanctionsCommand;
|
||||
pub static COMMAND_DESCRIPTOR: SanctionsCommand = SanctionsCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for SanctionsCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "sanctions",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID>",
|
||||
summary: "Affiche les sanctions d un membre",
|
||||
description: "Liste l historique des sanctions d un membre.",
|
||||
examples: &["+sanctions @User"],
|
||||
default_aliases: &["sanct"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
use chrono::Utc;
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{
|
||||
add_sanction, duration_from_input, parse_targets,
|
||||
};
|
||||
|
||||
pub async fn handle_tempban(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(duration_raw) = args.get(1) else {
|
||||
return;
|
||||
};
|
||||
let Some(duration) = duration_from_input(duration_raw) else {
|
||||
return;
|
||||
};
|
||||
let expires_at = Some(Utc::now() + chrono::Duration::seconds(duration.as_secs() as i64));
|
||||
|
||||
let reason = if args.len() > 2 {
|
||||
args[2..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
let mut done = 0usize;
|
||||
for uid in &targets {
|
||||
if guild_id
|
||||
.ban_with_reason(&ctx.http, *uid, 0, &reason)
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
done += 1;
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"tempban",
|
||||
&reason,
|
||||
None,
|
||||
expires_at,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("TempBan")
|
||||
.description(format!("{} membre(s) banni(s).", done))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct TempbanCommand;
|
||||
pub static COMMAND_DESCRIPTOR: TempbanCommand = TempbanCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for TempbanCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "tempban",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> <duree> [raison]",
|
||||
summary: "Ban temporaire",
|
||||
description: "Ban temporairement un ou plusieurs membres.",
|
||||
examples: &["+tempban @User 1d"],
|
||||
default_aliases: &["tb"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
use chrono::Utc;
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{
|
||||
add_sanction, channel_mute_users, duration_from_input, parse_targets,
|
||||
};
|
||||
|
||||
pub async fn handle_tempcmute(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(duration_raw) = args.get(1) else {
|
||||
return;
|
||||
};
|
||||
let Some(duration) = duration_from_input(duration_raw) else {
|
||||
return;
|
||||
};
|
||||
let expires_at = Some(Utc::now() + chrono::Duration::seconds(duration.as_secs() as i64));
|
||||
|
||||
let reason = if args.len() > 2 {
|
||||
args[2..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
let affected = channel_mute_users(ctx, msg.channel_id, &targets, true).await;
|
||||
|
||||
for uid in &targets {
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"tempcmute",
|
||||
&reason,
|
||||
Some(msg.channel_id),
|
||||
expires_at,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("TempCMute")
|
||||
.description(format!("{} membre(s) cmute.", affected))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct TempcmuteCommand;
|
||||
pub static COMMAND_DESCRIPTOR: TempcmuteCommand = TempcmuteCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for TempcmuteCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "tempcmute",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> <duree> [raison]",
|
||||
summary: "Mute salon temporaire",
|
||||
description: "Mute temporaire sur le salon courant.",
|
||||
examples: &["+tempcmute @User 5m"],
|
||||
default_aliases: &["tcm"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
use chrono::Utc;
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{
|
||||
add_sanction, duration_from_input, handle_timeout, parse_targets,
|
||||
};
|
||||
|
||||
pub async fn handle_tempmute(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(duration_raw) = args.get(1) else {
|
||||
return;
|
||||
};
|
||||
let Some(duration) = duration_from_input(duration_raw) else {
|
||||
return;
|
||||
};
|
||||
let expires_at = Some(Utc::now() + chrono::Duration::seconds(duration.as_secs() as i64));
|
||||
|
||||
let reason = if args.len() > 2 {
|
||||
args[2..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
let affected = handle_timeout(ctx, guild_id, &targets, expires_at).await;
|
||||
|
||||
for uid in &targets {
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"tempmute",
|
||||
&reason,
|
||||
None,
|
||||
expires_at,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("TempMute")
|
||||
.description(format!("{} membre(s) mute.", affected))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct TempmuteCommand;
|
||||
pub static COMMAND_DESCRIPTOR: TempmuteCommand = TempmuteCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for TempmuteCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "tempmute",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> <duree> [raison]",
|
||||
summary: "Mute temporaire",
|
||||
description: "Mute un ou plusieurs membres pour une duree donnee.",
|
||||
examples: &["+tempmute @User 10m"],
|
||||
default_aliases: &["tm"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::parse_targets;
|
||||
|
||||
pub async fn handle_unban(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut done = 0usize;
|
||||
for uid in &targets {
|
||||
if guild_id.unban(&ctx.http, *uid).await.is_ok() {
|
||||
done += 1;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("UnBan")
|
||||
.description(format!("{} membre(s) unban.", done))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct UnbanCommand;
|
||||
pub static COMMAND_DESCRIPTOR: UnbanCommand = UnbanCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for UnbanCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "unban",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]>",
|
||||
summary: "Retire un ban",
|
||||
description: "Unban un ou plusieurs membres.",
|
||||
examples: &["+unban @User"],
|
||||
default_aliases: &["ub"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
|
||||
pub async fn handle_unbanall(ctx: &Context, msg: &Message, _args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
let bans = guild_id
|
||||
.bans(&ctx.http, None, None)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut unbanned = 0usize;
|
||||
for ban in bans {
|
||||
if guild_id.unban(&ctx.http, ban.user.id).await.is_ok() {
|
||||
unbanned += 1;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("UnbanAll")
|
||||
.description(format!("{} bannissements retirés.", unbanned))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct UnbanAllCommand;
|
||||
pub static COMMAND_DESCRIPTOR: UnbanAllCommand = UnbanAllCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for UnbanAllCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "unbanall",
|
||||
category: "moderation",
|
||||
params: "aucun",
|
||||
summary: "Retire tous les bannissements",
|
||||
description: "Supprime tous les bans du serveur cible.",
|
||||
examples: &["+unbanall"],
|
||||
default_aliases: &["uball", "clearbans"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{channel_mute_users, parse_targets, pool};
|
||||
|
||||
pub async fn handle_uncmute(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let affected = channel_mute_users(ctx, msg.channel_id, &targets, false).await;
|
||||
|
||||
if let Some(pool) = pool(ctx).await {
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
for uid in &targets {
|
||||
let _ = sqlx::query(
|
||||
r#"
|
||||
UPDATE bot_sanctions
|
||||
SET active = FALSE
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND user_id = $3 AND active = TRUE AND kind IN ('cmute','tempcmute') AND channel_id = $4;
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.bind(uid.get() as i64)
|
||||
.bind(msg.channel_id.get() as i64)
|
||||
.execute(&pool)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("UnCMute")
|
||||
.description(format!("{} membre(s) uncmute.", affected))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct UncmuteCommand;
|
||||
pub static COMMAND_DESCRIPTOR: UncmuteCommand = UncmuteCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for UncmuteCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "uncmute",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]>",
|
||||
summary: "Retire un cmute",
|
||||
description: "Met fin au mute salon.",
|
||||
examples: &["+uncmute @User"],
|
||||
default_aliases: &["ucm"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{handle_timeout, parse_targets, pool};
|
||||
|
||||
pub async fn handle_unmute(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let affected = handle_timeout(ctx, guild_id, &targets, None).await;
|
||||
|
||||
if let Some(pool) = pool(ctx).await {
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
for uid in &targets {
|
||||
let _ = sqlx::query(
|
||||
r#"
|
||||
UPDATE bot_sanctions
|
||||
SET active = FALSE
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND user_id = $3 AND active = TRUE AND kind IN ('mute','tempmute');
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.bind(uid.get() as i64)
|
||||
.execute(&pool)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("UnMute")
|
||||
.description(format!("{} membre(s) unmute.", affected))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct UnmuteCommand;
|
||||
pub static COMMAND_DESCRIPTOR: UnmuteCommand = UnmuteCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for UnmuteCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "unmute",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]>",
|
||||
summary: "Retire un mute",
|
||||
description: "Met fin au mute d un ou plusieurs membres.",
|
||||
examples: &["+unmute @User"],
|
||||
default_aliases: &["um"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{channel_mute_users, handle_timeout, pool};
|
||||
|
||||
pub async fn handle_unmuteall(ctx: &Context, msg: &Message) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(pool) = pool(ctx).await else {
|
||||
return;
|
||||
};
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
|
||||
let rows = sqlx::query_as::<_, (i64, String, Option<i64>)>(
|
||||
r#"
|
||||
SELECT user_id, kind, channel_id
|
||||
FROM bot_sanctions
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND active = TRUE AND kind IN ('mute','tempmute','cmute','tempcmute');
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut changed = 0usize;
|
||||
for (uid, kind, channel_id) in rows {
|
||||
let user_id = UserId::new(uid as u64);
|
||||
if kind == "mute" || kind == "tempmute" {
|
||||
changed += handle_timeout(ctx, guild_id, &[user_id], None).await;
|
||||
} else if let Some(cid) = channel_id {
|
||||
changed += channel_mute_users(ctx, ChannelId::new(cid as u64), &[user_id], false).await;
|
||||
}
|
||||
}
|
||||
|
||||
let _ = sqlx::query(
|
||||
r#"
|
||||
UPDATE bot_sanctions
|
||||
SET active = FALSE
|
||||
WHERE bot_id = $1 AND guild_id = $2 AND active = TRUE AND kind IN ('mute','tempmute','cmute','tempcmute');
|
||||
"#,
|
||||
)
|
||||
.bind(bot_id.get() as i64)
|
||||
.bind(guild_id.get() as i64)
|
||||
.execute(&pool)
|
||||
.await;
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("UnMuteAll")
|
||||
.description(format!(
|
||||
"{} operation(s) de unmute/cmute annule(es).",
|
||||
changed
|
||||
))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct UnmuteallCommand;
|
||||
pub static COMMAND_DESCRIPTOR: UnmuteallCommand = UnmuteallCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for UnmuteallCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "unmuteall",
|
||||
category: "moderation",
|
||||
params: "aucun",
|
||||
summary: "Retire tous les mutes",
|
||||
description: "Supprime tous les mutes en cours.",
|
||||
examples: &["+unmuteall"],
|
||||
default_aliases: &["uma"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
use crate::commands::moderation_sanction_helpers::{add_sanction, parse_targets};
|
||||
|
||||
pub async fn handle_warn(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
};
|
||||
if args.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let targets = parse_targets(args[0]).await;
|
||||
if targets.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let reason = if args.len() > 1 {
|
||||
args[1..].join(" ")
|
||||
} else {
|
||||
"Aucune raison".to_string()
|
||||
};
|
||||
|
||||
for uid in &targets {
|
||||
add_sanction(
|
||||
ctx,
|
||||
guild_id,
|
||||
*uid,
|
||||
msg.author.id,
|
||||
"warn",
|
||||
&reason,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
send_embed(
|
||||
ctx,
|
||||
msg,
|
||||
CreateEmbed::new()
|
||||
.title("Warn")
|
||||
.description(format!("{} membre(s) warn.", targets.len()))
|
||||
.color(theme_color(ctx).await),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub struct WarnCommand;
|
||||
pub static COMMAND_DESCRIPTOR: WarnCommand = WarnCommand;
|
||||
impl crate::commands::command_contract::CommandSpec for WarnCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "warn",
|
||||
category: "moderation",
|
||||
params: "<@membre/ID[,..]> [raison]",
|
||||
summary: "Donne un warn",
|
||||
description: "Ajoute un warn a un ou plusieurs membres.",
|
||||
examples: &["+warn @User spam"],
|
||||
default_aliases: &["avert"],
|
||||
default_permission: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user