aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/state.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mumd/src/state.rs')
-rw-r--r--mumd/src/state.rs113
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());