aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mumctl/src/main.rs14
-rw-r--r--mumd/src/network/tcp.rs18
-rw-r--r--mumd/src/state.rs110
-rw-r--r--mumlib/src/state.rs66
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
+ }
+}