From 10c9682bba1df60757fc059b7d8c6e17c99a4c2a Mon Sep 17 00:00:00 2001 From: Zomatree Date: Mon, 4 Aug 2025 03:19:53 +0100 Subject: [PATCH] feat: ability to force disconnect existing voice connection --- crates/core/models/src/v0/channels.rs | 5 +++ .../delta/src/routes/channels/voice_join.rs | 45 +++++++++++++++---- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/crates/core/models/src/v0/channels.rs b/crates/core/models/src/v0/channels.rs index 39db5cb5..0d99f956 100644 --- a/crates/core/models/src/v0/channels.rs +++ b/crates/core/models/src/v0/channels.rs @@ -328,7 +328,12 @@ auto_derived!( /// Join a voice channel pub struct DataJoinCall { + /// Name of the node to join pub node: Option, + /// Whether to force disconnect any other existing voice connections. + /// + /// useful for disconnecting on another device and joining on a new. + pub force_disconnect: Option } ); diff --git a/crates/delta/src/routes/channels/voice_join.rs b/crates/delta/src/routes/channels/voice_join.rs index 7c3c86cd..c83e1609 100644 --- a/crates/delta/src/routes/channels/voice_join.rs +++ b/crates/delta/src/routes/channels/voice_join.rs @@ -1,6 +1,6 @@ use revolt_config::config; use revolt_models::v0; -use revolt_database::{util::{permissions::perms, reference::Reference}, voice::{get_channel_node, raise_if_in_voice, VoiceClient}, Channel, Database, SystemMessage, User, AMQP}; +use revolt_database::{util::{permissions::perms, reference::Reference}, voice::{delete_voice_state, get_channel_node, get_user_voice_channels, raise_if_in_voice, VoiceClient}, Channel, Database, SystemMessage, User, AMQP}; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; @@ -11,17 +11,31 @@ use rocket::{serde::json::Json, State}; /// Asks the voice server for a token to join the call. #[openapi(tag = "Voice")] #[post("//join_call", data="")] -pub async fn call(db: &State, amqp: &State, voice: &State, user: User, target: Reference, data: Json) -> Result> { - if !voice.is_enabled() { +pub async fn call( + db: &State, + amqp: &State, + voice_client: &State, + user: User, + target: Reference, + data: Json +) -> Result> { + if !voice_client.is_enabled() { return Err(create_error!(LiveKitUnavailable)) } + let v0::DataJoinCall { + node, + force_disconnect + } = data.into_inner(); + + if user.bot.is_some() && force_disconnect == Some(true) { + return Err(create_error!(IsBot)) + } + let config = config().await; let channel = target.as_channel(db).await?; - raise_if_in_voice(&user, channel.id()).await?; - let mut permissions = perms(db, &user).channel(&channel); let current_permissions = calculate_channel_permissions(&mut permissions).await; @@ -29,15 +43,30 @@ pub async fn call(db: &State, amqp: &State, voice: &State