use std::time::Duration; use serenity::all::{Context, CreateMessage, GuildChannel, VoiceState}; use tokio::time::sleep; use crate::utils::{debug::send_error, voice_state_to_guild_channel}; async fn get_channel_info(ctx: &Context, voice_state: &VoiceState) -> Option { let voice_channel = voice_state_to_guild_channel(&ctx, &voice_state).await?; let Ok(members) = voice_channel.members(&ctx.cache) else { return None }; let mut is_connected = false; let mut users_connected: usize = 0; for member in &members { if member.user.id == ctx.cache.current_user().id { is_connected = true } if ! member.user.bot { users_connected += 1; } } // Check if there is no real user in the voice channel if ! is_connected || users_connected > 0 { return None; } Some(voice_channel) } pub async fn handle_voice_update(ctx: Context, voice_state_old: VoiceState, voice_state: VoiceState) -> Option<()> { // The user did not disconnect so we don't need to handle if the bot was left alone // Logic is as follows: // User connected -> voice_state_old is None (we handle this before this function) // User moved to different VC or disconnected -> we only check old channel for number of users anyway if voice_state.channel_id.is_some() { return None } let mut voice_channel = get_channel_info(&ctx, &voice_state_old).await?; let manager = songbird::get(&ctx) .await .expect("Songbird Voice client placed in at initialisation.") .clone(); // bot is not playing any music so we don't need to handle this if manager.get(voice_channel.guild_id).is_none() { return None; } // There is a problem with this implementation // if bot is left alone and users joins and disconnects while this counts down // this is not a big problem since we want to disconnect anyway sleep(Duration::from_secs(5)).await; voice_channel = get_channel_info(&ctx, &voice_state_old).await?; match manager.remove(voice_channel.guild_id).await { Ok(()) => { let _ = voice_channel.send_message(ctx.http, CreateMessage::new() .content("Disconnected to save bandwidth") ).await; } Err(e) => { let _ = send_error(ctx.http, e.to_string()).await; } } None }