queue play command
This commit is contained in:
parent
821f283969
commit
febeeefb01
@ -5,7 +5,7 @@ authors = ["jellywx <judesouthworth@pm.me>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
songbird = { git = "https://github.com/serenity-rs/songbird", branch = "next" }
|
songbird = { git = "https://github.com/serenity-rs/songbird", branch = "next", features = ["builtin-queue"] }
|
||||||
poise = { git = "https://github.com/kangalioo/poise", branch = "master", features = ["collector"] }
|
poise = { git = "https://github.com/kangalioo/poise", branch = "master", features = ["collector"] }
|
||||||
sqlx = { version = "0.5", default-features = false, features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal"] }
|
sqlx = { version = "0.5", default-features = false, features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal"] }
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
|
163
src/cmds/play.rs
163
src/cmds/play.rs
@ -2,6 +2,8 @@ use poise::serenity::{
|
|||||||
builder::CreateActionRow, model::interactions::message_component::ButtonStyle,
|
builder::CreateActionRow, model::interactions::message_component::ButtonStyle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::models::guild_data::CtxGuildData;
|
||||||
|
use crate::utils::{join_channel, queue_audio};
|
||||||
use crate::{
|
use crate::{
|
||||||
cmds::autocomplete_sound, models::sound::SoundCtx, utils::play_from_query, Context, Error,
|
cmds::autocomplete_sound, models::sound::SoundCtx, utils::play_from_query, Context, Error,
|
||||||
};
|
};
|
||||||
@ -32,6 +34,167 @@ pub async fn play(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Play up to 25 sounds on queue
|
||||||
|
#[poise::command(slash_command, rename = "queue")]
|
||||||
|
pub async fn queue_play(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "Name or ID for queue position 1"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_1: String,
|
||||||
|
#[description = "Name or ID for queue position 2"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_2: String,
|
||||||
|
#[description = "Name or ID for queue position 3"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_3: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 4"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_4: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 5"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_5: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 6"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_6: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 7"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_7: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 8"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_8: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 9"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_9: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 10"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_10: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 11"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_11: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 12"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_12: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 13"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_13: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 14"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_14: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 15"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_15: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 16"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_16: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 17"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_17: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 18"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_18: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 19"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_19: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 20"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_20: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 21"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_21: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 22"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_22: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 23"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_23: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 24"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_24: Option<String>,
|
||||||
|
#[description = "Name or ID for queue position 25"]
|
||||||
|
#[autocomplete = "autocomplete_sound"]
|
||||||
|
sound_25: Option<String>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let _ = ctx.defer().await;
|
||||||
|
|
||||||
|
let guild = ctx.guild().unwrap();
|
||||||
|
|
||||||
|
let channel_to_join = guild
|
||||||
|
.voice_states
|
||||||
|
.get(&ctx.author().id)
|
||||||
|
.and_then(|voice_state| voice_state.channel_id);
|
||||||
|
|
||||||
|
match channel_to_join {
|
||||||
|
Some(user_channel) => {
|
||||||
|
let (call_handler, _) = join_channel(ctx.discord(), guild.clone(), user_channel).await;
|
||||||
|
|
||||||
|
let guild_data = ctx
|
||||||
|
.data()
|
||||||
|
.guild_data(ctx.guild_id().unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut lock = call_handler.lock().await;
|
||||||
|
|
||||||
|
let query_terms = [
|
||||||
|
Some(sound_1),
|
||||||
|
Some(sound_2),
|
||||||
|
sound_3,
|
||||||
|
sound_4,
|
||||||
|
sound_5,
|
||||||
|
sound_6,
|
||||||
|
sound_7,
|
||||||
|
sound_8,
|
||||||
|
sound_9,
|
||||||
|
sound_10,
|
||||||
|
sound_11,
|
||||||
|
sound_12,
|
||||||
|
sound_13,
|
||||||
|
sound_14,
|
||||||
|
sound_15,
|
||||||
|
sound_16,
|
||||||
|
sound_17,
|
||||||
|
sound_18,
|
||||||
|
sound_19,
|
||||||
|
sound_20,
|
||||||
|
sound_21,
|
||||||
|
sound_22,
|
||||||
|
sound_23,
|
||||||
|
sound_24,
|
||||||
|
sound_25,
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut sounds = vec![];
|
||||||
|
|
||||||
|
for sound in query_terms.iter().flatten() {
|
||||||
|
let search = ctx
|
||||||
|
.data()
|
||||||
|
.search_for_sound(&sound, ctx.guild_id().unwrap(), ctx.author().id, true)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if let Some(sound) = search.first() {
|
||||||
|
sounds.push(sound.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue_audio(
|
||||||
|
&sounds,
|
||||||
|
guild_data.read().await.volume,
|
||||||
|
&mut lock,
|
||||||
|
&ctx.data().database,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
ctx.say(format!("Queued {} sounds!", sounds.len())).await?;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
ctx.say("You are not in a voice chat!").await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Loop a sound in your current voice channel
|
/// Loop a sound in your current voice channel
|
||||||
#[poise::command(slash_command, rename = "loop")]
|
#[poise::command(slash_command, rename = "loop")]
|
||||||
pub async fn loop_play(
|
pub async fn loop_play(
|
||||||
|
@ -2,7 +2,7 @@ use songbird;
|
|||||||
|
|
||||||
use crate::{Context, Error};
|
use crate::{Context, Error};
|
||||||
|
|
||||||
/// Stop the bot from playing
|
/// Stop the bot from playing and clear the play queue
|
||||||
#[poise::command(slash_command, rename = "stop")]
|
#[poise::command(slash_command, rename = "stop")]
|
||||||
pub async fn stop_playing(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn stop_playing(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
let songbird = songbird::get(ctx.discord()).await.unwrap();
|
let songbird = songbird::get(ctx.discord()).await.unwrap();
|
||||||
|
@ -102,14 +102,15 @@ SELECT name, id, public, server_id, uploader_id
|
|||||||
|
|
||||||
let (handler, _) = join_channel(&ctx, guild, user_channel).await;
|
let (handler, _) = join_channel(&ctx, guild, user_channel).await;
|
||||||
|
|
||||||
let _ = play_audio(
|
play_audio(
|
||||||
&mut sound,
|
&mut sound,
|
||||||
volume,
|
volume,
|
||||||
&mut handler.lock().await,
|
&mut handler.lock().await,
|
||||||
&data.database,
|
&data.database,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
cmds::manage::download_file(),
|
cmds::manage::download_file(),
|
||||||
cmds::manage::delete_sound(),
|
cmds::manage::delete_sound(),
|
||||||
cmds::play::play(),
|
cmds::play::play(),
|
||||||
|
cmds::play::queue_play(),
|
||||||
cmds::play::loop_play(),
|
cmds::play::loop_play(),
|
||||||
cmds::play::soundboard(),
|
cmds::play::soundboard(),
|
||||||
poise::Command {
|
poise::Command {
|
||||||
|
19
src/utils.rs
19
src/utils.rs
@ -18,7 +18,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub async fn play_audio(
|
pub async fn play_audio(
|
||||||
sound: &mut Sound,
|
sound: &Sound,
|
||||||
volume: u8,
|
volume: u8,
|
||||||
call_handler: &mut MutexGuard<'_, Call>,
|
call_handler: &mut MutexGuard<'_, Call>,
|
||||||
db_pool: impl Executor<'_, Database = Database>,
|
db_pool: impl Executor<'_, Database = Database>,
|
||||||
@ -39,6 +39,23 @@ pub async fn play_audio(
|
|||||||
Ok(track_handler)
|
Ok(track_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn queue_audio(
|
||||||
|
sounds: &[Sound],
|
||||||
|
volume: u8,
|
||||||
|
call_handler: &mut MutexGuard<'_, Call>,
|
||||||
|
db_pool: impl Executor<'_, Database = Database> + Copy,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
for sound in sounds {
|
||||||
|
let (a, b) = create_player(sound.playable(db_pool).await?.into());
|
||||||
|
|
||||||
|
let _ = b.set_volume(volume as f32 / 100.0);
|
||||||
|
|
||||||
|
call_handler.enqueue(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn join_channel(
|
pub async fn join_channel(
|
||||||
ctx: &poise::serenity_prelude::Context,
|
ctx: &poise::serenity_prelude::Context,
|
||||||
guild: Guild,
|
guild: Guild,
|
||||||
|
Loading…
Reference in New Issue
Block a user