soundboard cmd

This commit is contained in:
jellywx 2021-06-25 14:51:52 +01:00
parent f0590328b0
commit b4b8d16bcc
3 changed files with 154 additions and 92 deletions

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
framework::RegexFramework, framework::RegexFramework,
guild_data::CtxGuildData, guild_data::CtxGuildData,
join_channel, play_audio, join_channel, play_audio, play_cmd,
sound::{JoinSoundCtx, Sound}, sound::{JoinSoundCtx, Sound},
MySQL, ReqwestClient, MySQL, ReqwestClient,
}; };
@ -22,6 +22,9 @@ use serenity::{
use songbird::{Event, EventContext, EventHandler as SongbirdEventHandler}; use songbird::{Event, EventContext, EventHandler as SongbirdEventHandler};
use crate::framework::{Args, CommandInvoke};
use serenity::model::interactions::{InteractionData, InteractionType};
use serenity::model::prelude::InteractionResponseType;
use std::{collections::HashMap, env}; use std::{collections::HashMap, env};
pub struct RestartTrack; pub struct RestartTrack;
@ -180,6 +183,12 @@ SELECT name, id, plays, public, server_id, uploader_id
} }
async fn interaction_create(&self, ctx: Context, interaction: Interaction) { async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
if interaction.guild_id.is_none() {
return;
}
match interaction.kind {
InteractionType::ApplicationCommand => {
let framework = ctx let framework = ctx
.data .data
.read() .read()
@ -190,4 +199,33 @@ SELECT name, id, plays, public, server_id, uploader_id
framework.execute(ctx, interaction).await; framework.execute(ctx, interaction).await;
} }
InteractionType::MessageComponent => {
if let (Some(InteractionData::MessageComponent(data)), Some(member)) =
(interaction.clone().data, interaction.clone().member)
{
let mut args = Args {
args: Default::default(),
};
args.args.insert("query".to_string(), data.custom_id);
play_cmd(
&ctx,
interaction.guild(ctx.cache.clone()).await.unwrap(),
member.user.id,
args,
false,
)
.await;
interaction
.create_interaction_response(ctx, |r| {
r.kind(InteractionResponseType::DeferredUpdateMessage)
})
.await
.unwrap();
}
}
_ => {}
}
}
} }

View File

