[WIP] fix: music queue bugs

This commit is contained in:
Miguel da Mota 2024-03-10 15:39:11 +01:00
parent c6af238f06
commit e79b4142de
4 changed files with 70 additions and 70 deletions

View file

@ -1,8 +1,10 @@
mod commands; mod commands;
mod util;
mod music; mod music;
mod util;
use serenity::all::{CommandInteraction, CreateInteractionResponseFollowup, GuildId, OnlineStatus, VoiceState}; use serenity::all::{
CommandInteraction, CreateInteractionResponseFollowup, GuildId, OnlineStatus, VoiceState,
};
use serenity::async_trait; use serenity::async_trait;
use serenity::builder::CreateEmbed; use serenity::builder::CreateEmbed;
use serenity::gateway::ActivityData; use serenity::gateway::ActivityData;
@ -24,45 +26,36 @@ impl TypeMapKey for HttpKey {
type Value = HttpClient; type Value = HttpClient;
} }
// lazy static stuff. I don't like it, but it has to be here, bc it has to be @ root // lazy static stuff. I don't like it, but it has to be here, bc it has to be @ root
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
use std::collections::HashMap;
use crate::music::music_queue::MusicQueue; use crate::music::music_queue::MusicQueue;
use std::collections::HashMap;
lazy_static! { lazy_static! {
static ref HASHMAP: Mutex<HashMap<GuildId, MusicQueue>> = { static ref HASHMAP: Mutex<HashMap<GuildId, MusicQueue>> = Mutex::new(HashMap::new());
Mutex::new(HashMap::new())
};
} }
pub async fn get_queue(guild_id: GuildId) -> MusicQueue { pub async fn get_queue(guild_id: &GuildId) -> MusicQueue {
match HASHMAP.lock().await.get(&guild_id) { match HASHMAP.lock().await.get(&guild_id) {
Some(music_queue) => music_queue.clone(), Some(music_queue) => music_queue.clone(),
None => { None => {
let q = MusicQueue { let q = MusicQueue {
guild_id: guild_id, guild_id: *guild_id,
queue: Vec::new(), queue: Vec::new(),
now_playing: None now_playing: None,
}; };
HASHMAP.lock().await.insert(guild_id, q.clone()); HASHMAP.lock().await.insert(*guild_id, q.clone());
q q
} }
} }
} }
pub async fn set_queue(guild_id: &GuildId, queue: MusicQueue) {
pub async fn set_queue(guild_id: GuildId, queue: MusicQueue) { HASHMAP.lock().await.insert(*guild_id, queue);
HASHMAP.lock().await.insert(guild_id, queue);
} }
struct Handler; struct Handler;
#[async_trait] #[async_trait]
@ -98,7 +91,8 @@ impl EventHandler for Handler {
println!("Commands are registered and Rustendo is ready for Freddy."); println!("Commands are registered and Rustendo is ready for Freddy.");
} }
async fn voice_state_update(&self, ctx: Context, old: Option<VoiceState>, new: VoiceState) { // FIXME: This does not work, when switching channels async fn voice_state_update(&self, ctx: Context, old: Option<VoiceState>, new: VoiceState) {
// FIXME: This does not work, when switching channels
if new.channel_id.is_some() { if new.channel_id.is_some() {
return; // User did not leave, ignore return; // User did not leave, ignore
} }
@ -106,7 +100,14 @@ impl EventHandler for Handler {
if !user_util::is_self_connected_to_vc(&ctx, &old.guild_id.unwrap()).await { if !user_util::is_self_connected_to_vc(&ctx, &old.guild_id.unwrap()).await {
return; // Bot is not connected to a VC, ignore return; // Bot is not connected to a VC, ignore
} }
if user_util::get_amount_of_members_in_vc(&ctx, &old.guild_id.unwrap(), &old.channel_id.unwrap()).await < 2 { if user_util::get_amount_of_members_in_vc(
&ctx,
&old.guild_id.unwrap(),
&old.channel_id.unwrap(),
)
.await
< 2
{
let manager = songbird::get(&ctx).await.expect("Cannot get Songbird"); let manager = songbird::get(&ctx).await.expect("Cannot get Songbird");
if let Err(e) = manager.remove(old.guild_id.unwrap()).await { if let Err(e) = manager.remove(old.guild_id.unwrap()).await {
println!("Failed to remove handler: {:?}", e); println!("Failed to remove handler: {:?}", e);

View file

@ -17,7 +17,7 @@ impl EventHandler for TrackEndNotifier {
// TODO: Does this need to be unsafe? // TODO: Does this need to be unsafe?
if let EventContext::Track(..) = ctx { if let EventContext::Track(..) = ctx {
println!("The track ended!"); println!("The track ended!");
let music_queue = crate::get_queue(self.guild_id).await; let music_queue = crate::get_queue(&self.guild_id).await;
let q = &music_queue.queue; let q = &music_queue.queue;
if q.is_empty() { if q.is_empty() {
// No more songs in queue, exit the vc // No more songs in queue, exit the vc
@ -35,13 +35,13 @@ impl EventHandler for TrackEndNotifier {
} }
return None; return None;
} }
let head = music_queue::get_head(&self.guild_id); let head = music_queue::get_head(&self.guild_id).await;
if head.is_none() { if head.is_none() {
println!("Cannot get head of queue"); println!("Cannot get head of queue");
return None; return None;
} }
let head = head.unwrap(); let head = head.unwrap();
music_manager::play_song(&self.cmdctx, &self.guild_id, head).await; music_manager::play_song(&self.cmdctx, &self.guild_id, &head).await;
} }
None None

View file

@ -78,8 +78,8 @@ pub async fn attempt_to_queue_song(
YoutubeDl::new(http_client, query.to_string()) YoutubeDl::new(http_client, query.to_string())
}; };
let currently_playing = music_queue::get_now_playing(guild_id); let currently_playing = music_queue::get_now_playing(guild_id).await;
music_queue::add_to_queue(guild_id, src.clone()); music_queue::add_to_queue(guild_id, src.clone()).await;
if currently_playing.is_some() { if currently_playing.is_some() {
// Add to queue // Add to queue
return Embed::create( return Embed::create(
@ -89,8 +89,10 @@ pub async fn attempt_to_queue_song(
); );
} }
let _query = music_queue::get_head(guild_id).expect("Cannot get head of queue"); let _query = music_queue::get_head(guild_id)
music_queue::set_now_playing(guild_id, Some(src.clone())); .await
.expect("Cannot get head of queue");
music_queue::set_now_playing(guild_id, Some(src.clone())).await;
let handler_lock = match manager.get(*guild_id) { let handler_lock = match manager.get(*guild_id) {
Some(handler) => handler, Some(handler) => handler,
@ -150,7 +152,7 @@ pub async fn play_song(ctx: &Context, guild_id: &GuildId, target: &YoutubeDl) {
return; return;
} }
music_queue::set_now_playing(guild_id, Some(target.clone())); music_queue::set_now_playing(guild_id, Some(target.clone())).await;
let handler_lock = match manager.get(*guild_id) { let handler_lock = match manager.get(*guild_id) {
Some(handler) => handler, Some(handler) => handler,
None => return, None => return,
@ -209,7 +211,7 @@ pub async fn attempt_to_stop(
"I am not connected. I cant stop doing something, when I'm not doing it".to_string(), "I am not connected. I cant stop doing something, when I'm not doing it".to_string(),
) )
} else { } else {
music_queue::delete_queue(guild_id); // Clear queue music_queue::delete_queue(guild_id).await; // Clear queue
Embed::create(username, "I stopped and left", "Just like your girlfriend.") Embed::create(username, "I stopped and left", "Just like your girlfriend.")
} }

View file

@ -10,38 +10,35 @@ pub struct MusicQueue {
} }
pub async fn delete_queue(guild_id: &GuildId) { pub async fn delete_queue(guild_id: &GuildId) {
let mut queue = crate::get_queue(*guild_id).await; let mut queue = crate::get_queue(guild_id).await;
queue.now_playing = None; queue.now_playing = None;
queue.queue = Vec::new(); queue.queue = Vec::new();
crate::set_queue(*guild_id, queue); crate::set_queue(guild_id, queue).await;
} }
pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) {
let mut queue = crate::get_queue(*guild_id).await; let mut queue = crate::get_queue(guild_id).await;
queue.queue.push(input); queue.queue.push(input);
crate::set_queue(*guild_id, queue); crate::set_queue(guild_id, queue).await;
} }
pub async fn get_head(guild_id: &GuildId) -> Option<&YoutubeDl> { pub async fn get_head(guild_id: &GuildId) -> Option<YoutubeDl> {
let music_queue = crate::get_queue(*guild_id).await; let mut music_queue = crate::get_queue(guild_id).await;
if music_queue.queue.is_empty() { if music_queue.queue.is_empty() {
return None; return None;
} }
let mut queue = music_queue.queue; let result = music_queue.queue.remove(0);
let result = queue.first(); crate::set_queue(guild_id, music_queue).await;
queue.remove(0); Some(result)
music_queue.queue = queue;
crate::set_queue(*guild_id, music_queue);
result
} }
pub fn set_now_playing(guild_id: &GuildId, now_playing: Option<YoutubeDl>) { pub async fn set_now_playing(guild_id: &GuildId, now_playing: Option<YoutubeDl>) {
let mut queue = crate::get_queue(*guild_id); let mut queue = crate::get_queue(guild_id).await;
queue.now_playing = now_playing; queue.now_playing = now_playing;
crate::set_queue(*guild_id, queue) crate::set_queue(guild_id, queue).await;
} }
pub fn get_now_playing(guild_id: &GuildId) -> Option<YoutubeDl> { pub async fn get_now_playing(guild_id: &GuildId) -> Option<YoutubeDl> {
let queue = crate::get_queue(*guild_id); let queue = crate::get_queue(guild_id).await;
queue.now_playing queue.now_playing
} }