use std::sync::Arc; use poise::serenity::model::{ channel::Channel, guild::Guild, id::{ChannelId, UserId}, }; use songbird::{create_player, error::JoinResult, tracks::TrackHandle, Call}; use sqlx::MySqlPool; use tokio::sync::{Mutex, MutexGuard}; use crate::{ models::{ guild_data::CtxGuildData, sound::{Sound, SoundCtx}, }, Data, }; pub async fn play_audio( sound: &mut Sound, volume: u8, call_handler: &mut MutexGuard<'_, Call>, mysql_pool: MySqlPool, loop_: bool, ) -> Result> { let (track, track_handler) = create_player(sound.playable(mysql_pool.clone()).await?.into()); let _ = track_handler.set_volume(volume as f32 / 100.0); if loop_ { let _ = track_handler.enable_loop(); } else { let _ = track_handler.disable_loop(); } call_handler.play(track); Ok(track_handler) } pub async fn join_channel( ctx: &poise::serenity_prelude::Context, guild: Guild, channel_id: ChannelId, ) -> (Arc>, JoinResult<()>) { let songbird = songbird::get(ctx).await.unwrap(); let current_user = ctx.cache.current_user_id(); let current_voice_state = guild .voice_states .get(¤t_user) .and_then(|voice_state| voice_state.channel_id); let (call, res) = if current_voice_state == Some(channel_id) { let call_opt = songbird.get(guild.id); if let Some(call) = call_opt { (call, Ok(())) } else { let (call, res) = songbird.join(guild.id, channel_id).await; (call, res) } } else { let (call, res) = songbird.join(guild.id, channel_id).await; (call, res) }; { // set call to deafen let _ = call.lock().await.deafen(true).await; } if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) { let _ = channel .edit_voice_state(&ctx, ctx.cache.current_user(), |v| v.suppress(false)) .await; } (call, res) } pub async fn play_from_query( ctx: &poise::serenity_prelude::Context, data: &Data, guild: Guild, user_id: UserId, query: &str, loop_: bool, ) -> String { let guild_id = guild.id; let channel_to_join = guild .voice_states .get(&user_id) .and_then(|voice_state| voice_state.channel_id); match channel_to_join { Some(user_channel) => { let pool = data.database.clone(); let mut sound_vec = data .search_for_sound(query, guild_id, user_id, true) .await .unwrap(); let sound_res = sound_vec.first_mut(); match sound_res { Some(sound) => { { let (call_handler, _) = join_channel(ctx, guild.clone(), user_channel).await; let guild_data = data.guild_data(guild_id).await.unwrap(); let mut lock = call_handler.lock().await; play_audio( sound, guild_data.read().await.volume, &mut lock, pool, loop_, ) .await .unwrap(); } format!("Playing sound {} with ID {}", sound.name, sound.id) } None => "Couldn't find sound by term provided".to_string(), } } None => "You are not in a voice chat!".to_string(), } }