arg macro to define arguments on commands
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
framework::RegexFramework,
|
||||
guild_data::CtxGuildData,
|
||||
join_channel, play_audio,
|
||||
sound::{JoinSoundCtx, Sound},
|
||||
@ -8,7 +9,9 @@ use crate::{
|
||||
use serenity::{
|
||||
async_trait,
|
||||
client::{Context, EventHandler},
|
||||
model::{channel::Channel, guild::Guild, id::GuildId, voice::VoiceState},
|
||||
model::{
|
||||
channel::Channel, guild::Guild, id::GuildId, interactions::Interaction, voice::VoiceState,
|
||||
},
|
||||
utils::shard_id,
|
||||
};
|
||||
|
||||
@ -33,6 +36,18 @@ pub struct Handler;
|
||||
|
||||
#[serenity::async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn cache_ready(&self, ctx: Context, _: Vec<GuildId>) {
|
||||
let framework = ctx
|
||||
.data
|
||||
.read()
|
||||
.await
|
||||
.get::<RegexFramework>()
|
||||
.cloned()
|
||||
.expect("RegexFramework not found in context");
|
||||
|
||||
framework.build_slash(ctx).await;
|
||||
}
|
||||
|
||||
async fn guild_create(&self, ctx: Context, guild: Guild, is_new: bool) {
|
||||
if is_new {
|
||||
if let Ok(token) = env::var("DISCORDBOTS_TOKEN") {
|
||||
@ -154,4 +169,8 @@ SELECT name, id, plays, public, server_id, uploader_id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use serenity::{
|
||||
async_trait,
|
||||
builder::CreateEmbed,
|
||||
cache::Cache,
|
||||
client::Context,
|
||||
constants::MESSAGE_CODE_LIMIT,
|
||||
framework::{
|
||||
standard::{Args, CommandResult, Delimiter},
|
||||
Framework,
|
||||
@ -13,7 +14,9 @@ use serenity::{
|
||||
guild::{Guild, Member},
|
||||
id::{ChannelId, GuildId, UserId},
|
||||
interactions::Interaction,
|
||||
prelude::{ApplicationCommandOptionType, InteractionResponseType},
|
||||
},
|
||||
prelude::TypeMapKey,
|
||||
Result as SerenityResult,
|
||||
};
|
||||
|
||||
@ -24,9 +27,6 @@ use regex::{Match, Regex, RegexBuilder};
|
||||
use std::{collections::HashMap, fmt};
|
||||
|
||||
use crate::{guild_data::CtxGuildData, MySQL};
|
||||
use serenity::builder::CreateEmbed;
|
||||
use serenity::cache::Cache;
|
||||
use serenity::model::prelude::InteractionResponseType;
|
||||
use std::sync::Arc;
|
||||
|
||||
type CommandFn = for<'fut> fn(
|
||||
@ -190,6 +190,15 @@ pub enum PermissionLevel {
|
||||
Restricted,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Arg {
|
||||
pub name: &'static str,
|
||||
pub description: &'static str,
|
||||
pub kind: ApplicationCommandOptionType,
|
||||
pub required: bool,
|
||||
pub default: bool,
|
||||
}
|
||||
|
||||
pub struct Command {
|
||||
pub fun: CommandFn,
|
||||
pub names: &'static [&'static str],
|
||||
@ -198,6 +207,7 @@ pub struct Command {
|
||||
pub examples: &'static [&'static str],
|
||||
pub required_permissions: PermissionLevel,
|
||||
pub allow_slash: bool,
|
||||
pub args: &'static [&'static Arg],
|
||||
}
|
||||
|
||||
impl Command {
|
||||
@ -267,53 +277,11 @@ impl fmt::Debug for Command {
|
||||
f.debug_struct("Command")
|
||||
.field("name", &self.names[0])
|
||||
.field("required_permissions", &self.required_permissions)
|
||||
.field("args", &self.args)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait SendIterator {
|
||||
async fn say_lines(
|
||||
self,
|
||||
http: impl AsRef<Http> + Send + Sync + 'async_trait,
|
||||
content: impl Iterator<Item = String> + Send + 'async_trait,
|
||||
) -> SerenityResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl SendIterator for ChannelId {
|
||||
async fn say_lines(
|
||||
self,
|
||||
http: impl AsRef<Http> + Send + Sync + 'async_trait,
|
||||
content: impl Iterator<Item = String> + Send + 'async_trait,
|
||||
) -> SerenityResult<()> {
|
||||
let mut current_content = String::new();
|
||||
|
||||
for line in content {
|
||||
if current_content.len() + line.len() > MESSAGE_CODE_LIMIT as usize {
|
||||
self.send_message(&http, |m| {
|
||||
m.allowed_mentions(|am| am.empty_parse())
|
||||
.content(¤t_content)
|
||||
})
|
||||
.await?;
|
||||
|
||||
current_content = line;
|
||||
} else {
|
||||
current_content = format!("{}\n{}", current_content, line);
|
||||
}
|
||||
}
|
||||
if !current_content.is_empty() {
|
||||
self.send_message(&http, |m| {
|
||||
m.allowed_mentions(|am| am.empty_parse())
|
||||
.content(¤t_content)
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RegexFramework {
|
||||
commands: HashMap<String, &'static Command>,
|
||||
command_matcher: Regex,
|
||||
@ -323,6 +291,10 @@ pub struct RegexFramework {
|
||||
case_insensitive: bool,
|
||||
}
|
||||
|
||||
impl TypeMapKey for RegexFramework {
|
||||
type Value = Arc<RegexFramework>;
|
||||
}
|
||||
|
||||
impl RegexFramework {
|
||||
pub fn new<T: Into<u64>>(client_id: T) -> Self {
|
||||
Self {
|
||||
@ -354,6 +326,8 @@ impl RegexFramework {
|
||||
}
|
||||
|
||||
pub fn add_command(mut self, command: &'static Command) -> Self {
|
||||
info!("{:?}", command);
|
||||
|
||||
for name in command.names {
|
||||
self.commands.insert(name.to_string(), command);
|
||||
}
|
||||
@ -388,6 +362,10 @@ impl RegexFramework {
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn build_slash(&self, http: impl AsRef<Http>) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
enum PermissionCheck {
|
||||
|
42
src/main.rs
42
src/main.rs
@ -215,6 +215,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
|
||||
framework = framework.build();
|
||||
|
||||
let framework_arc = Arc::new(framework);
|
||||
|
||||
let mut client =
|
||||
Client::builder(&env::var("DISCORD_TOKEN").expect("Missing token from environment"))
|
||||
.intents(
|
||||
@ -222,7 +224,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
| GatewayIntents::GUILD_MESSAGES
|
||||
| GatewayIntents::GUILDS,
|
||||
)
|
||||
.framework(framework)
|
||||
.framework_arc(framework_arc.clone())
|
||||
.application_id(application_id.0)
|
||||
.event_handler(Handler)
|
||||
.register_songbird()
|
||||
@ -242,7 +244,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
data.insert::<GuildDataCache>(guild_data_cache);
|
||||
data.insert::<JoinSoundCache>(join_sound_cache);
|
||||
data.insert::<MySQL>(mysql_pool);
|
||||
|
||||
data.insert::<RegexFramework>(framework_arc.clone());
|
||||
data.insert::<ReqwestClient>(Arc::new(reqwest::Client::new()));
|
||||
|
||||
if let Some(audio_index) = audio_index {
|
||||
@ -425,6 +427,20 @@ Please select a category from the following:
|
||||
#[command]
|
||||
#[aliases("p")]
|
||||
#[required_permissions(Managed)]
|
||||
#[arg(
|
||||
name = "query",
|
||||
description = "Play sound with the specified name or ID",
|
||||
kind = "String",
|
||||
required = true,
|
||||
default = true
|
||||
)]
|
||||
#[arg(
|
||||
name = "loop",
|
||||
description = "Whether to loop the sound or not (default: no)",
|
||||
kind = "Boolean",
|
||||
required = false,
|
||||
default = false
|
||||
)]
|
||||
async fn play(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
@ -443,8 +459,14 @@ async fn play(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[command("loop")]
|
||||
#[required_permissions(Managed)]
|
||||
#[arg(
|
||||
name = "query",
|
||||
description = "Play sound with the specified name or ID",
|
||||
kind = "String",
|
||||
required = true
|
||||
)]
|
||||
async fn loop_play(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
@ -524,6 +546,12 @@ async fn play_cmd(ctx: &Context, guild: Guild, user_id: UserId, args: Args, loop
|
||||
|
||||
#[command("ambience")]
|
||||
#[required_permissions(Managed)]
|
||||
#[arg(
|
||||
name = "name",
|
||||
description = "Play sound with the specified name",
|
||||
kind = "String",
|
||||
required = false
|
||||
)]
|
||||
async fn play_ambience(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
@ -687,6 +715,7 @@ There is a maximum sound limit per user. This can be removed by subscribing at *
|
||||
}
|
||||
|
||||
#[command("volume")]
|
||||
#[aliases("vol")]
|
||||
#[required_permissions(Managed)]
|
||||
async fn change_volume(
|
||||
ctx: &Context,
|
||||
@ -753,6 +782,7 @@ async fn change_volume(
|
||||
|
||||
#[command("prefix")]
|
||||
#[required_permissions(Restricted)]
|
||||
#[allow_slash(false)]
|
||||
async fn change_prefix(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
@ -1057,6 +1087,12 @@ INSERT INTO roles (guild_id, role)
|
||||
}
|
||||
|
||||
#[command("list")]
|
||||
#[arg(
|
||||
name = "me",
|
||||
description = "Whether to list your sounds or server sounds (default: server)",
|
||||
kind = "Boolean",
|
||||
required = false
|
||||
)]
|
||||
async fn list_sounds(
|
||||
ctx: &Context,
|
||||
invoke: &(dyn CommandInvoke + Sync + Send),
|
||||
|
Reference in New Issue
Block a user