replaced allow_slash with a method to disallow text commands for soundboard. made string argument selector stricter
This commit is contained in:
parent
14ef6385a0
commit
a38e4c808e
@ -5,7 +5,7 @@ use syn::parse::{Error, Result};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{Attribute, Ident, Lit, LitStr, Meta, NestedMeta, Path};
|
||||
|
||||
use crate::structures::{ApplicationCommandOptionType, Arg, PermissionLevel};
|
||||
use crate::structures::{ApplicationCommandOptionType, Arg, CommandKind, PermissionLevel};
|
||||
use crate::util::{AsOption, LitExt};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
@ -321,6 +321,18 @@ impl AttributeOption for PermissionLevel {
|
||||
}
|
||||
}
|
||||
|
||||
impl AttributeOption for CommandKind {
|
||||
fn parse(values: Values) -> Result<Self> {
|
||||
validate(&values, &[ValueKind::SingleList])?;
|
||||
|
||||
Ok(values
|
||||
.literals
|
||||
.get(0)
|
||||
.map(|(_, l)| CommandKind::from_str(&*l.to_str()).unwrap())
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl AttributeOption for Arg {
|
||||
fn parse(values: Values) -> Result<Self> {
|
||||
validate(&values, &[ValueKind::EqualsList])?;
|
||||
|
@ -70,7 +70,7 @@ pub fn command(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
aliases;
|
||||
group;
|
||||
required_permissions;
|
||||
allow_slash
|
||||
kind
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ pub fn command(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
group,
|
||||
examples,
|
||||
required_permissions,
|
||||
allow_slash,
|
||||
kind,
|
||||
mut cmd_args,
|
||||
} = options;
|
||||
|
||||
@ -152,7 +152,7 @@ pub fn command(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
group: #group,
|
||||
examples: &[#(#examples),*],
|
||||
required_permissions: #required_permissions,
|
||||
allow_slash: #allow_slash,
|
||||
kind: #kind,
|
||||
args: &[#(&#arg_idents),*],
|
||||
};
|
||||
|
||||
|
@ -214,6 +214,55 @@ impl ToTokens for PermissionLevel {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CommandKind {
|
||||
Slash,
|
||||
Both,
|
||||
Text,
|
||||
}
|
||||
|
||||
impl Default for CommandKind {
|
||||
fn default() -> Self {
|
||||
Self::Both
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandKind {
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
Some(match s.to_uppercase().as_str() {
|
||||
"SLASH" => Self::Slash,
|
||||
"BOTH" => Self::Both,
|
||||
"TEXT" => Self::Text,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for CommandKind {
|
||||
fn to_tokens(&self, stream: &mut TokenStream2) {
|
||||
let path = quote!(crate::framework::CommandKind);
|
||||
let variant;
|
||||
|
||||
match self {
|
||||
Self::Slash => {
|
||||
variant = quote!(Slash);
|
||||
}
|
||||
|
||||
Self::Both => {
|
||||
variant = quote!(Both);
|
||||
}
|
||||
|
||||
Self::Text => {
|
||||
variant = quote!(Text);
|
||||
}
|
||||
}
|
||||
|
||||
stream.extend(quote! {
|
||||
#path::#variant
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ApplicationCommandOptionType {
|
||||
SubCommand,
|
||||
@ -293,7 +342,7 @@ pub(crate) struct Options {
|
||||
pub group: String,
|
||||
pub examples: Vec<String>,
|
||||
pub required_permissions: PermissionLevel,
|
||||
pub allow_slash: bool,
|
||||
pub kind: CommandKind,
|
||||
pub cmd_args: Vec<Arg>,
|
||||
}
|
||||
|
||||
@ -301,7 +350,6 @@ impl Options {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
allow_slash: true,
|
||||
group: "Other".to_string(),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use crate::{
|
||||
THEME_COLOR,
|
||||
};
|
||||
|
||||
use crate::framework::CommandKind;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
#[command]
|
||||
@ -62,6 +63,28 @@ pub async fn help(
|
||||
)
|
||||
};
|
||||
|
||||
let args = if command.args.is_empty() {
|
||||
"**Arguments**
|
||||
• *This command has no arguments*"
|
||||
.to_string()
|
||||
} else {
|
||||
format!(
|
||||
"**Arguments**
|
||||
{}",
|
||||
command
|
||||
.args
|
||||
.iter()
|
||||
.map(|a| format!(
|
||||
" • `{}` {} - {}",
|
||||
a.name,
|
||||
if a.required { "" } else { "[optional]" },
|
||||
a.description
|
||||
))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
)
|
||||
};
|
||||
|
||||
invoke
|
||||
.respond(
|
||||
ctx.http.clone(),
|
||||
@ -69,15 +92,28 @@ pub async fn help(
|
||||
e.title(format!("{} Help", command_name))
|
||||
.color(THEME_COLOR)
|
||||
.description(format!(
|
||||
"**Aliases**
|
||||
"**Available In**
|
||||
`Slash Commands` {}
|
||||
` Text Commands` {}
|
||||
|
||||
**Aliases**
|
||||
{}
|
||||
|
||||
**Overview**
|
||||
• {}
|
||||
**Arguments**
|
||||
{}
|
||||
|
||||
{}",
|
||||
if command.kind != CommandKind::Text {
|
||||
"✅"
|
||||
} else {
|
||||
"❎"
|
||||
},
|
||||
if command.kind != CommandKind::Slash {
|
||||
"✅"
|
||||
} else {
|
||||
"❎"
|
||||
},
|
||||
command
|
||||
.names
|
||||
.iter()
|
||||
@ -85,17 +121,7 @@ pub async fn help(
|
||||
.collect::<Vec<String>>()
|
||||
.join(" "),
|
||||
command.desc,
|
||||
command
|
||||
.args
|
||||
.iter()
|
||||
.map(|a| format!(
|
||||
" • `{}` {} - {}",
|
||||
a.name,
|
||||
if a.required { "" } else { "[optional]" },
|
||||
a.description
|
||||
))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n"),
|
||||
args,
|
||||
examples
|
||||
))
|
||||
}),
|
||||
|
@ -186,6 +186,7 @@ pub async fn upload_new_sound(
|
||||
kind = "String",
|
||||
required = true
|
||||
)]
|
||||
#[example("`/delete beep` - delete the sound with the name \"beep\"")]
|
||||
pub async fn delete_sound(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
@ -278,6 +279,8 @@ pub async fn delete_sound(
|
||||
description = "Sound name or ID to change the privacy setting of",
|
||||
required = true
|
||||
)]
|
||||
#[example("`/public 12` - change sound with ID 12 to private")]
|
||||
#[example("`/public 12` - change sound with ID 12 back to public")]
|
||||
pub async fn change_public(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
|
@ -184,14 +184,14 @@ __Available ambience sounds:__
|
||||
}
|
||||
|
||||
#[command("soundboard")]
|
||||
#[aliases("board")]
|
||||
#[group("Play")]
|
||||
#[kind(Slash)]
|
||||
#[description("Get a menu of sounds with buttons to play them")]
|
||||
#[arg(
|
||||
name = "1",
|
||||
description = "Query for sound button 1",
|
||||
kind = "String",
|
||||
required = false
|
||||
required = true
|
||||
)]
|
||||
#[arg(
|
||||
name = "2",
|
||||
|
@ -40,6 +40,8 @@ fn format_search_results(search_results: Vec<Sound>) -> CreateGenericResponse {
|
||||
kind = "Boolean",
|
||||
required = false
|
||||
)]
|
||||
#[example("`/list` - list sounds uploaded to the server you're in")]
|
||||
#[example("`/list [me: True]` - list sounds you have uploaded across all servers")]
|
||||
pub async fn list_sounds(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
|
@ -20,6 +20,9 @@ use crate::{
|
||||
kind = "Integer",
|
||||
required = false
|
||||
)]
|
||||
#[example("`/volume` - check the volume on the current server")]
|
||||
#[example("`/volume 100` - reset the volume on the current server")]
|
||||
#[example("`/volume 10` - set the volume on the current server to 10%")]
|
||||
pub async fn change_volume(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
@ -66,7 +69,7 @@ pub async fn change_volume(
|
||||
|
||||
#[command("prefix")]
|
||||
#[required_permissions(Restricted)]
|
||||
#[allow_slash(false)]
|
||||
#[kind(Text)]
|
||||
#[group("Settings")]
|
||||
#[description("Change the prefix of the bot for using non-slash commands")]
|
||||
#[arg(
|
||||
@ -97,7 +100,7 @@ pub async fn change_prefix(
|
||||
}
|
||||
|
||||
if let Some(prefix) = args.named("prefix") {
|
||||
if prefix.len() <= 5 {
|
||||
if prefix.len() <= 5 && !prefix.is_empty() {
|
||||
let reply = format!("Prefix changed to `{}`", prefix);
|
||||
|
||||
{
|
||||
@ -142,7 +145,7 @@ pub async fn change_prefix(
|
||||
|
||||
#[command("roles")]
|
||||
#[required_permissions(Restricted)]
|
||||
#[allow_slash(false)]
|
||||
#[kind(Text)]
|
||||
#[group("Settings")]
|
||||
#[description("Change the roles allowed to use the bot")]
|
||||
pub async fn set_allowed_roles(
|
||||
@ -240,6 +243,8 @@ INSERT INTO roles (guild_id, role)
|
||||
description = "Name or ID of sound to set as your greet sound",
|
||||
required = false
|
||||
)]
|
||||
#[example("`/greet` - remove your join sound")]
|
||||
#[example("`/greet 1523` - set your join sound to sound with ID 1523")]
|
||||
pub async fn set_greet_sound(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
@ -312,6 +317,8 @@ pub async fn set_greet_sound(
|
||||
#[group("Settings")]
|
||||
#[description("Configure whether users should be able to use join sounds")]
|
||||
#[required_permissions(Restricted)]
|
||||
#[example("`/allow_greet` - disable greet sounds in the server")]
|
||||
#[example("`/allow_greet` - re-enable greet sounds in the server")]
|
||||
pub async fn allow_greet_sounds(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
|
@ -309,6 +309,13 @@ pub enum PermissionLevel {
|
||||
Restricted,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum CommandKind {
|
||||
Slash,
|
||||
Both,
|
||||
Text,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Arg {
|
||||
pub name: &'static str,
|
||||
@ -320,7 +327,7 @@ pub struct Arg {
|
||||
impl Arg {
|
||||
pub fn to_regex(&self) -> String {
|
||||
match self.kind {
|
||||
ApplicationCommandOptionType::String => format!(r#"(?P<{}>.*?)"#, self.name),
|
||||
ApplicationCommandOptionType::String => format!(r#"(?P<{}>.+?)"#, self.name),
|
||||
ApplicationCommandOptionType::Integer => format!(r#"(?P<{}>\d+)"#, self.name),
|
||||
ApplicationCommandOptionType::Boolean => format!(r#"(?P<{0}>{0})?"#, self.name),
|
||||
ApplicationCommandOptionType::User => format!(r#"<(@|@!)(?P<{}>\d+)>"#, self.name),
|
||||
@ -343,7 +350,7 @@ pub struct Command {
|
||||
pub examples: &'static [&'static str],
|
||||
pub group: &'static str,
|
||||
|
||||
pub allow_slash: bool,
|
||||
pub kind: CommandKind,
|
||||
pub required_permissions: PermissionLevel,
|
||||
pub args: &'static [&'static Arg],
|
||||
}
|
||||
@ -528,7 +535,11 @@ impl RegexFramework {
|
||||
.flatten()
|
||||
.map(|v| GuildId(v))
|
||||
{
|
||||
for command in self.commands_.iter().filter(|c| c.allow_slash) {
|
||||
for command in self
|
||||
.commands_
|
||||
.iter()
|
||||
.filter(|c| c.kind != CommandKind::Text)
|
||||
{
|
||||
guild_id
|
||||
.create_application_command(&http, |a| {
|
||||
a.name(command.names[0]).description(command.desc);
|
||||
@ -577,7 +588,11 @@ impl RegexFramework {
|
||||
}
|
||||
}
|
||||
|
||||
for command in self.commands_.iter().filter(|c| c.allow_slash) {
|
||||
for command in self
|
||||
.commands_
|
||||
.iter()
|
||||
.filter(|c| c.kind != CommandKind::Text)
|
||||
{
|
||||
let already_created = if let Some(current_command) = current_commands
|
||||
.iter()
|
||||
.find(|curr| curr.name == command.names[0])
|
||||
@ -752,27 +767,31 @@ impl Framework for RegexFramework {
|
||||
.get(&full_match.name("cmd").unwrap().as_str().to_lowercase())
|
||||
.unwrap();
|
||||
|
||||
let args = full_match
|
||||
.name("args")
|
||||
.map(|m| m.as_str())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
if command.kind != CommandKind::Slash {
|
||||
let args = full_match
|
||||
.name("args")
|
||||
.map(|m| m.as_str())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
|
||||
let member = guild.member(&ctx, &msg.author).await.unwrap();
|
||||
let member = guild.member(&ctx, &msg.author).await.unwrap();
|
||||
|
||||
if command.check_permissions(&ctx, &guild, &member).await {
|
||||
(command.fun)(&ctx, &msg, Args::from(&args, command.args))
|
||||
.await
|
||||
.unwrap();
|
||||
} else if command.required_permissions == PermissionLevel::Managed {
|
||||
let _ = msg.channel_id.say(&ctx, "You must either be an Admin or have a role specified in `?roles` to do this command").await;
|
||||
} else if command.required_permissions
|
||||
== PermissionLevel::Restricted
|
||||
{
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.say(&ctx, "You must be an Admin to do this command")
|
||||
.await;
|
||||
if command.check_permissions(&ctx, &guild, &member).await {
|
||||
(command.fun)(&ctx, &msg, Args::from(&args, command.args))
|
||||
.await
|
||||
.unwrap();
|
||||
} else if command.required_permissions
|
||||
== PermissionLevel::Managed
|
||||
{
|
||||
let _ = msg.channel_id.say(&ctx, "You must either be an Admin or have a role specified in `?roles` to do this command").await;
|
||||
} else if command.required_permissions
|
||||
== PermissionLevel::Restricted
|
||||
{
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.say(&ctx, "You must be an Admin to do this command")
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user