From 496af40b52b398b1322e02e1839271cd8d0e270d Mon Sep 17 00:00:00 2001 From: Nathan Perry Date: Wed, 4 Apr 2018 22:27:02 -0400 Subject: restructure modules --- src/commands.rs | 479 ----------------------------------------- src/commands/db.rs | 5 + src/commands/mod.rs | 95 ++++++++ src/commands/playback/mod.rs | 184 ++++++++++++++++ src/commands/playback/types.rs | 139 ++++++++++++ src/commands/sound.rs | 88 ++++++++ 6 files changed, 511 insertions(+), 479 deletions(-) delete mode 100644 src/commands.rs create mode 100644 src/commands/db.rs create mode 100644 src/commands/mod.rs create mode 100644 src/commands/playback/mod.rs create mode 100644 src/commands/playback/types.rs create mode 100644 src/commands/sound.rs (limited to 'src') diff --git a/src/commands.rs b/src/commands.rs deleted file mode 100644 index 542900e..0000000 --- a/src/commands.rs +++ /dev/null @@ -1,479 +0,0 @@ -use {must_env_lookup, Result, TARGET_GUILD_ID}; -use serenity::client::bridge::voice::ClientVoiceManager; -use serenity::framework::StandardFramework; -use serenity::model::channel::Message; -use serenity::model::id::ChannelId; -use serenity::prelude::*; -use serenity::voice::{LockedAudio, ytdl}; -use std::collections::VecDeque; -use std::sync::{Arc, RwLock}; -use std::thread; -use std::time::Duration; -use typemap::Key; - -pub struct VoiceManager; - -const DEFAULT_VOLUME: f32 = 0.05; - -impl Key for VoiceManager { - type Value = Arc>; -} - -impl VoiceManager { - pub fn register(c: &mut Client) { - let mut data = c.data.lock(); - data.insert::(Arc::clone(&c.voice_manager)); - } -} - -#[derive(Clone, Debug)] -struct PlayArgs { - url: String, - initiator: String, - sender_channel: ChannelId, -} - -#[derive(Clone)] -struct CurrentItem { - init_args: PlayArgs, - audio: LockedAudio, -} - -#[derive(Clone)] -pub struct PlayQueue { - queue: VecDeque, - playing: Option, - volume: f32, -} - -impl Key for PlayQueue { - type Value = Arc>; -} - -impl PlayQueue { - fn new() -> Self { - PlayQueue { - queue: VecDeque::new(), - playing: None, - volume: DEFAULT_VOLUME, - } - } - - pub fn register(c: &mut Client) { - let voice_manager = Arc::clone(&c.voice_manager); - - let mut data = c.data.lock(); - let queue = Arc::new(RwLock::new(PlayQueue::new())); - - data.insert::(Arc::clone(&queue)); - - thread::spawn(move || { - let queue_lck = Arc::clone(&queue); - let voice_manager = voice_manager; - - loop { - thread::sleep(Duration::from_millis(250)); - let (queue_is_empty, queue_has_playing) = { - let queue = queue_lck.read().unwrap(); - - let allow_continue = queue.playing.clone().map_or(false, |x| !x.audio.lock().finished); - - if allow_continue { - continue; - } - - (queue.queue.is_empty(), queue.playing.is_some()) - }; - - if queue_is_empty { - if queue_has_playing { - let mut queue = queue_lck.write().unwrap(); - - assert!({ - let audio_lck = queue.playing.clone().unwrap().audio; - let audio = audio_lck.lock(); - audio.finished - }); - - queue.playing = None; - - let mut manager = voice_manager.lock(); - manager.leave(*TARGET_GUILD_ID); - debug!("disconnected due to inactivity"); - } - continue; - } - - let mut queue = queue_lck.write().unwrap(); - let item = queue.queue.pop_front().unwrap(); - - trace!("checking ytdl for: {}", item.url); - - let src = match ytdl(&item.url) { - Ok(src) => src, - Err(e) => { - error!("bad link: {}; {:?}", &item.url, e); - let _ = send(item.sender_channel, &format!("what the fuck"), false); - continue; - } - }; - - trace!("got ytdl item for {}", item.url); - - let mut manager = voice_manager.lock(); - let handler = manager.join(*TARGET_GUILD_ID, must_env_lookup::("VOICE_CHANNEL")); - - match handler { - Some(handler) => { - let mut audio = handler.play_only(src); - { - audio.lock().volume(queue.volume); - } - - queue.playing = Some(CurrentItem { - init_args: item, - audio, - }); - - debug!("playing new song"); - }, - None => { - error!("couldn't join channel"); - let _ = send(item.sender_channel, "something happened somewhere somehow.", false); - } - } - } - }); - } -} - -fn send(channel: ChannelId, text: &str, tts: bool) -> Result<()> { - channel.send_message(|m| m.content(text).tts(tts))?; - Ok(()) -} - -pub fn register_commands(f: StandardFramework) -> StandardFramework { - f - .command("skip", |c| c - .desc("skip the rest of the current request") - .guild_only(true) - .cmd(skip)) - .command("pause", |c| c - .desc("pause playback (currently broken)") - .guild_only(true) - .cmd(pause)) - .command("resume", |c| c - .desc("resume playing (currently broken)") - .guild_only(true) - .cmd(resume)) - .command("list", |c| c - .known_as("queue") - .desc("list playing and queued requests") - .guild_only(true) - .cmd(list)) - .command("die", |c| c - .batch_known_as(vec!["sudoku", "stop"]) - .desc("stop playing and empty the queue") - .guild_only(true) - .cmd(die)) - .command("meme", |c| c - .guild_only(true) - .help_available(false) - .cmd(meme)) - .command("mute", |c| c - .desc("mute thulani (playback continues)") - .guild_only(true) - .cmd(mute)) - .command("unmute", |c| c - .desc("unmute thulani") - .guild_only(true) - .cmd(unmute)) - .command("play", |c| c - .desc("queue a request") - .guild_only(true) - .cmd(play)) - .command("volume", |c| c - .desc("set playback volume") - .guild_only(true) - .cmd(volume)) - .unrecognised_command(|ctx, msg, unrec| { - let url = match msg.content.split_whitespace().skip(1).next() { - Some(x) => x, - None => { - info!("received unrecognized command: {}", unrec); - let _ = send(msg.channel_id, "format your commands right. fuck you.", msg.tts); - return; - } - }; - - let _ = _play(ctx, msg, &url); - }) -} - -fn _play(ctx: &Context, msg: &Message, url: &str) -> Result<()> { - debug!("playing '{}'", url); - if !url.starts_with("http") { - send(msg.channel_id, "bAD LiNk", msg.tts)?; - return Ok(()); - } - - if url.contains("imgur") { - send(msg.channel_id, "IMGUR IS BAD, YOU TRASH CAN MAN", msg.tts)?; - return Ok(()); - } - - trace!("acquiring queue lock"); - - let queue_lock = ctx.data.lock().get::().cloned().unwrap(); - let mut play_queue = queue_lock.write().unwrap(); - - trace!("queue lock acquired"); - - play_queue.queue.push_back(PlayArgs{ - initiator: msg.author.name.clone(), - url: url.to_owned(), - sender_channel: msg.channel_id, - }); - - Ok(()) -} - -command!(play(ctx, msg, args) { - if args.len() == 0 { - _resume(ctx, msg)?; - return Ok(()); - } - - let url = match args.single::() { - Ok(url) => url, - Err(_) => { - send(msg.channel_id, "BAD LINK", msg.tts)?; - return Ok(()); - } - }; - - _play(ctx, msg, &url)?; -}); - -command!(pause(ctx, msg) { - let mut queue_lock = ctx.data.lock().get::().cloned().unwrap(); - - let done = || send(msg.channel_id, "r u srs", msg.tts); - let playing = { - let play_queue = queue_lock.read().unwrap(); - - let current_item = match play_queue.playing { - Some(ref x) => x, - None => { - done()?; - return Ok(()); - }, - }; - - let audio = current_item.audio.lock(); - audio.playing - }; - - if !playing { - done()?; - return Ok(()); - } - - { - let queue = queue_lock.write().unwrap(); - let ref audio = queue.playing.clone().unwrap().audio; - audio.lock().pause(); - } -}); - -command!(resume(ctx, msg) { - _resume(ctx, msg)?; -}); - -fn _resume(ctx: &mut Context, msg: &Message) -> Result<()> { - let queue_lock = ctx.data.lock().get::().cloned().unwrap(); - - let done = || send(msg.channel_id, "r u srs", msg.tts); - let playing = { - let play_queue = queue_lock.read().unwrap(); - - let current_item = match play_queue.playing { - Some(ref x) => x, - None => { - done()?; - return Ok(()); - }, - }; - - let audio = current_item.audio.lock(); - audio.playing - }; - - if playing { - done()?; - return Ok(()); - } - - { - let queue = queue_lock.write().unwrap(); - let ref audio = queue.playing.clone().unwrap().audio; - audio.lock().play(); - } - - Ok(()) -} - -command!(skip(ctx, _msg) { - let data = ctx.data.lock(); - - let mut mgr_lock = data.get::().cloned().unwrap(); - let mut manager = mgr_lock.lock(); - - let mut queue_lock = data.get::().cloned().unwrap(); - - if let Some(handler) = manager.get_mut(*TARGET_GUILD_ID) { - handler.stop(); - let mut play_queue = queue_lock.write().unwrap(); - play_queue.playing = None; - } else { - debug!("got skip with no handler attached"); - } -}); - -command!(die(ctx, msg) { - let data = ctx.data.lock(); - - let mut mgr_lock = data.get::().cloned().unwrap(); - let mut manager = mgr_lock.lock(); - - let mut queue_lock = data.get::().cloned().unwrap(); - - { - let mut play_queue = queue_lock.write().unwrap(); - - play_queue.playing = None; - play_queue.queue.clear(); - } - - if let Some(handler) = manager.get_mut(*TARGET_GUILD_ID) { - handler.stop(); - handler.leave(); - } else { - send(msg.channel_id, "YOU die", msg.tts)?; - debug!("got die with no handler attached"); - } -}); - -command!(list(ctx, msg) { - let mut queue_lock = ctx.data.lock().get::().cloned().unwrap(); - let mut play_queue = queue_lock.read().unwrap(); - - let channel_tmp = msg.channel().unwrap().guild().unwrap(); - let channel = channel_tmp.read(); - - match play_queue.playing { - Some(ref info) => { - let audio = info.audio.lock(); - let status = if audio.playing { "playing" } else { "paused:" }; - send(msg.channel_id, &format!("Currently {} `{}` ({})", status, info.init_args.url, info.init_args.initiator), msg.tts)?; - }, - None => { - debug!("`list` called with no items in queue"); - send(msg.channel_id, "Nothing is playing you meme", msg.tts)?; - return Ok(()); - }, - } - - play_queue.queue.iter().for_each(|info| { - channel.say(&format!("`{}` ({})", info.url, info.initiator)).unwrap(); - }); -}); - -command!(meme(_ctx, msg) { - send(msg.channel_id, "I am not yet capable of memeing", msg.tts)?; -}); - -command!(mute(ctx, _msg) { - let mut mgr_lock = ctx.data.lock().get::().cloned().unwrap(); - let mut manager = mgr_lock.lock(); - - manager.get_mut(*TARGET_GUILD_ID) - .map(|handler| { - if handler.self_mute { - trace!("Already muted.") - } else { - handler.mute(true); - trace!("Muted"); - } - }); -}); - -command!(unmute(ctx, msg) { - let mut mgr_lock = ctx.data.lock().get::().cloned().unwrap(); - let mut manager = mgr_lock.lock(); - - manager.get_mut(*TARGET_GUILD_ID) - .map(|handler| { - if !handler.self_mute { - trace!("Already unmuted.") - } else { - handler.mute(false); - trace!("Unmuted"); - let _ = send(msg.channel_id, "REEEEEEEEEEEEEE", msg.tts); - } - }); -}); - -command!(volume(ctx, msg, args) { - if args.len() == 0 { - let vol = { - let queue_lock = ctx.data.lock().get::().cloned().unwrap(); - let mut play_queue = queue_lock.read().unwrap(); - (play_queue.volume / DEFAULT_VOLUME * 100.0) as usize - }; - - send(msg.channel_id, &format!("Volume: {}/100", vol), msg.tts)?; - return Ok(()); - } - - let mut vol: usize = match args.single::() { - Ok(vol) if vol.is_nan() => { - send(msg.channel_id, "you're a fuck", msg.tts)?; - return Ok(()); - }, - Ok(vol) => vol as usize, - Err(_) => { - send(msg.channel_id, "???????", msg.tts)?; - return Ok(()); - }, - }; - - let mut vol: f32 = (vol as f32)/100.0; // force aliasing to reasonable values - - if vol > 3.0 { - vol = 3.0; - } - - if vol < 0.0 { - vol = 0.0; - } - - let mut queue_lock = ctx.data.lock().get::().cloned().unwrap(); - - { - let mut play_queue = queue_lock.write().unwrap(); - play_queue.volume = vol * DEFAULT_VOLUME; - } - - { - let play_queue = queue_lock.read().unwrap(); - - let current_item = match play_queue.playing { - Some(ref x) => x, - None => return Ok(()), - }; - - let mut audio = current_item.audio.lock(); - audio.volume(play_queue.volume); - }; -}); diff --git a/src/commands/db.rs b/src/commands/db.rs new file mode 100644 index 0000000..4e8293a --- /dev/null +++ b/src/commands/db.rs @@ -0,0 +1,5 @@ +use super::*; + +command!(meme(_ctx, msg) { + send(msg.channel_id, "I am not yet capable of memeing", msg.tts)?; +}); diff --git a/src/commands/mod.rs b/src/commands/mod.rs new file mode 100644 index 0000000..3a9cb66 --- /dev/null +++ b/src/commands/mod.rs @@ -0,0 +1,95 @@ +use {must_env_lookup, Result, TARGET_GUILD_ID}; +use serenity::framework::StandardFramework; +use serenity::model::channel::Message; +use serenity::model::id::ChannelId; +use serenity::prelude::*; +use serenity::voice::{LockedAudio, ytdl}; +use std::thread; +use std::time::Duration; + +mod playback; +mod sound; + +pub use self::sound::*; +pub use self::playback::*; + +cfg_if! { + if #[cfg(feature = "diesel")] { + mod db; + pub use self::db::*; + + fn register_db(f: StandardFramework) -> StandardFramework { + f + .command("meme", |c| c + .guild_only(true) + .help_available(false) + .cmd(meme)) + } + } else { + fn register_db(f: StandardFramework) -> StandardFramework { + f + } + } +} + +fn send(channel: ChannelId, text: &str, tts: bool) -> Result<()> { + channel.send_message(|m| m.content(text).tts(tts))?; + Ok(()) +} + +pub fn register_commands(f: StandardFramework) -> StandardFramework { + let f: StandardFramework = register_db(f); + f + .command("skip", |c| c + .desc("skip the rest of the current request") + .guild_only(true) + .cmd(skip)) + .command("pause", |c| c + .desc("pause playback (currently broken)") + .guild_only(true) + .cmd(pause)) + .command("resume", |c| c + .desc("resume playing (currently broken)") + .guild_only(true) + .cmd(resume)) + .command("list", |c| c + .known_as("queue") + .desc("list playing and queued requests") + .guild_only(true) + .cmd(list)) + .command("die", |c| c + .batch_known_as(vec!["sudoku", "stop"]) + .desc("stop playing and empty the queue") + .guild_only(true) + .cmd(die)) + .command("mute", |c| c + .desc("mute thulani (playback continues)") + .guild_only(true) + .cmd(mute)) + .command("unmute", |c| c + .desc("unmute thulani") + .guild_only(true) + .cmd(unmute)) + .command("play", |c| c + .desc("queue a request") + .guild_only(true) + .cmd(play)) + .command("volume", |c| c + .desc("set playback volume") + .guild_only(true) + .cmd(volume)) + .unrecognised_command(|ctx, msg, unrec| { + let url = match msg.content.split_whitespace().skip(1).next() { + Some(x) => x, + None => { + info!("received unrecognized command: {}", unrec); + let _ = send(msg.channel_id, "format your commands right. fuck you.", msg.tts); + return; + } + }; + + let _ = self::playback::_play(ctx, msg, &url); + }) +} + + diff --git a/src/commands/playback/mod.rs b/src/commands/playback/mod.rs new file mode 100644 index 0000000..1d4ee96 --- /dev/null +++ b/src/commands/playback/mod.rs @@ -0,0 +1,184 @@ +use super::*; + +pub use self::types::*; + +mod types; + +pub fn _play(ctx: &Context, msg: &Message, url: &str) -> Result<()> { + debug!("playing '{}'", url); + if !url.starts_with("http") { + send(msg.channel_id, "bAD LiNk", msg.tts)?; + return Ok(()); + } + + if url.contains("imgur") { + send(msg.channel_id, "IMGUR IS BAD, YOU TRASH CAN MAN", msg.tts)?; + return Ok(()); + } + + trace!("acquiring queue lock"); + + let queue_lock = ctx.data.lock().get::().cloned().unwrap(); + let mut play_queue = queue_lock.write().unwrap(); + + trace!("queue lock acquired"); + + play_queue.queue.push_back(PlayArgs{ + initiator: msg.author.name.clone(), + url: url.to_owned(), + sender_channel: msg.channel_id, + }); + + Ok(()) +} + +command!(play(ctx, msg, args) { + if args.len() == 0 { + _resume(ctx, msg)?; + return Ok(()); + } + + let url = match args.single::() { + Ok(url) => url, + Err(_) => { + send(msg.channel_id, "BAD LINK", msg.tts)?; + return Ok(()); + } + }; + + _play(ctx, msg, &url)?; +}); + +command!(pause(ctx, msg) { + let mut queue_lock = ctx.data.lock().get::().cloned().unwrap(); + + let done = || send(msg.channel_id, "r u srs", msg.tts); + let playing = { + let play_queue = queue_lock.read().unwrap(); + + let current_item = match play_queue.playing { + Some(ref x) => x, + None => { + done()?; + return Ok(()); + }, + }; + + let audio = current_item.audio.lock(); + audio.playing + }; + + if !playing { + done()?; + return Ok(()); + } + + { + let queue = queue_lock.write().unwrap(); + let ref audio = queue.playing.clone().unwrap().audio; + audio.lock().pause(); + } +}); + +command!(resume(ctx, msg) { + _resume(ctx, msg)?; +}); + +fn _resume(ctx: &mut Context, msg: &Message) -> Result<()> { + let queue_lock = ctx.data.lock().get::().cloned().unwrap(); + + let done = || send(msg.channel_id, "r u srs", msg.tts); + let playing = { + let play_queue = queue_lock.read().unwrap(); + + let current_item = match play_queue.playing { + Some(ref x) => x, + None => { + done()?; + return Ok(()); + }, + }; + + let audio = current_item.audio.lock(); + audio.playing + }; + + if playing { + done()?; + return Ok(()); + } + + { + let queue = queue_lock.write().unwrap(); + let ref audio = queue.playing.clone().unwrap().audio; + audio.lock().play(); + } + + Ok(()) +} + +command!(skip(ctx, _msg) { + let data = ctx.data.lock(); + + let mut mgr_lock = data.get::().cloned().unwrap(); + let mut manager = mgr_lock.lock(); + + let mut queue_lock = data.get::().cloned().unwrap(); + + if let Some(handler) = manager.get_mut(*TARGET_GUILD_ID) { + handler.stop(); + let mut play_queue = queue_lock.write().unwrap(); + play_queue.playing = None; + } else { + debug!("got skip with no handler attached"); + } +}); + +command!(die(ctx, msg) { + let data = ctx.data.lock(); + + let mut mgr_lock = data.get::().cloned().unwrap(); + let mut manager = mgr_lock.lock(); + + let mut queue_lock = data.get::().cloned().unwrap(); + + { + let mut play_queue = queue_lock.write().unwrap(); + + play_queue.playing = None; + play_queue.queue.clear(); + } + + if let Some(handler) = manager.get_mut(*TARGET_GUILD_ID) { + handler.stop(); + handler.leave(); + } else { + send(msg.channel_id, "YOU die", msg.tts)?; + debug!("got die with no handler attached"); + } +}); + +command!(list(ctx, msg) { + let mut queue_lock = ctx.data.lock().get::().cloned().unwrap(); + let mut play_queue = queue_lock.read().unwrap(); + + let channel_tmp = msg.channel().unwrap().guild().unwrap(); + let channel = channel_tmp.read(); + + match play_queue.playing { + Some(ref info) => { + let audio = info.audio.lock(); + let status = if audio.playing { "playing" } else { "paused:" }; + send(msg.channel_id, &format!("Currently {} `{}` ({})", status, info.init_args.url, info.init_args.initiator), msg.tts)?; + }, + None => { + debug!("`list` called with no items in queue"); + send(msg.channel_id, "Nothing is playing you meme", msg.tts)?; + return Ok(()); + }, + } + + play_queue.queue.iter().for_each(|info| { + channel.say(&format!("`{}` ({})", info.url, info.initiator)).unwrap(); + }); +}); diff --git a/src/commands/playback/types.rs b/src/commands/playback/types.rs new file mode 100644 index 0000000..41592ec --- /dev/null +++ b/src/commands/playback/types.rs @@ -0,0 +1,139 @@ +use serenity::client::bridge::voice::ClientVoiceManager; +use typemap::Key; +use std::sync::{Arc, RwLock}; +use std::collections::VecDeque; +use super::*; + +pub struct VoiceManager; + +impl Key for VoiceManager { + type Value = Arc>; +} + +impl VoiceManager { + pub fn register(c: &mut Client) { + let mut data = c.data.lock(); + data.insert::(Arc::clone(&c.voice_manager)); + } +} + +#[derive(Clone, Debug)] +pub struct PlayArgs { + pub url: String, + pub initiator: String, + pub sender_channel: ChannelId, +} + +#[derive(Clone)] +pub struct CurrentItem { + pub init_args: PlayArgs, + pub audio: LockedAudio, +} + +#[derive(Clone)] +pub struct PlayQueue { + pub queue: VecDeque, + pub playing: Option, + pub volume: f32, +} + +impl Key for PlayQueue { + type Value = Arc>; +} + +impl PlayQueue { + pub fn new() -> Self { + PlayQueue { + queue: VecDeque::new(), + playing: None, + volume: DEFAULT_VOLUME, + } + } + + pub fn register(c: &mut Client) { + let voice_manager = Arc::clone(&c.voice_manager); + + let mut data = c.data.lock(); + let queue = Arc::new(RwLock::new(PlayQueue::new())); + + data.insert::(Arc::clone(&queue)); + + thread::spawn(move || { + let queue_lck = Arc::clone(&queue); + let voice_manager = voice_manager; + + loop { + thread::sleep(Duration::from_millis(250)); + let (queue_is_empty, queue_has_playing) = { + let queue = queue_lck.read().unwrap(); + + let allow_continue = queue.playing.clone().map_or(false, |x| !x.audio.lock().finished); + + if allow_continue { + continue; + } + + (queue.queue.is_empty(), queue.playing.is_some()) + }; + + if queue_is_empty { + if queue_has_playing { + let mut queue = queue_lck.write().unwrap(); + + assert!({ + let audio_lck = queue.playing.clone().unwrap().audio; + let audio = audio_lck.lock(); + audio.finished + }); + + queue.playing = None; + + let mut manager = voice_manager.lock(); + manager.leave(*TARGET_GUILD_ID); + debug!("disconnected due to inactivity"); + } + continue; + } + + let mut queue = queue_lck.write().unwrap(); + let item = queue.queue.pop_front().unwrap(); + + trace!("checking ytdl for: {}", item.url); + + let src = match ytdl(&item.url) { + Ok(src) => src, + Err(e) => { + error!("bad link: {}; {:?}", &item.url, e); + let _ = send(item.sender_channel, &format!("what the fuck"), false); + continue; + } + }; + + trace!("got ytdl item for {}", item.url); + + let mut manager = voice_manager.lock(); + let handler = manager.join(*TARGET_GUILD_ID, must_env_lookup::("VOICE_CHANNEL")); + + match handler { + Some(handler) => { + let mut audio = handler.play_only(src); + { + audio.lock().volume(queue.volume); + } + + queue.playing = Some(CurrentItem { + init_args: item, + audio, + }); + + debug!("playing new song"); + }, + None => { + error!("couldn't join channel"); + let _ = send(item.sender_channel, "something happened somewhere somehow.", false); + } + } + } + }); + } +} diff --git a/src/commands/sound.rs b/src/commands/sound.rs new file mode 100644 index 0000000..6cac61d --- /dev/null +++ b/src/commands/sound.rs @@ -0,0 +1,88 @@ +use super::*; + +pub const DEFAULT_VOLUME: f32 = 0.05; + +command!(mute(ctx, _msg) { + let mut mgr_lock = ctx.data.lock().get::().cloned().unwrap(); + let mut manager = mgr_lock.lock(); + + manager.get_mut(*TARGET_GUILD_ID) + .map(|handler| { + if handler.self_mute { + trace!("Already muted.") + } else { + handler.mute(true); + trace!("Muted"); + } + }); +}); + +command!(unmute(ctx, msg) { + let mut mgr_lock = ctx.data.lock().get::().cloned().unwrap(); + let mut manager = mgr_lock.lock(); + + manager.get_mut(*TARGET_GUILD_ID) + .map(|handler| { + if !handler.self_mute { + trace!("Already unmuted.") + } else { + handler.mute(false); + trace!("Unmuted"); + let _ = send(msg.channel_id, "REEEEEEEEEEEEEE", msg.tts); + } + }); +}); + +command!(volume(ctx, msg, args) { + if args.len() == 0 { + let vol = { + let queue_lock = ctx.data.lock().get::().cloned().unwrap(); + let mut play_queue = queue_lock.read().unwrap(); + (play_queue.volume / DEFAULT_VOLUME * 100.0) as usize + }; + + send(msg.channel_id, &format!("Volume: {}/100", vol), msg.tts)?; + return Ok(()); + } + + let mut vol: usize = match args.single::() { + Ok(vol) if vol.is_nan() => { + send(msg.channel_id, "you're a fuck", msg.tts)?; + return Ok(()); + }, + Ok(vol) => vol as usize, + Err(_) => { + send(msg.channel_id, "???????", msg.tts)?; + return Ok(()); + }, + }; + + let mut vol: f32 = (vol as f32)/100.0; // force aliasing to reasonable values + + if vol > 3.0 { + vol = 3.0; + } + + if vol < 0.0 { + vol = 0.0; + } + + let mut queue_lock = ctx.data.lock().get::().cloned().unwrap(); + + { + let mut play_queue = queue_lock.write().unwrap(); + play_queue.volume = vol * DEFAULT_VOLUME; + } + + { + let play_queue = queue_lock.read().unwrap(); + + let current_item = match play_queue.playing { + Some(ref x) => x, + None => return Ok(()), + }; + + let mut audio = current_item.audio.lock(); + audio.volume(play_queue.volume); + }; +}); -- cgit v1.3.1