diff options
| -rw-r--r-- | Cargo.lock | 5 | ||||
| -rw-r--r-- | README.org | 49 | ||||
| -rw-r--r-- | mumd/Cargo.toml | 2 | ||||
| -rw-r--r-- | mumd/src/audio.rs | 11 | ||||
| -rw-r--r-- | mumd/src/network/udp.rs | 5 | ||||
| -rw-r--r-- | mumd/src/state.rs | 2 | ||||
| -rw-r--r-- | mumd/src/state/user.rs | 65 | ||||
| -rw-r--r-- | mumlib/Cargo.toml | 1 | ||||
| -rw-r--r-- | mumlib/src/state.rs | 66 | ||||
| -rw-r--r-- | usage.org | 173 |
10 files changed, 104 insertions, 275 deletions
@@ -786,9 +786,9 @@ dependencies = [ [[package]] name = "mumble-protocol" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb966bde3fc52998b9b74522e8aa22826823cc69cbf672893f79115195c76921" +checksum = "4954adf2418ebc052d723997cf3e090729132d59a795113db931aa5811e46542" dependencies = [ "byteorder", "bytes", @@ -842,7 +842,6 @@ dependencies = [ "colored", "fern", "log", - "mumble-protocol", "serde", "toml", ] @@ -2,7 +2,7 @@ Mumble daemon with controller (think mpd(1)/mpc(1)) written in Rust. ** Building -`mum` is [[https://aur.archlinux.org/packages/mum-git/][available on the AUR]]. +mum is [[https://aur.archlinux.org/packages/mum-git/][available on the AUR]]. We aim to publish tagged versions to cargo, as well as binaries on Github. *** Requirements @@ -10,14 +10,14 @@ These are for Arch Linux. You might need other packages on other distributions and operating systems, or they might be named something different. - rust (stable) -- `alsa-lib` -- `openssl` -- `opus` -- `libnotify` (optional) +- alsa-lib +- openssl +- opus +- libnotify (optional) Windows is not currently supported but could be in the future. macOS should work. Other operating systems haven't been tested. The limiting factor on Windows -is IPC communication which is (currently) done via the crate `ipc-channel`. +is IPC communication which is (currently) done via the crate ipc-channel. *** Installation 1. Build the binaries @@ -31,21 +31,18 @@ $ ln -s $PWD/target/release/mumd $HOME/.local/bin/ #+END_SRC *** Optional features -`mum` contains optional features that are enabled by default. To compile without -them, build with `--no-default-features`. Features can then be enabled with -`--features "FEATURES"`. +mum contains optional features that are enabled by default. To compile without +them, build with --no-default-features. Features can then be enabled with +--features "FEATURES". The following features can be specified: -| Name | Needed for | Additional crates | -|--------------------+---------------+-------------------| -| mumd/notifications | Notifications | 20 | +| Name | Needed for | +|--------------------+---------------+ +| mumd/notifications | Notifications | -Note that the "additional crates" isn't continually updated and might change. -Features might also have overlapping dependencies. - -Awaiting `-Z package-features`, changing which features are compiled requires -you to compile `mumd/` separately by entering its directory and specifying +Awaiting -Z package-features, changing which features are compiled requires +you to compile mumd/ separately by entering its directory and specifying its features. To summarize with an example, the following compiles with only the @@ -70,19 +67,23 @@ $ asciidoctor -b manpage *.txt ** Usage This describes how to connect to a server and join different channels. -See usage.org or `$ mumctl --help` for more information. +See mumctl --help or documentation/*.txt for more information. *** mumd -Start the daemon with `$ mumd`. Currently it attaches to the terminal, so if you -want to run it in the background you can detach it with e.g. (zsh): `$ mumd -&>/dev/null &|`. Somewhere down the line we're going to support `$ mumd ---daemonize`. +Start the daemon with mumd. Currently it attaches to the terminal, so if you +want to run it in the background you can detach it with e.g. (zsh): + +#+BEGIN_SRC sh +$ mumd &>/dev/null &| +#+END_SRC + +Somewhere down the line we're aiming to have a --daemonize. *** mumctl -Interfacing with the daemon is done through `mumctl`. Some examples: +Interfacing with the daemon is done through mumctl. Some examples: #+BEGIN_SRC sh -$ mumctl server connect 127.0.0.1 spock # connect to 127.0.0.1 with username 'spock' +$ mumctl connect 127.0.0.1 spock # connect to 127.0.0.1 with username 'spock' $ mumctl channel list ServerRoot -user1 diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index ba0f5a0..39b9d26 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -26,7 +26,7 @@ futures-util = "0.3" hound = "3.4" ipc-channel = "0.14" log = "0.4" -mumble-protocol = "0.3" +mumble-protocol = "0.3.1" native-tls = "0.2" openssl = { version = "0.10" } opus = "0.2" diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 812bb4c..8f9e2ab 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -231,12 +231,19 @@ impl Audio { .map(|e| cpal::Sample::to_f32(&e.unwrap())) .collect::<Vec<_>>(), }; - let mut signal = signal::from_iter(samples.iter().cloned()); + let iter: Box<dyn Iterator<Item = f32>> = match spec.channels { + 1 => Box::new(samples.into_iter().flat_map(|e| vec![e, e])), + 2 => Box::new(samples.into_iter()), + _ => unimplemented!() // TODO handle gracefully (this might not even happen) + }; + let mut signal = signal::from_interleaved_samples_iter::<_, [f32; 2]>(iter); let interp = Linear::new(signal.next(), signal.next()); let samples = signal .from_hz_to_hz(interp, spec.sample_rate as f64, SAMPLE_RATE as f64) .until_exhausted() - .collect::<Vec<_>>(); + // if the source audio is stereo and is being played as mono, discard the right audio + .flat_map(|e| if output_config.channels == 1 { vec![e[0]] } else { e.to_vec() }) + .collect::<Vec<f32>>(); (*event, samples) }) .collect(); diff --git a/mumd/src/network/udp.rs b/mumd/src/network/udp.rs index b303f8c..b1c202a 100644 --- a/mumd/src/network/udp.rs +++ b/mumd/src/network/udp.rs @@ -283,10 +283,7 @@ pub async fn handle_pings( while let Ok(read) = receiver.recv(&mut buf).await { assert_eq!(read, 24); - let packet = match PongPacket::try_from(buf.as_slice()) { - Ok(v) => v, - Err(_) => panic!(), - }; + let packet = PongPacket::try_from(buf.as_slice()).unwrap(); if let Some(handler) = pending.lock().unwrap().remove(&packet.id) { handler(packet); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 7a4704a..aba0931 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -16,7 +16,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 crate::state::user::UserDiff; use std::net::{SocketAddr, ToSocketAddrs}; use tokio::sync::{mpsc, watch}; diff --git a/mumd/src/state/user.rs b/mumd/src/state/user.rs index 913f91b..5770bca 100644 --- a/mumd/src/state/user.rs +++ b/mumd/src/state/user.rs @@ -78,7 +78,7 @@ impl User { } } - pub fn apply_user_diff(&mut self, diff: &mumlib::state::UserDiff) { + pub fn apply_user_diff(&mut self, diff: &crate::state::user::UserDiff) { if let Some(comment) = diff.comment.clone() { self.comment = Some(comment); } @@ -155,3 +155,66 @@ impl From<&User> for mumlib::state::User { } } } + +#[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 + } +} diff --git a/mumlib/Cargo.toml b/mumlib/Cargo.toml index 59feb75..74bdb32 100644 --- a/mumlib/Cargo.toml +++ b/mumlib/Cargo.toml @@ -11,6 +11,5 @@ edition = "2018" colored = "2.0" fern = "0.5" log = "0.4" -mumble-protocol = "0.3" serde = { version = "1.0", features = ["derive"] } toml = "0.5" diff --git a/mumlib/src/state.rs b/mumlib/src/state.rs index 3b1da56..0f1cef2 100644 --- a/mumlib/src/state.rs +++ b/mumlib/src/state.rs @@ -1,4 +1,3 @@ -use mumble_protocol::control::msgs; use serde::export::Formatter; use serde::{Deserialize, Serialize}; use std::fmt::Display; @@ -153,67 +152,4 @@ impl Display for User { true_to_str!(self.deaf, "d") ) } -} - -#[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 - } -} +}
\ No newline at end of file diff --git a/usage.org b/usage.org deleted file mode 100644 index 952cc41..0000000 --- a/usage.org +++ /dev/null @@ -1,173 +0,0 @@ -This file contains the current targeted usage. It works as both a design document -and a feature tracker. New commands and flags go here. - -* Usage overview - -Start the daemon with either one of: - -- `$ mumd`. Writes to stdout, ignores stdin. Can easily be disowned/started in - a screen/tmux. - -We want to support / explain how to do the following at some point: - -- `$ mumd --daemon` -- systemd-service - -The daemon doesn't do anything by itself. Interfacing with it is done through -`mumctl`. - -* 0.1 -The basic commands are the smallest subset of commands that allow the user to -actually use mum for something. In this case it means connecting to a server, -listing channels and connecting to channels. -** DONE server -*** DONE connect -#+BEGIN_SRC bash -$ mumctl server connect localhost your_name -connecting to localhost... -connected as your_name -root -│ another person -│ some person -| your_name -#+END_SRC -** DONE channel -*** DONE list -#+BEGIN_SRC bash -$ mumctl channel list -root [3](4) -│ another person -│ some person -| your_name -├─ some channel [1] -│ someone alone -├─ other channel [0] -├─ third channel [0](2) -│ └─ subsubchannel [2] -│ a user -│ and another user -└─ AFK [1] - someone eating food -#+END_SRC - -**** DONE --short -#+BEGIN_SRC bash -$ mumctl channel list --short -root [3](4) -├─ some channel [1] -├─ other channel [0] -├─ third channel [0](2) -│ └─ subsubchannel [2] -└─ AFK [1] -#+END_SRC -*** DONE connect -#+BEGIN_SRC bash -$ mumctl channel connect some channel -connecting to some channel... -connected -#+END_SRC -** DONE status -#+BEGIN_SRC bash -$ mumctl status -connected to localhost:65837 as your_name -currently in root with 2 other clients: - root - │ another person - │ some person - | your_name -#+END_SRC - -#+BEGIN_SRC bash -$ mumctl status --short -your_name@localhost:65387/root (3) - another person - some person - your_name -#+END_SRC - -* 0.2 -** server -*** TODO add -**** DONE With name -#+BEGIN_SRC bash -$ mumctl server add loopback 127.0.0.1 -username: *** -password: *** -#+END_SRC - -**** TODO Without name -#+BEGIN_SRC bash -$ mumctl server add 127.0.0.1 -username: *** -password: *** -#+END_SRC - -Password can be skipped by entering blank. -*** list -#+BEGIN_SRC bash -$ mumctl server list -loopback [4 / 100] -127.0.0.1 [4 / 100] -127.0.0.3 [OFFLINE] -#+END_SRC -*** TODO config -**** DONE username -#+BEGIN_SRC bash -$ mumctl server config loopback username xX_gamerboy_Xx -#+END_SRC -**** TODO password -#+BEGIN_SRC bash -$ mumctl server config loopback password *** -#+END_SRC - -Optionally ask stdin -#+BEGIN_SRC bash -$ mumctl server config loopback password -enter password: *** -#+END_SRC -*** TODO connect: handle invalid keys -#+BEGIN_SRC bash -server offered invalid key. what do you want to do? -[I]nspect, [A]ccept, [D]eny, [C]ompare, [T]emporarily trust (default D): -#+END_SRC -- Inspect: Print the key digest and ask again. -- Accept: Accept the key, connect to the server and trust the key. -- Deny: Abort the connection. Do not trust the key. -- Compare: Compare the key to a file to confirm legitimacy and ask again. -- Temporarily trust: Accept the key and connect, but do not trust the key. -*** DONE rename -#+BEGIN_SRC bash -$ mumctl server rename loopback my_server -#+END_SRC -** TODO config -#+BEGIN_SRC bash -$ mumctl config audio.input_volume 1.1 -$ mumctl config audio.input_volume -$ mumctl config audio.input_volume --help -#+END_SRC -** TODO volume -#+BEGIN_SRC bash -$ mumctl volume set User1 1.1 -$ mumctl volume User1 -110% -#+END_SRC - -* 0.3 -** mute -#+BEGIN_SRC bash -$ mumctl mute true -$ mumctl mute false -$ mumctl mute toggle -#+END_SRC -** deafen -#+BEGIN_SRC bash -$ mumctl deafen true -$ mumctl deafen false -$ mumctl deafen toggle -#+END_SRC -** user -#+BEGIN_SRC bash -$ mumctl user Username mute true -$ mumctl user Username mute false -$ mumctl user Username mute toggle -#+END_SRC |
