build slash commands at launch

This commit is contained in:
jellywx 2021-06-11 10:39:32 +01:00
parent 1286f5f50e
commit 1f61b72cc5
6 changed files with 63 additions and 21 deletions

View File

@ -339,9 +339,6 @@ impl AttributeOption for Arg {
"required" => { "required" => {
arg.required = value.to_bool(); arg.required = value.to_bool();
} }
"default" => {
arg.default = value.to_bool();
}
"kind" => arg.kind = ApplicationCommandOptionType::from_str(value.to_str()), "kind" => arg.kind = ApplicationCommandOptionType::from_str(value.to_str()),
_ => { _ => {
return Err(Error::new(key.span(), "unexpected attribute")); return Err(Error::new(key.span(), "unexpected attribute"));

View File

@ -119,7 +119,6 @@ pub fn command(attr: TokenStream, input: TokenStream) -> TokenStream {
description, description,
kind, kind,
required, required,
default,
} = arg; } = arg;
let an = n.with_suffix(name.as_str()).with_suffix(ARG); let an = n.with_suffix(name.as_str()).with_suffix(ARG);
@ -130,9 +129,8 @@ pub fn command(attr: TokenStream, input: TokenStream) -> TokenStream {
pub static #an: #arg_path = #arg_path { pub static #an: #arg_path = #arg_path {
name: #name, name: #name,
description: #description, description: #description,
required: #required,
default: #default,
kind: #kind, kind: #kind,
required: #required,
}; };
} }
}) })

View File

@ -273,7 +273,6 @@ pub(crate) struct Arg {
pub description: String, pub description: String,
pub kind: ApplicationCommandOptionType, pub kind: ApplicationCommandOptionType,
pub required: bool, pub required: bool,
pub default: bool,
} }
impl Default for Arg { impl Default for Arg {
@ -283,7 +282,6 @@ impl Default for Arg {
description: String::new(), description: String::new(),
kind: ApplicationCommandOptionType::String, kind: ApplicationCommandOptionType::String,
required: false, required: false,
default: false,
} }
} }
} }
@ -291,7 +289,7 @@ impl Default for Arg {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub(crate) struct Options { pub(crate) struct Options {
pub aliases: Vec<String>, pub aliases: Vec<String>,
pub description: AsOption<String>, pub description: String,
pub usage: AsOption<String>, pub usage: AsOption<String>,
pub examples: Vec<String>, pub examples: Vec<String>,
pub required_permissions: PermissionLevel, pub required_permissions: PermissionLevel,

View File

@ -221,13 +221,11 @@ pub fn rename_attributes(attributes: &mut Vec<Attribute>, name: &str, target: &s
} }
} }
pub fn append_line(desc: &mut AsOption<String>, mut line: String) { pub fn append_line(desc: &mut String, mut line: String) {
if line.starts_with(' ') { if line.starts_with(' ') {
line.remove(0); line.remove(0);
} }
let desc = desc.0.get_or_insert_with(String::default);
match line.rfind("\\$") { match line.rfind("\\$") {
Some(i) => { Some(i) => {
desc.push_str(line[..i].trim_end()); desc.push_str(line[..i].trim_end());

View File

@ -24,7 +24,7 @@ use log::{error, info, warn};
use regex::{Match, Regex, RegexBuilder}; use regex::{Match, Regex, RegexBuilder};
use std::{collections::HashMap, fmt}; use std::{collections::HashMap, env, fmt};
use crate::{guild_data::CtxGuildData, MySQL}; use crate::{guild_data::CtxGuildData, MySQL};
use std::sync::Arc; use std::sync::Arc;
@ -196,13 +196,12 @@ pub struct Arg {
pub description: &'static str, pub description: &'static str,
pub kind: ApplicationCommandOptionType, pub kind: ApplicationCommandOptionType,
pub required: bool, pub required: bool,
pub default: bool,
} }
pub struct Command { pub struct Command {
pub fun: CommandFn, pub fun: CommandFn,
pub names: &'static [&'static str], pub names: &'static [&'static str],
pub desc: Option<&'static str>, pub desc: &'static str,
pub usage: Option<&'static str>, pub usage: Option<&'static str>,
pub examples: &'static [&'static str], pub examples: &'static [&'static str],
pub required_permissions: PermissionLevel, pub required_permissions: PermissionLevel,
@ -364,7 +363,45 @@ impl RegexFramework {
} }
pub async fn build_slash(&self, http: impl AsRef<Http>) { pub async fn build_slash(&self, http: impl AsRef<Http>) {
// info!("Building slash commands...");
let mut count = 0;
if let Some(guild_id) = env::var("TEST_GUILD")
.map(|v| v.parse::<u64>().ok())
.ok()
.flatten()
.map(|v| GuildId(v))
{
for (handle, command) in self.commands.iter().filter(|(_, c)| c.allow_slash) {
guild_id
.create_application_command(&http, |a| {
a.name(handle).description(command.desc);
for arg in command.args {
a.create_option(|o| {
o.name(arg.name)
.description(arg.description)
.kind(arg.kind)
.required(arg.required)
});
}
a
})
.await
.expect(&format!(
"Failed to create application command for {}",
handle
));
count += 1;
}
} else {
// register application commands globally
}
info!("{} slash commands built! Ready to go", count);
} }
} }

