diff options
| -rw-r--r-- | mumctl/src/main.rs | 14 | ||||
| -rw-r--r-- | mumd/src/network/tcp.rs | 18 | ||||
| -rw-r--r-- | mumd/src/state.rs | 110 | ||||
| -rw-r--r-- | mumlib/src/state.rs | 66 |
4 files changed, 153 insertions, 55 deletions
diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs index 6e97296..9411b8f 100644 --- a/mumctl/src/main.rs +++ b/mumctl/src/main.rs @@ -172,11 +172,11 @@ fn main() { }; if let Some(config) = config { - config.write_default_cfg(); + config.write_default_cfg().unwrap(); } } -fn match_server_connect(matches : &clap::ArgMatches<>) { +fn match_server_connect(matches : &clap::ArgMatches<'_>) { let host = matches.value_of("host").unwrap(); let username = matches.value_of("username").unwrap(); let port = match matches.value_of("port").map(|e| e.parse()) { @@ -194,7 +194,7 @@ fn match_server_connect(matches : &clap::ArgMatches<>) { } } -fn match_server_config(matches: &clap::ArgMatches<>, config: &mut mumlib::config::Config) { +fn match_server_config(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) { let server_name = matches.value_of("server_name").unwrap(); if let Some(servers) = &mut config.servers { let server = servers @@ -252,7 +252,7 @@ fn match_server_config(matches: &clap::ArgMatches<>, config: &mut mumlib::config } } -fn match_server_rename(matches: &clap::ArgMatches<>, config: &mut mumlib::config::Config) { +fn match_server_rename(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) { if let Some(servers) = &mut config.servers { let prev_name = matches.value_of("prev_name").unwrap(); let next_name = matches.value_of("next_name").unwrap(); @@ -266,7 +266,7 @@ fn match_server_rename(matches: &clap::ArgMatches<>, config: &mut mumlib::config } } -fn match_server_remove(matches: &clap::ArgMatches<>, config: &mut mumlib::config::Config) { +fn match_server_remove(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) { let name = matches.value_of("name").unwrap(); if let Some(servers) = &mut config.servers { match servers.iter().position(|server| server.name == name) { @@ -282,7 +282,7 @@ fn match_server_remove(matches: &clap::ArgMatches<>, config: &mut mumlib::config } } -fn match_server_add(matches: &clap::ArgMatches<>, config: &mut mumlib::config::Config) { +fn match_server_add(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) { let name = matches.value_of("name").unwrap().to_string(); let host = matches.value_of("host").unwrap().to_string(); // optional arguments map None to None @@ -364,7 +364,7 @@ fn print_channel(channel: &Channel, depth: usize) { ); for user in &channel.users { println!( - "{}-{}", + "{}- {}", iter::repeat(INDENTATION) .take(depth + 1) .collect::<String>(), diff --git a/mumd/src/network/tcp.rs b/mumd/src/network/tcp.rs index 88d2b59..6471771 100644 --- a/mumd/src/network/tcp.rs +++ b/mumd/src/network/tcp.rs @@ -285,23 +285,17 @@ 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); } ControlPacket::ChannelState(msg) => { debug!("Channel state received"); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 0dbf9c5..e9db616 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,42 @@ impl State { } } - pub fn parse_initial_user_state(&mut self, msg: msgs::UserState) { + 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; + 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)); + None + } else { + let user = self.server_mut().unwrap().users_mut().get_mut(&sess).unwrap(); + let diff = UserDiff::from(msg); + user.apply_user_diff(&diff); + Some(diff) } - self.server.as_mut().unwrap().parse_user_state(msg); + } + + 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) { @@ -263,6 +273,7 @@ pub struct Server { host: Option<String>, } + impl Server { pub fn new() -> Self { Self { @@ -309,19 +320,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<u32, Channel> { &self.channels } @@ -330,6 +328,10 @@ impl Server { &self.users } + pub fn users_mut(&mut self) -> &mut HashMap<u32, User> { + &mut self.users + } + pub fn username(&self) -> Option<&str> { self.username.as_ref().map(|e| e.as_str()) } @@ -602,6 +604,44 @@ impl User { } } + 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 let Some(hash) = diff.hash.clone() { + self.hash = Some(hash); + } + if let Some(name) = diff.name.clone() { + self.name = name; + } + if let Some(priority_speaker) = diff.priority_speaker { + self.priority_speaker = priority_speaker; + } + if let Some(recording) = diff.recording { + self.recording = recording; + } + if let Some(suppress) = diff.suppress { + self.suppress = suppress; + } + if let Some(self_mute) = diff.self_mute { + self.self_mute = self_mute; + } + if let Some(self_deaf) = diff.self_deaf { + self.self_deaf = self_deaf; + } + if let Some(mute) = diff.mute { + self.mute = mute; + } + if let Some(deaf) = diff.deaf { + self.deaf = deaf; + } + + if let Some(channel_id) = diff.channel_id { + self.channel = channel_id; + } + } + pub fn name(&self) -> &str { &self.name } diff --git a/mumlib/src/state.rs b/mumlib/src/state.rs index b09726e..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<String>, + pub comment: Option<String>, //TODO not option, empty string instead pub hash: Option<String>, pub name: String, pub priority_speaker: bool, @@ -134,3 +135,66 @@ impl Display for User { write!(f, "{}", self.name) } } + +#[derive(Debug, Default)] +pub struct UserDiff { + pub comment: Option<String>, + pub hash: Option<String>, + pub name: Option<String>, + pub priority_speaker: Option<bool>, + pub recording: Option<bool>, + + pub suppress: Option<bool>, // by me + pub self_mute: Option<bool>, // by self + pub self_deaf: Option<bool>, // by self + pub mute: Option<bool>, // by admin + pub deaf: Option<bool>, // by admin + + pub channel_id: Option<u32>, +} + +impl UserDiff { + pub fn new() -> Self { + UserDiff::default() + } +} + +impl From<msgs::UserState> 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 + } +} |
