netoyage des commands

This commit is contained in:
Puechberty Arthur
2026-04-10 16:41:03 +02:00
parent 1b5e51c428
commit 9a47588cdf
45 changed files with 1381 additions and 710 deletions
+1 -1
View File
@@ -1177,7 +1177,7 @@ pub async fn handle_modal_interaction(ctx: &Context, modal: &ModalInteraction) -
)) ))
.color(theme_color(ctx).await) .color(theme_color(ctx).await)
.footer(CreateEmbedFooter::new( .footer(CreateEmbedFooter::new(
"Utilise +end giveaway <ID> pour terminer", "Utilise +endgiveaway <ID> pour terminer",
)); ));
let _ = modal let _ = modal
+1 -1
View File
@@ -594,7 +594,7 @@ pub async fn public_command_allowed(
.title("Commandes publiques desactivees") .title("Commandes publiques desactivees")
.description(format!( .description(format!(
"La commande `{}` est desactivee dans ce salon.", "La commande `{}` est desactivee dans ce salon.",
command_key.replace('_', " ") command_key.replace('_', "")
)) ))
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
+1 -1
View File
@@ -38,7 +38,7 @@ impl crate::commands::command_contract::CommandSpec for RemoveActivityCommand {
category: "botconfig", category: "botconfig",
params: "aucun", params: "aucun",
description: "Arrete la rotation d activite et retire lactivite courante du bot.", description: "Arrete la rotation d activite et retire lactivite courante du bot.",
examples: &["+remove activity", "+ry", "+help remove activity"], examples: &["+removeactivity", "+ry", "+help removeactivity"],
default_aliases: &["rma"], default_aliases: &["rma"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 7, default_permission: 7,
+47
View File
@@ -0,0 +1,47 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::activity::stop_rotation;
use crate::commands::common::send_embed;
use crate::db::DbPoolKey;
pub async fn handle_remove_activity(ctx: &Context, msg: &Message) {
stop_rotation(ctx).await;
ctx.set_activity(None);
let bot_id = ctx.cache.current_user().id;
let pool = {
let data = ctx.data.read().await;
data.get::<DbPoolKey>().cloned()
};
if let Some(pool) = pool {
let _ = crate::db::clear_bot_activity(&pool, bot_id).await;
}
let embed = CreateEmbed::new()
.title("Activité supprimée")
.description("L'activité du bot a été retirée.")
.color(0x57F287);
send_embed(ctx, msg, embed).await;
}
pub struct RemoveActivityCommand;
pub static COMMAND_DESCRIPTOR: RemoveActivityCommand = RemoveActivityCommand;
impl crate::commands::command_contract::CommandSpec for RemoveActivityCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "removeactivity",
category: "botconfig",
params: "aucun",
description: "Arrete la rotation d activite et retire lactivite courante du bot.",
examples: &["+removeactivity", "+ry", "+help removeactivity"],
default_aliases: &["rma"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ async fn handle_set_perm(ctx: &Context, msg: &Message, args: &[&str]) {
if args.len() < 3 || !args[0].eq_ignore_ascii_case("perm") { if args.len() < 3 || !args[0].eq_ignore_ascii_case("perm") {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Usage: `set perm <permission/commande> <role/membre>`") .description("Usage: `+setperm <permission/commande> <role/membre>`")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
return; return;
+1 -1
View File
@@ -1507,7 +1507,7 @@ impl crate::commands::command_contract::CommandSpec for TempvocCommand {
category: "channel", category: "channel",
params: "[cmd]", params: "[cmd]",
description: "Affiche le menu de configuration du systeme de vocaux temporaires.", description: "Affiche le menu de configuration du systeme de vocaux temporaires.",
examples: &["+tempvoc", "+tempvoc cmd", "+help tempvoc"], examples: &["+tempvoc", "+tempvoccmd", "+help tempvoc"],
default_aliases: &[], default_aliases: &[],
allow_in_dm: false, allow_in_dm: false,
default_permission: 5, default_permission: 5,
+2 -2
View File
@@ -9,7 +9,7 @@ use crate::commands::common::send_embed;
pub async fn handle_tempvoc_cmd(ctx: &Context, msg: &Message, _args: &[&str]) { pub async fn handle_tempvoc_cmd(ctx: &Context, msg: &Message, _args: &[&str]) {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Commandes Tempvoc") .title("Commandes Tempvoc")
.description("\n+tempvoc\n+tempvoc cmd\n\nLe salon de création est surveillé automatiquement: lorsqu'un membre le rejoint, un vocal temporaire est créé et l'utilisateur y est déplacé.") .description("\n+tempvoc\n+tempvoccmd\n\nLe salon de création est surveillé automatiquement: lorsqu'un membre le rejoint, un vocal temporaire est créé et l'utilisateur y est déplacé.")
.colour(Colour::from_rgb(100, 180, 255)) .colour(Colour::from_rgb(100, 180, 255))
.timestamp(Utc::now()); .timestamp(Utc::now());
@@ -26,7 +26,7 @@ impl crate::commands::command_contract::CommandSpec for TempvocCmdCommand {
category: "channel", category: "channel",
params: "aucun", params: "aucun",
description: "Affiche un rappel des commandes et du fonctionnement de tempvoc.", description: "Affiche un rappel des commandes et du fonctionnement de tempvoc.",
examples: &["+tempvoc cmd", "+help tempvoc_cmd"], examples: &["+tempvoccmd", "+help tempvoc_cmd"],
default_aliases: &[], default_aliases: &[],
allow_in_dm: false, allow_in_dm: false,
default_permission: 0, default_permission: 0,
+35
View File
@@ -0,0 +1,35 @@
use chrono::Utc;
use serenity::builder::CreateEmbed;
use serenity::model::Colour;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::send_embed;
pub async fn handle_tempvoc_cmd(ctx: &Context, msg: &Message, _args: &[&str]) {
let embed = CreateEmbed::new()
.title("Commandes Tempvoc")
.description("\n+tempvoc\n+tempvoccmd\n\nLe salon de création est surveillé automatiquement: lorsqu'un membre le rejoint, un vocal temporaire est créé et l'utilisateur y est déplacé.")
.colour(Colour::from_rgb(100, 180, 255))
.timestamp(Utc::now());
send_embed(ctx, msg, embed).await;
}
pub struct TempvocCmdCommand;
pub static COMMAND_DESCRIPTOR: TempvocCmdCommand = TempvocCmdCommand;
impl crate::commands::command_contract::CommandSpec for TempvocCmdCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "tempvoccmd",
category: "channel",
params: "aucun",
description: "Affiche un rappel des commandes et du fonctionnement de tempvoc.",
examples: &["+tempvoccmd", "+help tempvoccmd"],
default_aliases: &[],
allow_in_dm: false,
default_permission: 0,
}
}
}
+3 -3
View File
@@ -22,7 +22,7 @@ pub async fn handle_leave_settings(ctx: &Context, msg: &Message, args: &[&str])
msg, msg,
CreateEmbed::new() CreateEmbed::new()
.title("leave settings") .title("leave settings")
.description("Usage: +leave settings [on/off] [salon] [message...]") .description("Usage: +leavesettings [on/off] [salon] [message...]")
.color(0xED4245), .color(0xED4245),
) )
.await; .await;
@@ -131,8 +131,8 @@ impl crate::commands::command_contract::CommandSpec for LeaveSettingsCommand {
params: "settings [on/off] [salon] [message]", params: "settings [on/off] [salon] [message]",
description: "Configure les actions a executer quand un membre quitte le serveur.", description: "Configure les actions a executer quand un membre quitte le serveur.",
examples: &[ examples: &[
"+leave settings", "+leavesettings",
"+leave settings on #logs {user} a quitte", "+leavesettings on #logs {user} a quitte",
], ],
default_aliases: &["lset"], default_aliases: &["lset"],
allow_in_dm: false, allow_in_dm: false,
+142
View File
@@ -0,0 +1,142 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use serenity::builder::CreateEmbed;
use crate::commands::common::{send_embed, theme_color};
use crate::commands::logs_command_helpers::{parse_target_channel, pool};
pub async fn handle_leave_settings(ctx: &Context, msg: &Message, args: &[&str]) {
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;
if args.is_empty() || !args[0].eq_ignore_ascii_case("settings") {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("leave settings")
.description("Usage: +leavesettings [on/off] [salon] [message...]")
.color(0xED4245),
)
.await;
return;
}
if args.len() == 1 {
let row = sqlx::query_as::<_, (bool, Option<i64>, Option<String>)>(
r#"
SELECT enabled, channel_id, custom_message
FROM bot_join_leave_settings
WHERE bot_id = $1 AND guild_id = $2 AND kind = $3
LIMIT 1;
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind("leave")
.fetch_optional(&pool)
.await
.ok()
.flatten();
let desc = if let Some((enabled, channel_id, custom_message)) = row {
format!(
"Etat: {}\nSalon: {}\nMessage: {}",
if enabled { "on" } else { "off" },
channel_id
.map(|id| format!("<#{}>", id))
.unwrap_or_else(|| "non defini".to_string()),
custom_message.unwrap_or_else(|| "(defaut)".to_string())
)
} else {
"Aucun reglage configure.".to_string()
};
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("leave settings")
.description(desc)
.color(theme_color(ctx).await),
)
.await;
return;
}
let action = args[1].to_lowercase();
let enabled = action == "on";
let channel = if enabled {
parse_target_channel(msg, args, 2)
} else {
None
};
let message_start = if enabled { 3 } else { 2 };
let custom_message = if args.len() > message_start {
Some(args[message_start..].join(" "))
} else {
None
};
let _ = sqlx::query(
r#"
INSERT INTO bot_join_leave_settings (bot_id, guild_id, kind, enabled, channel_id, custom_message)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (bot_id, guild_id, kind)
DO UPDATE SET enabled = EXCLUDED.enabled, channel_id = EXCLUDED.channel_id,
custom_message = EXCLUDED.custom_message, updated_at = NOW();
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind("leave")
.bind(enabled)
.bind(channel.map(|c| c.get() as i64))
.bind(custom_message)
.execute(&pool)
.await;
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("leave settings")
.description(format!(
"{} {}",
if enabled { "Active" } else { "Desactive" },
channel
.map(|c| format!("dans <#{}>", c.get()))
.unwrap_or_default()
))
.color(theme_color(ctx).await),
)
.await;
}
pub struct LeaveSettingsCommand;
pub static COMMAND_DESCRIPTOR: LeaveSettingsCommand = LeaveSettingsCommand;
impl crate::commands::command_contract::CommandSpec for LeaveSettingsCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "leavesettings",
category: "config",
params: "settings [on/off] [salon] [message]",
description: "Configure les actions a executer quand un membre quitte le serveur.",
examples: &[
"+leavesettings",
"+leavesettings on #logs {user} a quitte",
],
default_aliases: &["lset"],
allow_in_dm: false,
default_permission: 5,
}
}
}
+3 -3
View File
@@ -15,7 +15,7 @@ pub async fn handle_set_boostembed(ctx: &Context, msg: &Message, args: &[&str])
msg, msg,
CreateEmbed::new() CreateEmbed::new()
.title("Set BoostEmbed") .title("Set BoostEmbed")
.description("Usage: +set boostembed <title|description|color> <valeur>") .description("Usage: +setboostembed <title|description|color> <valeur>")
.color(0xED4245), .color(0xED4245),
) )
.await; .await;
@@ -104,8 +104,8 @@ impl crate::commands::command_contract::CommandSpec for SetBoostembedCommand {
params: "<title|description|color> <valeur>", params: "<title|description|color> <valeur>",
description: "Configure le titre, la description et la couleur de l embed boost.", description: "Configure le titre, la description et la couleur de l embed boost.",
examples: &[ examples: &[
"+set boostembed title Merci", "+setboostembed title Merci",
"+set boostembed color #FF66CC", "+setboostembed color #FF66CC",
], ],
default_aliases: &["sboostembed"], default_aliases: &["sboostembed"],
allow_in_dm: false, allow_in_dm: false,
+2 -2
View File
@@ -98,7 +98,7 @@ pub async fn handle_set_modlogs(ctx: &Context, msg: &Message, args: &[&str]) {
CreateEmbed::new() CreateEmbed::new()
.title("Set ModLogs") .title("Set ModLogs")
.description(format!( .description(format!(
"Evenements actifs:\n{}\n\nUsage: +set modlogs <event> <on/off>", "Evenements actifs:\n{}\n\nUsage: +setmodlogs <event> <on/off>",
events.iter().cloned().collect::<Vec<_>>().join(", ") events.iter().cloned().collect::<Vec<_>>().join(", ")
)) ))
.color(theme_color(ctx).await), .color(theme_color(ctx).await),
@@ -116,7 +116,7 @@ impl crate::commands::command_contract::CommandSpec for SetModlogsCommand {
category: "config", category: "config",
params: "[event on/off]", params: "[event on/off]",
description: "Affiche ou modifie les evenements qui apparaissent dans les logs de moderation.", description: "Affiche ou modifie les evenements qui apparaissent dans les logs de moderation.",
examples: &["+set modlogs", "+set modlogs warn off"], examples: &["+setmodlogs", "+setmodlogs warn off"],
default_aliases: &["smodlog"], default_aliases: &["smodlog"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 6, default_permission: 6,
+115
View File
@@ -0,0 +1,115 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::{send_embed, theme_color};
use crate::commands::logs_command_helpers::pool;
pub async fn handle_set_boostembed(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
if args.len() < 2 {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Set BoostEmbed")
.description("Usage: +setboostembed <title|description|color> <valeur>")
.color(0xED4245),
)
.await;
return;
}
let field = args[0].to_lowercase();
let value = args[1..].join(" ");
let Some(pool) = pool(ctx).await else {
return;
};
let bot_id = ctx.cache.current_user().id;
let _ = sqlx::query(
r#"
INSERT INTO bot_boost_embed (bot_id, guild_id, enabled, title, description, color)
VALUES ($1, $2, TRUE, NULL, NULL, NULL)
ON CONFLICT (bot_id, guild_id)
DO NOTHING;
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.execute(&pool)
.await;
match field.as_str() {
"title" => {
let _ = sqlx::query(
"UPDATE bot_boost_embed SET title = $3, updated_at = NOW() WHERE bot_id = $1 AND guild_id = $2",
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(value)
.execute(&pool)
.await;
}
"description" => {
let _ = sqlx::query(
"UPDATE bot_boost_embed SET description = $3, updated_at = NOW() WHERE bot_id = $1 AND guild_id = $2",
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(value)
.execute(&pool)
.await;
}
"color" => {
let normalized = value
.trim()
.trim_start_matches('#')
.trim_start_matches("0x");
if let Ok(color) = u32::from_str_radix(normalized, 16) {
let _ = sqlx::query(
"UPDATE bot_boost_embed SET color = $3, updated_at = NOW() WHERE bot_id = $1 AND guild_id = $2",
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(color as i32)
.execute(&pool)
.await;
}
}
_ => {}
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Set BoostEmbed")
.description("Configuration mise a jour.")
.color(theme_color(ctx).await),
)
.await;
}
pub struct SetBoostembedCommand;
pub static COMMAND_DESCRIPTOR: SetBoostembedCommand = SetBoostembedCommand;
impl crate::commands::command_contract::CommandSpec for SetBoostembedCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setboostembed",
category: "config",
params: "<title|description|color> <valeur>",
description: "Configure le titre, la description et la couleur de l embed boost.",
examples: &[
"+setboostembed title Merci",
"+setboostembed color #FF66CC",
],
default_aliases: &["sboostembed"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+125
View File
@@ -0,0 +1,125 @@
use std::collections::BTreeSet;
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::{send_embed, theme_color};
use crate::commands::logs_command_helpers::pool;
pub async fn handle_set_modlogs(ctx: &Context, msg: &Message, args: &[&str]) {
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 row = sqlx::query_as::<_, (String,)>(
r#"
SELECT modlog_events
FROM bot_log_settings
WHERE bot_id = $1 AND guild_id = $2
LIMIT 1;
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.fetch_optional(&pool)
.await
.ok()
.flatten();
let mut events = row
.map(|(s,)| {
s.split(',')
.map(|v| v.trim().to_lowercase())
.filter(|v| !v.is_empty())
.collect::<BTreeSet<_>>()
})
.unwrap_or_else(|| {
[
"warn",
"mute",
"tempmute",
"unmute",
"cmute",
"tempcmute",
"uncmute",
"kick",
"ban",
"tempban",
"unban",
"lock",
"unlock",
"hide",
"unhide",
"addrole",
"delrole",
"derank",
"clear",
"sanctions",
]
.into_iter()
.map(|s| s.to_string())
.collect()
});
if args.len() >= 2 {
let event = args[0].to_lowercase();
let state = args[1].to_lowercase();
if state == "on" {
events.insert(event);
} else if state == "off" {
events.remove(&event);
}
let serialized = events.iter().cloned().collect::<Vec<_>>().join(",");
let _ = sqlx::query(
r#"
INSERT INTO bot_log_settings (bot_id, guild_id, modlog_events)
VALUES ($1, $2, $3)
ON CONFLICT (bot_id, guild_id)
DO UPDATE SET modlog_events = EXCLUDED.modlog_events, updated_at = NOW();
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(serialized)
.execute(&pool)
.await;
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Set ModLogs")
.description(format!(
"Evenements actifs:\n{}\n\nUsage: +setmodlogs <event> <on/off>",
events.iter().cloned().collect::<Vec<_>>().join(", ")
))
.color(theme_color(ctx).await),
)
.await;
}
pub struct SetModlogsCommand;
pub static COMMAND_DESCRIPTOR: SetModlogsCommand = SetModlogsCommand;
impl crate::commands::command_contract::CommandSpec for SetModlogsCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setmodlogs",
category: "config",
params: "[event on/off]",
description: "Affiche ou modifie les evenements qui apparaissent dans les logs de moderation.",
examples: &["+setmodlogs", "+setmodlogs warn off"],
default_aliases: &["smodlog"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+2 -2
View File
@@ -90,7 +90,7 @@ pub async fn handle_end(ctx: &Context, msg: &Message, args: &[&str]) {
msg, msg,
CreateEmbed::new() CreateEmbed::new()
.title("End") .title("End")
.description("Usage: +end giveaway <id_message>") .description("Usage: +endgiveaway <id_message>")
.color(0xED4245), .color(0xED4245),
) )
.await; .await;
@@ -106,7 +106,7 @@ impl crate::commands::command_contract::CommandSpec for EndCommand {
category: "event", category: "event",
params: "giveaway <id_message>", params: "giveaway <id_message>",
description: "Permet de stopper instantanement un giveaway avec l'identifiant du message.", description: "Permet de stopper instantanement un giveaway avec l'identifiant du message.",
examples: &["+end giveaway 123456789012345678"], examples: &["+endgiveaway 123456789012345678"],
default_aliases: &["gend"], default_aliases: &["gend"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 6, default_permission: 6,
+2 -2
View File
@@ -26,7 +26,7 @@ pub async fn handle_server(ctx: &Context, msg: &Message, args: &[&str]) {
if args.is_empty() { if args.is_empty() {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Usage: `+server pic`, `+server banner` ou `+server list`") .description("Usage: `+server pic`, `+server banner` ou `+serverlist`")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
return; return;
@@ -74,7 +74,7 @@ pub async fn handle_server(ctx: &Context, msg: &Message, args: &[&str]) {
_ => { _ => {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Usage: `+server pic`, `+server banner` ou `+server list`") .description("Usage: `+server pic`, `+server banner` ou `+serverlist`")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
} }
+1 -1
View File
@@ -65,7 +65,7 @@ impl crate::commands::command_contract::CommandSpec for ShowpicsCommand {
category: "info", category: "info",
params: "[nombre 1-5]", params: "[nombre 1-5]",
description: "Affiche jusqua 5 avatars de membres du serveur.", description: "Affiche jusqua 5 avatars de membres du serveur.",
examples: &["+show pics", "+help showpics"], examples: &["+showpics", "+help showpics"],
default_aliases: &[], default_aliases: &[],
allow_in_dm: false, allow_in_dm: false,
default_permission: 0, default_permission: 0,
+23 -17
View File
@@ -74,21 +74,21 @@ pub mod choose;
pub mod claim; pub mod claim;
#[path = "mod/cleanup.rs"] #[path = "mod/cleanup.rs"]
pub mod cleanup; pub mod cleanup;
#[path = "mod/clear_all_sanctions.rs"] #[path = "mod/clearallsanctions.rs"]
pub mod clear_all_sanctions; pub mod clear_all_sanctions;
#[path = "mod/clear_badwords.rs"] #[path = "mod/clearbadwords.rs"]
pub mod clear_badwords; pub mod clear_badwords;
#[path = "owner/clear_bl.rs"] #[path = "owner/clearbl.rs"]
pub mod clear_bl; pub mod clear_bl;
#[path = "mod/clear_limit.rs"] #[path = "mod/clearlimit.rs"]
pub mod clear_limit; pub mod clear_limit;
#[path = "mod/clear_messages.rs"] #[path = "mod/clearmessages.rs"]
pub mod clear_messages; pub mod clear_messages;
#[path = "owner/clear_owners.rs"] #[path = "owner/clearowners.rs"]
pub mod clear_owners; pub mod clear_owners;
#[path = "perms/clear_perms.rs"] #[path = "perms/clearperms.rs"]
pub mod clear_perms; pub mod clear_perms;
#[path = "mod/clear_sanctions.rs"] #[path = "mod/clearsanctions.rs"]
pub mod clear_sanctions; pub mod clear_sanctions;
#[path = "ticket/close.rs"] #[path = "ticket/close.rs"]
pub mod close; pub mod close;
@@ -102,7 +102,7 @@ pub mod compet;
pub mod create; pub mod create;
#[path = "perms/del.rs"] #[path = "perms/del.rs"]
pub mod del; pub mod del;
#[path = "mod/del_sanction.rs"] #[path = "mod/delsanction.rs"]
pub mod del_sanction; pub mod del_sanction;
#[path = "roles/delrole.rs"] #[path = "roles/delrole.rs"]
pub mod delrole; pub mod delrole;
@@ -140,7 +140,7 @@ pub mod join;
pub mod kick; pub mod kick;
#[path = "owner/leave.rs"] #[path = "owner/leave.rs"]
pub mod leave; pub mod leave;
#[path = "config/leave_settings.rs"] #[path = "config/leavesettings.rs"]
pub mod leave_settings; pub mod leave_settings;
#[path = "security/link.rs"] #[path = "security/link.rs"]
pub mod link; pub mod link;
@@ -205,7 +205,7 @@ pub mod public;
pub mod punish; pub mod punish;
#[path = "config/raidlog.rs"] #[path = "config/raidlog.rs"]
pub mod raidlog; pub mod raidlog;
#[path = "botconfig/remove_activity.rs"] #[path = "botconfig/removeactivity.rs"]
pub mod remove_activity; pub mod remove_activity;
#[path = "ticket/rename.rs"] #[path = "ticket/rename.rs"]
pub mod rename; pub mod rename;
@@ -233,11 +233,11 @@ pub mod server;
pub mod serverinfo; pub mod serverinfo;
#[path = "botconfig/set.rs"] #[path = "botconfig/set.rs"]
pub mod set; pub mod set;
#[path = "config/set_boostembed.rs"] #[path = "config/setboostembed.rs"]
pub mod set_boostembed; pub mod set_boostembed;
#[path = "config/set_modlogs.rs"] #[path = "config/setmodlogs.rs"]
pub mod set_modlogs; pub mod set_modlogs;
#[path = "mod/set_muterole.rs"] #[path = "mod/setmuterole.rs"]
pub mod set_muterole; pub mod set_muterole;
#[path = "botconfig/shadowbot.rs"] #[path = "botconfig/shadowbot.rs"]
pub mod shadowbot; pub mod shadowbot;
@@ -267,13 +267,13 @@ pub mod tempmute;
pub mod temprole; pub mod temprole;
#[path = "channel/tempvoc.rs"] #[path = "channel/tempvoc.rs"]
pub mod tempvoc; pub mod tempvoc;
#[path = "channel/tempvoc_cmd.rs"] #[path = "channel/tempvoccmd.rs"]
pub mod tempvoc_cmd; pub mod tempvoc_cmd;
#[path = "botconfig/theme.rs"] #[path = "botconfig/theme.rs"]
pub mod theme; pub mod theme;
#[path = "ticket/ticket.rs"] #[path = "ticket/ticket.rs"]
pub mod ticket; pub mod ticket;
#[path = "ticket/ticket_member.rs"] #[path = "ticket/ticketmember.rs"]
pub mod ticket_member; pub mod ticket_member;
#[path = "ticket/tickets.rs"] #[path = "ticket/tickets.rs"]
pub mod tickets; pub mod tickets;
@@ -481,9 +481,15 @@ pub fn all_command_metadata() -> Vec<CommandMetadata> {
} }
pub fn command_metadata_by_key(key: &str) -> Option<CommandMetadata> { pub fn command_metadata_by_key(key: &str) -> Option<CommandMetadata> {
let normalized = key.to_lowercase();
let compact = normalized.replace('_', "");
all_command_metadata() all_command_metadata()
.into_iter() .into_iter()
.find(|meta| meta.name == key) .find(|meta| {
meta.name.eq_ignore_ascii_case(&normalized)
|| meta.name.replace('_', "").eq_ignore_ascii_case(&compact)
})
} }
pub fn resolve_default_alias(alias: &str) -> Option<&'static str> { pub fn resolve_default_alias(alias: &str) -> Option<&'static str> {
+1 -1
View File
@@ -57,7 +57,7 @@ impl crate::commands::command_contract::CommandSpec for ClearAllSanctionsCommand
category: "mod", category: "mod",
params: "aucun", params: "aucun",
description: "Efface toutes les sanctions de tous les membres du serveur.", description: "Efface toutes les sanctions de tous les membres du serveur.",
examples: &["+clear all sanctions"], examples: &["+clearallsanctions"],
default_aliases: &["casanctions"], default_aliases: &["casanctions"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 8, default_permission: 8,
+1 -1
View File
@@ -41,7 +41,7 @@ impl crate::commands::command_contract::CommandSpec for ClearBadwordsCommand {
category: "mod", category: "mod",
params: "badwords", params: "badwords",
description: "Supprime l ensemble des mots interdits enregistres.", description: "Supprime l ensemble des mots interdits enregistres.",
examples: &["+clear badwords", "+help clear badwords"], examples: &["+clearbadwords", "+help clearbadwords"],
default_aliases: &["cbw"], default_aliases: &["cbw"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 7, default_permission: 7,
+2 -2
View File
@@ -17,7 +17,7 @@ pub async fn handle_clear_limit(ctx: &Context, msg: &Message, args: &[&str]) {
msg, msg,
CreateEmbed::new() CreateEmbed::new()
.title("Clear Limit") .title("Clear Limit")
.description("Usage: +clear limit <nombre>") .description("Usage: +clearlimit <nombre>")
.color(0xED4245), .color(0xED4245),
) )
.await; .await;
@@ -65,7 +65,7 @@ impl crate::commands::command_contract::CommandSpec for ClearLimitCommand {
category: "mod", category: "mod",
params: "limit <nombre>", params: "limit <nombre>",
description: "Definit la limite max de messages supprimables avec +clear.", description: "Definit la limite max de messages supprimables avec +clear.",
examples: &["+clear limit 100", "+help clear limit"], examples: &["+clearlimit 100", "+help clearlimit"],
default_aliases: &["climit"], default_aliases: &["climit"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 7, default_permission: 7,
+1 -1
View File
@@ -67,7 +67,7 @@ impl crate::commands::command_contract::CommandSpec for ClearSanctionsCommand {
category: "mod", category: "mod",
params: "<@membre/ID>", params: "<@membre/ID>",
description: "Efface completement les sanctions d un membre cible.", description: "Efface completement les sanctions d un membre cible.",
examples: &["+clear sanctions @User"], examples: &["+clearsanctions @User"],
default_aliases: &["csanctions"], default_aliases: &["csanctions"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 6, default_permission: 6,
+66
View File
@@ -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: "clearallsanctions",
category: "mod",
params: "aucun",
description: "Efface toutes les sanctions de tous les membres du serveur.",
examples: &["+clearallsanctions"],
default_aliases: &["casanctions"],
allow_in_dm: false,
default_permission: 8,
}
}
}
+50
View File
@@ -0,0 +1,50 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::automod_service::pool;
use crate::commands::common::send_embed;
use crate::db;
pub async fn handle_clear_badwords(ctx: &Context, msg: &Message, _args: &[&str]) {
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.get() as i64;
let cleared = db::clear_badwords(&pool, bot_id, guild_id.get() as i64)
.await
.unwrap_or(0);
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Clear BadWords")
.description(format!("{} mot(s) interdit(s) supprime(s).", cleared))
.color(0x57F287),
)
.await;
}
pub struct ClearBadwordsCommand;
pub static COMMAND_DESCRIPTOR: ClearBadwordsCommand = ClearBadwordsCommand;
impl crate::commands::command_contract::CommandSpec for ClearBadwordsCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "clearbadwords",
category: "mod",
params: "badwords",
description: "Supprime l ensemble des mots interdits enregistres.",
examples: &["+clearbadwords", "+help clearbadwords"],
default_aliases: &["cbw"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+74
View File
@@ -0,0 +1,74 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::automod_service::pool;
use crate::commands::common::send_embed;
use crate::db;
pub async fn handle_clear_limit(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
let Some(raw_value) = args.get(1) else {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Clear Limit")
.description("Usage: +clearlimit <nombre>")
.color(0xED4245),
)
.await;
return;
};
let Ok(value) = raw_value.parse::<i32>() else {
return;
};
let clamped = value.clamp(1, 1_000);
let Some(pool) = pool(ctx).await else {
return;
};
let bot_id = ctx.cache.current_user().id.get() as i64;
if db::set_clear_limit(&pool, bot_id, guild_id.get() as i64, clamped)
.await
.is_err()
{
return;
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Clear Limit")
.description(format!(
"Limite de suppression definie a **{}** message(s) par commande clear.",
clamped
))
.color(0x57F287),
)
.await;
}
pub struct ClearLimitCommand;
pub static COMMAND_DESCRIPTOR: ClearLimitCommand = ClearLimitCommand;
impl crate::commands::command_contract::CommandSpec for ClearLimitCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "clearlimit",
category: "mod",
params: "limit <nombre>",
description: "Definit la limite max de messages supprimables avec +clear.",
examples: &["+clearlimit 100", "+help clearlimit"],
default_aliases: &["climit"],
allow_in_dm: false,
default_permission: 7,
}
}
}
@@ -76,11 +76,11 @@ pub static COMMAND_DESCRIPTOR: ClearMessagesCommand = ClearMessagesCommand;
impl crate::commands::command_contract::CommandSpec for ClearMessagesCommand { impl crate::commands::command_contract::CommandSpec for ClearMessagesCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata { fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata { crate::commands::command_contract::CommandMetadata {
name: "clear_messages", name: "clearmessages",
category: "mod", category: "mod",
params: "<nombre> [@membre/ID]", params: "<nombre> [@membre/ID]",
description: "Supprime un nombre de messages, optionnellement filtres par membre.", description: "Supprime un nombre de messages, optionnellement filtres par membre.",
examples: &["+clear 20", "+clear 20 @User"], examples: &["+clearmessages 20", "+clearmessages 20 @User"],
default_aliases: &["purge"], default_aliases: &["purge"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 5, default_permission: 5,
+76
View File
@@ -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: "clearsanctions",
category: "mod",
params: "<@membre/ID>",
description: "Efface completement les sanctions d un membre cible.",
examples: &["+clearsanctions @User"],
default_aliases: &["csanctions"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+1 -1
View File
@@ -89,7 +89,7 @@ impl crate::commands::command_contract::CommandSpec for DelSanctionCommand {
category: "mod", category: "mod",
params: "<@membre/ID> <nombre>", params: "<@membre/ID> <nombre>",
description: "Supprime une sanction specifique dans l historique d un membre.", description: "Supprime une sanction specifique dans l historique d un membre.",
examples: &["+del sanction @User 1"], examples: &["+delsanction @User 1"],
default_aliases: &["delsanction"], default_aliases: &["delsanction"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 6, default_permission: 6,
+98
View File
@@ -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: "delsanction",
category: "mod",
params: "<@membre/ID> <nombre>",
description: "Supprime une sanction specifique dans l historique d un membre.",
examples: &["+delsanction @User 1"],
default_aliases: &["delsanction"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ pub async fn handle_set_muterole(ctx: &Context, msg: &Message, args: &[&str]) {
msg, msg,
CreateEmbed::new() CreateEmbed::new()
.title("Set MuteRole") .title("Set MuteRole")
.description("Usage: +set muterole <@role/ID/nom>") .description("Usage: +setmuterole <@role/ID/nom>")
.color(0xED4245), .color(0xED4245),
) )
.await; .await;
@@ -70,7 +70,7 @@ impl crate::commands::command_contract::CommandSpec for SetMuteRoleCommand {
category: "mod", category: "mod",
params: "muterole <@role/ID/nom>", params: "muterole <@role/ID/nom>",
description: "Definit le role utilise pour le mute lorsque le mode timeout est desactive.", description: "Definit le role utilise pour le mute lorsque le mode timeout est desactive.",
examples: &["+set muterole @Muted", "+help set muterole"], examples: &["+setmuterole @Muted", "+help setmuterole"],
default_aliases: &["smr"], default_aliases: &["smr"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 7, default_permission: 7,
+79
View File
@@ -0,0 +1,79 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::automod_service::pool;
use crate::commands::common::{parse_role, send_embed};
use crate::db;
pub async fn handle_set_muterole(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
let Some(raw_role) = args.get(1) else {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Set MuteRole")
.description("Usage: +setmuterole <@role/ID/nom>")
.color(0xED4245),
)
.await;
return;
};
let Ok(guild) = guild_id.to_partial_guild(&ctx.http).await else {
return;
};
let Some(role) = parse_role(&guild, raw_role) else {
return;
};
let Some(pool) = pool(ctx).await else {
return;
};
let bot_id = ctx.cache.current_user().id.get() as i64;
if db::set_mute_role(
&pool,
bot_id,
guild_id.get() as i64,
Some(role.id.get() as i64),
)
.await
.is_err()
{
return;
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("MuteRole")
.description(format!("Role muet defini sur <@&{}>.", role.id.get()))
.color(0x57F287),
)
.await;
}
pub struct SetMuteRoleCommand;
pub static COMMAND_DESCRIPTOR: SetMuteRoleCommand = SetMuteRoleCommand;
impl crate::commands::command_contract::CommandSpec for SetMuteRoleCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setmuterole",
category: "mod",
params: "muterole <@role/ID/nom>",
description: "Definit le role utilise pour le mute lorsque le mode timeout est desactive.",
examples: &["+setmuterole @Muted", "+help setmuterole"],
default_aliases: &["smr"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+1 -1
View File
@@ -43,7 +43,7 @@ impl crate::commands::command_contract::CommandSpec for ClearBlCommand {
category: "owner", category: "owner",
params: "aucun", params: "aucun",
description: "Supprime toutes les entrees de la blacklist globale.", description: "Supprime toutes les entrees de la blacklist globale.",
examples: &["+clear bl", "+cl", "+help clear bl"], examples: &["+clearbl", "+cl", "+help clearbl"],
default_aliases: &["cbl"], default_aliases: &["cbl"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 9, default_permission: 9,
+1 -1
View File
@@ -43,7 +43,7 @@ impl crate::commands::command_contract::CommandSpec for ClearOwnersCommand {
category: "owner", category: "owner",
params: "aucun", params: "aucun",
description: "Supprime tous les owners supplementaires en base de donnees.", description: "Supprime tous les owners supplementaires en base de donnees.",
examples: &["+clear owners", "+cs", "+help clear owners"], examples: &["+clearowners", "+cs", "+help clearowners"],
default_aliases: &["cro"], default_aliases: &["cro"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 9, default_permission: 9,
+52
View File
@@ -0,0 +1,52 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::admin_common::ensure_owner;
use crate::commands::common::send_embed;
use crate::db::{DbPoolKey, clear_blacklist};
pub async fn handle_clear_bl(ctx: &Context, msg: &Message) {
if ensure_owner(ctx, msg).await.is_err() {
return;
}
let bot_id = ctx.cache.current_user().id;
let pool = {
let data = ctx.data.read().await;
data.get::<DbPoolKey>().cloned()
};
let Some(pool) = pool else {
let embed = serenity::builder::CreateEmbed::new()
.title("Erreur")
.description("DB indisponible.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
};
let count = clear_blacklist(&pool, bot_id).await.unwrap_or(0);
let embed = serenity::builder::CreateEmbed::new()
.title("Blacklist réinitialisée")
.description(format!("{} membre(s) retiré(s) de la blacklist.", count))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
}
pub struct ClearBlCommand;
pub static COMMAND_DESCRIPTOR: ClearBlCommand = ClearBlCommand;
impl crate::commands::command_contract::CommandSpec for ClearBlCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "clearbl",
category: "owner",
params: "aucun",
description: "Supprime toutes les entrees de la blacklist globale.",
examples: &["+clearbl", "+cl", "+help clearbl"],
default_aliases: &["cbl"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+52
View File
@@ -0,0 +1,52 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::admin_common::ensure_owner;
use crate::commands::common::send_embed;
use crate::db::{DbPoolKey, clear_bot_owners};
pub async fn handle_clear_owners(ctx: &Context, msg: &Message) {
if ensure_owner(ctx, msg).await.is_err() {
return;
}
let bot_id = ctx.cache.current_user().id;
let pool = {
let data = ctx.data.read().await;
data.get::<DbPoolKey>().cloned()
};
let Some(pool) = pool else {
let embed = serenity::builder::CreateEmbed::new()
.title("Erreur")
.description("DB indisponible.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
};
let count = clear_bot_owners(&pool, bot_id).await.unwrap_or(0);
let embed = serenity::builder::CreateEmbed::new()
.title("Owners réinitialisés")
.description(format!("{} owner(s) supprimé(s).", count))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
}
pub struct ClearOwnersCommand;
pub static COMMAND_DESCRIPTOR: ClearOwnersCommand = ClearOwnersCommand;
impl crate::commands::command_contract::CommandSpec for ClearOwnersCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "clearowners",
category: "owner",
params: "aucun",
description: "Supprime tous les owners supplementaires en base de donnees.",
examples: &["+clearowners", "+cs", "+help clearowners"],
default_aliases: &["cro"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+5 -5
View File
@@ -38,7 +38,7 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("MP settings") .title("MP settings")
.description(format!( .description(format!(
"Envoi de MP: `{}`\nUtilise `+mp settings on/off`.", "Envoi de MP: `{}`\nUtilise `+mpsettings on/off`.",
if enabled { "on" } else { "off" } if enabled { "on" } else { "off" }
)) ))
.color(0x5865F2); .color(0x5865F2);
@@ -52,7 +52,7 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
_ => { _ => {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Usage: `+mp settings <on/off>`") .description("Usage: `+mpsettings <on/off>`")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
return; return;
@@ -93,7 +93,7 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(entry_id_raw) = args.get(1) else { let Some(entry_id_raw) = args.get(1) else {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Usage: `+mp delete <id>`") .description("Usage: `+mpdelete <id>`")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
return; return;
@@ -158,7 +158,7 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
if args.len() < 2 { if args.len() < 2 {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Usage: `+mp settings` ou `+mp <membre> <message>`") .description("Usage: `+mpsettings` ou `+mp <membre> <message>`")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
return; return;
@@ -182,7 +182,7 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
if !enabled { if !enabled {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("MP désactivés") .title("MP désactivés")
.description("Réactive-les avec `+mp settings on`.") .description("Réactive-les avec `+mpsettings on`.")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
return; return;
+3 -4
View File
@@ -67,10 +67,9 @@ pub async fn handle_alias(ctx: &Context, msg: &Message, args: &[&str]) {
} }
let command = args[0].trim_start_matches('+').to_lowercase(); let command = args[0].trim_start_matches('+').to_lowercase();
if !all_command_keys() let is_known = all_command_keys().iter().any(|candidate| candidate == &command)
.iter() || crate::commands::command_metadata_by_key(&command).is_some();
.any(|candidate| candidate == &command) if !is_known {
{
let embed = serenity::builder::CreateEmbed::new() let embed = serenity::builder::CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Commande cible inconnue.") .description("Commande cible inconnue.")
+1 -1
View File
@@ -39,7 +39,7 @@ impl crate::commands::command_contract::CommandSpec for ClearPermsCommand {
category: "perms", category: "perms",
params: "aucun", params: "aucun",
description: "Supprime toutes les permissions ACL configurees en base.", description: "Supprime toutes les permissions ACL configurees en base.",
examples: &["+clear perms", "+cs", "+help clear perms"], examples: &["+clearperms", "+cs", "+help clearperms"],
default_aliases: &["cpm"], default_aliases: &["cpm"],
allow_in_dm: false, allow_in_dm: false,
default_permission: 9, default_permission: 9,
+48
View File
@@ -0,0 +1,48 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::send_embed;
use crate::commands::perms_helpers::{ensure_owner, get_pool};
use crate::db::clear_role_permissions;
pub async fn handle_clear_perms(ctx: &Context, msg: &Message) {
if !ensure_owner(ctx, msg).await {
return;
}
let bot_id = ctx.cache.current_user().id;
let Some(pool) = get_pool(ctx).await else {
let embed = CreateEmbed::new()
.title("Erreur")
.description("DB indisponible.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
};
let removed = clear_role_permissions(&pool, bot_id).await.unwrap_or(0);
let embed = CreateEmbed::new()
.title("Permissions roles supprimees")
.description(format!("{} entree(s) supprimee(s).", removed))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
}
pub struct ClearPermsCommand;
pub static COMMAND_DESCRIPTOR: ClearPermsCommand = ClearPermsCommand;
impl crate::commands::command_contract::CommandSpec for ClearPermsCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "clearperms",
category: "perms",
params: "aucun",
description: "Supprime toutes les permissions ACL configurees en base.",
examples: &["+clearperms", "+cs", "+help clearperms"],
default_aliases: &["cpm"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ pub async fn handle_del(ctx: &Context, msg: &Message, args: &[&str]) {
if args.len() < 2 || !args[0].eq_ignore_ascii_case("perm") { if args.len() < 2 || !args[0].eq_ignore_ascii_case("perm") {
let embed = CreateEmbed::new() let embed = CreateEmbed::new()
.title("Erreur") .title("Erreur")
.description("Usage: `del perm <role>`") .description("Usage: `+delperm <role>`")
.color(0xED4245); .color(0xED4245);
send_embed(ctx, msg, embed).await; send_embed(ctx, msg, embed).await;
return; return;
+84 -38
View File
@@ -133,8 +133,8 @@ fn help_page_for_command(
) -> &'static str { ) -> &'static str {
match meta.name { match meta.name {
"modlog" | "messagelog" | "voicelog" | "boostlog" | "rolelog" | "raidlog" "modlog" | "messagelog" | "voicelog" | "boostlog" | "rolelog" | "raidlog"
| "autoconfiglog" | "nolog" | "join" | "boostembed" | "set_modlogs" | "set_boostembed" | "autoconfiglog" | "nolog" | "join" | "boostembed" | "setmodlogs" | "setboostembed"
| "leave_settings" | "viewlogs" => "logs", | "leavesettings" | "viewlogs" => "logs",
"warn" "warn"
| "mute" | "mute"
| "tempmute" | "tempmute"
@@ -151,12 +151,12 @@ fn help_page_for_command(
| "banlist" | "banlist"
| "unbanall" | "unbanall"
| "sanctions" | "sanctions"
| "del_sanction" | "delsanction"
| "clear_sanctions" | "clearsanctions"
| "clear_all_sanctions" | "clearallsanctions"
| "cleanup" | "cleanup"
| "renew" | "renew"
| "clear_messages" => "moderation", | "clearmessages" => "moderation",
"addrole" | "delrole" | "derank" | "massiverole" | "unmassiverole" | "temprole" "addrole" | "delrole" | "derank" | "massiverole" | "unmassiverole" | "temprole"
| "untemprole" | "sync" => "roles", | "untemprole" | "sync" => "roles",
"lock" | "unlock" | "lockall" | "unlockall" | "hide" | "unhide" | "hideall" "lock" | "unlock" | "lockall" | "unlockall" | "hide" | "unhide" | "hideall"
@@ -165,16 +165,24 @@ fn help_page_for_command(
| "create" | "newsticker" | "button" | "autoreact" | "snipe" | "loading" | "backup" | "create" | "newsticker" | "button" | "autoreact" | "snipe" | "loading" | "backup"
| "autobackup" => "outils", | "autobackup" => "outils",
"shadowbot" | "set" | "theme" | "playto" | "listen" | "watch" | "compet" | "stream" "shadowbot" | "set" | "theme" | "playto" | "listen" | "watch" | "compet" | "stream"
| "remove_activity" | "online" | "idle" | "dnd" | "invisible" | "change" | "changeall" => { | "removeactivity" | "online" | "idle" | "dnd" | "invisible" | "change" | "changeall" => {
"bot" "bot"
} }
"owner" | "unowner" | "clear_owners" | "bl" | "unbl" | "blinfo" | "clear_bl" "owner" | "unowner" | "clearowners" | "bl" | "unbl" | "blinfo" | "clearbl"
| "allbots" | "alladmins" | "botadmins" | "mainprefix" | "prefix" | "mp" | "invite" | "allbots" | "alladmins" | "botadmins" | "mainprefix" | "prefix" | "mp" | "invite"
| "leave" | "discussion" => "administration", | "leave" | "discussion" => "administration",
"perms" | "del" | "clear_perms" | "allperms" | "alias" | "help" | "helpsetting" => { "perms" | "del" | "clearperms" | "allperms" | "alias" | "help" | "helpsetting" => {
"permissions" "permissions"
} }
_ => match meta.category { _ => match meta.category {
"info" => "infos",
"mod" => "moderation",
"config" => "logs",
"botconfig" => "bot",
"owner" => "administration",
"perms" => "permissions",
"channel" => "salons_vocal",
"event" => "outils",
"infos" => "infos", "infos" => "infos",
"logs" => "logs", "logs" => "logs",
"moderation" => "moderation", "moderation" => "moderation",
@@ -209,12 +217,14 @@ fn help_page_title_for_command_key(key: &str) -> &'static str {
fn help_metadata_lookup_key(input: &str) -> Option<&'static str> { fn help_metadata_lookup_key(input: &str) -> Option<&'static str> {
let normalized = help_lookup_key(input); let normalized = help_lookup_key(input);
let underscored = normalized.replace(' ', "_"); let underscored = normalized.replace(' ', "_");
let compact = normalized.replace(' ', "");
crate::commands::all_command_metadata() crate::commands::all_command_metadata()
.into_iter() .into_iter()
.find(|meta| { .find(|meta| {
meta.name.eq_ignore_ascii_case(&normalized) meta.name.eq_ignore_ascii_case(&normalized)
|| meta.name.eq_ignore_ascii_case(&underscored) || meta.name.eq_ignore_ascii_case(&underscored)
|| meta.name.replace('_', "").eq_ignore_ascii_case(&compact)
|| meta || meta
.name .name
.replace('_', " ") .replace('_', " ")
@@ -321,18 +331,58 @@ async fn aliases_map(ctx: &Context) -> BTreeMap<String, Vec<String>> {
} }
fn command_doc(key: &str) -> Option<CommandDoc> { fn command_doc(key: &str) -> Option<CommandDoc> {
let meta = match key { let (meta, command, acl_key, alias_source_key) = match key {
"mp_settings" | "mp_sent" | "mp_delete" => crate::commands::command_metadata_by_key("mp")?, "mpsettings" => (
"server_list" => crate::commands::command_metadata_by_key("server")?, crate::commands::command_metadata_by_key("mp")?,
"change_reset" => crate::commands::command_metadata_by_key("change")?, "mpsettings",
"set_perm" => crate::commands::command_metadata_by_key("set")?, "mpsettings",
"del_perm" => crate::commands::command_metadata_by_key("del")?, Some("mp"),
other => crate::commands::command_metadata_by_key(other)?, ),
"mpsent" => (
crate::commands::command_metadata_by_key("mp")?,
"mpsent",
"mpsent",
Some("mp"),
),
"mpdelete" => (
crate::commands::command_metadata_by_key("mp")?,
"mpdelete",
"mpdelete",
Some("mp"),
),
"serverlist" => (
crate::commands::command_metadata_by_key("server")?,
"serverlist",
"serverlist",
Some("server"),
),
"changereset" => (
crate::commands::command_metadata_by_key("change")?,
"changereset",
"changereset",
Some("change"),
),
"setperm" => (
crate::commands::command_metadata_by_key("set")?,
"setperm",
"setperm",
Some("set"),
),
"delperm" => (
crate::commands::command_metadata_by_key("del")?,
"delperm",
"delperm",
Some("del"),
),
other => {
let meta = crate::commands::command_metadata_by_key(other)?;
(meta, meta.name, meta.name, Some(meta.name))
}
}; };
Some(CommandDoc { Some(CommandDoc {
key: meta.name, key: acl_key,
command: meta.name, command,
allow_in_dm: meta.allow_in_dm, allow_in_dm: meta.allow_in_dm,
default_permission: meta.default_permission, default_permission: meta.default_permission,
params: meta.params, params: meta.params,
@@ -342,7 +392,7 @@ fn command_doc(key: &str) -> Option<CommandDoc> {
} else { } else {
meta.examples meta.examples
}, },
alias_source_key: Some(meta.name), alias_source_key,
}) })
} }
@@ -351,7 +401,6 @@ fn help_lookup_key(input: &str) -> String {
.trim() .trim()
.trim_start_matches('+') .trim_start_matches('+')
.to_lowercase() .to_lowercase()
.replace('_', " ")
.split_whitespace() .split_whitespace()
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" ") .join(" ")
@@ -375,11 +424,11 @@ fn help_lookup_to_key(input: &str) -> Option<&'static str> {
"pic" => Some("pic"), "pic" => Some("pic"),
"banner" => Some("banner"), "banner" => Some("banner"),
"server" => Some("server"), "server" => Some("server"),
"server list" => Some("server_list"), "serverlist" => Some("serverlist"),
"snipe" => Some("snipe"), "snipe" => Some("snipe"),
"emoji" => Some("emoji"), "emoji" => Some("emoji"),
"giveaway" => Some("giveaway"), "giveaway" => Some("giveaway"),
"end" | "end giveaway" => Some("end"), "end" | "endgiveaway" => Some("end"),
"reroll" => Some("reroll"), "reroll" => Some("reroll"),
"choose" => Some("choose"), "choose" => Some("choose"),
"embed" => Some("embed"), "embed" => Some("embed"),
@@ -410,36 +459,36 @@ fn help_lookup_to_key(input: &str) -> Option<&'static str> {
"watch" => Some("watch"), "watch" => Some("watch"),
"compet" => Some("compet"), "compet" => Some("compet"),
"stream" => Some("stream"), "stream" => Some("stream"),
"remove activity" => Some("remove_activity"), "removeactivity" => Some("removeactivity"),
"online" => Some("online"), "online" => Some("online"),
"idle" => Some("idle"), "idle" => Some("idle"),
"dnd" => Some("dnd"), "dnd" => Some("dnd"),
"invisible" => Some("invisible"), "invisible" => Some("invisible"),
"mp" => Some("mp"), "mp" => Some("mp"),
"mp settings" => Some("mp_settings"), "mpsettings" => Some("mpsettings"),
"mp sent" => Some("mp_sent"), "mpsent" => Some("mpsent"),
"mp delete" | "mp del" => Some("mp_delete"), "mpdelete" | "mpdel" => Some("mpdelete"),
"discussion" => Some("discussion"), "discussion" => Some("discussion"),
"owner" => Some("owner"), "owner" => Some("owner"),
"unowner" => Some("unowner"), "unowner" => Some("unowner"),
"clear owners" => Some("clear_owners"), "clearowners" => Some("clearowners"),
"bl" => Some("bl"), "bl" => Some("bl"),
"unbl" => Some("unbl"), "unbl" => Some("unbl"),
"blinfo" => Some("blinfo"), "blinfo" => Some("blinfo"),
"clear bl" => Some("clear_bl"), "clearbl" => Some("clearbl"),
"say" => Some("say"), "say" => Some("say"),
"invite" => Some("invite"), "invite" => Some("invite"),
"leave" => Some("leave"), "leave" => Some("leave"),
"change" => Some("change"), "change" => Some("change"),
"change reset" => Some("change_reset"), "changereset" => Some("changereset"),
"changeall" => Some("changeall"), "changeall" => Some("changeall"),
"mainprefix" => Some("mainprefix"), "mainprefix" => Some("mainprefix"),
"prefix" => Some("prefix"), "prefix" => Some("prefix"),
"perms" => Some("perms"), "perms" => Some("perms"),
"allperms" => Some("allperms"), "allperms" => Some("allperms"),
"set perm" => Some("set_perm"), "setperm" => Some("setperm"),
"del perm" => Some("del_perm"), "delperm" => Some("delperm"),
"clear perms" => Some("clear_perms"), "clearperms" => Some("clearperms"),
"alias" => Some("alias"), "alias" => Some("alias"),
"helpsetting" | "helpetting" => Some("helpsetting"), "helpsetting" | "helpetting" => Some("helpsetting"),
_ => None, _ => None,
@@ -518,7 +567,7 @@ fn help_page_content(
let mut lines = Vec::with_capacity(commands.len()); let mut lines = Vec::with_capacity(commands.len());
for meta in commands { for meta in commands {
let label = meta.name.replace('_', " "); let label = meta.name.replace('_', "");
let alias_key = meta.name; let alias_key = meta.name;
let params = if meta.params.trim().is_empty() { let params = if meta.params.trim().is_empty() {
"aucun" "aucun"
@@ -854,14 +903,11 @@ async fn build_command_help_embed(
.join("\n"); .join("\n");
let mut embed = CreateEmbed::new() let mut embed = CreateEmbed::new()
.title(format!( .title(format!("Aide commande · +{}", doc.command.replace('_', "")))
"Aide commande · +{}",
doc.command.replace('_', " ")
))
.description(doc.description) .description(doc.description)
.field( .field(
"Commande", "Commande",
format!("`+{}`", doc.command.replace('_', " ")), format!("`+{}`", doc.command.replace('_', "")),
false, false,
) )
.field("Clé ACL", format!("`{}`", doc.key), false) .field("Clé ACL", format!("`{}`", doc.key), false)
+20 -4
View File
@@ -33,10 +33,26 @@ pub fn parse_user_or_role(input: &str) -> Option<(&'static str, u64)> {
} }
pub fn normalize_command_name(input: &str) -> String { pub fn normalize_command_name(input: &str) -> String {
input let normalized = input.trim_start_matches('+').to_lowercase();
.trim_start_matches('+') let underscored = normalized
.replace(' ', "_") .split_whitespace()
.to_lowercase() .collect::<Vec<_>>()
.join("_");
let compact = underscored.replace('_', "");
let known = crate::permissions::all_command_keys();
let direct = crate::permissions::command_key(&underscored, &[]);
if known.iter().any(|value| value == &direct) {
return direct;
}
let compact_mapped = crate::permissions::command_key(&compact, &[]);
if known.iter().any(|value| value == &compact_mapped) {
return compact_mapped;
}
underscored
} }
pub async fn ensure_owner(ctx: &Context, msg: &Message) -> bool { pub async fn ensure_owner(ctx: &Context, msg: &Message) -> bool {
+82 -130
View File
@@ -114,12 +114,19 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
} }
let mut parts = without_prefix.split_whitespace(); let mut parts = without_prefix.split_whitespace();
let mut command = parts.next().unwrap_or("").to_lowercase(); let typed_command = parts.next().unwrap_or("").to_lowercase();
let args = parts.collect::<Vec<_>>(); let typed_args = parts.collect::<Vec<_>>();
let mut command = typed_command;
let args = typed_args;
// Ne laisse pas un alias écraser une commande native. // Ne laisse pas un alias écraser une commande native.
let native_commands = permissions::all_command_keys(); let native_commands = permissions::all_command_keys();
if !native_commands.iter().any(|cmd| cmd == &command) { let is_native = native_commands.iter().any(|cmd| cmd == &command)
|| crate::commands::all_command_metadata()
.into_iter()
.any(|meta| meta.name.eq_ignore_ascii_case(&command));
if !is_native {
if let Some(alias_target) = alias::resolve_command_alias_name(ctx, &command).await { if let Some(alias_target) = alias::resolve_command_alias_name(ctx, &command).await {
command = alias_target; command = alias_target;
} else if let Some(default_target) = crate::commands::resolve_default_alias(&command) { } else if let Some(default_target) = crate::commands::resolve_default_alias(&command) {
@@ -133,17 +140,17 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
let dm_metadata = crate::commands::command_metadata_by_key(&command_key) let dm_metadata = crate::commands::command_metadata_by_key(&command_key)
.or_else(|| { .or_else(|| {
let mapped = match command_key.as_str() { let mapped = match command_key.as_str() {
"show_pics" => Some("showpics"), "showpics" => Some("showpics"),
"suggestion_create" | "suggestion_settings" => Some("suggestion"), "suggestion_create" | "suggestion_settings" => Some("suggestion"),
"ticket_settings" => Some("ticket"), "ticket_settings" => Some("ticket"),
"ticket_add" => Some("add"), "ticket_add" => Some("add"),
"ticket_remove" => Some("del"), "ticket_remove" => Some("del"),
"ticket_close" => Some("close"), "ticket_close" => Some("close"),
"set_perm" => Some("set"), "setperm" => Some("set"),
"change_reset" => Some("change"), "changereset" => Some("change"),
"server_list" => Some("server"), "serverlist" => Some("server"),
"end_giveaway" => Some("end"), "endgiveaway" => Some("end"),
"mp_settings" | "mp_sent" | "mp_delete" => Some("mp"), "mpsettings" | "mpsent" | "mpdelete" => Some("mp"),
_ => None, _ => None,
}; };
@@ -157,7 +164,7 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
.title("Commande indisponible en DM") .title("Commande indisponible en DM")
.description(format!( .description(format!(
"La commande `+{}` n'est pas autorisee en message prive.", "La commande `+{}` n'est pas autorisee en message prive.",
command.replace('_', " ") command.replace('_', "")
)) ))
.color(0xED4245); .color(0xED4245);
crate::commands::common::send_embed(ctx, msg, embed).await; crate::commands::common::send_embed(ctx, msg, embed).await;
@@ -184,44 +191,24 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"claim" => claim::handle_claim(ctx, msg, &args).await, "claim" => claim::handle_claim(ctx, msg, &args).await,
"rename" => rename::handle_rename(ctx, msg, &args).await, "rename" => rename::handle_rename(ctx, msg, &args).await,
"add" => ticket_member::handle_ticket_add(ctx, msg, &args).await, "add" => ticket_member::handle_ticket_add(ctx, msg, &args).await,
"del" "delperm" => {
if args let mut forwarded = vec!["perm"];
.first() forwarded.extend(args.iter().copied());
.map(|s| s.eq_ignore_ascii_case("perm")) del::handle_del(ctx, msg, &forwarded).await
.unwrap_or(false) =>
{
del::handle_del(ctx, msg, &args).await
} }
"del" "delsanction" => {
if args let mut forwarded = vec!["sanction"];
.first() forwarded.extend(args.iter().copied());
.map(|s| s.eq_ignore_ascii_case("sanction")) del_sanction::handle_del_sanction(ctx, msg, &forwarded).await
.unwrap_or(false) =>
{
del_sanction::handle_del_sanction(ctx, msg, &args).await
} }
"del" => ticket_member::handle_ticket_remove(ctx, msg, &args).await, "del" => ticket_member::handle_ticket_remove(ctx, msg, &args).await,
"close" => close::handle_close(ctx, msg, &args).await, "close" => close::handle_close(ctx, msg, &args).await,
"tickets" => tickets::handle_tickets(ctx, msg, &args).await, "tickets" => tickets::handle_tickets(ctx, msg, &args).await,
"show" "showpics" => showpics::handle_show_pics(ctx, msg, &args).await,
if args
.first()
.map(|s| s.eq_ignore_ascii_case("pics"))
.unwrap_or(false) =>
{
showpics::handle_show_pics(ctx, msg, &args[1..]).await
}
"piconly" => piconly::handle_piconly(ctx, msg, &args).await, "piconly" => piconly::handle_piconly(ctx, msg, &args).await,
"suggestion" => suggestion::handle_suggestion(ctx, msg, &args).await, "suggestion" => suggestion::handle_suggestion(ctx, msg, &args).await,
"autopublish" => autopublish::handle_autopublish(ctx, msg, &args).await, "autopublish" => autopublish::handle_autopublish(ctx, msg, &args).await,
"tempvoc" "tempvoccmd" => tempvoc_cmd::handle_tempvoc_cmd(ctx, msg, &args).await,
if args
.first()
.map(|s| s.eq_ignore_ascii_case("cmd"))
.unwrap_or(false) =>
{
tempvoc_cmd::handle_tempvoc_cmd(ctx, msg, &args[1..]).await
}
"tempvoc" => tempvoc::handle_tempvoc(ctx, msg, &args).await, "tempvoc" => tempvoc::handle_tempvoc(ctx, msg, &args).await,
"ping" => ping::handle_ping(ctx, msg, &args).await, "ping" => ping::handle_ping(ctx, msg, &args).await,
"timeout" => timeout::handle_timeout_toggle(ctx, msg, &args).await, "timeout" => timeout::handle_timeout_toggle(ctx, msg, &args).await,
@@ -255,6 +242,7 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"pic" => pic::handle_pic(ctx, msg, &args).await, "pic" => pic::handle_pic(ctx, msg, &args).await,
"banner" => banner::handle_banner(ctx, msg, &args).await, "banner" => banner::handle_banner(ctx, msg, &args).await,
"server" => server::handle_server(ctx, msg, &args).await, "server" => server::handle_server(ctx, msg, &args).await,
"serverlist" => server::handle_server_list(ctx, msg).await,
"snipe" => snipe::handle_snipe(ctx, msg, &args).await, "snipe" => snipe::handle_snipe(ctx, msg, &args).await,
"emoji" => emoji::handle_emoji(ctx, msg, &args).await, "emoji" => emoji::handle_emoji(ctx, msg, &args).await,
"giveaway" => giveaway::handle_giveaway(ctx, msg, &args).await, "giveaway" => giveaway::handle_giveaway(ctx, msg, &args).await,
@@ -269,6 +257,11 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"boostembed" => boostembed::handle_boostembed(ctx, msg, &args).await, "boostembed" => boostembed::handle_boostembed(ctx, msg, &args).await,
"nolog" => nolog::handle_nolog(ctx, msg, &args).await, "nolog" => nolog::handle_nolog(ctx, msg, &args).await,
"sanctions" => sanctions::handle_sanctions(ctx, msg, &args).await, "sanctions" => sanctions::handle_sanctions(ctx, msg, &args).await,
"endgiveaway" => {
let mut forwarded = vec!["giveaway"];
forwarded.extend(args.iter().copied());
end::handle_end(ctx, msg, &forwarded).await
}
"end" => end::handle_end(ctx, msg, &args).await, "end" => end::handle_end(ctx, msg, &args).await,
"reroll" => reroll::handle_reroll(ctx, msg, &args).await, "reroll" => reroll::handle_reroll(ctx, msg, &args).await,
"choose" => choose::handle_choose(ctx, msg, &args).await, "choose" => choose::handle_choose(ctx, msg, &args).await,
@@ -405,30 +398,18 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"autoreact" => autoreact::handle_autoreact(ctx, msg, &args).await, "autoreact" => autoreact::handle_autoreact(ctx, msg, &args).await,
"calc" => calc::handle_calc(ctx, msg, &args).await, "calc" => calc::handle_calc(ctx, msg, &args).await,
"shadowbot" => shadowbot::handle_shadowbot(ctx, msg, &args).await, "shadowbot" => shadowbot::handle_shadowbot(ctx, msg, &args).await,
"set" "setperm" => {
if args let mut forwarded = vec!["perm"];
.first() forwarded.extend(args.iter().copied());
.map(|s| s.eq_ignore_ascii_case("muterole")) set::handle_set(ctx, msg, &forwarded).await
.unwrap_or(false) =>
{
set_muterole::handle_set_muterole(ctx, msg, &args).await
} }
"set" "setmuterole" => {
if args let mut forwarded = vec!["muterole"];
.first() forwarded.extend(args.iter().copied());
.map(|s| s.eq_ignore_ascii_case("modlogs")) set_muterole::handle_set_muterole(ctx, msg, &forwarded).await
.unwrap_or(false) =>
{
set_modlogs::handle_set_modlogs(ctx, msg, &args[1..]).await
}
"set"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("boostembed"))
.unwrap_or(false) =>
{
set_boostembed::handle_set_boostembed(ctx, msg, &args[1..]).await
} }
"setmodlogs" => set_modlogs::handle_set_modlogs(ctx, msg, &args).await,
"setboostembed" => set_boostembed::handle_set_boostembed(ctx, msg, &args).await,
"set" => set::handle_set(ctx, msg, &args).await, "set" => set::handle_set(ctx, msg, &args).await,
"theme" => theme::handle_theme(ctx, msg, &args).await, "theme" => theme::handle_theme(ctx, msg, &args).await,
"playto" => playto::handle_playto(ctx, msg, &args).await, "playto" => playto::handle_playto(ctx, msg, &args).await,
@@ -439,27 +420,32 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"help" => help::handle_help(ctx, msg, &args).await, "help" => help::handle_help(ctx, msg, &args).await,
"helpsetting" => helpsetting::handle_helpsetting(ctx, msg, &args).await, "helpsetting" => helpsetting::handle_helpsetting(ctx, msg, &args).await,
"alias" => alias::handle_alias(ctx, msg, &args).await, "alias" => alias::handle_alias(ctx, msg, &args).await,
"mpsettings" => {
let mut forwarded = vec!["settings"];
forwarded.extend(args.iter().copied());
mp::handle_mp(ctx, msg, &forwarded).await
}
"mpsent" => {
let mut forwarded = vec!["sent"];
forwarded.extend(args.iter().copied());
mp::handle_mp(ctx, msg, &forwarded).await
}
"mpdelete" | "mpdel" => {
let mut forwarded = vec!["delete"];
forwarded.extend(args.iter().copied());
mp::handle_mp(ctx, msg, &forwarded).await
}
"mp" => mp::handle_mp(ctx, msg, &args).await, "mp" => mp::handle_mp(ctx, msg, &args).await,
"invite" => invite::handle_invite(ctx, msg, &args).await, "invite" => invite::handle_invite(ctx, msg, &args).await,
"leave" "leavesettings" => {
if args let mut forwarded = vec!["settings"];
.first() forwarded.extend(args.iter().copied());
.map(|s| s.eq_ignore_ascii_case("settings")) leave_settings::handle_leave_settings(ctx, msg, &forwarded).await
.unwrap_or(false) =>
{
leave_settings::handle_leave_settings(ctx, msg, &args).await
} }
"leave" => leave::handle_leave(ctx, msg, &args).await, "leave" => leave::handle_leave(ctx, msg, &args).await,
"viewlogs" => viewlogs::handle_viewlogs(ctx, msg, &args).await, "viewlogs" => viewlogs::handle_viewlogs(ctx, msg, &args).await,
"discussion" => discussion::handle_discussion(ctx, msg, &args).await, "discussion" => discussion::handle_discussion(ctx, msg, &args).await,
"remove" "removeactivity" => remove_activity::handle_remove_activity(ctx, msg).await,
if args
.first()
.map(|s| s.eq_ignore_ascii_case("activity"))
.unwrap_or(false) =>
{
remove_activity::handle_remove_activity(ctx, msg).await
}
"online" => online::handle_online(ctx, msg).await, "online" => online::handle_online(ctx, msg).await,
"idle" => idle::handle_idle(ctx, msg).await, "idle" => idle::handle_idle(ctx, msg).await,
"dnd" => dnd::handle_dnd(ctx, msg).await, "dnd" => dnd::handle_dnd(ctx, msg).await,
@@ -470,67 +456,33 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"unbl" => unbl::handle_unbl(ctx, msg, &args).await, "unbl" => unbl::handle_unbl(ctx, msg, &args).await,
"blinfo" => blinfo::handle_blinfo(ctx, msg, &args).await, "blinfo" => blinfo::handle_blinfo(ctx, msg, &args).await,
"say" => say::handle_say(ctx, msg, &args).await, "say" => say::handle_say(ctx, msg, &args).await,
"changereset" => {
let mut forwarded = vec!["reset"];
forwarded.extend(args.iter().copied());
change::handle_change(ctx, msg, &forwarded).await
}
"change" => change::handle_change(ctx, msg, &args).await, "change" => change::handle_change(ctx, msg, &args).await,
"changeall" => changeall::handle_changeall(ctx, msg, &args).await, "changeall" => changeall::handle_changeall(ctx, msg, &args).await,
"mainprefix" => mainprefix::handle_mainprefix(ctx, msg, &args).await, "mainprefix" => mainprefix::handle_mainprefix(ctx, msg, &args).await,
"prefix" => prefix::handle_prefix(ctx, msg, &args).await, "prefix" => prefix::handle_prefix(ctx, msg, &args).await,
"perms" => perms::handle_perms(ctx, msg, &args).await, "perms" => perms::handle_perms(ctx, msg, &args).await,
"allperms" => allperms::handle_allperms(ctx, msg, &args).await, "allperms" => allperms::handle_allperms(ctx, msg, &args).await,
"clear" "clearowners" => clear_owners::handle_clear_owners(ctx, msg).await,
if args "clearbl" => clear_bl::handle_clear_bl(ctx, msg).await,
.first() "clearperms" => clear_perms::handle_clear_perms(ctx, msg).await,
.map(|s| s.eq_ignore_ascii_case("owners")) "clearlimit" => {
.unwrap_or(false) => let mut forwarded = vec!["limit"];
{ forwarded.extend(args.iter().copied());
clear_owners::handle_clear_owners(ctx, msg).await clear_limit::handle_clear_limit(ctx, msg, &forwarded).await
} }
"clear" "clearbadwords" => clear_badwords::handle_clear_badwords(ctx, msg, &args).await,
if args "clearsanctions" => {
.first() let mut forwarded = vec!["sanctions"];
.map(|s| s.eq_ignore_ascii_case("bl")) forwarded.extend(args.iter().copied());
.unwrap_or(false) => clear_sanctions::handle_clear_sanctions(ctx, msg, &forwarded).await
{
clear_bl::handle_clear_bl(ctx, msg).await
}
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("perms"))
.unwrap_or(false) =>
{
clear_perms::handle_clear_perms(ctx, msg).await
}
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("limit"))
.unwrap_or(false) =>
{
clear_limit::handle_clear_limit(ctx, msg, &args).await
}
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("badwords"))
.unwrap_or(false) =>
{
clear_badwords::handle_clear_badwords(ctx, msg, &args).await
}
"clear"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("sanctions"))
.unwrap_or(false) =>
{
clear_sanctions::handle_clear_sanctions(ctx, msg, &args).await
}
"clear"
if args.len() >= 2
&& args[0].eq_ignore_ascii_case("all")
&& args[1].eq_ignore_ascii_case("sanctions") =>
{
clear_all_sanctions::handle_clear_all_sanctions(ctx, msg).await
} }
"clearallsanctions" => clear_all_sanctions::handle_clear_all_sanctions(ctx, msg).await,
"clearmessages" => clear_messages::handle_clear_messages(ctx, msg, &args).await,
"clear" => clear_messages::handle_clear_messages(ctx, msg, &args).await, "clear" => clear_messages::handle_clear_messages(ctx, msg, &args).await,
_ => {} _ => {}
} }
+71 -478
View File
@@ -1,6 +1,7 @@
use serenity::builder::CreateEmbed; use serenity::builder::CreateEmbed;
use serenity::model::prelude::*; use serenity::model::prelude::*;
use serenity::prelude::*; use serenity::prelude::*;
use std::collections::BTreeSet;
use std::env; use std::env;
use crate::commands::common::send_embed; use crate::commands::common::send_embed;
@@ -9,519 +10,111 @@ use crate::db::{
has_perm_level_access, is_bot_owner, has_perm_level_access, is_bot_owner,
}; };
const EXTRA_COMMAND_KEYS: &[&str] = &[
"ticket_settings",
"ticket_add",
"ticket_remove",
"ticket_close",
"suggestion_settings",
"setperm",
"delperm",
"changereset",
"serverlist",
"endgiveaway",
"mpsettings",
];
fn first_arg_is(args: &[&str], expected: &str) -> bool {
args.first()
.map(|value| value.eq_ignore_ascii_case(expected))
.unwrap_or(false)
}
pub fn command_key(command: &str, args: &[&str]) -> String { pub fn command_key(command: &str, args: &[&str]) -> String {
match command { let normalized = command.to_lowercase();
match normalized.as_str() {
"ticket" => "ticket_settings".to_string(), "ticket" => "ticket_settings".to_string(),
"claim" => "claim".to_string(),
"rename" => "rename".to_string(),
"add" => "ticket_add".to_string(), "add" => "ticket_add".to_string(),
"del" => { "del" => "ticket_remove".to_string(),
if args
.first()
.map(|s| s.eq_ignore_ascii_case("perm"))
.unwrap_or(false)
{
"del_perm".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("sanction"))
.unwrap_or(false)
{
"del_sanction".to_string()
} else {
"ticket_remove".to_string()
}
}
"close" => "ticket_close".to_string(), "close" => "ticket_close".to_string(),
"tickets" => "tickets".to_string(), "clear" => "clearmessages".to_string(),
"show" => {
if args
.first()
.map(|s| s.eq_ignore_ascii_case("pics"))
.unwrap_or(false)
{
"show_pics".to_string()
} else {
"show".to_string()
}
}
"showpics" => "show_pics".to_string(),
"suggestion" => { "suggestion" => {
if args if first_arg_is(args, "settings") {
.first()
.map(|s| s.eq_ignore_ascii_case("settings"))
.unwrap_or(false)
{
"suggestion_settings".to_string() "suggestion_settings".to_string()
} else { } else {
"suggestion_create".to_string() "suggestion_create".to_string()
} }
} }
"autopublish" => "autopublish".to_string(),
"tempvoc" => {
if args
.first()
.map(|s| s.eq_ignore_ascii_case("cmd"))
.unwrap_or(false)
{
"tempvoc_cmd".to_string()
} else {
"tempvoc".to_string()
}
}
"clear" => {
if args
.first()
.map(|s| s.eq_ignore_ascii_case("owners"))
.unwrap_or(false)
{
"clear_owners".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("bl"))
.unwrap_or(false)
{
"clear_bl".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("limit"))
.unwrap_or(false)
{
"clear_limit".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("badwords"))
.unwrap_or(false)
{
"clear_badwords".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("perms"))
.unwrap_or(false)
{
"clear_perms".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("sanctions"))
.unwrap_or(false)
{
"clear_sanctions".to_string()
} else if args.len() >= 2
&& args[0].eq_ignore_ascii_case("all")
&& args[1].eq_ignore_ascii_case("sanctions")
{
"clear_all_sanctions".to_string()
} else {
"clear_messages".to_string()
}
}
"change" => { "change" => {
if args if first_arg_is(args, "reset") {
.first() "changereset".to_string()
.map(|s| s.eq_ignore_ascii_case("reset"))
.unwrap_or(false)
{
"change_reset".to_string()
} else { } else {
"change".to_string() "change".to_string()
} }
} }
"remove" => {
if args
.first()
.map(|s| s.eq_ignore_ascii_case("activity"))
.unwrap_or(false)
{
"remove_activity".to_string()
} else {
"remove".to_string()
}
}
"set" => {
if args
.first()
.map(|s| s.eq_ignore_ascii_case("perm"))
.unwrap_or(false)
{
"set_perm".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("muterole"))
.unwrap_or(false)
{
"set_muterole".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("modlogs"))
.unwrap_or(false)
{
"set_modlogs".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("boostembed"))
.unwrap_or(false)
{
"set_boostembed".to_string()
} else {
"set".to_string()
}
}
"mp" => {
if args
.first()
.map(|s| s.eq_ignore_ascii_case("settings"))
.unwrap_or(false)
{
"mp_settings".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("sent"))
.unwrap_or(false)
{
"mp".to_string()
} else if args
.first()
.map(|s| s.eq_ignore_ascii_case("delete") || s.eq_ignore_ascii_case("del"))
.unwrap_or(false)
{
"mp".to_string()
} else {
"mp".to_string()
}
}
"server" => { "server" => {
if args if first_arg_is(args, "list") {
.first() "serverlist".to_string()
.map(|s| s.eq_ignore_ascii_case("list"))
.unwrap_or(false)
{
"server_list".to_string()
} else { } else {
"server".to_string() "server".to_string()
} }
} }
"end" => { "end" => {
if args if first_arg_is(args, "giveaway") {
.first() "endgiveaway".to_string()
.map(|s| s.eq_ignore_ascii_case("giveaway"))
.unwrap_or(false)
{
"end_giveaway".to_string()
} else { } else {
"end".to_string() "end".to_string()
} }
} }
"help" => "help".to_string(), "mp" => {
"helpsetting" => "helpsetting".to_string(), if first_arg_is(args, "settings") {
"helpetting" => "helpsetting".to_string(), "mpsettings".to_string()
"alias" => "alias".to_string(),
"modlog" => "modlog".to_string(),
"messagelog" => "messagelog".to_string(),
"voicelog" => "voicelog".to_string(),
"boostlog" => "boostlog".to_string(),
"rolelog" => "rolelog".to_string(),
"raidlog" => "raidlog".to_string(),
"autoconfiglog" => "autoconfiglog".to_string(),
"join" => "join".to_string(),
"boostembed" => "boostembed".to_string(),
"nolog" => "nolog".to_string(),
"invite" => "invite".to_string(),
"leave" => {
if args
.first()
.map(|s| s.eq_ignore_ascii_case("settings"))
.unwrap_or(false)
{
"leave_settings".to_string()
} else { } else {
"leave".to_string() "mp".to_string()
} }
} }
"discussion" => "discussion".to_string(), "mpsent" | "mpdelete" | "mpdel" => "mp".to_string(),
other => other.to_string(), "helpetting" => "helpsetting".to_string(),
_ => normalized,
} }
} }
pub fn all_command_keys() -> Vec<String> { pub fn all_command_keys() -> Vec<String> {
vec![ let mut keys = BTreeSet::new();
"ping",
"allbots", for meta in crate::commands::all_command_metadata() {
"alladmins", keys.insert(command_key(meta.name, &[]));
"botadmins", }
"boosters",
"rolemembers", for key in EXTRA_COMMAND_KEYS {
"rolemenu", keys.insert((*key).to_string());
"ancien", }
"serverinfo",
"vocinfo", keys.into_iter().collect()
"role", }
"channel",
"user", fn metadata_key_for_permission(command_key: &str) -> &str {
"member", match command_key {
"pic", "ticket_settings" => "ticket",
"banner", "ticket_add" | "ticket_remove" => "add",
"server", "ticket_close" => "close",
"snipe", "suggestion_create" | "suggestion_settings" => "suggestion",
"emoji", "setperm" => "set",
"giveaway", "delperm" => "del",
"end", "changereset" => "change",
"end_giveaway", "serverlist" => "server",
"sanctions", "endgiveaway" => "end",
"del_sanction", "mpsettings" => "mp",
"clear_sanctions", _ => command_key,
"clear_all_sanctions", }
"clear_messages",
"clear_limit",
"clear_badwords",
"timeout",
"muterole",
"set_muterole",
"antispam",
"antiraideautoconfig",
"antilink",
"antimassmention",
"badwords",
"spam",
"link",
"strikes",
"punish",
"noderank",
"public",
"resetantiraide",
"warn",
"mute",
"tempmute",
"unmute",
"cmute",
"tempcmute",
"uncmute",
"mutelist",
"unmuteall",
"kick",
"ban",
"tempban",
"unban",
"banlist",
"slowmode",
"lock",
"unlock",
"lockall",
"unlockall",
"hide",
"unhide",
"hideall",
"unhideall",
"addrole",
"delrole",
"derank",
"reroll",
"choose",
"embed",
"backup",
"ticket_settings",
"claim",
"rename",
"ticket_add",
"ticket_remove",
"ticket_close",
"tickets",
"show_pics",
"piconly",
"suggestion_create",
"suggestion_settings",
"autopublish",
"tempvoc",
"tempvoc_cmd",
"autobackup",
"loading",
"create",
"newsticker",
"massiverole",
"unmassiverole",
"voicemove",
"voicekick",
"cleanup",
"bringall",
"renew",
"unbanall",
"temprole",
"untemprole",
"sync",
"button",
"autoreact",
"calc",
"shadowbot",
"set",
"set_modlogs",
"set_boostembed",
"theme",
"playto",
"listen",
"watch",
"compet",
"stream",
"remove_activity",
"online",
"idle",
"dnd",
"invisible",
"owner",
"unowner",
"clear_owners",
"bl",
"unbl",
"blinfo",
"clear_bl",
"say",
"change",
"changeall",
"change_reset",
"mainprefix",
"prefix",
"perms",
"set_perm",
"del_perm",
"clear_perms",
"allperms",
"help",
"helpsetting",
"alias",
"modlog",
"messagelog",
"voicelog",
"boostlog",
"rolelog",
"raidlog",
"autoconfiglog",
"join",
"leave_settings",
"boostembed",
"nolog",
"mp",
"mp_settings",
"server_list",
"invite",
"leave",
"discussion",
]
.into_iter()
.map(String::from)
.collect()
} }
pub fn default_permission(command_key: &str) -> u8 { pub fn default_permission(command_key: &str) -> u8 {
match command_key { let metadata_key = metadata_key_for_permission(command_key);
"ticket_settings" | "suggestion_settings" | "autopublish" | "piconly" | "tempvoc" => 8, crate::commands::command_metadata_by_key(metadata_key)
"claim" | "rename" | "ticket_add" | "ticket_remove" | "ticket_close" | "tickets" => 2, .map(|meta| meta.default_permission)
"show_pics" | "suggestion_create" | "tempvoc_cmd" => 0, .unwrap_or(0)
"owner" | "unowner" | "clear_owners" => 9,
"bl" | "unbl" | "blinfo" | "clear_bl" => 9,
"change" | "changeall" | "change_reset" | "mainprefix" | "set_perm" | "del_perm"
| "clear_perms" => 9,
"set_modlogs" | "set_boostembed" | "set_muterole" => 8,
"prefix" | "perms" | "allperms" => 8,
"help" | "server_list" => 0,
"helpsetting" | "alias" | "leave" => 9,
"mp_settings" => 9,
"mp" | "mp_sent" | "mp_delete" | "invite" | "discussion" => 8,
"set"
| "theme"
| "playto"
| "listen"
| "watch"
| "compet"
| "stream"
| "remove_activity"
| "online"
| "idle"
| "dnd"
| "invisible"
| "say"
| "giveaway"
| "end_giveaway"
| "reroll"
| "choose"
| "embed"
| "backup"
| "autobackup"
| "loading"
| "create"
| "newsticker"
| "massiverole"
| "unmassiverole"
| "voicemove"
| "voicekick"
| "cleanup"
| "bringall"
| "renew"
| "unbanall"
| "temprole"
| "untemprole"
| "sync"
| "button"
| "autoreact"
| "sanctions"
| "del_sanction"
| "clear_sanctions"
| "clear_all_sanctions"
| "clear_messages"
| "clear_limit"
| "clear_badwords"
| "timeout"
| "muterole"
| "antispam"
| "antiraideautoconfig"
| "antilink"
| "antimassmention"
| "badwords"
| "spam"
| "link"
| "strikes"
| "punish"
| "noderank"
| "public"
| "resetantiraide"
| "warn"
| "mute"
| "tempmute"
| "unmute"
| "cmute"
| "tempcmute"
| "uncmute"
| "mutelist"
| "unmuteall"
| "kick"
| "ban"
| "tempban"
| "unban"
| "banlist"
| "slowmode"
| "lock"
| "unlock"
| "lockall"
| "unlockall"
| "hide"
| "unhide"
| "hideall"
| "unhideall"
| "addrole"
| "delrole"
| "derank"
| "rolemenu"
| "ancien"
| "modlog"
| "messagelog"
| "voicelog"
| "boostlog"
| "rolelog"
| "raidlog"
| "autoconfiglog"
| "join"
| "boostembed"
| "leave_settings"
| "nolog" => 8,
_ => 0,
}
} }
fn is_forced_owner_from_env(user_id: UserId) -> bool { fn is_forced_owner_from_env(user_id: UserId) -> bool {