View File

@ -296,6 +296,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
} }
#[command] #[command]
#[description("Get information on the commands of the bot")]
async fn help( async fn help(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -427,19 +428,18 @@ Please select a category from the following:
#[command] #[command]
#[aliases("p")] #[aliases("p")]
#[required_permissions(Managed)] #[required_permissions(Managed)]
#[description("Play a sound in your current voice channel")]
#[arg( #[arg(
name = "query", name = "query",
description = "Play sound with the specified name or ID", description = "Play sound with the specified name or ID",
kind = "String", kind = "String",
required = true, required = true
default = true
)] )]
#[arg( #[arg(
name = "loop", name = "loop",
description = "Whether to loop the sound or not (default: no)", description = "Whether to loop the sound or not (default: no)",
kind = "Boolean", kind = "Boolean",
required = false, required = false
default = false
)] )]
async fn play( async fn play(
ctx: &Context, ctx: &Context,
@ -461,6 +461,7 @@ async fn play(
#[command("loop")] #[command("loop")]
#[required_permissions(Managed)] #[required_permissions(Managed)]
#[description("Play a sound on loop in your current voice channel")]
#[arg( #[arg(
name = "query", name = "query",
description = "Play sound with the specified name or ID", description = "Play sound with the specified name or ID",
@ -546,6 +547,7 @@ async fn play_cmd(ctx: &Context, guild: Guild, user_id: UserId, args: Args, loop
#[command("ambience")] #[command("ambience")]
#[required_permissions(Managed)] #[required_permissions(Managed)]
#[description("Play ambient sound in your current voice channel")]
#[arg( #[arg(
name = "name", name = "name",
description = "Play sound with the specified name", description = "Play sound with the specified name",
@ -641,6 +643,7 @@ __Available ambience sounds:__
#[command("stop")] #[command("stop")]
#[required_permissions(Managed)] #[required_permissions(Managed)]
#[description("Stop the bot from playing")]
async fn stop_playing( async fn stop_playing(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -663,6 +666,7 @@ async fn stop_playing(
#[command] #[command]
#[aliases("dc")] #[aliases("dc")]
#[required_permissions(Managed)] #[required_permissions(Managed)]
#[description("Disconnect the bot")]
async fn disconnect( async fn disconnect(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -678,6 +682,7 @@ async fn disconnect(
#[command] #[command]
#[aliases("invite")] #[aliases("invite")]
#[description("Get additional information on the bot")]
async fn info( async fn info(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -717,6 +722,7 @@ There is a maximum sound limit per user. This can be removed by subscribing at *
#[command("volume")] #[command("volume")]
#[aliases("vol")] #[aliases("vol")]
#[required_permissions(Managed)] #[required_permissions(Managed)]
#[description("Change the bot's volume in this server")]
async fn change_volume( async fn change_volume(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -1087,6 +1093,7 @@ INSERT INTO roles (guild_id, role)
} }
#[command("list")] #[command("list")]
#[description("Show the sounds uploaded by you or to your server")]
#[arg( #[arg(
name = "me", name = "me",
description = "Whether to list your sounds or server sounds (default: server)", description = "Whether to list your sounds or server sounds (default: server)",
@ -1154,6 +1161,7 @@ async fn list_sounds(
} }
#[command("public")] #[command("public")]
#[description("Change a sound between public and private")]
async fn change_public( async fn change_public(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -1219,6 +1227,7 @@ async fn change_public(
} }
#[command("delete")] #[command("delete")]
#[description("Delete a sound you have uploaded")]
async fn delete_sound( async fn delete_sound(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -1323,6 +1332,7 @@ fn format_search_results(search_results: Vec<Sound>) -> CreateGenericResponse {
} }
#[command("search")] #[command("search")]
#[description("Search for sounds")]
async fn search_sounds( async fn search_sounds(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -1355,6 +1365,7 @@ async fn search_sounds(
} }
#[command("popular")] #[command("popular")]
#[description("Show popular sounds")]
async fn show_popular_sounds( async fn show_popular_sounds(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -1389,6 +1400,7 @@ SELECT name, id, plays, public, server_id, uploader_id
} }
#[command("random")] #[command("random")]
#[description("Show a page of random sounds")]
async fn show_random_sounds( async fn show_random_sounds(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -1424,6 +1436,7 @@ SELECT name, id, plays, public, server_id, uploader_id
} }
#[command("greet")] #[command("greet")]
#[description("Set a join sound")]
async fn set_greet_sound( async fn set_greet_sound(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),
@ -1490,7 +1503,8 @@ async fn set_greet_sound(
} }
#[command("allow_greet")] #[command("allow_greet")]
#[required_permissions(Managed)] #[description("Configure whether users should be able to use join sounds")]
#[required_permissions(Restricted)]
async fn allow_greet_sounds( async fn allow_greet_sounds(
ctx: &Context, ctx: &Context,
invoke: &(dyn CommandInvoke + Sync + Send), invoke: &(dyn CommandInvoke + Sync + Send),