From 0cc89730e82464e8f6c4ee69a4791fdd0135178c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 7 Jun 2021 00:21:35 +0200 Subject: store User{Connected,Disconnected}-events --- mumd/src/state.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 84583e0..f831258 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -60,6 +60,11 @@ pub enum ExecutionContext { ), } +pub enum Event { + UserConnected(String, Option), + UserDisconnected(String, Option), +} + #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum StatePhase { Disconnected, @@ -75,6 +80,8 @@ pub struct State { message_buffer: Vec<(String, u32)>, phase_watcher: (watch::Sender, watch::Receiver), + + events: Vec, } impl State { @@ -95,6 +102,7 @@ impl State { audio_output, message_buffer: Vec::new(), phase_watcher, + events: Vec::new(), }; state.reload_config(); Ok(state) @@ -129,19 +137,21 @@ impl State { // this is someone else // send notification only if we've passed the connecting phase if matches!(*self.phase_receiver().borrow(), StatePhase::Connected(_)) { - let channel_id = msg.get_channel_id(); + let this_channel = msg.get_channel_id(); + let other_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); + //TODO can this fail? + let this_channel_name = self.server().unwrap().channels().get(&this_channel).map(|c| c.name()); - if channel_id - == self.get_users_channel(self.server().unwrap().session_id().unwrap()) - { - if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { + if this_channel == other_channel { + if let Some(this_channel_name) = this_channel_name { notifications::send(format!( "{} connected and joined {}", - &msg.get_name(), - channel.name() + msg.get_name(), + this_channel_name, )); } - + let this_channel_name = this_channel_name.map(|s| s.to_string()); + self.push_event(Event::UserConnected(msg.get_name().to_string(), this_channel_name)); self.audio_output .play_effect(NotificationEvents::UserConnected); } @@ -233,10 +243,13 @@ impl State { let this_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); let other_channel = self.get_users_channel(msg.get_session()); if this_channel == other_channel { + let channel_name = self.server().unwrap().channels().get(&this_channel).map(|c| c.name().to_string()); self.audio_output .play_effect(NotificationEvents::UserDisconnected); if let Some(user) = self.server().unwrap().users().get(&msg.get_session()) { notifications::send(format!("{} disconnected", &user.name())); + let user_name = user.name().to_string(); + self.push_event(Event::UserDisconnected(user_name, channel_name)); } } @@ -279,6 +292,10 @@ impl State { .play_effect(NotificationEvents::ServerConnect); } + pub fn push_event(&mut self, event: Event) { + self.events.push(event); + } + pub fn audio_input(&self) -> &AudioInput { &self.audio_input } -- cgit v1.2.1 From 2b63fa8ac1b7e7d995955758f8cd9ab2ec7d4e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 7 Jun 2021 00:50:15 +0200 Subject: events command --- mumctl/src/main.rs | 15 +++++++++++++++ mumd/src/state.rs | 24 ++++++++++++++++-------- mumlib/src/command.rs | 46 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs index bde24a1..0af322d 100644 --- a/mumctl/src/main.rs +++ b/mumctl/src/main.rs @@ -87,6 +87,10 @@ enum Command { }, /// Send a message to a channel or a user Message(Target), + Events { + #[structopt(short = "f", long = "follow")] + follow: bool, + }, } #[derive(Debug, StructOpt)] @@ -399,6 +403,17 @@ fn match_opt() -> Result<(), Error> { send_command(msg)??; } }, + Command::Events { follow } => { + for response in send_command_multi(MumCommand::Events { block: follow })? { + match response { + Ok(Some(CommandResponse::Event { event })) => { + println!("{}", event) + } + Ok(_) => unreachable!("Response should only be a Some(Event)"), + Err(e) => error!("{}", e), + } + } + } } let config_path = config::default_cfg_path(); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index f831258..c51c139 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -15,7 +15,7 @@ use mumble_protocol::control::msgs; use mumble_protocol::control::ControlPacket; use mumble_protocol::ping::PongPacket; use mumble_protocol::voice::Serverbound; -use mumlib::command::{Command, CommandResponse, MessageTarget}; +use mumlib::command::{Command, CommandResponse, Event, MessageTarget}; use mumlib::config::Config; use mumlib::Error; use std::{ @@ -60,11 +60,6 @@ pub enum ExecutionContext { ), } -pub enum Event { - UserConnected(String, Option), - UserDisconnected(String, Option), -} - #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum StatePhase { Disconnected, @@ -435,6 +430,19 @@ pub fn handle_command( new_deaf.map(|b| CommandResponse::DeafenStatus { is_deafened: b }) )) } + Command::Events { block } => { + if block { + warn!("Blocking event list is unimplemented"); + now!(Ok(None)) + } else { + let events: Vec<_> = state + .events + .iter() + .map(|event| Ok(Some(CommandResponse::Event { event: event.clone() }))) + .collect(); + ExecutionContext::Now(Box::new(move || Box::new(events.into_iter()))) + } + } Command::InputVolumeSet(volume) => { state.audio_input.set_volume(volume); now!(Ok(None)) @@ -618,12 +626,12 @@ pub fn handle_command( }), Box::new(move |pong| { Ok(pong.map(|pong| { - (CommandResponse::ServerStatus { + CommandResponse::ServerStatus { version: pong.version, users: pong.users, max_users: pong.max_users, bandwidth: pong.bandwidth, - }) + } })) }), ), diff --git a/mumlib/src/command.rs b/mumlib/src/command.rs index 351d7f6..7551bb3 100644 --- a/mumlib/src/command.rs +++ b/mumlib/src/command.rs @@ -1,6 +1,26 @@ use crate::state::{Channel, Server}; use serde::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Event { + UserConnected(String, Option), + UserDisconnected(String, Option), +} + +impl fmt::Display for Event { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Event::UserConnected(user, channel) => { + write!(f, "{} connected to {}", user, channel.as_deref().unwrap_or("unknown channel")) + } + Event::UserDisconnected(user, channel) => { + write!(f, "{} disconnected from {}", user, channel.as_deref().unwrap_or("unknown channel")) + } + } + } +} #[derive(Clone, Debug, Deserialize, Serialize)] pub enum Command { @@ -10,11 +30,21 @@ pub enum Command { ChannelList, ConfigReload, DeafenSelf(Option), + Events { + block: bool + }, InputVolumeSet(f32), MuteOther(String, Option), MuteSelf(Option), OutputVolumeSet(f32), + PastMessages { + block: bool, + }, Ping, + SendMessage { + message: String, + targets: Vec, + }, ServerConnect { host: String, port: u16, @@ -29,13 +59,6 @@ pub enum Command { }, Status, UserVolumeSet(String, f32), - PastMessages { - block: bool, - }, - SendMessage { - message: String, - targets: Vec, - }, } #[derive(Debug, Deserialize, Serialize)] @@ -46,9 +69,15 @@ pub enum CommandResponse { DeafenStatus { is_deafened: bool, }, + Event { + event: Event, + }, MuteStatus { is_muted: bool, }, + PastMessage { + message: (String, String), + }, Pong, ServerConnect { welcome_message: Option, @@ -62,9 +91,6 @@ pub enum CommandResponse { Status { server_state: Server, }, - PastMessage { - message: (String, String), - }, } #[derive(Clone, Debug, Deserialize, Serialize)] -- cgit v1.2.1 From 17f077d48b361a4cf8f5743750ca7408a8800797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 7 Jun 2021 01:30:40 +0200 Subject: timestamps on mumble events --- Cargo.lock | 2 ++ mumd/Cargo.toml | 1 + mumd/src/state.rs | 12 ++++++------ mumlib/Cargo.toml | 2 +- mumlib/src/command.rs | 23 ++++++++++++++++++----- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 679a1e9..2f4bb07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,6 +139,7 @@ dependencies = [ "libc", "num-integer", "num-traits", + "serde", "time", "winapi", ] @@ -814,6 +815,7 @@ version = "0.4.0" dependencies = [ "bincode", "bytes", + "chrono", "cpal", "dasp_frame", "dasp_interpolate", diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index d8e2635..1e8e63f 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -42,6 +42,7 @@ tokio-stream = "0.1.0" tokio-native-tls = "0.3" tokio-util = { version = "0.6", features = ["codec", "net"] } bincode = "1.3.2" +chrono = "0.4" libnotify = { version = "1.0", optional = true } diff --git a/mumd/src/state.rs b/mumd/src/state.rs index c51c139..ec25204 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -15,7 +15,7 @@ use mumble_protocol::control::msgs; use mumble_protocol::control::ControlPacket; use mumble_protocol::ping::PongPacket; use mumble_protocol::voice::Serverbound; -use mumlib::command::{Command, CommandResponse, Event, MessageTarget}; +use mumlib::command::{Command, CommandResponse, MessageTarget, MumbleEvent, MumbleEventKind}; use mumlib::config::Config; use mumlib::Error; use std::{ @@ -76,7 +76,7 @@ pub struct State { phase_watcher: (watch::Sender, watch::Receiver), - events: Vec, + events: Vec, } impl State { @@ -146,7 +146,7 @@ impl State { )); } let this_channel_name = this_channel_name.map(|s| s.to_string()); - self.push_event(Event::UserConnected(msg.get_name().to_string(), this_channel_name)); + self.push_event(MumbleEventKind::UserConnected(msg.get_name().to_string(), this_channel_name)); self.audio_output .play_effect(NotificationEvents::UserConnected); } @@ -244,7 +244,7 @@ impl State { if let Some(user) = self.server().unwrap().users().get(&msg.get_session()) { notifications::send(format!("{} disconnected", &user.name())); let user_name = user.name().to_string(); - self.push_event(Event::UserDisconnected(user_name, channel_name)); + self.push_event(MumbleEventKind::UserDisconnected(user_name, channel_name)); } } @@ -287,8 +287,8 @@ impl State { .play_effect(NotificationEvents::ServerConnect); } - pub fn push_event(&mut self, event: Event) { - self.events.push(event); + pub fn push_event(&mut self, kind: MumbleEventKind) { + self.events.push(MumbleEvent { timestamp: chrono::Local::now().naive_local(), kind }); } pub fn audio_input(&self) -> &AudioInput { diff --git a/mumlib/Cargo.toml b/mumlib/Cargo.toml index 5c9d4e1..5ec9365 100644 --- a/mumlib/Cargo.toml +++ b/mumlib/Cargo.toml @@ -13,7 +13,7 @@ readme = "../README.md" [dependencies] colored = "2" -chrono = "0.4" +chrono = { version = "0.4", features = [ "serde" ] } dirs = "3" fern = "0.6" log = "0.4" diff --git a/mumlib/src/command.rs b/mumlib/src/command.rs index 7551bb3..402d6b0 100644 --- a/mumlib/src/command.rs +++ b/mumlib/src/command.rs @@ -1,21 +1,34 @@ use crate::state::{Channel, Server}; +use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Debug, Clone, Serialize, Deserialize)] -pub enum Event { +pub struct MumbleEvent { + pub timestamp: NaiveDateTime, + pub kind: MumbleEventKind +} + +impl fmt::Display for MumbleEvent { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "[{}] {}", self.timestamp.format("%d %b %H:%M"), self.kind) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum MumbleEventKind { UserConnected(String, Option), UserDisconnected(String, Option), } -impl fmt::Display for Event { +impl fmt::Display for MumbleEventKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Event::UserConnected(user, channel) => { + MumbleEventKind::UserConnected(user, channel) => { write!(f, "{} connected to {}", user, channel.as_deref().unwrap_or("unknown channel")) } - Event::UserDisconnected(user, channel) => { + MumbleEventKind::UserDisconnected(user, channel) => { write!(f, "{} disconnected from {}", user, channel.as_deref().unwrap_or("unknown channel")) } } @@ -70,7 +83,7 @@ pub enum CommandResponse { is_deafened: bool, }, Event { - event: Event, + event: MumbleEvent, }, MuteStatus { is_muted: bool, -- cgit v1.2.1 From f22d3847a23484122fad83b22d7ca48316c9d7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 7 Jun 2021 17:17:41 +0200 Subject: additional events --- mumd/src/network/tcp.rs | 3 +++ mumd/src/state.rs | 40 +++++++++++++++++++++++++--------------- mumlib/src/command.rs | 20 ++++++++++++++++++++ 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/mumd/src/network/tcp.rs b/mumd/src/network/tcp.rs index 5cc2bf7..4140f2a 100644 --- a/mumd/src/network/tcp.rs +++ b/mumd/src/network/tcp.rs @@ -13,6 +13,7 @@ use mumble_protocol::control::{msgs, ClientControlCodec, ControlCodec, ControlPa use mumble_protocol::crypt::ClientCryptState; use mumble_protocol::voice::VoicePacket; use mumble_protocol::{Clientbound, Serverbound}; +use mumlib::command::MumbleEventKind; use std::collections::HashMap; use std::convert::{Into, TryInto}; use std::net::SocketAddr; @@ -337,6 +338,8 @@ async fn listen( if let Some(user) = user { notifications::send(format!("{}: {}", user, msg.get_message())); //TODO: probably want a config flag for this + let user = user.to_string(); + state.push_event(MumbleEventKind::TextMessageReceived(user)) //TODO also include message target } state.register_message((msg.get_message().to_owned(), msg.get_actor())); drop(state); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index ec25204..3aa330f 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -170,6 +170,7 @@ impl State { .users_mut() .get_mut(&session) .unwrap(); + let username = user.name().to_string(); let mute = if msg.has_self_mute() && user.self_mute() != msg.get_self_mute() { Some(msg.get_self_mute()) @@ -185,35 +186,43 @@ impl State { let diff = UserDiff::from(msg); user.apply_user_diff(&diff); - let user = self.server().unwrap().users().get(&session).unwrap(); if Some(session) != self.server().unwrap().session_id() { - //send notification if the user moved to or from any channel + // Send notification if the user moved either to or from our channel if let Some(to_channel) = diff.channel_id { let this_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); - if from_channel == this_channel || to_channel == this_channel { + + if from_channel == this_channel { + // User moved from our channel to somewhere else if let Some(channel) = self.server().unwrap().channels().get(&to_channel) { + let channel = channel.name().to_string(); notifications::send(format!( "{} moved to channel {}", - user.name(), - channel.name() + &username, + &channel, )); - } else { - warn!("{} moved to invalid channel {}", user.name(), to_channel); + self.push_event(MumbleEventKind::UserLeftChannel(username.clone(), channel)); } - self.audio_output - .play_effect(if from_channel == this_channel { - NotificationEvents::UserJoinedChannel - } else { - NotificationEvents::UserLeftChannel - }); + self.audio_output.play_effect(NotificationEvents::UserLeftChannel); + } else if to_channel == this_channel { + // User moved from somewhere else to our channel + if let Some(channel) = self.server().unwrap().channels().get(&from_channel) { + let channel = channel.name().to_string(); + notifications::send(format!( + "{} moved to your channel from {}", + &username, + &channel, + )); + self.push_event(MumbleEventKind::UserJoinedChannel(username.clone(), channel)); + } + self.audio_output.play_effect(NotificationEvents::UserJoinedChannel); } } //send notification if a user muted/unmuted if mute != None || deaf != None { - let mut s = user.name().to_string(); + let mut s = username; if let Some(mute) = mute { s += if mute { " muted" } else { " unmuted" }; } @@ -224,7 +233,8 @@ impl State { s += if deaf { " deafened" } else { " undeafened" }; } s += " themselves"; - notifications::send(s); + notifications::send(s.clone()); + self.push_event(MumbleEventKind::UserMuteStateChanged(s)); } } } diff --git a/mumlib/src/command.rs b/mumlib/src/command.rs index 402d6b0..818fd70 100644 --- a/mumlib/src/command.rs +++ b/mumlib/src/command.rs @@ -20,8 +20,15 @@ impl fmt::Display for MumbleEvent { pub enum MumbleEventKind { UserConnected(String, Option), UserDisconnected(String, Option), + /// This logic is kinda weird so we only store the rendered message. + UserMuteStateChanged(String), + TextMessageReceived(String), + UserJoinedChannel(String, String), + UserLeftChannel(String, String), } +//TODO These strings are (mostly) duplicated with their respective notifications. +// The only difference is that the text message event doesn't contain the text message. impl fmt::Display for MumbleEventKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -31,6 +38,19 @@ impl fmt::Display for MumbleEventKind { MumbleEventKind::UserDisconnected(user, channel) => { write!(f, "{} disconnected from {}", user, channel.as_deref().unwrap_or("unknown channel")) } + MumbleEventKind::UserMuteStateChanged(message) => { + write!(f, "{}", message) + } + MumbleEventKind::TextMessageReceived(user) => { + write!(f, "{} sent a text message", user) + } + MumbleEventKind::UserJoinedChannel(name, from) => { + write!(f, "{} moved to your channel from {}", name, from) + } + MumbleEventKind::UserLeftChannel(name, to) => { + write!(f, "{} moved to {}", name, to) + } + } } } -- cgit v1.2.1 From 2aafe6967e38851d56f747cb3e615da7e9fa9bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Tue, 8 Jun 2021 09:46:59 +0200 Subject: doc --- mumctl/src/main.rs | 1 + mumd/src/state.rs | 1 + mumlib/src/command.rs | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs index 0af322d..f43dd22 100644 --- a/mumctl/src/main.rs +++ b/mumctl/src/main.rs @@ -87,6 +87,7 @@ enum Command { }, /// Send a message to a channel or a user Message(Target), + /// Get events that have happened since we connected Events { #[structopt(short = "f", long = "follow")] follow: bool, diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 3aa330f..d0a7e4b 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -297,6 +297,7 @@ impl State { .play_effect(NotificationEvents::ServerConnect); } + /// Store a new event pub fn push_event(&mut self, kind: MumbleEventKind) { self.events.push(MumbleEvent { timestamp: chrono::Local::now().naive_local(), kind }); } diff --git a/mumlib/src/command.rs b/mumlib/src/command.rs index 818fd70..fff921a 100644 --- a/mumlib/src/command.rs +++ b/mumlib/src/command.rs @@ -4,6 +4,7 @@ use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; use std::fmt; +/// Something that happened in our channel at a point in time. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MumbleEvent { pub timestamp: NaiveDateTime, @@ -16,12 +17,12 @@ impl fmt::Display for MumbleEvent { } } +/// The different kinds of events that can happen. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum MumbleEventKind { UserConnected(String, Option), UserDisconnected(String, Option), - /// This logic is kinda weird so we only store the rendered message. - UserMuteStateChanged(String), + UserMuteStateChanged(String), // This logic is kinda weird so we only store the rendered message. TextMessageReceived(String), UserJoinedChannel(String, String), UserLeftChannel(String, String), -- cgit v1.2.1 From d3eb004bcca01c87cb12ba297e568eaf9d25cd77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Tue, 8 Jun 2021 09:47:10 +0200 Subject: mumlib error unimplemented --- mumd/src/state.rs | 2 +- mumlib/src/error.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mumd/src/state.rs b/mumd/src/state.rs index d0a7e4b..cdd663d 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -444,7 +444,7 @@ pub fn handle_command( Command::Events { block } => { if block { warn!("Blocking event list is unimplemented"); - now!(Ok(None)) + now!(Err(Error::Unimplemented)) } else { let events: Vec<_> = state .events diff --git a/mumlib/src/error.rs b/mumlib/src/error.rs index e88bd97..c492a5f 100644 --- a/mumlib/src/error.rs +++ b/mumlib/src/error.rs @@ -11,6 +11,7 @@ pub enum Error { InvalidServerAddr(String, u16), InvalidUsername(String), InvalidServerPassword, + Unimplemented, } impl std::error::Error for Error {} @@ -26,6 +27,7 @@ impl fmt::Display for Error { } Error::InvalidUsername(username) => write!(f, "Invalid username: {}", username), Error::InvalidServerPassword => write!(f, "Invalid server password"), + Error::Unimplemented => write!(f, "Unimplemented"), } } } -- cgit v1.2.1 From 52a4740f252391c944bf910c1a81a07bd7aea610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Tue, 8 Jun 2021 10:00:33 +0200 Subject: always send user joined/left channels and events --- mumd/src/state.rs | 53 ++++++++++++++++++++++++++++++++------------------- mumlib/src/command.rs | 8 ++++---- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/mumd/src/state.rs b/mumd/src/state.rs index cdd663d..8d92877 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -134,21 +134,23 @@ impl State { if matches!(*self.phase_receiver().borrow(), StatePhase::Connected(_)) { let this_channel = msg.get_channel_id(); let other_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); - //TODO can this fail? - let this_channel_name = self.server().unwrap().channels().get(&this_channel).map(|c| c.name()); + let this_channel_name = self + .server() + .unwrap() + .channels() + .get(&this_channel) + .map(|c| c.name()) + .unwrap_or("") + .to_string(); if this_channel == other_channel { - if let Some(this_channel_name) = this_channel_name { - notifications::send(format!( - "{} connected and joined {}", - msg.get_name(), - this_channel_name, - )); - } - let this_channel_name = this_channel_name.map(|s| s.to_string()); + notifications::send(format!( + "{} connected and joined {}", + msg.get_name(), + this_channel_name, + )); self.push_event(MumbleEventKind::UserConnected(msg.get_name().to_string(), this_channel_name)); - self.audio_output - .play_effect(NotificationEvents::UserConnected); + self.audio_output.play_effect(NotificationEvents::UserConnected); } } } @@ -248,14 +250,25 @@ impl State { let this_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); let other_channel = self.get_users_channel(msg.get_session()); if this_channel == other_channel { - let channel_name = self.server().unwrap().channels().get(&this_channel).map(|c| c.name().to_string()); - self.audio_output - .play_effect(NotificationEvents::UserDisconnected); - if let Some(user) = self.server().unwrap().users().get(&msg.get_session()) { - notifications::send(format!("{} disconnected", &user.name())); - let user_name = user.name().to_string(); - self.push_event(MumbleEventKind::UserDisconnected(user_name, channel_name)); - } + let channel_name = self + .server() + .unwrap() + .channels() + .get(&this_channel) + .map(|c| c.name()) + .unwrap_or("") + .to_string(); + let user_name = self + .server() + .unwrap() + .users() + .get(&msg.get_session()) + .map(|u| u.name()) + .unwrap_or("") + .to_string(); + notifications::send(format!("{} disconnected", &user_name)); + self.push_event(MumbleEventKind::UserDisconnected(user_name, channel_name)); + self.audio_output.play_effect(NotificationEvents::UserDisconnected); } self.server_mut() diff --git a/mumlib/src/command.rs b/mumlib/src/command.rs index fff921a..f1b52b8 100644 --- a/mumlib/src/command.rs +++ b/mumlib/src/command.rs @@ -20,8 +20,8 @@ impl fmt::Display for MumbleEvent { /// The different kinds of events that can happen. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum MumbleEventKind { - UserConnected(String, Option), - UserDisconnected(String, Option), + UserConnected(String, String), + UserDisconnected(String, String), UserMuteStateChanged(String), // This logic is kinda weird so we only store the rendered message. TextMessageReceived(String), UserJoinedChannel(String, String), @@ -34,10 +34,10 @@ impl fmt::Display for MumbleEventKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { MumbleEventKind::UserConnected(user, channel) => { - write!(f, "{} connected to {}", user, channel.as_deref().unwrap_or("unknown channel")) + write!(f, "{} connected to {}", user, channel) } MumbleEventKind::UserDisconnected(user, channel) => { - write!(f, "{} disconnected from {}", user, channel.as_deref().unwrap_or("unknown channel")) + write!(f, "{} disconnected from {}", user, channel) } MumbleEventKind::UserMuteStateChanged(message) => { write!(f, "{}", message) -- cgit v1.2.1 From 572c136a13c2ed92f2ec75bbb01072b3d0f98e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Tue, 8 Jun 2021 10:04:34 +0200 Subject: update manpage --- documentation/mumctl.1 | 9 +++++++-- documentation/mumctl.txt | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/documentation/mumctl.1 b/documentation/mumctl.1 index e875fd7..c50398f 100644 --- a/documentation/mumctl.1 +++ b/documentation/mumctl.1 @@ -2,12 +2,12 @@ .\" Title: mumd .\" Author: [see the "AUTHOR(S)" section] .\" Generator: Asciidoctor 2.0.15 -.\" Date: 2021-06-06 +.\" Date: 2021-06-08 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MUMCTL" "1" "2021-06-06" "\ \&" "\ \&" +.TH "MUMCTL" "1" "2021-06-08" "\ \&" "\ \&" .ie \n(.g .ds Aq \(aq .el .ds Aq ' .ss \n[.ss] 0 @@ -94,6 +94,11 @@ mumctl disconnect Disconnect from the currently connected server. .RE .sp +mumctl events +.RS 4 +Print all events that have occured since mumd was started. +.RE +.sp mumctl help .RS 4 Show a help message. diff --git a/documentation/mumctl.txt b/documentation/mumctl.txt index e513255..68e4c0e 100644 --- a/documentation/mumctl.txt +++ b/documentation/mumctl.txt @@ -58,6 +58,9 @@ mumctl deafen :: mumctl disconnect :: Disconnect from the currently connected server. +mumctl events :: + Print all events that have occured since mumd was started. + mumctl help :: Show a help message. -- cgit v1.2.1 From 3c9fb5d91f231a84549cfe288aebc978c6c5b7d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Tue, 8 Jun 2021 10:05:12 +0200 Subject: update changelog --- CHANGELOG | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 63c01a2..b1dd6fe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -21,7 +21,8 @@ Added * Added tunneling audio through TCP if UDP connection goes down. * --version now includes the current commit hash. * Server passwords. Thanks @rbran! - * Added support for sending and receiving text messages + * Added support for sending and receiving text messages. + * See a list of occured events with +mumctl events+. Changed ~~~~~~~ -- cgit v1.2.1