diff options
| author | Nathan Perry <np@nathanperry.dev> | 2019-07-16 17:22:04 -0400 |
|---|---|---|
| committer | Nathan Perry <np@nathanperry.dev> | 2019-07-16 17:22:04 -0400 |
| commit | ca46177a5df0eac30b3ca2bc33c5015e03f18688 (patch) | |
| tree | 33e0f137d6ce84d721c7102239c790c922e4e320 | |
| parent | 54f729b3e2315e7d70f8daa01132cb233d302b1c (diff) | |
restricted prefixes
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | src/audio/play_queue.rs | 12 | ||||
| -rw-r--r-- | src/commands/meme/history.rs | 3 | ||||
| -rw-r--r-- | src/commands/mod.rs | 12 | ||||
| -rw-r--r-- | src/game.rs | 5 | ||||
| -rw-r--r-- | src/main.rs | 71 |
6 files changed, 80 insertions, 24 deletions
@@ -4,3 +4,4 @@ .vscode *.log user_id_mapping.json +restrict.json diff --git a/src/audio/play_queue.rs b/src/audio/play_queue.rs index 2543c61..aa2ccc5 100644 --- a/src/audio/play_queue.rs +++ b/src/audio/play_queue.rs @@ -153,17 +153,17 @@ impl PlayQueue { .stdin(process::Stdio::null()) .spawn()?; - let mut audio_reader = ffmpeg_command.stdout.unwrap(); + let audio_reader = ffmpeg_command.stdout.unwrap(); - let mut pre_silence = vec![0u8; PRE_SILENCE_BYTES]; - let mut post_silence = vec![0u8; POST_SILENCE_BYTES]; + let pre_silence = vec![0u8; PRE_SILENCE_BYTES]; + let post_silence = vec![0u8; POST_SILENCE_BYTES]; let reader = Cursor::new(pre_silence).chain(audio_reader).chain(Cursor::new(post_silence)); voice::pcm(true, reader) }, Right(ref vec) => { - let mut transcoder = process::Command::new("ffmpeg") + let transcoder = process::Command::new("ffmpeg") .args(&[ "-format", "opus", "-i", "pipe:0", @@ -206,8 +206,8 @@ impl PlayQueue { } }); - let mut pre_silence = vec![0u8; PRE_SILENCE_BYTES]; - let mut post_silence = vec![0u8; POST_SILENCE_BYTES]; + let pre_silence = vec![0u8; PRE_SILENCE_BYTES]; + let post_silence = vec![0u8; POST_SILENCE_BYTES]; let reader = Cursor::new(pre_silence) .chain(stdout.unwrap()) diff --git a/src/commands/meme/history.rs b/src/commands/meme/history.rs index 7a38325..e5f15f5 100644 --- a/src/commands/meme/history.rs +++ b/src/commands/meme/history.rs @@ -109,8 +109,6 @@ pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { .enumerate() .rev() .map(|(i, rec)| { - use chrono; - let dt = chrono::DateTime::from_utc(rec.time, chrono::Utc{}); let ago = TIME_FORMATTER.convert((chrono::Utc::now() - dt).to_std().unwrap()); @@ -142,7 +140,6 @@ pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { pub fn stats(_: &mut Context, msg: &Message, _: Args) -> Result<()> { use db; - use chrono; use serenity::model::{ id::UserId, user::User, diff --git a/src/commands/mod.rs b/src/commands/mod.rs index c315278..f4ff9cb 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,6 +1,6 @@ use serenity::{ framework::StandardFramework, - model::id::ChannelId, + model::id::{ChannelId, MessageId}, }; use crate::Result; @@ -151,7 +151,13 @@ fn register_db(f: StandardFramework) -> StandardFramework { f } +#[inline] pub(crate) fn send<A: AsRef<str>>(channel: ChannelId, text: A, tts: bool) -> Result<()> { - channel.send_message(|m| m.content(text.as_ref()).tts(tts))?; - Ok(()) + send_result(channel, text, tts).map(|_| ()) +} + +#[inline] +pub(crate) fn send_result<A: AsRef<str>>(channel: ChannelId, text: A, tts: bool) -> Result<MessageId> { + let result = channel.send_message(|m| m.content(text.as_ref()).tts(tts))?; + Ok(result.id) } diff --git a/src/game.rs b/src/game.rs index 368831b..807953d 100644 --- a/src/game.rs +++ b/src/game.rs @@ -204,11 +204,6 @@ pub fn get_user_id<S: AsRef<str>>(g: &Guild, s: S) -> StdResult<UserId, UserLook } fn game(_ctx: &mut Context, msg: &Message, args: Args, min_status: GameStatus) -> Result<()> { - use fnv::{ - FnvHashMap, - FnvHashSet, - }; - let guild = msg.channel_id.to_channel()? .guild() .ok_or(err_msg("couldn't find guild"))?; diff --git a/src/main.rs b/src/main.rs index d3458b6..90e6e6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,15 +36,18 @@ extern crate typemap; extern crate url; use std::{ + default::Default, + fs::File, thread, time::{ Duration, - Instant + Instant, }, }; use dotenv::dotenv; use failure::Error; +use fnv::{FnvHashMap, FnvHashSet}; use serenity::{ framework::{ standard::help_commands, @@ -52,7 +55,7 @@ use serenity::{ }, model::{ gateway::Ready, - id::{ChannelId, GuildId, UserId}, + id::{ChannelId, GuildId, MessageId, UserId}, }, prelude::*, }; @@ -106,8 +109,26 @@ impl EventHandler for Handler { let _ = guild.map(|g| g.id().edit_nickname(Some("thulani"))); } } + + fn message_delete(&self, _ctx: Context, channel_id: ChannelId, deleted_message_id: MessageId) { + MESSAGE_WATCH.lock() + .remove(&deleted_message_id) + .iter() + .for_each(|id| { + if let Err(e) = channel_id.delete_message(id) { + error!("deleting message: {}", e); + } + }); + } } +lazy_static! { + static ref MESSAGE_WATCH: Mutex<FnvHashMap<MessageId, MessageId>> = Mutex::new(FnvHashMap::default()); + static ref PREFIXES: Vec<&'static str> = vec!["!thulani ", "!thulan ", "!thulando madando ", "!thulando "]; + static ref RESTRICTED_PREFIXES: Vec<&'static str> = vec!["!todd ", "!toddbert ", "!toddlani "]; +} + + fn run() -> Result<()> { let token = &dotenv::var("THULANI_TOKEN").map_err(|_| format_err!("missing token"))?; let mut client = Client::new(token, Handler)?; @@ -115,23 +136,59 @@ fn run() -> Result<()> { audio::VoiceManager::register(&mut client); audio::PlayQueue::register(&mut client); + let all_prefixes = { + let mut all_prefixes: Vec<&'static str> = vec![]; + all_prefixes.extend(PREFIXES.iter()); + all_prefixes.extend(RESTRICTED_PREFIXES.iter()); + all_prefixes + }; + + let restrict_ids = File::open("restrict.json") + .map_err(Error::from) + .and_then(|f| serde_json::from_reader::<_, Vec<u64>>(f).map_err(Error::from)); + + if let Err(ref e) = restrict_ids { + error!("opening restrict file: {}", e); + } + + let restrict_ids = restrict_ids + .unwrap_or_default() + .into_iter() + .collect::<FnvHashSet<_>>(); + let owner_id = must_env_lookup::<u64>("OWNER_ID"); let mut framework = StandardFramework::new() .configure(|c| c .allow_dm(false) .allow_whitespace(true) - .prefixes(vec!["!thulani ", "!thulan ", "!thulando madando ", "!thulando "]) + .prefixes(all_prefixes) .ignore_bots(true) .on_mention(false) .owners(vec![UserId(owner_id)].into_iter().collect()) .case_insensitivity(true) .delimiter("\t") ) - .before(|_ctx, message, cmd| { - let result = message.guild_id.map_or(false, |x| x.0 == *TARGET_GUILD); - debug!("got command '{}' from user '{}' ({}). accept: {}", cmd, message.author.name, message.author.id, result); + .before(move |_ctx, message, cmd| { + debug!("got command '{}' from user '{}' ({})", cmd, message.author.name, message.author.id); + if !message.guild_id.map_or(false, |x| x.0 == *TARGET_GUILD) { + info!("rejecting command '{}' from user '{}': wrong guild", cmd, message.author.name); + return false; + } + + if RESTRICTED_PREFIXES.iter().any(|prefix| message.content.starts_with(prefix)) + && restrict_ids.contains(&message.author.id.0) { + info!("rejecting command '{}' from user '{}': restricted prefix", cmd, message.author.name); + match crate::commands::send_result(message.channel_id, "no", message.tts) { + Err(e) => error!("sending restricted prefix response: {}", e), + Ok(msg_id) => { + let mut mp = MESSAGE_WATCH.lock(); + mp.insert(message.id, msg_id); + } + } + return false; + } - result + true }) .after(|_ctx, msg, cmd, err| { match err { |
