diff options
Diffstat (limited to 'mumd/src/state.rs')
| -rw-r--r-- | mumd/src/state.rs | 113 |
1 files changed, 97 insertions, 16 deletions
diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 44d8b21..ea081fc 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -4,6 +4,7 @@ pub mod user; use crate::audio::Audio; use crate::network::ConnectionInfo; +use crate::notify; use crate::state::server::Server; use log::*; @@ -13,6 +14,7 @@ use mumble_protocol::voice::Serverbound; use mumlib::command::{Command, CommandResponse}; use mumlib::config::Config; use mumlib::error::{ChannelIdentifierError, Error}; +use mumlib::state::UserDiff; use std::net::ToSocketAddrs; use tokio::sync::{mpsc, watch}; use crate::network::tcp::{TcpEvent, TcpEventData}; @@ -205,31 +207,106 @@ impl State { } } - pub fn parse_user_state(&mut self, msg: msgs::UserState) -> Option<mumlib::state::UserDiff> { + pub fn parse_user_state(&mut self, msg: msgs::UserState) -> Option<UserDiff> { if !msg.has_session() { warn!("Can't parse user state without session"); return None; } - let sess = msg.get_session(); + let session = msg.get_session(); // check if this is initial state - if !self.server().unwrap().users().contains_key(&sess) { - if !msg.has_name() { - warn!("Missing name in initial user state"); - } else if msg.get_name() == self.server().unwrap().username().unwrap() { - // this is us - *self.server_mut().unwrap().session_id_mut() = Some(sess); - } else { - // this is someone else - self.audio_mut().add_client(sess); + if !self.server().unwrap().users().contains_key(&session) { + self.parse_initial_user_state(session, msg); + return None; + } else { + return Some(self.parse_updated_user_state(session, msg)); + } + } + + fn parse_initial_user_state(&mut self, session: u32, msg: msgs::UserState) { + if !msg.has_name() { + warn!("Missing name in initial user state"); + } else if msg.get_name() == self.server().unwrap().username().unwrap() { + // this is us + *self.server_mut().unwrap().session_id_mut() = Some(session); + } else { + // this is someone else + self.audio_mut().add_client(session); + + // send notification only if we've passed the connecting phase + if *self.phase_receiver().borrow() == StatePhase::Connected { + let channel_id = if msg.has_channel_id() { + msg.get_channel_id() + } else { + 0 + }; + if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { + notify::send(format!("{} connected and joined {}", &msg.get_name(), channel.name())); + } } - self.server_mut().unwrap().users_mut().insert(sess, user::User::new(msg)); + } + self.server_mut().unwrap().users_mut().insert(session, user::User::new(msg)); + } + + fn parse_updated_user_state(&mut self, session: u32, msg: msgs::UserState) -> UserDiff { + let user = self.server_mut().unwrap().users_mut().get_mut(&session).unwrap(); + + let mute = if msg.has_self_mute() && user.self_mute() != msg.get_self_mute() { + Some(msg.get_self_mute()) + } else { None + }; + let deaf = if msg.has_self_deaf() && user.self_deaf() != msg.get_self_deaf() { + Some(msg.get_self_deaf()) } else { - let user = self.server_mut().unwrap().users_mut().get_mut(&sess).unwrap(); - let diff = mumlib::state::UserDiff::from(msg); - user.apply_user_diff(&diff); - Some(diff) + None + }; + + let diff = UserDiff::from(msg); + user.apply_user_diff(&diff); + let user = self.server().unwrap().users().get(&session).unwrap(); + + // send notification if the user moved to or from any channel + //TODO our channel only + if let Some(channel_id) = diff.channel_id { + if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { + notify::send(format!( + "{} moved to channel {}", + &user.name(), + channel.name())); + } else { + warn!("{} moved to invalid channel {}", &user.name(), channel_id); + } } + + // send notification if a user muted/unmuted + //TODO our channel only + let notif_desc = + if let Some(deaf) = deaf { + if deaf { + Some(format!("{} muted and deafend themselves", &user.name())) + } else if !deaf { + Some(format!("{} unmuted and undeafend themselves", &user.name())) + } else { + warn!("Invalid user state received"); + None + } + } else if let Some(mute) = mute { + if mute { + Some(format!("{} muted themselves", &user.name())) + } else if !mute { + Some(format!("{} unmuted themselves", &user.name())) + } else { + warn!("Invalid user state received"); + None + } + } else { + None + }; + if let Some(notif_desc) = notif_desc { + notify::send(notif_desc); + } + + diff } pub fn remove_client(&mut self, msg: msgs::UserRemove) { @@ -237,6 +314,10 @@ impl State { warn!("Tried to remove user state without session"); return; } + if let Some(user) = self.server().unwrap().users().get(&msg.get_session()) { + notify::send(format!("{} disconnected", &user.name())); + } + self.audio().remove_client(msg.get_session()); self.server_mut().unwrap().users_mut().remove(&msg.get_session()); info!("User {} disconnected", msg.get_session()); |
