split voice ops into its own library

This commit is contained in:
Zomatree
2024-05-13 14:09:08 +01:00
parent 675c7d6c0d
commit ffbc899792
17 changed files with 446 additions and 217 deletions

View File

@@ -1,17 +1,17 @@
use std::collections::HashSet;
use futures::TryFutureExt;
use livekit_api::services::room::{RoomClient, UpdateParticipantOptions};
use livekit_protocol::ParticipantPermission;
use redis_kiss::{get_connection, redis::Pipeline, AsyncCommands};
use revolt_database::{
util::{permissions::DatabasePermissionQuery, reference::Reference},
Database, File, PartialMember, User,
events::client::EventV1, util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, File, PartialMember, User
};
use revolt_models::v0;
use revolt_models::v0::{self, PartialUserVoiceState};
use revolt_permissions::{calculate_server_permissions, ChannelPermission};
use revolt_result::{create_error, Result, ToRevoltError};
use rocket::{serde::json::Json, State};
use rocket::{form::validate::Contains, serde::json::Json, State};
use validator::Validate;
/// # Edit Member
@@ -99,6 +99,25 @@ pub async fn edit(
permissions.throw_if_lacking_channel_permission(ChannelPermission::DeafenMembers)?;
}
if let Some(new_channel) = &data.voice_channel {
permissions.throw_if_lacking_channel_permission(ChannelPermission::MoveMembers)?;
// ensure the channel we are moving them to is in the server and is a voice channel
let channel = Reference::from_unchecked(new_channel.clone())
.as_channel(db)
.await
.map_err(|_| create_error!(UnknownChannel))?;
if !channel.server().is_some_and(|v| v == member.id.server) {
Err(create_error!(UnknownChannel))?
}
if channel.voice().is_none() {
Err(create_error!(NotAVoiceChannel))?
}
}
// Resolve our ranking
let our_ranking = query.get_member_rank().unwrap_or(i64::MIN);
@@ -136,6 +155,7 @@ pub async fn edit(
remove,
can_publish,
can_receive,
voice_channel
} = data;
let mut partial = PartialMember {
@@ -171,13 +191,15 @@ pub async fn edit(
)
.await?;
if can_publish.is_some() || can_receive.is_some() {
if can_publish.is_some() || can_receive.is_some() || voice_channel.is_some() {
let mut conn = get_connection().await.to_internal_error()?;
let unique_key = format!("{}-{}", &member.id.user, &member.id.server);
// if we edit the member while they are in a voice channel we need to also update the perms
// otherwise it wont take place until they leave and rejoin
if let Some(channel) = conn
.get::<_, Option<String>>(format!("vc-{}-{}", &member.id.user, &member.id.server))
.get::<_, Option<String>>(format!("vc-{}", &unique_key))
.await
.to_internal_error()?
{
@@ -186,7 +208,7 @@ pub async fn edit(
if let Some(can_publish) = can_publish {
pipeline.set(
format!("can_publish-{}-{}", &channel, &member.id.user),
format!("can_publish-{}", unique_key),
can_publish,
);
@@ -196,13 +218,18 @@ pub async fn edit(
if let Some(can_receive) = can_receive {
pipeline.set(
format!("can_receive-{}-{}", &channel, &member.id.user),
format!("can_receive-{}", unique_key),
can_receive,
);
new_perms.can_subscribe = can_receive;
};
if let Some(new_channel) = voice_channel {
pipeline
.smove(format!("vc-members-{channel}"), format!("vc-members-{new_channel}"), &member.id.user);
};
pipeline
.query_async(&mut conn.into_inner())
.await
@@ -220,6 +247,18 @@ pub async fn edit(
)
.await
.to_internal_error()?;
EventV1::UserVoiceStateUpdate {
id: member.id.user.clone(),
channel_id: channel.clone(),
data: PartialUserVoiceState {
can_publish,
can_receive,
..Default::default()
}
}
.p(channel)
.await;
};
};