diff --git a/src/player/commands/list.rs b/src/player/commands/list.rs index 0fcee67..59afa80 100644 --- a/src/player/commands/list.rs +++ b/src/player/commands/list.rs @@ -18,10 +18,18 @@ impl serenity::framework::standard::Command for List { #[allow(unreachable_code, unused_mut)] fn execute( &self, - _: &mut serenity::client::Context, + ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, _: serenity::framework::standard::Args, ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { + if !channel_contains_author(ctx, msg) { + println!( + "user {} is not in the same voice channel as the bot", + msg.author.name + ); + return Ok(()); + } + let mut output = String::new(); { diff --git a/src/player/commands/pause.rs b/src/player/commands/pause.rs index d986c7b..a94cde7 100644 --- a/src/player/commands/pause.rs +++ b/src/player/commands/pause.rs @@ -19,10 +19,18 @@ impl serenity::framework::standard::Command for Pause { #[allow(unreachable_code, unused_mut)] fn execute( &self, - _: &mut serenity::client::Context, - _: &serenity::model::channel::Message, + ctx: &mut serenity::client::Context, + msg: &serenity::model::channel::Message, _: serenity::framework::standard::Args, ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { + if !channel_contains_author(ctx, msg) { + println!( + "user {} is not in the same voice channel as the bot", + msg.author.name + ); + return Ok(()); + } + let song_lock = self.media.song_mut(); if let Some(song) = song_lock.borrow_mut().deref_mut() { diff --git a/src/player/commands/play.rs b/src/player/commands/play.rs index 7fe6f57..1626726 100644 --- a/src/player/commands/play.rs +++ b/src/player/commands/play.rs @@ -159,6 +159,14 @@ impl serenity::framework::standard::Command for Play { msg: &serenity::model::channel::Message, mut args: serenity::framework::standard::Args, ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { + if !channel_contains_author(ctx, msg) { + println!( + "user {} is not in the same voice channel as the bot", + msg.author.name + ); + return Ok(()); + } + if args.len() == 0 { if !Self::check_for_continue(self.media.song_mut()) { print_error!(msg.channel_id.say("Must provide a URL to a video or audio")); diff --git a/src/player/commands/skip.rs b/src/player/commands/skip.rs index 7b8c06a..71dc9c0 100644 --- a/src/player/commands/skip.rs +++ b/src/player/commands/skip.rs @@ -23,6 +23,14 @@ impl serenity::framework::standard::Command for Skip { msg: &serenity::model::channel::Message, _: serenity::framework::standard::Args, ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { + if !channel_contains_author(ctx, msg) { + println!( + "user {} is not in the same voice channel as the bot", + msg.author.name + ); + return Ok(()); + } + let mut manager_lock = ctx.data.lock().get::().cloned().unwrap(); let mut manager = manager_lock.lock(); diff --git a/src/player/commands/stop.rs b/src/player/commands/stop.rs index 593732b..fedee64 100644 --- a/src/player/commands/stop.rs +++ b/src/player/commands/stop.rs @@ -22,6 +22,14 @@ impl serenity::framework::standard::Command for Stop { msg: &serenity::model::channel::Message, _: serenity::framework::standard::Args, ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { + if !channel_contains_author(ctx, msg) { + println!( + "user {} is not in the same voice channel as the bot", + msg.author.name + ); + return Ok(()); + } + print_error!(self.media.reset(ctx, msg)); Ok(()) diff --git a/src/player/player.rs b/src/player/player.rs index 7629da3..9a40f77 100644 --- a/src/player/player.rs +++ b/src/player/player.rs @@ -5,6 +5,8 @@ use serenity::client::CACHE; use serenity::model::id::{ChannelId, GuildId}; use serenity::voice::Handler; +use super::prelude::*; + pub fn guild_id(channel_id: ChannelId) -> Option { match CACHE.read().guild_channel(channel_id) { Some(channel) => Some(channel.read().guild_id), @@ -24,3 +26,57 @@ pub fn handler<'a>( ) -> Option<&'a mut Handler> { manager.get_mut(guild_id) } + +pub fn channel_contains_author( + ctx: &mut serenity::client::Context, + msg: &serenity::model::channel::Message, +) -> bool { + let manager_lock = ctx.data.lock().get::().cloned().unwrap(); + + let mut manager = manager_lock.lock(); + let guild_id = match guild_id(msg.channel_id) { + Some(guild_id) => guild_id, + None => { + println!("error getting guild_id"); + return true; + } + }; + + let handler = match handler(guild_id, &mut manager) { + Some(handler) => handler, + None => { + println!("error getting handler"); + return true; + } + }; + + if let Some(voice_channel_id_bot) = handler.channel_id { + let author = &msg.author; + + let guild = match guild_id.to_guild_cached() { + Some(guild) => guild, + None => { + println!("error getting guild from cache"); + return true; + } + }; + + let guild_lock = guild.read(); + + let voice_state = match guild_lock.voice_states.get(&author.id) { + Some(state) => state, + None => { + println!("error getting voice state from user {}", author.name); + return false; + } + }; + + if let Some(voice_channel_id_user) = voice_state.channel_id { + if voice_channel_id_bot != voice_channel_id_user { + return false; + } + } + } + + true +} diff --git a/src/player/prelude.rs b/src/player/prelude.rs index 500dfaf..3d638e9 100644 --- a/src/player/prelude.rs +++ b/src/player/prelude.rs @@ -14,4 +14,4 @@ pub use super::voicemanager::VoiceManager; pub use super::youtube::youtube_dl; -pub use super::player::{guild_id, handler}; +pub use super::player::{channel_contains_author, guild_id, handler};