@ -10,14 +10,14 @@ use serenity::{
channel::{Channel, GuildChannel, Message}, channel::{Channel, GuildChannel, Message},
guild::{Guild, Member}, guild::{Guild, Member},
id::{ChannelId, GuildId, UserId}, id::{ChannelId, GuildId, UserId},
interactions::{ApplicationCommand, Interaction, InteractionData, InteractionType}, interactions::{ApplicationCommand, Interaction, InteractionData},
prelude::{ApplicationCommandOptionType, InteractionResponseType}, prelude::{ApplicationCommandOptionType, InteractionResponseType},
}, },
prelude::TypeMapKey, prelude::TypeMapKey,
Result as SerenityResult, Result as SerenityResult,
}; };
use log::{error, info, warn}; use log::{debug, error, info, warn};
use regex::{Match, Regex, RegexBuilder}; use regex::{Match, Regex, RegexBuilder};
@ -30,6 +30,7 @@ use std::{
use crate::{guild_data::CtxGuildData, MySQL}; use crate::{guild_data::CtxGuildData, MySQL};
use serde_json::Value; use serde_json::Value;
use serenity::builder::CreateComponents;
type CommandFn = for<'fut> fn( type CommandFn = for<'fut> fn(
&'fut Context, &'fut Context,
@ -38,7 +39,7 @@ type CommandFn = for<'fut> fn(
) -> BoxFuture<'fut, CommandResult>; ) -> BoxFuture<'fut, CommandResult>;
pub struct Args { pub struct Args {
args: HashMap<String, String>, pub args: HashMap<String, String>,
} }
impl Args { impl Args {
@ -87,6 +88,7 @@ impl Args {
pub struct CreateGenericResponse { pub struct CreateGenericResponse {
content: String, content: String,
embed: Option<CreateEmbed>, embed: Option<CreateEmbed>,
components: Option<CreateComponents>,
} }
impl CreateGenericResponse { impl CreateGenericResponse {
@ -94,6 +96,7 @@ impl CreateGenericResponse {
Self { Self {
content: "".to_string(), content: "".to_string(),
embed: None, embed: None,
components: None,
} }
} }
@ -112,6 +115,19 @@ impl CreateGenericResponse {
self self
} }
pub fn components<F: FnOnce(&mut CreateComponents) -> &mut CreateComponents>(
mut self,
f: F,
) -> Self {
let mut components = CreateComponents::default();
f(&mut components);
self.components = Some(components);
self
}
} }
#[async_trait] #[async_trait]
@ -178,6 +194,10 @@ impl CommandInvoke for Message {
m.set_embed(embed.clone()); m.set_embed(embed.clone());
} }
if let Some(components) = generic_response.components {
m.set_components(components.clone());
}
m m
}) })
.await .await
@ -197,6 +217,10 @@ impl CommandInvoke for Message {
m.set_embed(embed.clone()); m.set_embed(embed.clone());
} }
if let Some(components) = generic_response.components {
m.set_components(components.clone());
}
m m
}) })
.await .await
@ -252,6 +276,10 @@ impl CommandInvoke for Interaction {
d.add_embed(embed.clone()); d.add_embed(embed.clone());
} }
if let Some(components) = generic_response.components {
d.set_components(components.clone());
}
d d
}) })
}) })
@ -271,6 +299,10 @@ impl CommandInvoke for Interaction {
d.add_embed(embed.clone()); d.add_embed(embed.clone());
} }
if let Some(components) = generic_response.components {
d.set_components(components.clone());
}
d d
}) })
.await .await
@ -453,8 +485,6 @@ impl RegexFramework {
} }
pub fn add_command(mut self, command: &'static Command) -> Self { pub fn add_command(mut self, command: &'static Command) -> Self {
info!("{:?}", command);
self.commands_.insert(command); self.commands_.insert(command);
for name in command.names { for name in command.names {
@ -475,7 +505,7 @@ impl RegexFramework {
command_names = command_names_vec.join("|"); command_names = command_names_vec.join("|");
} }
info!("Command names: {}", command_names); debug!("Command names: {}", command_names);
{ {
let match_string = r#"^(?:(?:<@ID>\s*)|(?:<@!ID>\s*)|(?P<prefix>\S{1,5}?))(?P<cmd>COMMANDS)(?:$|\s+(?P<args>.*))$"# let match_string = r#"^(?:(?:<@ID>\s*)|(?:<@!ID>\s*)|(?P<prefix>\S{1,5}?))(?P<cmd>COMMANDS)(?:$|\s+(?P<args>.*))$"#
@ -534,7 +564,7 @@ impl RegexFramework {
.await .await
.expect("Failed to fetch existing commands"); .expect("Failed to fetch existing commands");
info!("Existing commands: {:?}", current_commands); debug!("Existing commands: {:?}", current_commands);
// delete commands not in use // delete commands not in use
for command in &current_commands { for command in &current_commands {
@ -613,8 +643,6 @@ impl RegexFramework {
} }
pub async fn execute(&self, ctx: Context, interaction: Interaction) { pub async fn execute(&self, ctx: Context, interaction: Interaction) {
if interaction.kind == InteractionType::ApplicationCommand && interaction.guild_id.is_some()
{
if let Some(InteractionData::ApplicationCommand(data)) = interaction.data.clone() { if let Some(InteractionData::ApplicationCommand(data)) = interaction.data.clone() {
let command = { let command = {
let name = data.name; let name = data.name;
@ -673,7 +701,6 @@ impl RegexFramework {
} }
} }
} }
}
} }
enum PermissionCheck { enum PermissionCheck {

View File

@ -48,7 +48,6 @@ use dashmap::DashMap;
use std::{collections::HashMap, convert::TryFrom, env, sync::Arc, time::Duration}; use std::{collections::HashMap, convert::TryFrom, env, sync::Arc, time::Duration};
use serenity::model::prelude::InteractionResponseType;
use tokio::sync::{MutexGuard, RwLock}; use tokio::sync::{MutexGuard, RwLock};
struct MySQL; struct MySQL;
@ -1154,16 +1153,12 @@ async fn soundboard(
let sounds = Sound::get_guild_sounds(invoke.guild_id().unwrap(), pool).await?; let sounds = Sound::get_guild_sounds(invoke.guild_id().unwrap(), pool).await?;
if let Some(interaction) = invoke.interaction() {
interaction
.create_interaction_response(&ctx, |r| r.kind(InteractionResponseType::Pong))
.await?;
}
invoke invoke
.channel_id() .respond(
.send_message(&ctx, |m| { ctx.http.clone(),
m.components(|c| { CreateGenericResponse::new()
.content("Select a sound from below:")
.components(|c| {
for row in sounds.as_slice().chunks(5) { for row in sounds.as_slice().chunks(5) {
let mut action_row: CreateActionRow = Default::default(); let mut action_row: CreateActionRow = Default::default();
for sound in row { for sound in row {
@ -1173,11 +1168,13 @@ async fn soundboard(
.custom_id(sound.id) .custom_id(sound.id)
}); });
} }
c.add_action_row(action_row);
} }
c c
}) }),
}) )
.await?; .await?;
Ok(()) Ok(())