2025-01-31 22:23:13 +00:00
|
|
|
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<GuildChannel> {
|
|
|
|
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<()> {
|
|
|
|
// Logic is as follows:
|
|
|
|
// User connected -> voice_state_old is None (we handle this before this function)
|
2025-02-01 23:11:29 +00:00
|
|
|
// Bot was moved to different vc -> we check if the new voice_state has the bot's user id
|
|
|
|
// User moved to different VC or disconnected -> we check old channel instead (the bot could be still there)
|
|
|
|
let mut voice_channel: GuildChannel;
|
|
|
|
if voice_state.user_id == ctx.cache.current_user().id {
|
|
|
|
voice_channel = get_channel_info(&ctx, &voice_state).await?;
|
|
|
|
}
|
|
|
|
// Someone disconnected or moved channels
|
|
|
|
else {
|
|
|
|
voice_channel = get_channel_info(&ctx, &voice_state_old).await?;
|
2025-01-31 22:23:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let manager = songbird::get(&ctx)
|
|
|
|
.await
|
|
|
|
.expect("Songbird Voice client placed in at initialisation.")
|
|
|
|
.clone();
|
|
|
|
|
2025-02-01 23:11:29 +00:00
|
|
|
// bot is not connected to any channel via songbird, don't need to do anything
|
2025-01-31 22:23:13 +00:00
|
|
|
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
|
2025-02-01 23:11:29 +00:00
|
|
|
sleep(Duration::from_secs(120)).await;
|
2025-01-31 22:23:13 +00:00
|
|
|
|
2025-02-01 23:11:29 +00:00
|
|
|
if voice_state.user_id == ctx.cache.current_user().id {
|
|
|
|
voice_channel = get_channel_info(&ctx, &voice_state).await?;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
voice_channel = get_channel_info(&ctx, &voice_state_old).await?;
|
|
|
|
}
|
|
|
|
|
|
|
|
// bot is not connected to any channel via songbird, don't need to do anything
|
|
|
|
// ? could have been removed while sleeping if the song stopped playing
|
|
|
|
if manager.get(voice_channel.guild_id).is_none() {
|
|
|
|
return None;
|
|
|
|
}
|
2025-01-31 22:23:13 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|