netoyage et optimisation des commande pour que elle soit trier correctement

This commit is contained in:
Puechberty Arthur
2026-04-10 17:57:12 +02:00
parent 9a47588cdf
commit 00ae9cda11
72 changed files with 1788 additions and 1497 deletions
+73 -36
View File
@@ -12,7 +12,19 @@ pub async fn handle_autopublish(ctx: &Context, msg: &Message, args: &[&str]) {
return;
};
if args.is_empty() {
if !args.is_empty() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Autopublish")
.description("Utilisation: +autopublish")
.color(0xED4245),
)
.await;
return;
}
let Some(pool) = ({
let data = ctx.data.read().await;
data.get::<db::DbPoolKey>().cloned()
@@ -21,7 +33,9 @@ pub async fn handle_autopublish(ctx: &Context, msg: &Message, args: &[&str]) {
};
let bot_id = ctx.cache.current_user().id.get() as i64;
let channels = db::get_autopublish_channels(&pool, bot_id, guild_id.get() as i64)
let guild_id_i64 = guild_id.get() as i64;
let channels = db::get_autopublish_channels(&pool, bot_id, guild_id_i64)
.await
.unwrap_or_default();
let description = if channels.is_empty() {
@@ -43,23 +57,12 @@ pub async fn handle_autopublish(ctx: &Context, msg: &Message, args: &[&str]) {
.colour(Colour::from_rgb(100, 150, 255)),
)
.await;
return;
}
let enabled = args[0].eq_ignore_ascii_case("on") || args[0].eq_ignore_ascii_case("enable");
let disabled = args[0].eq_ignore_ascii_case("off") || args[0].eq_ignore_ascii_case("disable");
if !enabled && !disabled {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Autopublish")
.description("Utilisation: +autopublish on|off [#canal]")
.color(0xED4245),
)
.await;
pub async fn handle_autopublishon(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
}
};
let Some(pool) = ({
let data = ctx.data.read().await;
@@ -71,15 +74,11 @@ pub async fn handle_autopublish(ctx: &Context, msg: &Message, args: &[&str]) {
let bot_id = ctx.cache.current_user().id.get() as i64;
let guild_id_i64 = guild_id.get() as i64;
let channel_id = args
.get(1)
.first()
.and_then(|value| parse_channel_id(value))
.unwrap_or(msg.channel_id);
let result = if enabled {
db::add_autopublish_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await
} else {
db::remove_autopublish_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await
};
let result = db::add_autopublish_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await;
if result.is_err() {
send_embed(
@@ -94,21 +93,63 @@ pub async fn handle_autopublish(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let embed = if enabled {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Autopublish activé")
.description(format!("Salon: <#{}>", channel_id.get()))
.colour(Colour::from_rgb(0, 200, 120))
.timestamp(Utc::now())
} else {
.timestamp(Utc::now()),
)
.await;
}
pub async fn handle_autopublishoff(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
let Some(pool) = ({
let data = ctx.data.read().await;
data.get::<db::DbPoolKey>().cloned()
}) else {
return;
};
let bot_id = ctx.cache.current_user().id.get() as i64;
let guild_id_i64 = guild_id.get() as i64;
let channel_id = args
.first()
.and_then(|value| parse_channel_id(value))
.unwrap_or(msg.channel_id);
let result =
db::remove_autopublish_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await;
if result.is_err() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Autopublish")
.description("Impossible de mettre à jour le salon d'annonces.")
.color(0xED4245),
)
.await;
return;
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Autopublish désactivé")
.description(format!("Salon: <#{}>", channel_id.get()))
.colour(Colour::from_rgb(255, 120, 0))
.timestamp(Utc::now())
};
send_embed(ctx, msg, embed).await;
.timestamp(Utc::now()),
)
.await;
}
pub struct AutopublishCommand;
@@ -119,13 +160,9 @@ impl crate::commands::command_contract::CommandSpec for AutopublishCommand {
crate::commands::command_contract::CommandMetadata {
name: "autopublish",
category: "automation",
params: "on|off [#canal]",
description: "Affiche, active ou desactive la publication automatique des annonces.",
examples: &[
"+autopublish",
"+autopublish on #annonces",
"+help autopublish",
],
params: "aucun",
description: "Affiche les salons ou la publication automatique des annonces est active.",
examples: &["+autopublish", "+help autopublish"],
default_aliases: &["apb"],
allow_in_dm: false,
default_permission: 5,
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_autopublishoff_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::autopublish::handle_autopublishoff(ctx, msg, args).await;
}
pub struct AutopublishoffCommand;
pub static COMMAND_DESCRIPTOR: AutopublishoffCommand = AutopublishoffCommand;
impl crate::commands::command_contract::CommandSpec for AutopublishoffCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "autopublishoff",
category: "automation",
params: "[#canal]",
description: "Desactive la publication automatique des annonces sur un salon.",
examples: &["+autopublishoff", "+autopublishoff #annonces", "+help autopublishoff"],
default_aliases: &["apboff"],
allow_in_dm: false,
default_permission: 5,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_autopublishon_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::autopublish::handle_autopublishon(ctx, msg, args).await;
}
pub struct AutopublishonCommand;
pub static COMMAND_DESCRIPTOR: AutopublishonCommand = AutopublishonCommand;
impl crate::commands::command_contract::CommandSpec for AutopublishonCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "autopublishon",
category: "automation",
params: "[#canal]",
description: "Active la publication automatique des annonces sur un salon.",
examples: &["+autopublishon", "+autopublishon #annonces", "+help autopublishon"],
default_aliases: &["apbon"],
allow_in_dm: false,
default_permission: 5,
}
}
}
+80 -34
View File
@@ -106,7 +106,19 @@ pub async fn handle_piconly(ctx: &Context, msg: &Message, args: &[&str]) {
let bot_id = ctx.cache.current_user().id.get() as i64;
let guild_id_i64 = guild_id.get() as i64;
if args.is_empty() {
if !args.is_empty() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("PicOnly")
.description("Utilisation: +piconly")
.color(0xED4245),
)
.await;
return;
}
let channels = db::get_piconly_channels(&pool, bot_id, guild_id_i64)
.await
.unwrap_or_default();
@@ -130,37 +142,29 @@ pub async fn handle_piconly(ctx: &Context, msg: &Message, args: &[&str]) {
.timestamp(Utc::now()),
)
.await;
return;
}
let adding = args[0].eq_ignore_ascii_case("add");
let deleting = args[0].eq_ignore_ascii_case("del")
|| args[0].eq_ignore_ascii_case("remove")
|| args[0].eq_ignore_ascii_case("delete");
if !adding && !deleting {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("PicOnly")
.description("Utilisation: +piconly <add/del> [#salon]")
.color(0xED4245),
)
.await;
pub async fn handle_piconlyadd(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
}
};
let Some(pool) = ({
let data = ctx.data.read().await;
data.get::<db::DbPoolKey>().cloned()
}) else {
return;
};
let bot_id = ctx.cache.current_user().id.get() as i64;
let guild_id_i64 = guild_id.get() as i64;
let channel_id = args
.get(1)
.first()
.and_then(|raw| parse_channel_id(raw))
.unwrap_or(msg.channel_id);
let result = if adding {
db::add_piconly_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await
} else {
db::remove_piconly_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await
};
let result = db::add_piconly_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await;
if result.is_err() {
send_embed(
@@ -175,19 +179,61 @@ pub async fn handle_piconly(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let embed = if adding {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Salon selfie ajoute")
.description(format!("Salon: <#{}>", channel_id.get()))
.timestamp(Utc::now())
} else {
.timestamp(Utc::now()),
)
.await;
}
pub async fn handle_piconlydel(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
let Some(pool) = ({
let data = ctx.data.read().await;
data.get::<db::DbPoolKey>().cloned()
}) else {
return;
};
let bot_id = ctx.cache.current_user().id.get() as i64;
let guild_id_i64 = guild_id.get() as i64;
let channel_id = args
.first()
.and_then(|raw| parse_channel_id(raw))
.unwrap_or(msg.channel_id);
let result = db::remove_piconly_channel(&pool, bot_id, guild_id_i64, channel_id.get() as i64).await;
if result.is_err() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("PicOnly")
.description("Impossible de mettre a jour le salon selfie.")
.color(0xED4245),
)
.await;
return;
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Salon selfie retire")
.description(format!("Salon: <#{}>", channel_id.get()))
.timestamp(Utc::now())
};
send_embed(ctx, msg, embed).await;
.timestamp(Utc::now()),
)
.await;
}
pub struct PiconlyCommand;
@@ -198,9 +244,9 @@ impl crate::commands::command_contract::CommandSpec for PiconlyCommand {
crate::commands::command_contract::CommandMetadata {
name: "piconly",
category: "automation",
params: "<add/del> [salon]",
description: "Definit ou supprime un salon selfie, ou les membres ne peuvent envoyer que des photos.",
examples: &["+piconly", "+piconly add #selfie", "+piconly del #selfie"],
params: "aucun",
description: "Affiche la liste des salons selfie, ou les membres ne peuvent envoyer que des photos.",
examples: &["+piconly", "+help piconly"],
default_aliases: &["selfieonly"],
allow_in_dm: false,
default_permission: 6,
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_piconlyadd_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::piconly::handle_piconlyadd(ctx, msg, args).await;
}
pub struct PiconlyaddCommand;
pub static COMMAND_DESCRIPTOR: PiconlyaddCommand = PiconlyaddCommand;
impl crate::commands::command_contract::CommandSpec for PiconlyaddCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "piconlyadd",
category: "automation",
params: "[#salon]",
description: "Ajoute un salon selfie (photos uniquement).",
examples: &["+piconlyadd", "+piconlyadd #selfie", "+help piconlyadd"],
default_aliases: &["selfieadd"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_piconlydel_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::piconly::handle_piconlydel(ctx, msg, args).await;
}
pub struct PiconlydelCommand;
pub static COMMAND_DESCRIPTOR: PiconlydelCommand = PiconlydelCommand;
impl crate::commands::command_contract::CommandSpec for PiconlydelCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "piconlydel",
category: "automation",
params: "[#salon]",
description: "Retire un salon selfie (photos uniquement).",
examples: &["+piconlydel", "+piconlydel #selfie", "+help piconlydel"],
default_aliases: &["selfiedel"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+25 -16
View File
@@ -6,6 +6,29 @@ use crate::commands::common::send_embed;
use crate::commands::perms_helpers::{ensure_owner, get_pool, normalize_command_name};
use crate::db::{reset_command_permissions, set_command_permission};
pub async fn handle_changereset(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 = reset_command_permissions(&pool, bot_id).await.unwrap_or(0);
let embed = CreateEmbed::new()
.title("Permissions reinitialisees")
.description(format!("Overrides supprimes: {}", removed))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
}
pub async fn handle_change(ctx: &Context, msg: &Message, args: &[&str]) {
if !ensure_owner(ctx, msg).await {
return;
@@ -21,20 +44,6 @@ pub async fn handle_change(ctx: &Context, msg: &Message, args: &[&str]) {
return;
};
if args
.first()
.map(|s| s.eq_ignore_ascii_case("reset"))
.unwrap_or(false)
{
let removed = reset_command_permissions(&pool, bot_id).await.unwrap_or(0);
let embed = CreateEmbed::new()
.title("Permissions reinitialisees")
.description(format!("Overrides supprimes: {}", removed))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
return;
}
if args.len() < 2 {
let embed = CreateEmbed::new()
.title("Erreur")
@@ -79,8 +88,8 @@ impl crate::commands::command_contract::CommandSpec for ChangeCommand {
crate::commands::command_contract::CommandMetadata {
name: "change",
category: "botconfig",
params: "<commande> <niveau 0-9> | reset",
description: "Definit le niveau ACL requis pour une commande ou reinitialise les overrides.",
params: "<commande> <niveau 0-9>",
description: "Definit le niveau ACL requis pour une commande cible.",
examples: &["+change", "+ce", "+help change"],
default_aliases: &["chg"],
allow_in_dm: false,
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_changereset_command(ctx: &Context, msg: &Message, _args: &[&str]) {
crate::commands::change::handle_changereset(ctx, msg).await;
}
pub struct ChangeresetCommand;
pub static COMMAND_DESCRIPTOR: ChangeresetCommand = ChangeresetCommand;
impl crate::commands::command_contract::CommandSpec for ChangeresetCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "changereset",
category: "botconfig",
params: "aucun",
description: "Reinitialise tous les overrides ACL des commandes.",
examples: &["+changereset", "+help changereset"],
default_aliases: &["chgr"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+18 -63
View File
@@ -8,12 +8,12 @@ use crate::commands::perms_helpers::{
};
use crate::db::{grant_command_access, grant_perm_level};
async fn handle_set_perm(ctx: &Context, msg: &Message, args: &[&str]) {
pub async fn handle_setperm(ctx: &Context, msg: &Message, args: &[&str]) {
if !ensure_owner(ctx, msg).await {
return;
}
if args.len() < 3 || !args[0].eq_ignore_ascii_case("perm") {
if args.len() < 2 {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+setperm <permission/commande> <role/membre>`")
@@ -22,7 +22,7 @@ async fn handle_set_perm(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let Some((scope_type, scope_id)) = parse_user_or_role(args[2]) else {
let Some((scope_type, scope_id)) = parse_user_or_role(args[1]) else {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Role/membre invalide.")
@@ -41,7 +41,7 @@ async fn handle_set_perm(ctx: &Context, msg: &Message, args: &[&str]) {
return;
};
if let Ok(level) = args[1].parse::<u8>() {
if let Ok(level) = args[0].parse::<u8>() {
if level > 9 {
let embed = CreateEmbed::new()
.title("Erreur")
@@ -65,7 +65,7 @@ async fn handle_set_perm(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let command = normalize_command_name(args[1]);
let command = normalize_command_name(args[0]);
let _ = grant_command_access(&pool, bot_id, scope_type, scope_id, &command).await;
let who = if scope_type == "role" {
@@ -81,30 +81,8 @@ async fn handle_set_perm(ctx: &Context, msg: &Message, args: &[&str]) {
send_embed(ctx, msg, embed).await;
}
pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
if args
.first()
.map(|a| a.eq_ignore_ascii_case("perm"))
.unwrap_or(false)
{
handle_set_perm(ctx, msg, args).await;
return;
}
pub async fn handle_setname(ctx: &Context, msg: &Message, args: &[&str]) {
if args.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+set name|pic|banner|profil ...`")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let sub = args[0].to_lowercase();
match sub.as_str() {
"name" => {
if args.len() < 2 {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+setname <nom>`")
@@ -113,7 +91,7 @@ pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let name = args[1..].join(" ");
let name = args.join(" ");
let mut me = match ctx.http.get_current_user().await {
Ok(user) => user,
Err(err) => {
@@ -141,8 +119,9 @@ pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
};
send_embed(ctx, msg, embed).await;
}
"pic" => {
if args.len() < 2 {
pub async fn handle_setpic(ctx: &Context, msg: &Message, args: &[&str]) {
if args.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+setpic <lien_image>`")
@@ -151,7 +130,7 @@ pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let Ok(attachment) = CreateAttachment::url(&ctx.http, args[1]).await else {
let Ok(attachment) = CreateAttachment::url(&ctx.http, args[0]).await else {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Impossible de télécharger l'image.")
@@ -187,8 +166,9 @@ pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
};
send_embed(ctx, msg, embed).await;
}
"banner" => {
if args.len() < 2 {
pub async fn handle_setbanner(ctx: &Context, msg: &Message, args: &[&str]) {
if args.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+setbanner <lien_image>`")
@@ -197,7 +177,7 @@ pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let Ok(attachment) = CreateAttachment::url(&ctx.http, args[1]).await else {
let Ok(attachment) = CreateAttachment::url(&ctx.http, args[0]).await else {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Impossible de télécharger l'image.")
@@ -233,8 +213,9 @@ pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
};
send_embed(ctx, msg, embed).await;
}
"profil" => {
let raw = args[1..].join(" ");
pub async fn handle_setprofil(ctx: &Context, msg: &Message, args: &[&str]) {
let raw = args.join(" ");
let parts: Vec<&str> = raw.split(";;").map(|s| s.trim()).collect();
if parts.len() != 3 {
@@ -305,30 +286,4 @@ pub async fn handle_set(ctx: &Context, msg: &Message, args: &[&str]) {
};
send_embed(ctx, msg, embed).await;
}
_ => {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Sous-commande inconnue. Utilise `name`, `pic`, `banner` ou `profil`.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
}
}
}
pub struct SetCommand;
pub static COMMAND_DESCRIPTOR: SetCommand = SetCommand;
impl crate::commands::command_contract::CommandSpec for SetCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "set",
category: "botconfig",
params: "name <nom> | pic <url> | banner <url> | profil <nom> ;; <url_pic> ;; <url_banner> | perm ...",
description: "Modifie le nom, lavatar, la banniere ou des options avancees via les sous commandes.",
examples: &["+set", "+st", "+help set"],
default_aliases: &["cfg"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_setbanner_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::set::handle_setbanner(ctx, msg, args).await;
}
pub struct SetbannerCommand;
pub static COMMAND_DESCRIPTOR: SetbannerCommand = SetbannerCommand;
impl crate::commands::command_contract::CommandSpec for SetbannerCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setbanner",
category: "botconfig",
params: "<url>",
description: "Modifie la banniere du bot.",
examples: &["+setbanner https://exemple/banner.png", "+help setbanner"],
default_aliases: &["stbn"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_setname_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::set::handle_setname(ctx, msg, args).await;
}
pub struct SetnameCommand;
pub static COMMAND_DESCRIPTOR: SetnameCommand = SetnameCommand;
impl crate::commands::command_contract::CommandSpec for SetnameCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setname",
category: "botconfig",
params: "<nom>",
description: "Modifie le nom du bot.",
examples: &["+setname MonBot", "+help setname"],
default_aliases: &["stn"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_setperm_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::set::handle_setperm(ctx, msg, args).await;
}
pub struct SetpermCommand;
pub static COMMAND_DESCRIPTOR: SetpermCommand = SetpermCommand;
impl crate::commands::command_contract::CommandSpec for SetpermCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setperm",
category: "botconfig",
params: "<permission/commande> <role/membre>",
description: "Attribue un niveau ACL ou un acces commande a un role ou membre.",
examples: &["+setperm 6 @Moderateur", "+setperm mute @Role", "+help setperm"],
default_aliases: &["stp"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_setpic_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::set::handle_setpic(ctx, msg, args).await;
}
pub struct SetpicCommand;
pub static COMMAND_DESCRIPTOR: SetpicCommand = SetpicCommand;
impl crate::commands::command_contract::CommandSpec for SetpicCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setpic",
category: "botconfig",
params: "<url>",
description: "Modifie l'avatar du bot.",
examples: &["+setpic https://exemple/image.png", "+help setpic"],
default_aliases: &["stpic"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+27
View File
@@ -0,0 +1,27 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_setprofil_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::set::handle_setprofil(ctx, msg, args).await;
}
pub struct SetprofilCommand;
pub static COMMAND_DESCRIPTOR: SetprofilCommand = SetprofilCommand;
impl crate::commands::command_contract::CommandSpec for SetprofilCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "setprofil",
category: "botconfig",
params: "<nom> ;; <url_pic> ;; <url_banner>",
description: "Met a jour en une commande le nom, l'avatar et la banniere du bot.",
examples: &[
"+setprofil Shadow ;; https://img/a.png ;; https://img/b.png",
"+help setprofil",
],
default_aliases: &["stpr"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+20 -20
View File
@@ -15,20 +15,7 @@ pub async fn handle_join(ctx: &Context, msg: &Message, args: &[&str]) {
};
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("join settings")
.description("Usage: +join settings [on/off] [salon] [message...]")
.color(0xED4245),
)
.await;
return;
}
if args.len() == 1 {
if args.is_empty() {
let row = sqlx::query_as::<_, (bool, Option<i64>, Option<String>)>(
r#"
SELECT enabled, channel_id, custom_message
@@ -70,14 +57,27 @@ pub async fn handle_join(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let action = args[1].to_lowercase();
let action = args[0].to_lowercase();
if action != "on" && action != "off" {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("join settings")
.description("Usage: +joinsettings [on/off] [salon] [message...]")
.color(0xED4245),
)
.await;
return;
}
let enabled = action == "on";
let channel = if enabled {
parse_target_channel(msg, args, 2)
parse_target_channel(msg, args, 1)
} else {
None
};
let message_start = if enabled { 3 } else { 2 };
let message_start = if enabled { 2 } else { 1 };
let custom_message = if args.len() > message_start {
Some(args[message_start..].join(" "))
} else {
@@ -125,15 +125,15 @@ pub static COMMAND_DESCRIPTOR: JoinCommand = JoinCommand;
impl crate::commands::command_contract::CommandSpec for JoinCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "join",
name: "joinsettings",
category: "config",
params: "settings [on/off] [salon] [message]",
params: "[on/off] [salon] [message]",
description: "Permet de configurer les actions quand un membre rejoint.",
examples: &[
"+joinsettings",
"+joinsettings on #welcome Bienvenue {user}",
],
default_aliases: &["jset"],
default_aliases: &["jset", "join"],
allow_in_dm: false,
default_permission: 5,
}
-142
View File
@@ -1,142 +0,0 @@
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: "leave_settings",
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,
}
}
}
+18 -5
View File
@@ -16,7 +16,7 @@ pub async fn handle_leave_settings(ctx: &Context, msg: &Message, args: &[&str])
};
let bot_id = ctx.cache.current_user().id;
if args.is_empty() || !args[0].eq_ignore_ascii_case("settings") {
if args.is_empty() {
send_embed(
ctx,
msg,
@@ -71,14 +71,27 @@ pub async fn handle_leave_settings(ctx: &Context, msg: &Message, args: &[&str])
return;
}
let action = args[1].to_lowercase();
let action = args[0].to_lowercase();
if action != "on" && action != "off" {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("leave settings")
.description("Usage: +leavesettings [on/off] [salon] [message...]")
.color(0xED4245),
)
.await;
return;
}
let enabled = action == "on";
let channel = if enabled {
parse_target_channel(msg, args, 2)
parse_target_channel(msg, args, 1)
} else {
None
};
let message_start = if enabled { 3 } else { 2 };
let message_start = if enabled { 2 } else { 1 };
let custom_message = if args.len() > message_start {
Some(args[message_start..].join(" "))
} else {
@@ -128,7 +141,7 @@ impl crate::commands::command_contract::CommandSpec for LeaveSettingsCommand {
crate::commands::command_contract::CommandMetadata {
name: "leavesettings",
category: "config",
params: "settings [on/off] [salon] [message]",
params: "[on/off] [salon] [message]",
description: "Configure les actions a executer quand un membre quitte le serveur.",
examples: &[
"+leavesettings",
-115
View File
@@ -1,115 +0,0 @@
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: "set_boostembed",
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
@@ -1,125 +0,0 @@
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: "set_modlogs",
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,
}
}
}
+7 -20
View File
@@ -8,12 +8,8 @@ fn owned_component_id(action: &str, owner_id: UserId) -> String {
format!("{}:{}", action, owner_id.get())
}
async fn handle_end_giveaway(ctx: &Context, msg: &Message, args: &[&str]) {
let message_id_raw = args
.get(1)
.or_else(|| args.first())
.copied()
.unwrap_or_default();
pub async fn handle_endgiveaway(ctx: &Context, msg: &Message, args: &[&str]) {
let message_id_raw = args.first().copied().unwrap_or_default();
let Ok(message_id) = message_id_raw.trim().parse::<u64>() else {
send_embed(
@@ -76,21 +72,12 @@ pub async fn handle_end(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
if args
.first()
.map(|v| v.eq_ignore_ascii_case("giveaway"))
.unwrap_or(false)
{
handle_end_giveaway(ctx, msg, args).await;
return;
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("End")
.description("Usage: +endgiveaway <id_message>")
.description("Usage: +end")
.color(0xED4245),
)
.await;
@@ -104,10 +91,10 @@ impl crate::commands::command_contract::CommandSpec for EndCommand {
crate::commands::command_contract::CommandMetadata {
name: "end",
category: "event",
params: "giveaway <id_message>",
description: "Permet de stopper instantanement un giveaway avec l'identifiant du message.",
examples: &["+endgiveaway 123456789012345678"],
default_aliases: &["gend"],
params: "aucun",
description: "Affiche le panneau interactif pour terminer un giveaway.",
examples: &["+end", "+help end"],
default_aliases: &["endmenu"],
allow_in_dm: false,
default_permission: 6,
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_endgiveaway_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::end::handle_endgiveaway(ctx, msg, args).await;
}
pub struct EndgiveawayCommand;
pub static COMMAND_DESCRIPTOR: EndgiveawayCommand = EndgiveawayCommand;
impl crate::commands::command_contract::CommandSpec for EndgiveawayCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "endgiveaway",
category: "event",
params: "<id_message>",
description: "Termine instantanement un giveaway a partir de l'identifiant du message.",
examples: &["+endgiveaway 123456789012345678", "+help endgiveaway"],
default_aliases: &["gend"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+8 -17
View File
@@ -127,6 +127,10 @@ async fn show_menu(ctx: &Context, msg: &Message) {
.await;
}
pub async fn handle_suggestionsettings(ctx: &Context, msg: &Message, _args: &[&str]) {
show_menu(ctx, msg).await;
}
async fn submit_suggestion(
ctx: &Context,
guild_id: GuildId,
@@ -199,22 +203,13 @@ async fn submit_suggestion(
}
pub async fn handle_suggestion(ctx: &Context, msg: &Message, args: &[&str]) {
if args
.first()
.map(|value| value.eq_ignore_ascii_case("settings"))
.unwrap_or(false)
{
show_menu(ctx, msg).await;
return;
}
if args.is_empty() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Suggestion")
.description("Utilisation: +suggestion <contenu> ou +suggestion settings")
.description("Utilisation: +suggestion <contenu>")
.color(0xED4245),
)
.await;
@@ -505,13 +500,9 @@ impl crate::commands::command_contract::CommandSpec for SuggestionCommand {
crate::commands::command_contract::CommandMetadata {
name: "suggestion",
category: "fun",
params: "<contenu...> | settings",
description: "Publie une suggestion utilisateur ou ouvre le panneau de configuration.",
examples: &[
"+suggestion Ameliorer le salon",
"+suggestion settings",
"+help suggestion",
],
params: "<contenu...>",
description: "Publie une suggestion utilisateur dans le salon configure.",
examples: &["+suggestion Ameliorer le salon", "+help suggestion"],
default_aliases: &[],
allow_in_dm: false,
default_permission: 0,
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_suggestionsettings_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::suggestion::handle_suggestionsettings(ctx, msg, args).await;
}
pub struct SuggestionsettingsCommand;
pub static COMMAND_DESCRIPTOR: SuggestionsettingsCommand = SuggestionsettingsCommand;
impl crate::commands::command_contract::CommandSpec for SuggestionsettingsCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "suggestionsettings",
category: "fun",
params: "aucun",
description: "Ouvre le panneau de configuration des suggestions du serveur.",
examples: &["+suggestionsettings", "+sgset", "+help suggestionsettings"],
default_aliases: &["sgset"],
allow_in_dm: false,
default_permission: 0,
}
}
}
-170
View File
@@ -1,170 +0,0 @@
use serenity::builder::{CreateEmbed, CreateMessage};
use serenity::http::GuildPagination;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::{add_list_fields, send_embed, theme_color};
pub async fn handle_server(ctx: &Context, msg: &Message, args: &[&str]) {
if args
.first()
.map(|value| value.eq_ignore_ascii_case("list"))
.unwrap_or(false)
{
handle_server_list(ctx, msg).await;
return;
}
let Some(guild_id) = msg.guild_id else {
return;
};
let Ok(guild) = guild_id.to_partial_guild(&ctx).await else {
return;
};
if args.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+server pic`, `+server banner` ou `+serverlist`")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
match args[0].to_lowercase().as_str() {
"pic" | "icon" | "avatar" => {
let icon_url = guild.icon_url().unwrap_or_default();
if icon_url.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Ce serveur n'a pas d'icône.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let embed = CreateEmbed::new()
.title(format!("Icône du serveur {}", guild.name))
.image(icon_url)
.color(0x5865F2);
send_embed(ctx, msg, embed).await;
}
"banner" => {
let banner_url = guild.banner_url().unwrap_or_default();
if banner_url.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Ce serveur n'a pas de bannière.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let embed = CreateEmbed::new()
.title(format!("Bannière du serveur {}", guild.name))
.image(banner_url)
.color(0x5865F2);
send_embed(ctx, msg, embed).await;
}
_ => {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+server pic`, `+server banner` ou `+serverlist`")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
}
}
}
pub async fn handle_server_list(ctx: &Context, msg: &Message) {
let guilds = guilds_sorted(ctx).await;
let lines = guilds
.iter()
.enumerate()
.map(|(index, (guild_id, name))| format!("{} · {} · `{}`", index + 1, name, guild_id.get()))
.collect::<Vec<_>>();
let mut embed = CreateEmbed::new()
.title("Serveurs du bot")
.color(theme_color(ctx).await);
embed = add_list_fields(embed, &lines, "Guildes");
let _ = msg
.channel_id
.send_message(&ctx.http, CreateMessage::new().embed(embed))
.await;
}
pub(crate) async fn resolve_guild_target(ctx: &Context, input: &str) -> Option<GuildId> {
let guilds = guilds_sorted(ctx).await;
if let Ok(index) = input.parse::<usize>() {
if index >= 1 && index <= guilds.len() {
return Some(guilds[index - 1].0);
}
}
input
.parse::<u64>()
.ok()
.map(GuildId::new)
.filter(|id| guilds.iter().any(|(guild_id, _)| guild_id == id))
}
async fn guilds_sorted(ctx: &Context) -> Vec<(GuildId, String)> {
let mut all_guilds = Vec::new();
let mut after: Option<GuildId> = None;
loop {
let page = if let Some(after_id) = after {
ctx.http
.get_guilds(Some(GuildPagination::After(after_id)), Some(100))
.await
.unwrap_or_default()
} else {
ctx.http
.get_guilds(None, Some(100))
.await
.unwrap_or_default()
};
if page.is_empty() {
break;
}
after = page.last().map(|guild| guild.id);
all_guilds.extend(page.into_iter().map(|guild| (guild.id, guild.name)));
if all_guilds.len() % 100 != 0 {
break;
}
}
all_guilds.sort_by(|a, b| {
a.1.to_lowercase()
.cmp(&b.1.to_lowercase())
.then_with(|| a.0.get().cmp(&b.0.get()))
});
all_guilds
}
pub struct ServerCommand;
pub static COMMAND_DESCRIPTOR: ServerCommand = ServerCommand;
impl crate::commands::command_contract::CommandSpec for ServerCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "server",
category: "info",
params: "pic | banner | list",
description: "Affiche licone ou la banniere du serveur, ou liste les serveurs du bot selon la sous commande.",
examples: &["+server", "+sr", "+help server"],
default_aliases: &["srv"],
allow_in_dm: false,
default_permission: 0,
}
}
}
+49
View File
@@ -0,0 +1,49 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::send_embed;
pub async fn handle_serverbanner(ctx: &Context, msg: &Message, _args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
let Ok(guild) = guild_id.to_partial_guild(&ctx).await else {
return;
};
let banner_url = guild.banner_url().unwrap_or_default();
if banner_url.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Ce serveur n'a pas de banniere.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let embed = CreateEmbed::new()
.title(format!("Banniere du serveur {}", guild.name))
.image(banner_url)
.color(0x5865F2);
send_embed(ctx, msg, embed).await;
}
pub struct ServerbannerCommand;
pub static COMMAND_DESCRIPTOR: ServerbannerCommand = ServerbannerCommand;
impl crate::commands::command_contract::CommandSpec for ServerbannerCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "serverbanner",
category: "info",
params: "aucun",
description: "Affiche la banniere du serveur courant.",
examples: &["+serverbanner", "+sbn", "+help serverbanner"],
default_aliases: &["sbn"],
allow_in_dm: false,
default_permission: 0,
}
}
}
+42
View File
@@ -0,0 +1,42 @@
use serenity::builder::{CreateEmbed, CreateMessage};
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::{add_list_fields, theme_color};
pub async fn handle_serverlist(ctx: &Context, msg: &Message, _args: &[&str]) {
let guilds = crate::commands::servertarget::guilds_sorted(ctx).await;
let lines = guilds
.iter()
.enumerate()
.map(|(index, (guild_id, name))| format!("{} · {} · `{}`", index + 1, name, guild_id.get()))
.collect::<Vec<_>>();
let mut embed = CreateEmbed::new()
.title("Serveurs du bot")
.color(theme_color(ctx).await);
embed = add_list_fields(embed, &lines, "Guildes");
let _ = msg
.channel_id
.send_message(&ctx.http, CreateMessage::new().embed(embed))
.await;
}
pub struct ServerlistCommand;
pub static COMMAND_DESCRIPTOR: ServerlistCommand = ServerlistCommand;
impl crate::commands::command_contract::CommandSpec for ServerlistCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "serverlist",
category: "info",
params: "aucun",
description: "Liste les serveurs ou le bot est present.",
examples: &["+serverlist", "+sls", "+help serverlist"],
default_aliases: &["sls"],
allow_in_dm: false,
default_permission: 0,
}
}
}
+49
View File
@@ -0,0 +1,49 @@
use serenity::builder::CreateEmbed;
use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::send_embed;
pub async fn handle_serverpic(ctx: &Context, msg: &Message, _args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
let Ok(guild) = guild_id.to_partial_guild(&ctx).await else {
return;
};
let icon_url = guild.icon_url().unwrap_or_default();
if icon_url.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Ce serveur n'a pas d'icone.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let embed = CreateEmbed::new()
.title(format!("Icone du serveur {}", guild.name))
.image(icon_url)
.color(0x5865F2);
send_embed(ctx, msg, embed).await;
}
pub struct ServerpicCommand;
pub static COMMAND_DESCRIPTOR: ServerpicCommand = ServerpicCommand;
impl crate::commands::command_contract::CommandSpec for ServerpicCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "serverpic",
category: "info",
params: "aucun",
description: "Affiche l'icone du serveur courant.",
examples: &["+serverpic", "+spi", "+help serverpic"],
default_aliases: &["spi"],
allow_in_dm: false,
default_permission: 0,
}
}
}
+55
View File
@@ -0,0 +1,55 @@
use serenity::http::GuildPagination;
use serenity::model::prelude::*;
use serenity::prelude::*;
pub(crate) async fn resolve_guild_target(ctx: &Context, input: &str) -> Option<GuildId> {
let guilds = guilds_sorted(ctx).await;
if let Ok(index) = input.parse::<usize>() {
if index >= 1 && index <= guilds.len() {
return Some(guilds[index - 1].0);
}
}
input
.parse::<u64>()
.ok()
.map(GuildId::new)
.filter(|id| guilds.iter().any(|(guild_id, _)| guild_id == id))
}
pub(crate) async fn guilds_sorted(ctx: &Context) -> Vec<(GuildId, String)> {
let mut all_guilds = Vec::new();
let mut after: Option<GuildId> = None;
loop {
let page = if let Some(after_id) = after {
ctx.http
.get_guilds(Some(GuildPagination::After(after_id)), Some(100))
.await
.unwrap_or_default()
} else {
ctx.http
.get_guilds(None, Some(100))
.await
.unwrap_or_default()
};
if page.is_empty() {
break;
}
after = page.last().map(|guild| guild.id);
all_guilds.extend(page.into_iter().map(|guild| (guild.id, guild.name)));
if all_guilds.len() % 100 != 0 {
break;
}
}
all_guilds.sort_by(|a, b| {
a.1.to_lowercase()
.cmp(&b.1.to_lowercase())
.then_with(|| a.0.get().cmp(&b.0.get()))
});
all_guilds
}
+77 -5
View File
@@ -7,6 +7,8 @@ pub mod admin_service;
pub mod advanced_tools;
#[path = "perms/alias.rs"]
pub mod alias;
#[path = "perms/unalias.rs"]
pub mod unalias;
#[path = "info/alladmins.rs"]
pub mod alladmins;
#[path = "info/allbots.rs"]
@@ -30,6 +32,10 @@ pub mod autoconfiglog;
pub mod automod_service;
#[path = "automation/autopublish.rs"]
pub mod autopublish;
#[path = "automation/autopublishoff.rs"]
pub mod autopublishoff;
#[path = "automation/autopublishon.rs"]
pub mod autopublishon;
#[path = "automation/autoreact.rs"]
pub mod autoreact;
#[path = "automation/backup.rs"]
@@ -64,6 +70,8 @@ pub mod button;
pub mod calc;
#[path = "botconfig/change.rs"]
pub mod change;
#[path = "botconfig/changereset.rs"]
pub mod changereset;
#[path = "botconfig/changeall.rs"]
pub mod changeall;
#[path = "info/channel.rs"]
@@ -102,6 +110,8 @@ pub mod compet;
pub mod create;
#[path = "perms/del.rs"]
pub mod del;
#[path = "perms/delperm.rs"]
pub mod delperm;
#[path = "mod/delsanction.rs"]
pub mod del_sanction;
#[path = "roles/delrole.rs"]
@@ -118,6 +128,8 @@ pub mod embed;
pub mod emoji;
#[path = "event/end.rs"]
pub mod end;
#[path = "event/endgiveaway.rs"]
pub mod endgiveaway;
#[path = "event/giveaway.rs"]
pub mod giveaway;
#[path = "perms/help.rs"]
@@ -169,6 +181,12 @@ pub mod moderation_tools;
pub mod modlog;
#[path = "owner/mp.rs"]
pub mod mp;
#[path = "owner/mpdelete.rs"]
pub mod mpdelete;
#[path = "owner/mpsent.rs"]
pub mod mpsent;
#[path = "owner/mpsettings.rs"]
pub mod mpsettings;
#[path = "mod/mute.rs"]
pub mod mute;
#[path = "mod/mutelist.rs"]
@@ -179,6 +197,10 @@ pub mod muterole;
pub mod newsticker;
#[path = "roles/noderank.rs"]
pub mod noderank;
#[path = "roles/noderankadd.rs"]
pub mod noderankadd;
#[path = "roles/noderankdel.rs"]
pub mod noderankdel;
#[path = "config/nolog.rs"]
pub mod nolog;
#[path = "botconfig/online.rs"]
@@ -193,6 +215,10 @@ pub mod perms_service;
pub mod pic;
#[path = "automation/piconly.rs"]
pub mod piconly;
#[path = "automation/piconlyadd.rs"]
pub mod piconlyadd;
#[path = "automation/piconlydel.rs"]
pub mod piconlydel;
#[path = "info/ping.rs"]
pub mod ping;
#[path = "botconfig/playto.rs"]
@@ -203,6 +229,12 @@ pub mod prefix;
pub mod public;
#[path = "mod/punish.rs"]
pub mod punish;
#[path = "mod/punishadd.rs"]
pub mod punishadd;
#[path = "mod/punishdel.rs"]
pub mod punishdel;
#[path = "mod/punishsetup.rs"]
pub mod punishsetup;
#[path = "config/raidlog.rs"]
pub mod raidlog;
#[path = "botconfig/removeactivity.rs"]
@@ -227,12 +259,28 @@ pub mod rolemenu;
pub mod sanctions;
#[path = "fun/say.rs"]
pub mod say;
#[path = "info/server.rs"]
pub mod server;
#[path = "info/serverbanner.rs"]
pub mod serverbanner;
#[path = "info/serverlist.rs"]
pub mod serverlist;
#[path = "info/serverpic.rs"]
pub mod serverpic;
#[path = "info/servertarget.rs"]
pub mod servertarget;
#[path = "info/serverinfo.rs"]
pub mod serverinfo;
#[path = "botconfig/set.rs"]
pub mod set;
#[path = "botconfig/setbanner.rs"]
pub mod setbanner;
#[path = "botconfig/setname.rs"]
pub mod setname;
#[path = "botconfig/setperm.rs"]
pub mod setperm;
#[path = "botconfig/setpic.rs"]
pub mod setpic;
#[path = "botconfig/setprofil.rs"]
pub mod setprofil;
#[path = "config/setboostembed.rs"]
pub mod set_boostembed;
#[path = "config/setmodlogs.rs"]
@@ -255,6 +303,8 @@ pub mod stream;
pub mod strikes;
#[path = "fun/suggestion.rs"]
pub mod suggestion;
#[path = "fun/suggestionsettings.rs"]
pub mod suggestionsettings;
#[path = "roles/sync.rs"]
pub mod sync;
#[path = "mod/tempban.rs"]
@@ -343,10 +393,13 @@ pub fn all_command_metadata() -> Vec<CommandMetadata> {
member::COMMAND_DESCRIPTOR.metadata(),
pic::COMMAND_DESCRIPTOR.metadata(),
banner::COMMAND_DESCRIPTOR.metadata(),
server::COMMAND_DESCRIPTOR.metadata(),
serverpic::COMMAND_DESCRIPTOR.metadata(),
serverbanner::COMMAND_DESCRIPTOR.metadata(),
serverlist::COMMAND_DESCRIPTOR.metadata(),
snipe::COMMAND_DESCRIPTOR.metadata(),
emoji::COMMAND_DESCRIPTOR.metadata(),
giveaway::COMMAND_DESCRIPTOR.metadata(),
endgiveaway::COMMAND_DESCRIPTOR.metadata(),
modlog::COMMAND_DESCRIPTOR.metadata(),
messagelog::COMMAND_DESCRIPTOR.metadata(),
voicelog::COMMAND_DESCRIPTOR.metadata(),
@@ -376,6 +429,9 @@ pub fn all_command_metadata() -> Vec<CommandMetadata> {
link::COMMAND_DESCRIPTOR.metadata(),
strikes::COMMAND_DESCRIPTOR.metadata(),
punish::COMMAND_DESCRIPTOR.metadata(),
punishsetup::COMMAND_DESCRIPTOR.metadata(),
punishadd::COMMAND_DESCRIPTOR.metadata(),
punishdel::COMMAND_DESCRIPTOR.metadata(),
public::COMMAND_DESCRIPTOR.metadata(),
resetantiraide::COMMAND_DESCRIPTOR.metadata(),
backup::COMMAND_DESCRIPTOR.metadata(),
@@ -387,8 +443,13 @@ pub fn all_command_metadata() -> Vec<CommandMetadata> {
tickets::COMMAND_DESCRIPTOR.metadata(),
showpics::COMMAND_DESCRIPTOR.metadata(),
piconly::COMMAND_DESCRIPTOR.metadata(),
piconlyadd::COMMAND_DESCRIPTOR.metadata(),
piconlydel::COMMAND_DESCRIPTOR.metadata(),
suggestion::COMMAND_DESCRIPTOR.metadata(),
suggestionsettings::COMMAND_DESCRIPTOR.metadata(),
autopublish::COMMAND_DESCRIPTOR.metadata(),
autopublishon::COMMAND_DESCRIPTOR.metadata(),
autopublishoff::COMMAND_DESCRIPTOR.metadata(),
tempvoc::COMMAND_DESCRIPTOR.metadata(),
tempvoc_cmd::COMMAND_DESCRIPTOR.metadata(),
autobackup::COMMAND_DESCRIPTOR.metadata(),
@@ -430,6 +491,8 @@ pub fn all_command_metadata() -> Vec<CommandMetadata> {
delrole::COMMAND_DESCRIPTOR.metadata(),
derank::COMMAND_DESCRIPTOR.metadata(),
noderank::COMMAND_DESCRIPTOR.metadata(),
noderankadd::COMMAND_DESCRIPTOR.metadata(),
noderankdel::COMMAND_DESCRIPTOR.metadata(),
del_sanction::COMMAND_DESCRIPTOR.metadata(),
clear_sanctions::COMMAND_DESCRIPTOR.metadata(),
clear_all_sanctions::COMMAND_DESCRIPTOR.metadata(),
@@ -440,7 +503,11 @@ pub fn all_command_metadata() -> Vec<CommandMetadata> {
autoreact::COMMAND_DESCRIPTOR.metadata(),
calc::COMMAND_DESCRIPTOR.metadata(),
shadowbot::COMMAND_DESCRIPTOR.metadata(),
set::COMMAND_DESCRIPTOR.metadata(),
setname::COMMAND_DESCRIPTOR.metadata(),
setpic::COMMAND_DESCRIPTOR.metadata(),
setbanner::COMMAND_DESCRIPTOR.metadata(),
setprofil::COMMAND_DESCRIPTOR.metadata(),
setperm::COMMAND_DESCRIPTOR.metadata(),
theme::COMMAND_DESCRIPTOR.metadata(),
playto::COMMAND_DESCRIPTOR.metadata(),
listen::COMMAND_DESCRIPTOR.metadata(),
@@ -461,17 +528,22 @@ pub fn all_command_metadata() -> Vec<CommandMetadata> {
clear_bl::COMMAND_DESCRIPTOR.metadata(),
say::COMMAND_DESCRIPTOR.metadata(),
change::COMMAND_DESCRIPTOR.metadata(),
changereset::COMMAND_DESCRIPTOR.metadata(),
changeall::COMMAND_DESCRIPTOR.metadata(),
mainprefix::COMMAND_DESCRIPTOR.metadata(),
prefix::COMMAND_DESCRIPTOR.metadata(),
perms::COMMAND_DESCRIPTOR.metadata(),
del::COMMAND_DESCRIPTOR.metadata(),
delperm::COMMAND_DESCRIPTOR.metadata(),
clear_perms::COMMAND_DESCRIPTOR.metadata(),
allperms::COMMAND_DESCRIPTOR.metadata(),
help::COMMAND_DESCRIPTOR.metadata(),
helpsetting::COMMAND_DESCRIPTOR.metadata(),
alias::COMMAND_DESCRIPTOR.metadata(),
unalias::COMMAND_DESCRIPTOR.metadata(),
mp::COMMAND_DESCRIPTOR.metadata(),
mpsettings::COMMAND_DESCRIPTOR.metadata(),
mpsent::COMMAND_DESCRIPTOR.metadata(),
mpdelete::COMMAND_DESCRIPTOR.metadata(),
invite::COMMAND_DESCRIPTOR.metadata(),
leave::COMMAND_DESCRIPTOR.metadata(),
leave_settings::COMMAND_DESCRIPTOR.metadata(),
+1 -1
View File
@@ -39,7 +39,7 @@ impl crate::commands::command_contract::CommandSpec for ClearBadwordsCommand {
crate::commands::command_contract::CommandMetadata {
name: "clearbadwords",
category: "mod",
params: "badwords",
params: "aucun",
description: "Supprime l ensemble des mots interdits enregistres.",
examples: &["+clearbadwords", "+help clearbadwords"],
default_aliases: &["cbw"],
+2 -2
View File
@@ -11,7 +11,7 @@ pub async fn handle_clear_limit(ctx: &Context, msg: &Message, args: &[&str]) {
return;
};
let Some(raw_value) = args.get(1) else {
let Some(raw_value) = args.first() else {
send_embed(
ctx,
msg,
@@ -63,7 +63,7 @@ impl crate::commands::command_contract::CommandSpec for ClearLimitCommand {
crate::commands::command_contract::CommandMetadata {
name: "clearlimit",
category: "mod",
params: "limit <nombre>",
params: "<nombre>",
description: "Definit la limite max de messages supprimables avec +clear.",
examples: &["+clearlimit 100", "+help clearlimit"],
default_aliases: &["climit"],
+2 -2
View File
@@ -10,11 +10,11 @@ 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 {
if args.is_empty() {
return;
}
let Some(target) = parse_user_id(args[1]) else {
let Some(target) = parse_user_id(args[0]) else {
return;
};
+3 -3
View File
@@ -10,14 +10,14 @@ 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 {
if args.len() < 2 {
return;
}
let Some(target) = parse_user_id(args[1]) else {
let Some(target) = parse_user_id(args[0]) else {
return;
};
let Ok(index) = args[2].parse::<usize>() else {
let Ok(index) = args[1].parse::<usize>() else {
return;
};
if index == 0 {
+75 -30
View File
@@ -35,7 +35,19 @@ pub async fn handle_punish(ctx: &Context, msg: &Message, args: &[&str]) {
let bot_id = ctx.cache.current_user().id.get() as i64;
let guild_id_raw = guild_id.get() as i64;
if args.is_empty() {
if !args.is_empty() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Punish")
.description("Usage: +punish")
.color(0xED4245),
)
.await;
return;
}
let rules = db::list_punish_rules(&pool, bot_id, guild_id_raw)
.await
.unwrap_or_default();
@@ -60,10 +72,19 @@ pub async fn handle_punish(ctx: &Context, msg: &Message, args: &[&str]) {
.color(0x5865F2),
)
.await;
return;
}
if args[0].eq_ignore_ascii_case("setup") {
pub async fn handle_punishsetup(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 guild_id_raw = guild_id.get() as i64;
let _ = db::setup_default_punish_rules(&pool, bot_id, guild_id_raw).await;
send_embed(
ctx,
@@ -74,24 +95,42 @@ pub async fn handle_punish(ctx: &Context, msg: &Message, args: &[&str]) {
.color(0x57F287),
)
.await;
}
pub async fn handle_punishadd(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 guild_id_raw = guild_id.get() as i64;
if args.len() < 3 {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Punish")
.description("Usage: +punishadd <nombre> <duree> <sanction> [duree]")
.color(0xED4245),
)
.await;
return;
}
if args[0].eq_ignore_ascii_case("add") {
if args.len() < 4 {
return;
}
let Ok(threshold) = args[1].parse::<i32>() else {
let Ok(threshold) = args[0].parse::<i32>() else {
return;
};
let Some(window_seconds) = parse_duration_to_seconds(args[2]) else {
let Some(window_seconds) = parse_duration_to_seconds(args[1]) else {
return;
};
let Some(sanction) = parse_sanction(args[3]) else {
let Some(sanction) = parse_sanction(args[2]) else {
return;
};
let sanction_seconds = args.get(4).and_then(|raw| parse_duration_to_seconds(raw));
let sanction_seconds = args.get(3).and_then(|raw| parse_duration_to_seconds(raw));
let _ = db::upsert_punish_rule(
&pool,
@@ -113,11 +152,29 @@ pub async fn handle_punish(ctx: &Context, msg: &Message, args: &[&str]) {
.color(0x57F287),
)
.await;
return;
}
if args[0].eq_ignore_ascii_case("del") {
let Some(raw_index) = args.get(1) else {
pub async fn handle_punishdel(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 guild_id_raw = guild_id.get() as i64;
let Some(raw_index) = args.first() else {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Punish")
.description("Usage: +punishdel <numero>")
.color(0xED4245),
)
.await;
return;
};
let Ok(index) = raw_index.parse::<usize>() else {
@@ -143,18 +200,6 @@ pub async fn handle_punish(ctx: &Context, msg: &Message, args: &[&str]) {
.color(0x57F287),
)
.await;
return;
}
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("Punish")
.description("Usage: +punish | +punish add <nombre> <duree> <sanction> [duree] | +punish del <numero> | +punish setup")
.color(0xED4245),
)
.await;
}
pub struct PunishCommand;
@@ -165,9 +210,9 @@ impl crate::commands::command_contract::CommandSpec for PunishCommand {
crate::commands::command_contract::CommandMetadata {
name: "punish",
category: "mod",
params: "[add <nombre> <duree> <sanction> [duree] | del <numero> | setup]",
description: "Affiche et gere les sanctions automatiques appliquees selon les strikes.",
examples: &["+punish", "+punish add 8 1h mute 30m", "+punish setup"],
params: "aucun",
description: "Affiche les sanctions automatiques appliquees selon les strikes.",
examples: &["+punish", "+help punish"],
default_aliases: &["pn"],
allow_in_dm: false,
default_permission: 7,
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_punishadd_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::punish::handle_punishadd(ctx, msg, args).await;
}
pub struct PunishaddCommand;
pub static COMMAND_DESCRIPTOR: PunishaddCommand = PunishaddCommand;
impl crate::commands::command_contract::CommandSpec for PunishaddCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "punishadd",
category: "mod",
params: "<nombre> <duree> <sanction> [duree]",
description: "Ajoute ou met a jour une regle Punish.",
examples: &["+punishadd 8 1h mute 30m", "+help punishadd"],
default_aliases: &["pna"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_punishdel_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::punish::handle_punishdel(ctx, msg, args).await;
}
pub struct PunishdelCommand;
pub static COMMAND_DESCRIPTOR: PunishdelCommand = PunishdelCommand;
impl crate::commands::command_contract::CommandSpec for PunishdelCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "punishdel",
category: "mod",
params: "<numero>",
description: "Supprime une regle Punish par son index.",
examples: &["+punishdel 2", "+help punishdel"],
default_aliases: &["pnd"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_punishsetup_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::punish::handle_punishsetup(ctx, msg, args).await;
}
pub struct PunishsetupCommand;
pub static COMMAND_DESCRIPTOR: PunishsetupCommand = PunishsetupCommand;
impl crate::commands::command_contract::CommandSpec for PunishsetupCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "punishsetup",
category: "mod",
params: "aucun",
description: "Recharge les regles Punish par defaut.",
examples: &["+punishsetup", "+help punishsetup"],
default_aliases: &["pnsetup"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+2 -2
View File
@@ -11,7 +11,7 @@ pub async fn handle_set_muterole(ctx: &Context, msg: &Message, args: &[&str]) {
return;
};
let Some(raw_role) = args.get(1) else {
let Some(raw_role) = args.first() else {
send_embed(
ctx,
msg,
@@ -68,7 +68,7 @@ impl crate::commands::command_contract::CommandSpec for SetMuteRoleCommand {
crate::commands::command_contract::CommandMetadata {
name: "setmuterole",
category: "mod",
params: "muterole <@role/ID/nom>",
params: "<@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"],
+1 -1
View File
@@ -3,7 +3,7 @@ use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::send_embed;
use crate::commands::server::resolve_guild_target;
use crate::commands::servertarget::resolve_guild_target;
pub async fn handle_discussion(ctx: &Context, msg: &Message, args: &[&str]) {
if args.len() < 2 {
+1 -1
View File
@@ -3,7 +3,7 @@ use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::send_embed;
use crate::commands::server::resolve_guild_target;
use crate::commands::servertarget::resolve_guild_target;
pub async fn handle_invite(ctx: &Context, msg: &Message, args: &[&str]) {
if args.is_empty() {
+1 -1
View File
@@ -3,7 +3,7 @@ use serenity::model::prelude::*;
use serenity::prelude::*;
use crate::commands::common::send_embed;
use crate::commands::server::resolve_guild_target;
use crate::commands::servertarget::resolve_guild_target;
pub async fn handle_leave(ctx: &Context, msg: &Message, args: &[&str]) {
let target = if args.is_empty() {
+12 -27
View File
@@ -13,12 +13,7 @@ use crate::db::{
log_sent_mp_message, mark_sent_mp_deleted, set_mp_enabled,
};
pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
if args
.first()
.map(|value| value.eq_ignore_ascii_case("settings"))
.unwrap_or(false)
{
pub async fn handle_mpsettings(ctx: &Context, msg: &Message, args: &[&str]) {
let bot_id = ctx.cache.current_user().id;
let Some(pool) = pool(ctx).await else {
let embed = CreateEmbed::new()
@@ -29,7 +24,7 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
return;
};
if args.len() == 1 {
if args.is_empty() {
let enabled = get_mp_enabled(&pool, bot_id)
.await
.ok()
@@ -46,7 +41,7 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
let enabled = match args[1].to_lowercase().as_str() {
let enabled = match args[0].to_lowercase().as_str() {
"on" | "true" | "yes" => true,
"off" | "false" | "no" => false,
_ => {
@@ -68,29 +63,19 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
return;
}
if args
.first()
.map(|value| value.eq_ignore_ascii_case("sent"))
.unwrap_or(false)
{
pub async fn handle_mpsent(ctx: &Context, msg: &Message, args: &[&str]) {
let page = args
.get(1)
.first()
.and_then(|value| value.parse::<i64>().ok())
.filter(|value| *value >= 1)
.unwrap_or(1);
let _ = send_mp_sent_page(ctx, msg, page).await;
return;
}
if args
.first()
.map(|value| value.eq_ignore_ascii_case("delete") || value.eq_ignore_ascii_case("del"))
.unwrap_or(false)
{
let Some(entry_id_raw) = args.get(1) else {
pub async fn handle_mpdelete(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(entry_id_raw) = args.first() else {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+mpdelete <id>`")
@@ -152,13 +137,13 @@ pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
.color(0x57F287);
send_embed(ctx, msg, embed).await;
}
return;
}
pub async fn handle_mp(ctx: &Context, msg: &Message, args: &[&str]) {
if args.len() < 2 {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+mpsettings` ou `+mp <membre> <message>`")
.description("Usage: `+mp <membre> <message>`")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
@@ -462,9 +447,9 @@ impl crate::commands::command_contract::CommandSpec for MpCommand {
crate::commands::command_contract::CommandMetadata {
name: "mp",
category: "owner",
params: "settings [on|off] | sent [page] | delete <id> | <@membre/ID> <message...>",
description: "Permet de configurer, envoyer, lister et supprimer des messages prives envoyes.",
examples: &["+mp", "+help mp"],
params: "<@membre/ID> <message...>",
description: "Envoie un message prive a un membre cible.",
examples: &["+mp @Arthur Salut", "+help mp"],
default_aliases: &["dmsg"],
allow_in_dm: false,
default_permission: 9,
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_mpdelete_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::mp::handle_mpdelete(ctx, msg, args).await;
}
pub struct MpdeleteCommand;
pub static COMMAND_DESCRIPTOR: MpdeleteCommand = MpdeleteCommand;
impl crate::commands::command_contract::CommandSpec for MpdeleteCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "mpdelete",
category: "owner",
params: "<id>",
description: "Supprime un MP envoye precedemment a partir de son identifiant interne.",
examples: &["+mpdelete 12", "+mpdel 12", "+help mpdelete"],
default_aliases: &["mpdel"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_mpsent_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::mp::handle_mpsent(ctx, msg, args).await;
}
pub struct MpsentCommand;
pub static COMMAND_DESCRIPTOR: MpsentCommand = MpsentCommand;
impl crate::commands::command_contract::CommandSpec for MpsentCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "mpsent",
category: "owner",
params: "[page]",
description: "Affiche l'historique des MP envoyes par le bot.",
examples: &["+mpsent", "+mpsent 2", "+help mpsent"],
default_aliases: &["mps"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_mpsettings_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::mp::handle_mpsettings(ctx, msg, args).await;
}
pub struct MpsettingsCommand;
pub static COMMAND_DESCRIPTOR: MpsettingsCommand = MpsettingsCommand;
impl crate::commands::command_contract::CommandSpec for MpsettingsCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "mpsettings",
category: "owner",
params: "[on|off]",
description: "Affiche ou modifie l'etat global de l'envoi de MP par le bot.",
examples: &["+mpsettings", "+mpsettings off", "+help mpsettings"],
default_aliases: &["mpset"],
allow_in_dm: false,
default_permission: 9,
}
}
}
+44 -26
View File
@@ -18,7 +18,7 @@ pub async fn handle_alias(ctx: &Context, msg: &Message, args: &[&str]) {
return;
};
if args.len() == 1 {
if args.is_empty() {
let aliases = list_command_aliases(&pool, bot_id)
.await
.unwrap_or_default();
@@ -44,28 +44,6 @@ pub async fn handle_alias(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
if args[0].eq_ignore_ascii_case("remove") || args[0].eq_ignore_ascii_case("delete") {
let alias_name = args[1].trim_start_matches('+').to_lowercase();
if alias_name.is_empty() {
let embed = serenity::builder::CreateEmbed::new()
.title("Erreur")
.description("Alias invalide.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let removed = remove_command_alias(&pool, bot_id, &alias_name)
.await
.unwrap_or(0);
let embed = serenity::builder::CreateEmbed::new()
.title("Alias supprimé")
.description(format!("`{}` : {} suppression(s).", alias_name, removed))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
return;
}
let command = args[0].trim_start_matches('+').to_lowercase();
let is_known = all_command_keys().iter().any(|candidate| candidate == &command)
|| crate::commands::command_metadata_by_key(&command).is_some();
@@ -99,6 +77,46 @@ pub async fn handle_alias(ctx: &Context, msg: &Message, args: &[&str]) {
send_embed(ctx, msg, embed).await;
}
pub async fn handle_unalias(ctx: &Context, msg: &Message, args: &[&str]) {
let bot_id = ctx.cache.current_user().id;
let Some(pool) = pool(ctx).await else {
let embed = serenity::builder::CreateEmbed::new()
.title("Erreur")
.description("DB indisponible.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
};
let Some(raw_alias) = args.first() else {
let embed = serenity::builder::CreateEmbed::new()
.title("Erreur")
.description("Usage: `+unalias <alias>`")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
};
let alias_name = raw_alias.trim_start_matches('+').to_lowercase();
if alias_name.is_empty() {
let embed = serenity::builder::CreateEmbed::new()
.title("Erreur")
.description("Alias invalide.")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let removed = remove_command_alias(&pool, bot_id, &alias_name)
.await
.unwrap_or(0);
let embed = serenity::builder::CreateEmbed::new()
.title("Alias supprimé")
.description(format!("`{}` : {} suppression(s).", alias_name, removed))
.color(0x57F287);
send_embed(ctx, msg, embed).await;
}
async fn pool(ctx: &Context) -> Option<sqlx::PgPool> {
let data = ctx.data.read().await;
data.get::<DbPoolKey>().cloned()
@@ -124,9 +142,9 @@ impl crate::commands::command_contract::CommandSpec for AliasCommand {
crate::commands::command_contract::CommandMetadata {
name: "alias",
category: "perms",
params: "<commande> <alias> | remove <alias> | list",
description: "Liste, ajoute ou supprime des aliases de commandes stockes en base.",
examples: &["+alias", "+as", "+help alias"],
params: "[<commande> <alias>]",
description: "Liste les aliases (sans argument) ou ajoute un alias de commande.",
examples: &["+alias", "+alias mute m", "+help alias"],
default_aliases: &["als"],
allow_in_dm: false,
default_permission: 6,
+3 -20
View File
@@ -11,16 +11,16 @@ pub async fn handle_del(ctx: &Context, msg: &Message, args: &[&str]) {
return;
}
if args.len() < 2 || !args[0].eq_ignore_ascii_case("perm") {
if args.is_empty() {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Usage: `+delperm <role>`")
.description("Usage: `+delperm <role/membre>`")
.color(0xED4245);
send_embed(ctx, msg, embed).await;
return;
}
let Some((scope_type, scope_id)) = parse_user_or_role(args[1]) else {
let Some((scope_type, scope_id)) = parse_user_or_role(args[0]) else {
let embed = CreateEmbed::new()
.title("Erreur")
.description("Role/membre invalide.")
@@ -50,20 +50,3 @@ pub async fn handle_del(ctx: &Context, msg: &Message, args: &[&str]) {
send_embed(ctx, msg, embed).await;
}
pub struct DelCommand;
pub static COMMAND_DESCRIPTOR: DelCommand = DelCommand;
impl crate::commands::command_contract::CommandSpec for DelCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "del",
category: "perms",
params: "perm <@&rôle/@membre/ID>",
description: "Supprime les permissions ACL associees a un role ou utilisateur.",
examples: &["+del", "+dl", "+help del"],
default_aliases: &["dlp"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_delperm_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::del::handle_del(ctx, msg, args).await;
}
pub struct DelpermCommand;
pub static COMMAND_DESCRIPTOR: DelpermCommand = DelpermCommand;
impl crate::commands::command_contract::CommandSpec for DelpermCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "delperm",
category: "perms",
params: "<@&role/@membre/ID>",
description: "Supprime les permissions ACL associees a un role ou utilisateur.",
examples: &["+delperm @Role", "+help delperm"],
default_aliases: &["dlp"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+40 -52
View File
@@ -133,8 +133,8 @@ fn help_page_for_command(
) -> &'static str {
match meta.name {
"modlog" | "messagelog" | "voicelog" | "boostlog" | "rolelog" | "raidlog"
| "autoconfiglog" | "nolog" | "join" | "boostembed" | "setmodlogs" | "setboostembed"
| "leavesettings" | "viewlogs" => "logs",
| "autoconfiglog" | "nolog" | "joinsettings" | "boostembed" | "setmodlogs"
| "setboostembed" | "leavesettings" | "viewlogs" => "logs",
"warn"
| "mute"
| "tempmute"
@@ -164,14 +164,19 @@ fn help_page_for_command(
"giveaway" | "end" | "reroll" | "choose" | "calc" | "emoji" | "embed" | "say"
| "create" | "newsticker" | "button" | "autoreact" | "snipe" | "loading" | "backup"
| "autobackup" => "outils",
"shadowbot" | "set" | "theme" | "playto" | "listen" | "watch" | "compet" | "stream"
| "removeactivity" | "online" | "idle" | "dnd" | "invisible" | "change" | "changeall" => {
"shadowbot" | "setname" | "setpic" | "setbanner" | "setprofil" | "setperm"
| "theme" | "playto" | "listen" | "watch" | "compet" | "stream"
| "removeactivity" | "online" | "idle" | "dnd" | "invisible" | "change"
| "changereset" | "changeall" => {
"bot"
}
"owner" | "unowner" | "clearowners" | "bl" | "unbl" | "blinfo" | "clearbl"
| "allbots" | "alladmins" | "botadmins" | "mainprefix" | "prefix" | "mp" | "invite"
| "leave" | "discussion" => "administration",
"perms" | "del" | "clearperms" | "allperms" | "alias" | "help" | "helpsetting" => {
| "allbots" | "alladmins" | "botadmins" | "mainprefix" | "prefix" | "mp"
| "mpsettings" | "mpsent" | "mpdelete" | "invite" | "leave" | "discussion" => {
"administration"
}
"perms" | "delperm" | "clearperms" | "allperms" | "alias" | "help"
| "helpsetting" => {
"permissions"
}
_ => match meta.category {
@@ -193,6 +198,7 @@ fn help_page_for_command(
"administration" => "administration",
"permissions" => "permissions",
"general" => "infos",
"automation" => "outils",
"profile" => "bot",
"admin" => "administration",
_ => "infos",
@@ -332,48 +338,6 @@ async fn aliases_map(ctx: &Context) -> BTreeMap<String, Vec<String>> {
fn command_doc(key: &str) -> Option<CommandDoc> {
let (meta, command, acl_key, alias_source_key) = match key {
"mpsettings" => (
crate::commands::command_metadata_by_key("mp")?,
"mpsettings",
"mpsettings",
Some("mp"),
),
"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))
@@ -423,22 +387,37 @@ fn help_lookup_to_key(input: &str) -> Option<&'static str> {
"member" => Some("member"),
"pic" => Some("pic"),
"banner" => Some("banner"),
"server" => Some("server"),
"server" | "server list" => Some("serverlist"),
"server pic" | "serverpic" => Some("serverpic"),
"server banner" | "serverbanner" => Some("serverbanner"),
"serverlist" => Some("serverlist"),
"suggestion settings" | "suggestionsettings" => Some("suggestionsettings"),
"snipe" => Some("snipe"),
"emoji" => Some("emoji"),
"giveaway" => Some("giveaway"),
"end" | "endgiveaway" => Some("end"),
"end" => Some("end"),
"end giveaway" | "endgiveaway" => Some("endgiveaway"),
"reroll" => Some("reroll"),
"choose" => Some("choose"),
"embed" => Some("embed"),
"backup" | "backup list" | "backup delete" | "backup load" => Some("backup"),
"autopublish" => Some("autopublish"),
"autopublish on" | "autopublishon" => Some("autopublishon"),
"autopublish off" | "autopublishoff" => Some("autopublishoff"),
"autobackup" => Some("autobackup"),
"loading" => Some("loading"),
"create" => Some("create"),
"newsticker" => Some("newsticker"),
"piconly" => Some("piconly"),
"piconly add" | "piconlyadd" => Some("piconlyadd"),
"piconly del" | "piconly remove" | "piconly delete" | "piconlydel" => {
Some("piconlydel")
}
"massiverole" => Some("massiverole"),
"unmassiverole" => Some("unmassiverole"),
"noderank" => Some("noderank"),
"noderank add" | "noderankadd" => Some("noderankadd"),
"noderank del" | "noderank remove" | "noderankdel" => Some("noderankdel"),
"voicemove" => Some("voicemove"),
"voicekick" => Some("voicekick"),
"cleanup" => Some("cleanup"),
@@ -452,7 +431,10 @@ fn help_lookup_to_key(input: &str) -> Option<&'static str> {
"autoreact" => Some("autoreact"),
"calc" => Some("calc"),
"shadowbot" => Some("shadowbot"),
"set" => Some("set"),
"set" | "set name" | "setname" => Some("setname"),
"set pic" | "setpic" => Some("setpic"),
"set banner" | "setbanner" => Some("setbanner"),
"set profil" | "setprofil" => Some("setprofil"),
"theme" => Some("theme"),
"playto" => Some("playto"),
"listen" => Some("listen"),
@@ -479,6 +461,7 @@ fn help_lookup_to_key(input: &str) -> Option<&'static str> {
"say" => Some("say"),
"invite" => Some("invite"),
"leave" => Some("leave"),
"join" | "join settings" | "joinsettings" => Some("joinsettings"),
"change" => Some("change"),
"changereset" => Some("changereset"),
"changeall" => Some("changeall"),
@@ -488,8 +471,13 @@ fn help_lookup_to_key(input: &str) -> Option<&'static str> {
"allperms" => Some("allperms"),
"setperm" => Some("setperm"),
"delperm" => Some("delperm"),
"punish" => Some("punish"),
"punish setup" | "punishsetup" => Some("punishsetup"),
"punish add" | "punishadd" => Some("punishadd"),
"punish del" | "punishdel" => Some("punishdel"),
"clearperms" => Some("clearperms"),
"alias" => Some("alias"),
"alias remove" | "alias delete" | "unalias" => Some("unalias"),
"helpsetting" | "helpetting" => Some("helpsetting"),
_ => None,
};
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_unalias_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::alias::handle_unalias(ctx, msg, args).await;
}
pub struct UnaliasCommand;
pub static COMMAND_DESCRIPTOR: UnaliasCommand = UnaliasCommand;
impl crate::commands::command_contract::CommandSpec for UnaliasCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "unalias",
category: "perms",
params: "<alias>",
description: "Supprime un alias de commande en base.",
examples: &["+unalias m", "+help unalias"],
default_aliases: &["uals"],
allow_in_dm: false,
default_permission: 6,
}
}
}
+86 -10
View File
@@ -17,7 +17,19 @@ pub async fn handle_noderank(ctx: &Context, msg: &Message, args: &[&str]) {
let bot_id = ctx.cache.current_user().id.get() as i64;
let guild_id_raw = guild_id.get() as i64;
if args.is_empty() {
if !args.is_empty() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("NoDeRank")
.description("Utilisation: +noderank")
.color(0xED4245),
)
.await;
return;
}
let roles = db::list_noderank_roles(&pool, bot_id, guild_id_raw)
.await
.unwrap_or_default();
@@ -40,21 +52,48 @@ pub async fn handle_noderank(ctx: &Context, msg: &Message, args: &[&str]) {
.color(0x5865F2),
)
.await;
}
pub async fn handle_noderankadd(ctx: &Context, msg: &Message, args: &[&str]) {
if args.is_empty() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("NoDeRank")
.description("Utilisation: +noderankadd <@role/ID/nom>")
.color(0xED4245),
)
.await;
return;
}
if args.len() < 2 {
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 guild_id_raw = guild_id.get() as i64;
let Ok(guild) = guild_id.to_partial_guild(&ctx.http).await else {
return;
};
let Some(role) = parse_role(&guild, args[1]) else {
let Some(role) = parse_role(&guild, args[0]) else {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("NoDeRank")
.description("Role introuvable.")
.color(0xED4245),
)
.await;
return;
};
if args[0].eq_ignore_ascii_case("add") {
let _ = db::add_noderank_role(&pool, bot_id, guild_id_raw, role.id.get() as i64).await;
send_embed(
ctx,
@@ -65,10 +104,48 @@ pub async fn handle_noderank(ctx: &Context, msg: &Message, args: &[&str]) {
.color(0x57F287),
)
.await;
}
pub async fn handle_noderankdel(ctx: &Context, msg: &Message, args: &[&str]) {
if args.is_empty() {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("NoDeRank")
.description("Utilisation: +noderankdel <@role/ID/nom>")
.color(0xED4245),
)
.await;
return;
}
if args[0].eq_ignore_ascii_case("del") || args[0].eq_ignore_ascii_case("remove") {
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 guild_id_raw = guild_id.get() as i64;
let Ok(guild) = guild_id.to_partial_guild(&ctx.http).await else {
return;
};
let Some(role) = parse_role(&guild, args[0]) else {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("NoDeRank")
.description("Role introuvable.")
.color(0xED4245),
)
.await;
return;
};
let _ = db::remove_noderank_role(&pool, bot_id, guild_id_raw, role.id.get() as i64).await;
send_embed(
ctx,
@@ -80,7 +157,6 @@ pub async fn handle_noderank(ctx: &Context, msg: &Message, args: &[&str]) {
)
.await;
}
}
pub struct NoderankCommand;
pub static COMMAND_DESCRIPTOR: NoderankCommand = NoderankCommand;
@@ -90,9 +166,9 @@ impl crate::commands::command_contract::CommandSpec for NoderankCommand {
crate::commands::command_contract::CommandMetadata {
name: "noderank",
category: "roles",
params: "[add/del <@role/ID/nom>]",
description: "Definit des roles proteges qui ne sont pas retires par +derank.",
examples: &["+noderank", "+noderank add @VIP", "+noderank del @VIP"],
params: "aucun",
description: "Affiche la liste des roles proteges qui ne sont pas retires par +derank.",
examples: &["+noderank", "+help noderank"],
default_aliases: &["ndr"],
allow_in_dm: false,
default_permission: 7,
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_noderankadd_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::noderank::handle_noderankadd(ctx, msg, args).await;
}
pub struct NoderankaddCommand;
pub static COMMAND_DESCRIPTOR: NoderankaddCommand = NoderankaddCommand;
impl crate::commands::command_contract::CommandSpec for NoderankaddCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "noderankadd",
category: "roles",
params: "<@role/ID/nom>",
description: "Ajoute un role a la liste NoDeRank.",
examples: &["+noderankadd @VIP", "+help noderankadd"],
default_aliases: &["ndra"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use serenity::model::prelude::*;
use serenity::prelude::*;
pub async fn handle_noderankdel_command(ctx: &Context, msg: &Message, args: &[&str]) {
crate::commands::noderank::handle_noderankdel(ctx, msg, args).await;
}
pub struct NoderankdelCommand;
pub static COMMAND_DESCRIPTOR: NoderankdelCommand = NoderankdelCommand;
impl crate::commands::command_contract::CommandSpec for NoderankdelCommand {
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
crate::commands::command_contract::CommandMetadata {
name: "noderankdel",
category: "roles",
params: "<@role/ID/nom>",
description: "Retire un role de la liste NoDeRank.",
examples: &["+noderankdel @VIP", "+help noderankdel"],
default_aliases: &["ndrd"],
allow_in_dm: false,
default_permission: 7,
}
}
}
+49 -82
View File
@@ -7,20 +7,24 @@ use crate::commands::moderation_tools;
use crate::commands::remove_activity;
use crate::commands::{
addrole, alias, ancien, antilink, antimassmention, antiraideautoconfig, antispam, autobackup,
autoconfiglog, autopublish, autoreact, backup, badwords, ban, banlist, banner, bl, blinfo,
boostembed, boosters, boostlog, bringall, button, calc, change, changeall, channel, choose,
claim, cleanup, clear_all_sanctions, clear_badwords, clear_bl, clear_limit, clear_messages,
clear_owners, clear_perms, clear_sanctions, close, cmute, compet, create, del, del_sanction,
delrole, derank, discussion, dnd, embed, emoji, end, giveaway, help, helpsetting, hide,
hideall, idle, invisible, invite, join, kick, leave, leave_settings, link, listen, loading,
lock, lockall, mainprefix, massiverole, member, messagelog, modlog, mp, mute, mutelist,
muterole, newsticker, noderank, nolog, online, owner, perms, pic, piconly, ping, playto,
prefix, public, punish, raidlog, rename, renew, reroll, resetantiraide, role, rolelog,
rolemembers, rolemenu, sanctions, say, server, serverinfo, set, set_boostembed, set_modlogs,
set_muterole, shadowbot, showpics, slowmode, snipe, spam, stream, strikes, suggestion, sync,
autoconfiglog, autopublish, autopublishoff, autopublishon, autoreact, backup, badwords, ban,
banlist, banner, bl, blinfo, boostembed, boosters, boostlog, bringall, button, calc, change,
changeall, changereset,
channel, choose, claim, cleanup, clear_all_sanctions, clear_badwords, clear_bl, clear_limit,
clear_messages, clear_owners, clear_perms, clear_sanctions, close, cmute, compet, create,
del_sanction, delperm, delrole, derank, discussion, dnd, embed, emoji, end, endgiveaway,
giveaway, help, helpsetting, hide, hideall, idle, invisible, invite, join, kick, leave,
leave_settings, link, listen, loading, lock, lockall, mainprefix, massiverole, member,
messagelog, modlog, mp, mpdelete, mpsent, mpsettings, mute, mutelist, muterole, newsticker,
noderank, noderankadd, noderankdel, nolog, online, owner, perms, pic, piconly, piconlyadd,
piconlydel, ping, playto, prefix, public, punish, punishadd, punishdel, punishsetup,
raidlog, rename, renew, reroll, resetantiraide, role, rolelog, rolemembers, rolemenu,
sanctions, say, serverbanner, serverinfo, serverlist, serverpic, set_boostembed,
set_modlogs, set_muterole, setbanner, setname, setperm, setpic, setprofil, shadowbot,
showpics, slowmode, snipe, spam, stream, strikes, suggestion, suggestionsettings, sync,
tempban, tempcmute, tempmute, temprole, tempvoc, tempvoc_cmd, theme, ticket, ticket_member,
tickets, timeout, unban, unbanall, unbl, uncmute, unhide, unhideall, unlock, unlockall,
unmassiverole, unmute, unmuteall, unowner, untemprole, user, viewlogs, vocinfo, voicekick,
unalias, unmassiverole, unmute, unmuteall, unowner, untemprole, user, viewlogs, vocinfo, voicekick,
voicelog, voicemove, warn, watch,
};
use crate::commands::{alladmins, allbots, allperms, botadmins};
@@ -141,16 +145,10 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
.or_else(|| {
let mapped = match command_key.as_str() {
"showpics" => Some("showpics"),
"suggestion_create" | "suggestion_settings" => Some("suggestion"),
"ticket_settings" => Some("ticket"),
"ticket_add" => Some("add"),
"ticket_remove" => Some("del"),
"ticket_close" => Some("close"),
"setperm" => Some("set"),
"changereset" => Some("change"),
"serverlist" => Some("server"),
"endgiveaway" => Some("end"),
"mpsettings" | "mpsent" | "mpdelete" => Some("mp"),
_ => None,
};
@@ -191,23 +189,22 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"claim" => claim::handle_claim(ctx, msg, &args).await,
"rename" => rename::handle_rename(ctx, msg, &args).await,
"add" => ticket_member::handle_ticket_add(ctx, msg, &args).await,
"delperm" => {
let mut forwarded = vec!["perm"];
forwarded.extend(args.iter().copied());
del::handle_del(ctx, msg, &forwarded).await
}
"delsanction" => {
let mut forwarded = vec!["sanction"];
forwarded.extend(args.iter().copied());
del_sanction::handle_del_sanction(ctx, msg, &forwarded).await
}
"delperm" => delperm::handle_delperm_command(ctx, msg, &args).await,
"delsanction" => del_sanction::handle_del_sanction(ctx, msg, &args).await,
"del" => ticket_member::handle_ticket_remove(ctx, msg, &args).await,
"close" => close::handle_close(ctx, msg, &args).await,
"tickets" => tickets::handle_tickets(ctx, msg, &args).await,
"showpics" => showpics::handle_show_pics(ctx, msg, &args).await,
"piconly" => piconly::handle_piconly(ctx, msg, &args).await,
"piconlyadd" => piconlyadd::handle_piconlyadd_command(ctx, msg, &args).await,
"piconlydel" => piconlydel::handle_piconlydel_command(ctx, msg, &args).await,
"suggestion" => suggestion::handle_suggestion(ctx, msg, &args).await,
"suggestionsettings" => {
suggestionsettings::handle_suggestionsettings_command(ctx, msg, &args).await
}
"autopublish" => autopublish::handle_autopublish(ctx, msg, &args).await,
"autopublishon" => autopublishon::handle_autopublishon_command(ctx, msg, &args).await,
"autopublishoff" => autopublishoff::handle_autopublishoff_command(ctx, msg, &args).await,
"tempvoccmd" => tempvoc_cmd::handle_tempvoc_cmd(ctx, msg, &args).await,
"tempvoc" => tempvoc::handle_tempvoc(ctx, msg, &args).await,
"ping" => ping::handle_ping(ctx, msg, &args).await,
@@ -224,6 +221,9 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"link" => link::handle_link_override(ctx, msg, &args).await,
"strikes" => strikes::handle_strikes(ctx, msg, &args).await,
"punish" => punish::handle_punish(ctx, msg, &args).await,
"punishsetup" => punishsetup::handle_punishsetup_command(ctx, msg, &args).await,
"punishadd" => punishadd::handle_punishadd_command(ctx, msg, &args).await,
"punishdel" => punishdel::handle_punishdel_command(ctx, msg, &args).await,
"public" => public::handle_public(ctx, msg, &args).await,
"resetantiraide" => resetantiraide::handle_resetantiraide(ctx, msg, &args).await,
"allbots" => allbots::handle_allbots(ctx, msg, &args).await,
@@ -241,8 +241,9 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"member" => member::handle_member(ctx, msg, &args).await,
"pic" => pic::handle_pic(ctx, msg, &args).await,
"banner" => banner::handle_banner(ctx, msg, &args).await,
"server" => server::handle_server(ctx, msg, &args).await,
"serverlist" => server::handle_server_list(ctx, msg).await,
"serverpic" => serverpic::handle_serverpic(ctx, msg, &args).await,
"serverbanner" => serverbanner::handle_serverbanner(ctx, msg, &args).await,
"serverlist" => serverlist::handle_serverlist(ctx, msg, &args).await,
"snipe" => snipe::handle_snipe(ctx, msg, &args).await,
"emoji" => emoji::handle_emoji(ctx, msg, &args).await,
"giveaway" => giveaway::handle_giveaway(ctx, msg, &args).await,
@@ -253,15 +254,11 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"rolelog" => rolelog::handle_rolelog(ctx, msg, &args).await,
"raidlog" => raidlog::handle_raidlog(ctx, msg, &args).await,
"autoconfiglog" => autoconfiglog::handle_autoconfiglog(ctx, msg).await,
"join" => join::handle_join(ctx, msg, &args).await,
"joinsettings" => join::handle_join(ctx, msg, &args).await,
"boostembed" => boostembed::handle_boostembed(ctx, msg, &args).await,
"nolog" => nolog::handle_nolog(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
}
"endgiveaway" => endgiveaway::handle_endgiveaway_command(ctx, msg, &args).await,
"end" => end::handle_end(ctx, msg, &args).await,
"reroll" => reroll::handle_reroll(ctx, msg, &args).await,
"choose" => choose::handle_choose(ctx, msg, &args).await,
@@ -391,6 +388,8 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
crate::commands::logs_service::log_moderation_command(ctx, msg, "derank", &args).await;
}
"noderank" => noderank::handle_noderank(ctx, msg, &args).await,
"noderankadd" => noderankadd::handle_noderankadd_command(ctx, msg, &args).await,
"noderankdel" => noderankdel::handle_noderankdel_command(ctx, msg, &args).await,
"temprole" => temprole::handle_temprole(ctx, msg, &args).await,
"untemprole" => untemprole::handle_untemprole(ctx, msg, &args).await,
"sync" => sync::handle_sync(ctx, msg, &args).await,
@@ -398,19 +397,14 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"autoreact" => autoreact::handle_autoreact(ctx, msg, &args).await,
"calc" => calc::handle_calc(ctx, msg, &args).await,
"shadowbot" => shadowbot::handle_shadowbot(ctx, msg, &args).await,
"setperm" => {
let mut forwarded = vec!["perm"];
forwarded.extend(args.iter().copied());
set::handle_set(ctx, msg, &forwarded).await
}
"setmuterole" => {
let mut forwarded = vec!["muterole"];
forwarded.extend(args.iter().copied());
set_muterole::handle_set_muterole(ctx, msg, &forwarded).await
}
"setperm" => setperm::handle_setperm_command(ctx, msg, &args).await,
"setname" => setname::handle_setname_command(ctx, msg, &args).await,
"setpic" => setpic::handle_setpic_command(ctx, msg, &args).await,
"setbanner" => setbanner::handle_setbanner_command(ctx, msg, &args).await,
"setprofil" => setprofil::handle_setprofil_command(ctx, msg, &args).await,
"setmuterole" => set_muterole::handle_set_muterole(ctx, msg, &args).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,
"theme" => theme::handle_theme(ctx, msg, &args).await,
"playto" => playto::handle_playto(ctx, msg, &args).await,
"listen" => listen::handle_listen(ctx, msg, &args).await,
@@ -420,28 +414,13 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"help" => help::handle_help(ctx, msg, &args).await,
"helpsetting" => helpsetting::handle_helpsetting(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
}
"unalias" => unalias::handle_unalias_command(ctx, msg, &args).await,
"mpsettings" => mpsettings::handle_mpsettings_command(ctx, msg, &args).await,
"mpsent" => mpsent::handle_mpsent_command(ctx, msg, &args).await,
"mpdelete" | "mpdel" => mpdelete::handle_mpdelete_command(ctx, msg, &args).await,
"mp" => mp::handle_mp(ctx, msg, &args).await,
"invite" => invite::handle_invite(ctx, msg, &args).await,
"leavesettings" => {
let mut forwarded = vec!["settings"];
forwarded.extend(args.iter().copied());
leave_settings::handle_leave_settings(ctx, msg, &forwarded).await
}
"leavesettings" => leave_settings::handle_leave_settings(ctx, msg, &args).await,
"leave" => leave::handle_leave(ctx, msg, &args).await,
"viewlogs" => viewlogs::handle_viewlogs(ctx, msg, &args).await,
"discussion" => discussion::handle_discussion(ctx, msg, &args).await,
@@ -456,11 +435,7 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"unbl" => unbl::handle_unbl(ctx, msg, &args).await,
"blinfo" => blinfo::handle_blinfo(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
}
"changereset" => changereset::handle_changereset_command(ctx, msg, &args).await,
"change" => change::handle_change(ctx, msg, &args).await,
"changeall" => changeall::handle_changeall(ctx, msg, &args).await,
"mainprefix" => mainprefix::handle_mainprefix(ctx, msg, &args).await,
@@ -470,17 +445,9 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"clearowners" => clear_owners::handle_clear_owners(ctx, msg).await,
"clearbl" => clear_bl::handle_clear_bl(ctx, msg).await,
"clearperms" => clear_perms::handle_clear_perms(ctx, msg).await,
"clearlimit" => {
let mut forwarded = vec!["limit"];
forwarded.extend(args.iter().copied());
clear_limit::handle_clear_limit(ctx, msg, &forwarded).await
}
"clearlimit" => clear_limit::handle_clear_limit(ctx, msg, &args).await,
"clearbadwords" => clear_badwords::handle_clear_badwords(ctx, msg, &args).await,
"clearsanctions" => {
let mut forwarded = vec!["sanctions"];
forwarded.extend(args.iter().copied());
clear_sanctions::handle_clear_sanctions(ctx, msg, &forwarded).await
}
"clearsanctions" => clear_sanctions::handle_clear_sanctions(ctx, msg, &args).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,
+2 -57
View File
@@ -15,22 +15,9 @@ const EXTRA_COMMAND_KEYS: &[&str] = &[
"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 {
let normalized = command.to_lowercase();
match normalized.as_str() {
@@ -39,42 +26,7 @@ pub fn command_key(command: &str, args: &[&str]) -> String {
"del" => "ticket_remove".to_string(),
"close" => "ticket_close".to_string(),
"clear" => "clearmessages".to_string(),
"suggestion" => {
if first_arg_is(args, "settings") {
"suggestion_settings".to_string()
} else {
"suggestion_create".to_string()
}
}
"change" => {
if first_arg_is(args, "reset") {
"changereset".to_string()
} else {
"change".to_string()
}
}
"server" => {
if first_arg_is(args, "list") {
"serverlist".to_string()
} else {
"server".to_string()
}
}
"end" => {
if first_arg_is(args, "giveaway") {
"endgiveaway".to_string()
} else {
"end".to_string()
}
}
"mp" => {
if first_arg_is(args, "settings") {
"mpsettings".to_string()
} else {
"mp".to_string()
}
}
"mpsent" | "mpdelete" | "mpdel" => "mp".to_string(),
"mpdel" => "mpdelete".to_string(),
"helpetting" => "helpsetting".to_string(),
_ => normalized,
}
@@ -99,13 +51,6 @@ fn metadata_key_for_permission(command_key: &str) -> &str {
"ticket_settings" => "ticket",
"ticket_add" | "ticket_remove" => "add",
"ticket_close" => "close",
"suggestion_create" | "suggestion_settings" => "suggestion",
"setperm" => "set",
"delperm" => "del",
"changereset" => "change",
"serverlist" => "server",
"endgiveaway" => "end",
"mpsettings" => "mp",
_ => command_key,
}
}