mirror of
https://github.com/arthur-pbty/shadowbot.git
synced 2026-06-10 19:04:31 +02:00
chore(commands): reorganize command files by metadata categories
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{add_list_fields, send_embed};
|
||||
use crate::db::{
|
||||
DbPoolKey, get_command_alias, list_command_aliases, remove_command_alias, set_command_alias,
|
||||
};
|
||||
use crate::permissions::all_command_keys;
|
||||
|
||||
pub async fn handle_alias(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;
|
||||
};
|
||||
|
||||
if args.len() == 1 {
|
||||
let aliases = list_command_aliases(&pool, bot_id)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
let lines = aliases
|
||||
.into_iter()
|
||||
.map(|(alias, command)| format!("`{}` -> `{}`", alias, command))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Aliases")
|
||||
.color(0x5865F2);
|
||||
embed = add_list_fields(embed, &lines, "Aliases enregistrés");
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() < 2 {
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Usage: `+alias <commande> <alias>`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
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();
|
||||
if !all_command_keys()
|
||||
.iter()
|
||||
.any(|candidate| candidate == &command)
|
||||
{
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Commande cible inconnue.")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
|
||||
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 _ = set_command_alias(&pool, bot_id, &alias_name, &command).await;
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Alias créé")
|
||||
.description(format!(
|
||||
"`{}` devient un alias de `{}`",
|
||||
alias_name, command
|
||||
))
|
||||
.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()
|
||||
}
|
||||
|
||||
pub async fn resolve_alias(ctx: &Context, command: &str) -> Option<String> {
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
let pool = pool(ctx).await?;
|
||||
get_command_alias(&pool, bot_id, command)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
pub async fn resolve_command_alias_name(ctx: &Context, command: &str) -> Option<String> {
|
||||
resolve_alias(ctx, command).await
|
||||
}
|
||||
pub struct AliasCommand;
|
||||
pub static COMMAND_DESCRIPTOR: AliasCommand = AliasCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for AliasCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
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"],
|
||||
default_aliases: &["als"],
|
||||
allow_in_dm: false,
|
||||
default_permission: 6,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
use serenity::builder::{CreateActionRow, CreateButton, CreateEmbed, CreateMessage};
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::perms_helpers::ensure_owner;
|
||||
use crate::commands::{common::theme_color, common::truncate_text};
|
||||
use crate::permissions::{all_command_keys, command_required_permission, default_permission};
|
||||
|
||||
const ALLPERMS_PAGE_SIZE: usize = 12;
|
||||
const ALLPERMS_CUSTOM_ID_PREFIX: &str = "allperms";
|
||||
|
||||
async fn collect_allperms_lines(ctx: &Context) -> Vec<String> {
|
||||
let mut commands = all_command_keys();
|
||||
if !commands.iter().any(|c| c == "allperms") {
|
||||
commands.push("allperms".to_string());
|
||||
}
|
||||
commands.sort();
|
||||
|
||||
let mut lines = Vec::with_capacity(commands.len());
|
||||
for cmd in commands {
|
||||
let required = command_required_permission(ctx, &cmd).await;
|
||||
let default = default_permission(&cmd);
|
||||
|
||||
if required == default {
|
||||
lines.push(format!("`{}` -> `{}`", cmd, required));
|
||||
} else {
|
||||
lines.push(format!(
|
||||
"`{}` -> `{}` (defaut `{}`)",
|
||||
cmd, required, default
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
lines
|
||||
}
|
||||
|
||||
fn total_pages_for(total_items: usize) -> usize {
|
||||
((total_items + ALLPERMS_PAGE_SIZE.saturating_sub(1)) / ALLPERMS_PAGE_SIZE).max(1)
|
||||
}
|
||||
|
||||
fn build_allperms_embed(lines: &[String], page: usize, color: u32) -> CreateEmbed {
|
||||
let total_pages = total_pages_for(lines.len());
|
||||
let safe_page = page.min(total_pages.saturating_sub(1));
|
||||
let start = safe_page * ALLPERMS_PAGE_SIZE;
|
||||
let end = (start + ALLPERMS_PAGE_SIZE).min(lines.len());
|
||||
let chunk = if start < end { &lines[start..end] } else { &[] };
|
||||
|
||||
let value = if chunk.is_empty() {
|
||||
"Aucune commande.".to_string()
|
||||
} else {
|
||||
truncate_text(&chunk.join("\n"), 1024)
|
||||
};
|
||||
|
||||
CreateEmbed::new()
|
||||
.title("Permissions de toutes les commandes")
|
||||
.description(format!(
|
||||
"{} commande(s) · Page {}/{}",
|
||||
lines.len(),
|
||||
safe_page + 1,
|
||||
total_pages
|
||||
))
|
||||
.field("Niveaux requis", value, false)
|
||||
.color(color)
|
||||
}
|
||||
|
||||
fn allperms_components(owner_id: UserId, page: usize, total_pages: usize) -> Vec<CreateActionRow> {
|
||||
let safe_total = total_pages.max(1);
|
||||
let safe_page = page.min(safe_total.saturating_sub(1));
|
||||
let prev_page = safe_page.saturating_sub(1);
|
||||
let next_page = (safe_page + 1).min(safe_total.saturating_sub(1));
|
||||
|
||||
vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new(format!(
|
||||
"{}:{}:{}",
|
||||
ALLPERMS_CUSTOM_ID_PREFIX,
|
||||
owner_id.get(),
|
||||
prev_page
|
||||
))
|
||||
.label("◀ Precedent")
|
||||
.style(ButtonStyle::Primary)
|
||||
.disabled(safe_page == 0),
|
||||
CreateButton::new(format!(
|
||||
"{}:{}:{}",
|
||||
ALLPERMS_CUSTOM_ID_PREFIX,
|
||||
owner_id.get(),
|
||||
next_page
|
||||
))
|
||||
.label("Suivant ▶")
|
||||
.style(ButtonStyle::Primary)
|
||||
.disabled(safe_page + 1 >= safe_total),
|
||||
])]
|
||||
}
|
||||
|
||||
pub async fn handle_allperms(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
if !ensure_owner(ctx, msg).await {
|
||||
return;
|
||||
}
|
||||
|
||||
let lines = collect_allperms_lines(ctx).await;
|
||||
let total_pages = total_pages_for(lines.len());
|
||||
let requested_page = args
|
||||
.first()
|
||||
.and_then(|s| s.parse::<usize>().ok())
|
||||
.unwrap_or(1)
|
||||
.saturating_sub(1);
|
||||
let page = requested_page.min(total_pages.saturating_sub(1));
|
||||
|
||||
let color = theme_color(ctx).await;
|
||||
let embed = build_allperms_embed(&lines, page, color);
|
||||
let components = allperms_components(msg.author.id, page, total_pages);
|
||||
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.send_message(
|
||||
&ctx.http,
|
||||
CreateMessage::new().embed(embed).components(components),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub struct AllpermsCommand;
|
||||
pub static COMMAND_DESCRIPTOR: AllpermsCommand = AllpermsCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for AllpermsCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "allperms",
|
||||
category: "perms",
|
||||
params: "[page]",
|
||||
description: "Affiche le niveau ACL requis pour chaque commande avec pagination.",
|
||||
examples: &["+allperms", "+as", "+help allperms"],
|
||||
default_aliases: &["apm"],
|
||||
allow_in_dm: false,
|
||||
default_permission: 7,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::send_embed;
|
||||
use crate::commands::perms_helpers::{ensure_owner, get_pool};
|
||||
use crate::db::clear_role_permissions;
|
||||
|
||||
pub async fn handle_clear_perms(ctx: &Context, msg: &Message) {
|
||||
if !ensure_owner(ctx, msg).await {
|
||||
return;
|
||||
}
|
||||
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
let Some(pool) = get_pool(ctx).await else {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("DB indisponible.")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
};
|
||||
|
||||
let removed = clear_role_permissions(&pool, bot_id).await.unwrap_or(0);
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Permissions roles supprimees")
|
||||
.description(format!("{} entree(s) supprimee(s).", removed))
|
||||
.color(0x57F287);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
}
|
||||
|
||||
pub struct ClearPermsCommand;
|
||||
pub static COMMAND_DESCRIPTOR: ClearPermsCommand = ClearPermsCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for ClearPermsCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "clear_perms",
|
||||
category: "perms",
|
||||
params: "aucun",
|
||||
description: "Supprime toutes les permissions ACL configurees en base.",
|
||||
examples: &["+clear perms", "+cs", "+help clear perms"],
|
||||
default_aliases: &["cpm"],
|
||||
allow_in_dm: false,
|
||||
default_permission: 9,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::send_embed;
|
||||
use crate::commands::perms_helpers::{ensure_owner, get_pool, parse_user_or_role};
|
||||
use crate::db::remove_scope_permissions;
|
||||
|
||||
pub async fn handle_del(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
if !ensure_owner(ctx, msg).await {
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() < 2 || !args[0].eq_ignore_ascii_case("perm") {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Usage: `del perm <role>`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
|
||||
let Some((scope_type, scope_id)) = parse_user_or_role(args[1]) else {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Role/membre invalide.")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).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 = remove_scope_permissions(&pool, bot_id, scope_type, scope_id)
|
||||
.await
|
||||
.unwrap_or(0);
|
||||
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Permissions supprimees")
|
||||
.description(format!("{} entree(s) supprimee(s).", removed))
|
||||
.color(0x57F287);
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::send_embed;
|
||||
use crate::db::{DbPoolKey, get_help_aliases_enabled, set_help_aliases_enabled};
|
||||
|
||||
pub async fn handle_helpalias(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;
|
||||
};
|
||||
|
||||
if args.is_empty() {
|
||||
let enabled = get_help_aliases_enabled(&pool, bot_id)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or(true);
|
||||
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Aliases dans help")
|
||||
.description(format!(
|
||||
"État actuel: `{}`",
|
||||
if enabled { "on" } else { "off" }
|
||||
))
|
||||
.color(0x5865F2);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
|
||||
let enabled = match args[0].to_lowercase().as_str() {
|
||||
"on" | "true" | "yes" => true,
|
||||
"off" | "false" | "no" => false,
|
||||
_ => {
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Usage: `+helpalias <on/off>`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let _ = set_help_aliases_enabled(&pool, bot_id, enabled).await;
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Help aliases mis à jour")
|
||||
.description(format!(
|
||||
"Aliases dans l'aide: `{}`",
|
||||
if enabled { "on" } else { "off" }
|
||||
))
|
||||
.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()
|
||||
}
|
||||
pub struct HelpaliasCommand;
|
||||
pub static COMMAND_DESCRIPTOR: HelpaliasCommand = HelpaliasCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for HelpaliasCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "helpalias",
|
||||
category: "perms",
|
||||
params: "<on|off>",
|
||||
description: "Active ou desactive laffichage des aliases dans laide.",
|
||||
examples: &["+helpalias", "+hs", "+help helpalias"],
|
||||
default_aliases: &["hal"],
|
||||
allow_in_dm: true,
|
||||
default_permission: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
use serenity::builder::{
|
||||
CreateActionRow, CreateButton, CreateEmbed, CreateInteractionResponse,
|
||||
CreateInteractionResponseMessage, CreateMessage, CreateSelectMenu, CreateSelectMenuKind,
|
||||
CreateSelectMenuOption,
|
||||
};
|
||||
use serenity::model::application::ComponentInteractionDataKind;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::send_embed;
|
||||
use crate::db::{
|
||||
DbPoolKey, get_help_aliases_enabled, get_help_perms_enabled, get_help_type,
|
||||
set_help_aliases_enabled, set_help_perms_enabled, set_help_type,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct HelpSettingsData {
|
||||
layout: String,
|
||||
aliases_enabled: bool,
|
||||
perms_enabled: bool,
|
||||
}
|
||||
|
||||
fn normalize_layout(value: &str) -> Option<&'static str> {
|
||||
match value.to_lowercase().as_str() {
|
||||
"button" => Some("button"),
|
||||
"select" => Some("select"),
|
||||
"hybrid" => Some("hybrid"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn owner_id_from_custom_id(custom_id: &str) -> Option<u64> {
|
||||
custom_id.rsplit(':').next()?.parse::<u64>().ok()
|
||||
}
|
||||
|
||||
fn mode_from_custom_id(custom_id: &str) -> Option<&str> {
|
||||
let parts = custom_id.split(':').collect::<Vec<_>>();
|
||||
if parts.len() != 4 || parts[0] != "helpsetting" || parts[1] != "setmode" {
|
||||
return None;
|
||||
}
|
||||
Some(parts[2])
|
||||
}
|
||||
|
||||
async fn pool(ctx: &Context) -> Option<sqlx::PgPool> {
|
||||
let data = ctx.data.read().await;
|
||||
data.get::<DbPoolKey>().cloned()
|
||||
}
|
||||
|
||||
async fn read_settings(pool: &sqlx::PgPool, bot_id: UserId) -> HelpSettingsData {
|
||||
let layout = get_help_type(pool, bot_id)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or_else(|| "button".to_string());
|
||||
let aliases_enabled = get_help_aliases_enabled(pool, bot_id)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or(true);
|
||||
let perms_enabled = get_help_perms_enabled(pool, bot_id)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or(true);
|
||||
|
||||
HelpSettingsData {
|
||||
layout,
|
||||
aliases_enabled,
|
||||
perms_enabled,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_embed(settings: &HelpSettingsData) -> CreateEmbed {
|
||||
CreateEmbed::new()
|
||||
.title("Configuration de l'aide")
|
||||
.description("Tu peux modifier ces paramètres via boutons ou menu select.")
|
||||
.field("Mode d'affichage", format!("`{}`", settings.layout), true)
|
||||
.field(
|
||||
"Aliases",
|
||||
format!(
|
||||
"`{}`",
|
||||
if settings.aliases_enabled {
|
||||
"on"
|
||||
} else {
|
||||
"off"
|
||||
}
|
||||
),
|
||||
true,
|
||||
)
|
||||
.field(
|
||||
"Permissions",
|
||||
format!("`{}`", if settings.perms_enabled { "on" } else { "off" }),
|
||||
true,
|
||||
)
|
||||
.color(0x5865F2)
|
||||
}
|
||||
|
||||
fn build_components(owner_id: UserId, settings: &HelpSettingsData) -> Vec<CreateActionRow> {
|
||||
let mode_button_style = if settings.layout == "button" {
|
||||
ButtonStyle::Success
|
||||
} else {
|
||||
ButtonStyle::Secondary
|
||||
};
|
||||
let mode_select_style = if settings.layout == "select" {
|
||||
ButtonStyle::Success
|
||||
} else {
|
||||
ButtonStyle::Secondary
|
||||
};
|
||||
let mode_hybrid_style = if settings.layout == "hybrid" {
|
||||
ButtonStyle::Success
|
||||
} else {
|
||||
ButtonStyle::Secondary
|
||||
};
|
||||
|
||||
let aliases_style = if settings.aliases_enabled {
|
||||
ButtonStyle::Success
|
||||
} else {
|
||||
ButtonStyle::Danger
|
||||
};
|
||||
let perms_style = if settings.perms_enabled {
|
||||
ButtonStyle::Success
|
||||
} else {
|
||||
ButtonStyle::Danger
|
||||
};
|
||||
|
||||
let mode_row = CreateActionRow::Buttons(vec![
|
||||
CreateButton::new(format!("helpsetting:setmode:button:{}", owner_id.get()))
|
||||
.label("Mode Button")
|
||||
.style(mode_button_style),
|
||||
CreateButton::new(format!("helpsetting:setmode:select:{}", owner_id.get()))
|
||||
.label("Mode Select")
|
||||
.style(mode_select_style),
|
||||
CreateButton::new(format!("helpsetting:setmode:hybrid:{}", owner_id.get()))
|
||||
.label("Mode Hybrid")
|
||||
.style(mode_hybrid_style),
|
||||
]);
|
||||
|
||||
let toggle_row = CreateActionRow::Buttons(vec![
|
||||
CreateButton::new(format!("helpsetting:toggle:aliases:{}", owner_id.get()))
|
||||
.label(if settings.aliases_enabled {
|
||||
"Aliases: on"
|
||||
} else {
|
||||
"Aliases: off"
|
||||
})
|
||||
.style(aliases_style),
|
||||
CreateButton::new(format!("helpsetting:toggle:perms:{}", owner_id.get()))
|
||||
.label(if settings.perms_enabled {
|
||||
"Perms: on"
|
||||
} else {
|
||||
"Perms: off"
|
||||
})
|
||||
.style(perms_style),
|
||||
CreateButton::new(format!("helpsetting:refresh:{}", owner_id.get()))
|
||||
.label("Rafraîchir")
|
||||
.style(ButtonStyle::Primary),
|
||||
]);
|
||||
|
||||
let quick_options = vec![
|
||||
CreateSelectMenuOption::new("Mode button", "mode:button"),
|
||||
CreateSelectMenuOption::new("Mode select", "mode:select"),
|
||||
CreateSelectMenuOption::new("Mode hybrid", "mode:hybrid"),
|
||||
CreateSelectMenuOption::new("Aliases on", "aliases:on"),
|
||||
CreateSelectMenuOption::new("Aliases off", "aliases:off"),
|
||||
CreateSelectMenuOption::new("Perms on", "perms:on"),
|
||||
CreateSelectMenuOption::new("Perms off", "perms:off"),
|
||||
];
|
||||
|
||||
let quick_menu = CreateSelectMenu::new(
|
||||
format!("helpsetting:quick:{}", owner_id.get()),
|
||||
CreateSelectMenuKind::String {
|
||||
options: quick_options,
|
||||
},
|
||||
)
|
||||
.placeholder("Action rapide (select)");
|
||||
|
||||
vec![
|
||||
mode_row,
|
||||
toggle_row,
|
||||
CreateActionRow::SelectMenu(quick_menu),
|
||||
]
|
||||
}
|
||||
|
||||
async fn send_settings_panel(
|
||||
ctx: &Context,
|
||||
msg: &Message,
|
||||
pool: &sqlx::PgPool,
|
||||
bot_id: UserId,
|
||||
owner_id: UserId,
|
||||
) {
|
||||
let settings = read_settings(pool, bot_id).await;
|
||||
let embed = build_embed(&settings);
|
||||
let components = build_components(owner_id, &settings);
|
||||
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.send_message(
|
||||
&ctx.http,
|
||||
CreateMessage::new().embed(embed).components(components),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn apply_quick_action(pool: &sqlx::PgPool, bot_id: UserId, action: &str) {
|
||||
match action {
|
||||
"mode:button" => {
|
||||
let _ = set_help_type(pool, bot_id, "button").await;
|
||||
}
|
||||
"mode:select" => {
|
||||
let _ = set_help_type(pool, bot_id, "select").await;
|
||||
}
|
||||
"mode:hybrid" => {
|
||||
let _ = set_help_type(pool, bot_id, "hybrid").await;
|
||||
}
|
||||
"aliases:on" => {
|
||||
let _ = set_help_aliases_enabled(pool, bot_id, true).await;
|
||||
}
|
||||
"aliases:off" => {
|
||||
let _ = set_help_aliases_enabled(pool, bot_id, false).await;
|
||||
}
|
||||
"perms:on" => {
|
||||
let _ = set_help_perms_enabled(pool, bot_id, true).await;
|
||||
}
|
||||
"perms:off" => {
|
||||
let _ = set_help_perms_enabled(pool, bot_id, false).await;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_component_interaction(ctx: &Context, component: &ComponentInteraction) -> bool {
|
||||
let custom_id = &component.data.custom_id;
|
||||
if !custom_id.starts_with("helpsetting:") {
|
||||
return false;
|
||||
}
|
||||
|
||||
let Some(owner_id) = owner_id_from_custom_id(custom_id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if component.user.id.get() != owner_id {
|
||||
let _ = component
|
||||
.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Seul l'auteur de la commande peut utiliser ces contrôles.")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
return true;
|
||||
}
|
||||
|
||||
let bot_id = ctx.cache.current_user().id;
|
||||
let Some(pool) = pool(ctx).await else {
|
||||
let _ = component
|
||||
.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("DB indisponible.")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
return true;
|
||||
};
|
||||
|
||||
if custom_id.starts_with("helpsetting:setmode:") {
|
||||
if let Some(mode) = mode_from_custom_id(custom_id).and_then(normalize_layout) {
|
||||
let _ = set_help_type(&pool, bot_id, mode).await;
|
||||
}
|
||||
} else if custom_id.starts_with("helpsetting:toggle:aliases:") {
|
||||
let settings = read_settings(&pool, bot_id).await;
|
||||
let _ = set_help_aliases_enabled(&pool, bot_id, !settings.aliases_enabled).await;
|
||||
} else if custom_id.starts_with("helpsetting:toggle:perms:") {
|
||||
let settings = read_settings(&pool, bot_id).await;
|
||||
let _ = set_help_perms_enabled(&pool, bot_id, !settings.perms_enabled).await;
|
||||
} else if custom_id.starts_with("helpsetting:quick:") {
|
||||
if let ComponentInteractionDataKind::StringSelect { values } = &component.data.kind {
|
||||
if let Some(action) = values.first() {
|
||||
apply_quick_action(&pool, bot_id, action).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let settings = read_settings(&pool, bot_id).await;
|
||||
let embed = build_embed(&settings);
|
||||
let components = build_components(component.user.id, &settings);
|
||||
|
||||
let _ = component
|
||||
.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.embed(embed)
|
||||
.components(components),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub async fn handle_helpsetting(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()
|
||||
.title("Erreur")
|
||||
.description("DB indisponible.")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
};
|
||||
|
||||
if args.is_empty() {
|
||||
send_settings_panel(ctx, msg, &pool, bot_id, msg.author.id).await;
|
||||
return;
|
||||
}
|
||||
|
||||
match args[0].to_lowercase().as_str() {
|
||||
"type" | "mode" => {
|
||||
let Some(value) = args.get(1).and_then(|value| normalize_layout(value)) else {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Usage: `+helpsetting type <button|select|hybrid>`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
};
|
||||
let _ = set_help_type(&pool, bot_id, value).await;
|
||||
send_settings_panel(ctx, msg, &pool, bot_id, msg.author.id).await;
|
||||
}
|
||||
"aliases" | "alias" => {
|
||||
let Some(value) = args.get(1) else {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Usage: `+helpsetting aliases <on|off>`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
};
|
||||
let enabled = match value.to_lowercase().as_str() {
|
||||
"on" | "true" | "yes" => true,
|
||||
"off" | "false" | "no" => false,
|
||||
_ => {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Valeurs valides: `on`, `off`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
let _ = set_help_aliases_enabled(&pool, bot_id, enabled).await;
|
||||
send_settings_panel(ctx, msg, &pool, bot_id, msg.author.id).await;
|
||||
}
|
||||
"perms" | "permissions" => {
|
||||
let Some(value) = args.get(1) else {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Usage: `+helpsetting perms <on|off>`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
};
|
||||
let enabled = match value.to_lowercase().as_str() {
|
||||
"on" | "true" | "yes" => true,
|
||||
"off" | "false" | "no" => false,
|
||||
_ => {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Valeurs valides: `on`, `off`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
let _ = set_help_perms_enabled(&pool, bot_id, enabled).await;
|
||||
send_settings_panel(ctx, msg, &pool, bot_id, msg.author.id).await;
|
||||
}
|
||||
_ => {
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Sous-commandes: `type`, `aliases`, `perms`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HelpsettingCommand;
|
||||
pub static COMMAND_DESCRIPTOR: HelpsettingCommand = HelpsettingCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for HelpsettingCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "helpsetting",
|
||||
category: "perms",
|
||||
params: "[type|aliases|perms] [value]",
|
||||
description: "Permet de configurer le mode d'affichage, l'affichage des alias et l'affichage des permissions du système d'aide.",
|
||||
examples: &[
|
||||
"+helpsetting",
|
||||
"+helpsetting type hybrid",
|
||||
"+helpsetting perms off",
|
||||
],
|
||||
default_aliases: &["hs", "helpetting"],
|
||||
allow_in_dm: false,
|
||||
default_permission: 6,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::send_embed;
|
||||
use crate::db::{DbPoolKey, get_help_type, set_help_type};
|
||||
|
||||
pub async fn handle_helptype(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;
|
||||
};
|
||||
|
||||
if args.is_empty() {
|
||||
let current = get_help_type(&pool, bot_id)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or_else(|| "button".to_string());
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Mode help")
|
||||
.description(format!(
|
||||
"Mode actuel: `{}`\nValeurs: `button`, `select`, `hybrid`",
|
||||
current
|
||||
))
|
||||
.color(0x5865F2);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
|
||||
let normalized = match args[0].to_lowercase().as_str() {
|
||||
"button" => "button",
|
||||
"select" => "select",
|
||||
"hybrid" => "hybrid",
|
||||
_ => {
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Erreur")
|
||||
.description("Usage: `+helptype <button/select/hybrid>`")
|
||||
.color(0xED4245);
|
||||
send_embed(ctx, msg, embed).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let _ = set_help_type(&pool, bot_id, normalized).await;
|
||||
let embed = serenity::builder::CreateEmbed::new()
|
||||
.title("Mode help mis à jour")
|
||||
.description(format!("Nouveau mode: `{}`", normalized))
|
||||
.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()
|
||||
}
|
||||
pub struct HelptypeCommand;
|
||||
pub static COMMAND_DESCRIPTOR: HelptypeCommand = HelptypeCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for HelptypeCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "helptype",
|
||||
category: "perms",
|
||||
params: "<button|select|hybrid>",
|
||||
description: "Definit le mode daffichage de laide entre button, select et hybrid.",
|
||||
examples: &["+helptype", "+he", "+help helptype"],
|
||||
default_aliases: &["htp"],
|
||||
allow_in_dm: true,
|
||||
default_permission: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::{add_list_fields, send_embed, truncate_text};
|
||||
use crate::commands::perms_helpers::{ensure_owner, get_pool};
|
||||
use crate::db::{list_role_command_access, list_role_perm_levels, list_role_scopes};
|
||||
|
||||
pub async fn handle_perms(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let _ = args;
|
||||
|
||||
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 roles = list_role_scopes(&pool, bot_id).await.unwrap_or_default();
|
||||
let mut lines = Vec::new();
|
||||
|
||||
for rid in roles {
|
||||
let perm_levels = list_role_perm_levels(&pool, bot_id, rid as u64)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
let command_access = list_role_command_access(&pool, bot_id, rid as u64)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
let perms = if perm_levels.is_empty() {
|
||||
"aucun".to_string()
|
||||
} else {
|
||||
perm_levels
|
||||
.iter()
|
||||
.map(|p| p.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
};
|
||||
|
||||
let commands = if command_access.is_empty() {
|
||||
"aucune".to_string()
|
||||
} else {
|
||||
truncate_text(&command_access.join(", "), 80)
|
||||
};
|
||||
|
||||
lines.push(format!(
|
||||
"<@&{}> · perms [{}] · cmd [{}]",
|
||||
rid, perms, commands
|
||||
));
|
||||
}
|
||||
|
||||
let mut embed = CreateEmbed::new().title("Permissions du bot");
|
||||
embed = add_list_fields(embed, &lines, "Roles configures");
|
||||
send_embed(ctx, msg, embed).await;
|
||||
}
|
||||
|
||||
pub struct PermsCommand;
|
||||
pub static COMMAND_DESCRIPTOR: PermsCommand = PermsCommand;
|
||||
|
||||
impl crate::commands::command_contract::CommandSpec for PermsCommand {
|
||||
fn metadata(&self) -> crate::commands::command_contract::CommandMetadata {
|
||||
crate::commands::command_contract::CommandMetadata {
|
||||
name: "perms",
|
||||
category: "perms",
|
||||
params: "aucun",
|
||||
description: "Affiche les permissions ACL configurees par role ou scope.",
|
||||
examples: &["+perms", "+ps", "+help perms"],
|
||||
default_aliases: &["prm"],
|
||||
allow_in_dm: false,
|
||||
default_permission: 6,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user