From 9f4c05059f1990a23995e3363f88ab753187042d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Sun, 18 Oct 2020 02:08:32 +0200 Subject: parse user state diff and handle connecting clients --- mumd/src/network/tcp.rs | 17 +++------ mumd/src/state.rs | 97 +++++++++++++++++++++++++++++++------------------ mumlib/src/state.rs | 21 +++++++++++ 3 files changed, 89 insertions(+), 46 deletions(-) diff --git a/mumd/src/network/tcp.rs b/mumd/src/network/tcp.rs index 88d2b59..c4804f8 100644 --- a/mumd/src/network/tcp.rs +++ b/mumd/src/network/tcp.rs @@ -285,23 +285,18 @@ async fn listen( ControlPacket::UserState(msg) => { let mut state = state.lock().unwrap(); let session = msg.get_session(); - if *state.phase_receiver().borrow() == StatePhase::Connecting { - state.audio_mut().add_client(msg.get_session()); - state.parse_initial_user_state(*msg); - } else { - state.server_mut().unwrap().parse_user_state(*msg); - } + + let user_state_diff = state.parse_user_state(*msg); + //TODO do something with user state diff + debug!("user state diff: {:#?}", &user_state_diff); + let server = state.server_mut().unwrap(); let user = server.users().get(&session).unwrap(); info!("User {} connected to {}", user.name(), user.channel()); } ControlPacket::UserRemove(msg) => { info!("User {} left", msg.get_session()); - state - .lock() - .unwrap() - .audio_mut() - .remove_client(msg.get_session()); + state.lock().unwrap().remove_client(msg.get_session()); } ControlPacket::ChannelState(msg) => { debug!("Channel state received"); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 0dbf9c5..494f61f 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -8,6 +8,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 serde::{Deserialize, Serialize}; use std::collections::hash_map::Entry; use std::collections::HashMap; @@ -178,33 +179,33 @@ impl State { } } - pub fn parse_initial_user_state(&mut self, msg: msgs::UserState) { + pub fn parse_user_state(&mut self, msg: msgs::UserState) -> Option { if !msg.has_session() { warn!("Can't parse user state without session"); - return; + return None; } - if !msg.has_name() { - warn!("Missing name in initial user state"); - } else if msg.get_name() == self.server.as_ref().unwrap().username.as_ref().unwrap() { - match self.server.as_ref().unwrap().session_id { - None => { - debug!("Found our session id: {}", msg.get_session()); - self.server_mut().unwrap().session_id = Some(msg.get_session()); - } - Some(session) => { - if session != msg.get_session() { - error!( - "Got two different session IDs ({} and {}) for ourselves", - session, - msg.get_session() - ); - } else { - debug!("Got our session ID twice"); - } - } + let sess = 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"); + } + if msg.get_name() == self.server().unwrap().username.as_ref().unwrap() { + // this is us + self.server_mut().unwrap().session_id = Some(sess); + } else { + // this is someone else + self.audio_mut().add_client(sess); } + self.server_mut().unwrap().users_mut().insert(sess, User::new(msg)); + return None; + } else { + return Some(self.server_mut().unwrap().users_mut().get(&sess).unwrap().parse_state_diff(msg)); } - self.server.as_mut().unwrap().parse_user_state(msg); + } + + pub fn remove_client(&mut self, session: u32) { + } pub fn reload_config(&mut self) { @@ -309,19 +310,6 @@ impl Server { } } - pub fn parse_user_state(&mut self, msg: msgs::UserState) { - if !msg.has_session() { - warn!("Can't parse user state without session"); - return; - } - match self.users.entry(msg.get_session()) { - Entry::Vacant(e) => { - e.insert(User::new(msg)); - } - Entry::Occupied(mut e) => e.get_mut().parse_user_state(msg), - } - } - pub fn channels(&self) -> &HashMap { &self.channels } @@ -330,6 +318,10 @@ impl Server { &self.users } + pub fn users_mut(&mut self) -> &mut HashMap { + &mut self.users + } + pub fn username(&self) -> Option<&str> { self.username.as_ref().map(|e| e.as_str()) } @@ -602,6 +594,41 @@ impl User { } } + pub fn parse_state_diff(&self, mut msg: msgs::UserState) -> UserDiff { + let mut ud = UserDiff::new(); + if msg.has_comment() { + ud.comment = Some(msg.take_comment()); + } + if msg.has_hash() { + ud.hash = Some(msg.take_hash()); + } + if msg.has_name() { + ud.name = Some(msg.take_name()); + } + if msg.has_priority_speaker() { + ud.priority_speaker = Some(msg.get_priority_speaker()); + } + if msg.has_recording() { + ud.recording = Some(msg.get_recording()); + } + if msg.has_suppress() { + ud.suppress = Some(msg.get_suppress()); + } + if msg.has_self_mute() { + ud.self_mute = Some(msg.get_self_mute()); + } + if msg.has_self_deaf() { + ud.self_deaf = Some(msg.get_self_deaf()); + } + if msg.has_mute() { + ud.mute = Some(msg.get_mute()); + } + if msg.has_deaf() { + ud.deaf = Some(msg.get_deaf()); + } + ud + } + pub fn name(&self) -> &str { &self.name } diff --git a/mumlib/src/state.rs b/mumlib/src/state.rs index b09726e..ef25a79 100644 --- a/mumlib/src/state.rs +++ b/mumlib/src/state.rs @@ -134,3 +134,24 @@ impl Display for User { write!(f, "{}", self.name) } } + +#[derive(Debug, Default)] +pub struct UserDiff { + pub comment: Option, + pub hash: Option, + pub name: Option, + pub priority_speaker: Option, + pub recording: Option, + + pub suppress: Option, // by me + pub self_mute: Option, // by self + pub self_deaf: Option, // by self + pub mute: Option, // by admin + pub deaf: Option, // by admin +} + +impl UserDiff { + pub fn new() -> Self { + UserDiff::default() + } +} -- cgit v1.2.1 From d9a3470fcb4c8c63dd5fb76dd7f2f7eb977d8b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Sun, 18 Oct 2020 02:30:39 +0200 Subject: implement remove_client --- mumd/src/network/tcp.rs | 3 +-- mumd/src/state.rs | 10 ++++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/mumd/src/network/tcp.rs b/mumd/src/network/tcp.rs index c4804f8..6471771 100644 --- a/mumd/src/network/tcp.rs +++ b/mumd/src/network/tcp.rs @@ -295,8 +295,7 @@ async fn listen( info!("User {} connected to {}", user.name(), user.channel()); } ControlPacket::UserRemove(msg) => { - info!("User {} left", msg.get_session()); - state.lock().unwrap().remove_client(msg.get_session()); + state.lock().unwrap().remove_client(*msg); } ControlPacket::ChannelState(msg) => { debug!("Channel state received"); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 494f61f..8dc3d68 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -204,8 +204,14 @@ impl State { } } - pub fn remove_client(&mut self, session: u32) { - + pub fn remove_client(&mut self, msg: msgs::UserRemove) { + if !msg.has_session() { + warn!("Tried to remove user state without session"); + return; + } + self.audio().remove_client(msg.get_session()); + self.server_mut().unwrap().users_mut().remove(&msg.get_session()); + info!("User {} disconnected", msg.get_session()); } pub fn reload_config(&mut self) { -- cgit v1.2.1 From f98c4d84b24698187102bcc3660246b2a1acb23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 21 Oct 2020 01:41:34 +0200 Subject: update user state in mumd --- mumctl/src/main.rs | 4 ++-- mumd/src/state.rs | 57 ++++++++++++++++++++++++++++++----------------------- mumlib/src/state.rs | 45 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs index 6e97296..1ed48dc 100644 --- a/mumctl/src/main.rs +++ b/mumctl/src/main.rs @@ -172,7 +172,7 @@ fn main() { }; if let Some(config) = config { - config.write_default_cfg(); + config.write_default_cfg().unwrap(); } } @@ -364,7 +364,7 @@ fn print_channel(channel: &Channel, depth: usize) { ); for user in &channel.users { println!( - "{}-{}", + "{}- {}", iter::repeat(INDENTATION) .take(depth + 1) .collect::(), diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 8dc3d68..e9db616 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -198,9 +198,12 @@ impl State { self.audio_mut().add_client(sess); } self.server_mut().unwrap().users_mut().insert(sess, User::new(msg)); - return None; + None } else { - return Some(self.server_mut().unwrap().users_mut().get(&sess).unwrap().parse_state_diff(msg)); + let user = self.server_mut().unwrap().users_mut().get_mut(&sess).unwrap(); + let diff = UserDiff::from(msg); + user.apply_user_diff(&diff); + Some(diff) } } @@ -270,6 +273,7 @@ pub struct Server { host: Option, } + impl Server { pub fn new() -> Self { Self { @@ -600,39 +604,42 @@ impl User { } } - pub fn parse_state_diff(&self, mut msg: msgs::UserState) -> UserDiff { - let mut ud = UserDiff::new(); - if msg.has_comment() { - ud.comment = Some(msg.take_comment()); + pub fn apply_user_diff(&mut self, diff: &UserDiff) { + debug!("applying user diff\n{:#?}", diff); + if let Some(comment) = diff.comment.clone() { + self.comment = Some(comment); } - if msg.has_hash() { - ud.hash = Some(msg.take_hash()); + if let Some(hash) = diff.hash.clone() { + self.hash = Some(hash); } - if msg.has_name() { - ud.name = Some(msg.take_name()); + if let Some(name) = diff.name.clone() { + self.name = name; } - if msg.has_priority_speaker() { - ud.priority_speaker = Some(msg.get_priority_speaker()); + if let Some(priority_speaker) = diff.priority_speaker { + self.priority_speaker = priority_speaker; } - if msg.has_recording() { - ud.recording = Some(msg.get_recording()); + if let Some(recording) = diff.recording { + self.recording = recording; } - if msg.has_suppress() { - ud.suppress = Some(msg.get_suppress()); + if let Some(suppress) = diff.suppress { + self.suppress = suppress; } - if msg.has_self_mute() { - ud.self_mute = Some(msg.get_self_mute()); + if let Some(self_mute) = diff.self_mute { + self.self_mute = self_mute; } - if msg.has_self_deaf() { - ud.self_deaf = Some(msg.get_self_deaf()); + if let Some(self_deaf) = diff.self_deaf { + self.self_deaf = self_deaf; } - if msg.has_mute() { - ud.mute = Some(msg.get_mute()); + if let Some(mute) = diff.mute { + self.mute = mute; } - if msg.has_deaf() { - ud.deaf = Some(msg.get_deaf()); + if let Some(deaf) = diff.deaf { + self.deaf = deaf; + } + + if let Some(channel_id) = diff.channel_id { + self.channel = channel_id; } - ud } pub fn name(&self) -> &str { diff --git a/mumlib/src/state.rs b/mumlib/src/state.rs index ef25a79..b6b4039 100644 --- a/mumlib/src/state.rs +++ b/mumlib/src/state.rs @@ -1,3 +1,4 @@ +use mumble_protocol::control::msgs; use serde::export::Formatter; use serde::{Deserialize, Serialize}; use std::fmt::Display; @@ -116,7 +117,7 @@ impl<'a> Iterator for UsersIter<'a> { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct User { - pub comment: Option, + pub comment: Option, //TODO not option, empty string instead pub hash: Option, pub name: String, pub priority_speaker: bool, @@ -148,6 +149,8 @@ pub struct UserDiff { pub self_deaf: Option, // by self pub mute: Option, // by admin pub deaf: Option, // by admin + + pub channel_id: Option, } impl UserDiff { @@ -155,3 +158,43 @@ impl UserDiff { UserDiff::default() } } + +impl From for UserDiff { + fn from(mut msg: msgs::UserState) -> Self { + let mut ud = UserDiff::new(); + if msg.has_comment() { + ud.comment = Some(msg.take_comment()); + } + if msg.has_hash() { + ud.hash = Some(msg.take_hash()); + } + if msg.has_name() { + ud.name = Some(msg.take_name()); + } + if msg.has_priority_speaker() { + ud.priority_speaker = Some(msg.get_priority_speaker()); + } + if msg.has_recording() { + ud.recording = Some(msg.get_recording()); + } + if msg.has_suppress() { + ud.suppress = Some(msg.get_suppress()); + } + if msg.has_self_mute() { + ud.self_mute = Some(msg.get_self_mute()); + } + if msg.has_self_deaf() { + ud.self_deaf = Some(msg.get_self_deaf()); + } + if msg.has_mute() { + ud.mute = Some(msg.get_mute()); + } + if msg.has_deaf() { + ud.deaf = Some(msg.get_deaf()); + } + if msg.has_channel_id() { + ud.channel_id = Some(msg.get_channel_id()); + } + ud + } +} -- cgit v1.2.1