Add autoleave and fix some bugs

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/25/head
trivernis 3 years ago
parent b2ba31a9e9
commit 18cd1e7d28
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -40,8 +40,13 @@ pub async fn get_client() -> BotResult<Client> {
let lava_client = LavalinkClient::builder(current_application.id.0)
.set_host(env::var("LAVALINK_HOST").unwrap_or("172.0.0.1".to_string()))
.set_password(env::var("LAVALINK_PORT").expect("Missing lavalink port"))
.set_password(env::var("LAVALINK_PASSWORD").expect("Missing lavalink password"))
.set_port(
env::var("LAVALINK_PORT")
.ok()
.and_then(|s| s.parse().ok())
.expect("Missing lavalink port"),
)
.build(LavalinkHandler { data })
.await?;
{

@ -4,7 +4,7 @@ use serenity::framework::standard::{Args, CommandResult};
use serenity::model::channel::Message;
use crate::commands::common::handle_autodelete;
use crate::commands::music::{get_channel_for_author, is_dj};
use crate::commands::music::{get_channel_for_author, get_music_player_for_guild, is_dj};
use crate::providers::music::player::MusicPlayer;
use bot_serenityutils::core::SHORT_TIMEOUT;
use bot_serenityutils::ephemeral_message::EphemeralMessage;
@ -34,6 +34,13 @@ async fn join(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
get_channel_for_author(&msg.author.id, &guild)
)
};
if get_music_player_for_guild(ctx, guild.id).await.is_some() {
EphemeralMessage::create(&ctx.http, msg.channel_id, SHORT_TIMEOUT, |m| {
m.content("‼️ I'm already in a Voice Channel")
})
.await?;
return Ok(());
}
log::debug!("Joining channel {} for guild {}", channel_id, guild.id);
MusicPlayer::join(ctx, guild.id, channel_id).await?;
EphemeralMessage::create(&ctx.http, msg.channel_id, SHORT_TIMEOUT, |m| {

@ -20,8 +20,15 @@ async fn leave(ctx: &Context, msg: &Message) -> CommandResult {
let guild = msg.guild(&ctx.cache).await.unwrap();
log::debug!("Leave request received for guild {}", guild.id);
let manager = songbird::get(ctx).await.unwrap();
if let Some(handler) = manager.get(guild.id) {
let mut handler_lock = handler.lock().await;
let _ = handler_lock.leave().await;
}
let mut data = ctx.data.write().await;
let players = data.get_mut::<MusicPlayers>().unwrap();
match players.remove(&guild.id.0) {
None => {
EphemeralMessage::create(&ctx.http, msg.channel_id, SHORT_TIMEOUT, |m| {
@ -32,8 +39,10 @@ async fn leave(ctx: &Context, msg: &Message) -> CommandResult {
Some(player) => {
let mut player = player.lock().await;
player.stop().await?;
player.delete_now_playing().await?;
}
}
manager.remove(guild.id).await?;
handle_autodelete(ctx, msg).await?;

@ -9,7 +9,7 @@ use crate::messages::add_ephemeral_handle_to_database;
use crate::providers::music::add_youtube_song_to_database;
use crate::providers::music::player::MusicPlayer;
use crate::providers::music::queue::Song;
use crate::utils::context_data::{DatabaseContainer, Store};
use crate::utils::context_data::{DatabaseContainer, MusicPlayers, Store};
use crate::utils::error::*;
use bot_serenityutils::core::MessageHandle;
use bot_serenityutils::error::SerenityUtilsResult;
@ -230,14 +230,19 @@ async fn stop_button_action(
if let Some(handler) = handler {
let mut handler_lock = handler.lock().await;
handler_lock.remove_all_global_events();
let _ = handler_lock.leave().await;
}
if manager.get(guild_id).is_some() {
manager.remove(guild_id).await.map_err(BotError::from)?;
let player = get_music_player_for_guild(ctx, guild_id).await.unwrap();
let mut player = player.lock().await;
player.stop().await?;
let mut data = ctx.data.write().await;
let players = data.get_mut::<MusicPlayers>().unwrap();
if let Some(player) = players.remove(&guild_id.0) {
let mut player = player.lock().await;
player.stop().await?;
}
log::debug!("Left the voice channel");
} else {
log::debug!("Not in a voice channel");

@ -6,11 +6,16 @@ use crate::utils::context_data::MusicPlayers;
use crate::utils::error::BotResult;
use bot_serenityutils::core::MessageHandle;
use lavalink_rs::LavalinkClient;
use serenity::client::Context;
use serenity::http::Http;
use serenity::model::id::{ChannelId, GuildId};
use serenity::prelude::TypeMap;
use serenity::{
client::Context,
http::Http,
model::id::{ChannelId, GuildId},
};
use songbird::Songbird;
use std::mem;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::{Mutex, RwLock};
pub struct MusicPlayer {
@ -58,6 +63,13 @@ impl MusicPlayer {
player
};
wait_for_disconnect(
Arc::clone(&ctx.data),
Arc::clone(&player),
manager,
guild_id,
);
Ok(player)
}
@ -118,6 +130,9 @@ impl MusicPlayer {
}
};
if query_information.tracks.len() == 0 {
return Ok(false);
}
let track = query_information.tracks[0].clone();
self.client.play(self.guild_id.0, track).start().await?;
self.queue.set_current(next);
@ -179,3 +194,48 @@ impl MusicPlayer {
self.leave_flag = flag;
}
}
/// Stats a tokio coroutine to check for player disconnect conditions
fn wait_for_disconnect(
data: Arc<RwLock<TypeMap>>,
player: Arc<Mutex<MusicPlayer>>,
manager: Arc<Songbird>,
guild_id: GuildId,
) {
let mut leave_in: i32 = 5;
tokio::spawn(async move {
loop {
tokio::time::sleep(Duration::from_secs(60)).await;
if manager.get(guild_id).is_none() {
return; // leave when there's no connection to handle
}
let mut player_lock = player.lock().await;
if player_lock.leave_flag {
log::debug!("Waiting to leave");
if leave_in <= 0 {
log::debug!("Leaving voice channel");
if let Some(handler) = manager.get(guild_id) {
let mut handler_lock = handler.lock().await;
let _ = handler_lock.leave().await;
}
let _ = manager.remove(guild_id).await;
let mut data = data.write().await;
let players = data.get_mut::<MusicPlayers>().unwrap();
players.remove(&guild_id.0);
let _ = player_lock.stop().await;
let _ = player_lock.delete_now_playing().await;
log::debug!("Left the voice channel");
return;
}
leave_in -= 1;
} else {
log::debug!("Resetting leave value");
leave_in = 5
}
}
});
}

Loading…
Cancel
Save