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

@@ -7,9 +7,9 @@ use revolt_database::{
use revolt_models::v0;
use revolt_permissions::{calculate_channel_permissions, ChannelPermission};
use revolt_presence::filter_online;
use revolt_result::{create_error, Result};
use revolt_result::Result;
use revolt_voice::{delete_voice_state, get_voice_channel_members, get_voice_state};
use redis_kiss::{get_connection, AsyncCommands, Conn};
use super::state::{Cache, State};
@@ -127,9 +127,6 @@ impl State {
// Filter server channels by permission.
let channels = self.cache.filter_accessible_channels(db, channels).await;
let mut voice_states = Vec::new();
let mut conn = get_connection().await.unwrap();
// Append known user IDs from DMs.
for channel in &channels {
match channel {
@@ -202,8 +199,11 @@ impl State {
self.insert_subscription(channel.id().to_string());
}
// fetch voice states for all the channels we can see
let mut voice_states = Vec::new();
for channel in &channels {
if let Ok(Some(voice_state)) = self.fetch_voice_state(&mut conn, channel).await {
if let Ok(Some(voice_state)) = self.fetch_voice_state(channel).await {
voice_states.push(voice_state)
}
}
@@ -564,41 +564,21 @@ impl State {
async fn fetch_voice_state(
&self,
conn: &mut Conn,
channel: &Channel,
) -> Result<Option<v0::ChannelVoiceState>> {
let members = conn
.smembers::<_, Vec<String>>(format!("vc-members-{}", channel.id()))
.await
.map_err(|_| create_error!(InternalError))?;
let channel_or_server_id = channel.server().unwrap_or_else(|| channel.id());
let members = get_voice_channel_members(&channel.id()).await?;
if !members.is_empty() {
let mut participants = Vec::with_capacity(members.len());
for id in members {
let unique_key = format!("{channel_or_server_id}-{id}");
for user_id in members {
if let Some(voice_state) = get_voice_state(&channel.id(), channel.server().as_deref(), &user_id).await? {
participants.push(voice_state);
} else {
log::info!("Voice state not found but member in voice channel members, removing.");
let (can_publish, can_receive, screensharing, camera) = conn
.mget::<_, (bool, bool, bool, bool)>(&[
format!("can_publish-{unique_key}"),
format!("can_receive-{unique_key}"),
format!("screensharing-{unique_key}"),
format!("camera-{unique_key}"),
])
.await
.map_err(|_| create_error!(InternalError))?;
let voice_state = v0::UserVoiceState {
id,
can_receive,
can_publish,
screensharing,
camera,
};
participants.push(voice_state);
delete_voice_state(&channel.id(), channel.server().as_deref(), &user_id).await?;
}
}
Ok(Some(v0::ChannelVoiceState {

View File

@@ -1,7 +1,9 @@
use std::env;
use std::{env, sync::Arc};
use async_std::net::TcpListener;
use revolt_presence::clear_region;
use once_cell::sync::OnceCell;
use revolt_voice::VoiceClient;
#[macro_use]
extern crate log;
@@ -12,6 +14,15 @@ pub mod events;
mod database;
mod websocket;
pub static VOICE_CLIENT: OnceCell<Arc<VoiceClient>> = OnceCell::new();
pub fn get_voice_client() -> Arc<VoiceClient> {
VOICE_CLIENT
.get()
.expect("get_voice_client called before set")
.clone()
}
#[async_std::main]
async fn main() {
// Configure requirements for Bonfire.
@@ -21,6 +32,8 @@ async fn main() {
// Clean up the current region information.
clear_region(None).await;
VOICE_CLIENT.set(Arc::new(VoiceClient::from_revolt_config().await)).unwrap();
// Setup a TCP listener to accept WebSocket connections on.
// By default, we bind to port 9000 on all interfaces.
let bind = env::var("HOST").unwrap_or_else(|_| "0.0.0.0:9000".into());