aboutsummaryrefslogtreecommitdiff
path: root/src/bot.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bot.rs')
-rw-r--r--src/bot.rs234
1 files changed, 131 insertions, 103 deletions
diff --git a/src/bot.rs b/src/bot.rs
index abc0fd0..b3db4e9 100644
--- a/src/bot.rs
+++ b/src/bot.rs
@@ -1,54 +1,67 @@
use std::{
- sync::Mutex,
fs::File,
- result::Result as StdResult, path::PathBuf, str::FromStr,
-};
-
-use serenity::{
- prelude::*,
- model::{
- gateway::Ready,
- id::{
- ChannelId,
- MessageId,
- },
- channel::Message,
- event::ResumedEvent,
- },
- framework::StandardFramework,
+ future::Future,
+ path::PathBuf,
+ pin::Pin,
+ result::Result as StdResult,
+ str::FromStr,
+ sync::Mutex,
};
+use chrono::Datelike;
use fnv::{
FnvHashMap,
FnvHashSet,
};
-
-use serde_json::Value;
-use chrono::Datelike;
use lazy_static::lazy_static;
use log::{
debug,
- info,
error,
+ info,
trace,
warn,
};
+use serenity::{
+ all::{
+ GuildId,
+ ReactionType,
+ },
+ framework::{
+ standard::{
+ BucketBuilder,
+ CommandError,
+ Configuration,
+ },
+ StandardFramework,
+ },
+ model::{
+ channel::Message,
+ event::ResumedEvent,
+ gateway::Ready,
+ id::{
+ ChannelId,
+ MessageId,
+ },
+ },
+ prelude::*,
+};
use crate::{
- Result,
- Error,
audio,
- util::OAUTH_URL,
- util::CtxExt,
commands::register_commands,
config::CONFIG,
+ util,
+ util::OAUTH_URL,
+ Error,
+ Result,
};
struct Handler;
+
+#[serenity::async_trait]
impl EventHandler for Handler {
- fn ready(&self, ctx: Context, r: Ready) {
- let guild = r.guilds.iter()
- .find(|g| g.id() == CONFIG.discord.guild());
+ async fn ready(&self, ctx: Context, r: Ready) {
+ let guild = r.guilds.iter().find(|g| g.id() == CONFIG.discord.guild());
if guild.is_none() {
info!("bot isn't in configured guild. join here: {:?}", OAUTH_URL.as_str());
@@ -70,24 +83,26 @@ impl EventHandler for Handler {
});
}
- fn resume(&self, _ctx: Context, _resume: ResumedEvent) {
+ async fn resume(&self, _ctx: Context, _resume: ResumedEvent) {
info!("reconnected to discord");
}
- fn message_delete(&self, _ctx: Context, _channel_id: ChannelId, deleted_message_id: MessageId) {
- MESSAGE_WATCH.lock()
- .unwrap()
- .remove(&deleted_message_id);
- }
-
- fn unknown(&self, _ctx: Context, name: String, _raw: Value) {
- info!("unknown event: {:?}", name);
+ async fn message_delete(
+ &self,
+ _ctx: Context,
+ _: ChannelId,
+ deleted_message_id: MessageId,
+ _: Option<GuildId>,
+ ) {
+ MESSAGE_WATCH.lock().unwrap().remove(&deleted_message_id);
}
}
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 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 "];
static ref ALL_PREFIXES: Vec<&'static str> = {
let mut all_prefixes: Vec<&'static str> = vec![];
@@ -95,7 +110,6 @@ lazy_static! {
all_prefixes.extend(RESTRICTED_PREFIXES.iter());
all_prefixes
};
-
static ref RESTRICT_IDS: FnvHashSet<u64> = {
let default_path = PathBuf::from_str("restrict.json").unwrap();
let restrict_path = CONFIG.restrict.as_ref().unwrap_or(&default_path);
@@ -108,10 +122,7 @@ lazy_static! {
warn!("opening restrict file: {}", e);
}
- let result = restrict_ids
- .unwrap_or_default()
- .into_iter()
- .collect::<FnvHashSet<_>>();
+ let result = restrict_ids.unwrap_or_default().into_iter().collect::<FnvHashSet<_>>();
info!("restricted ids: {:?}", result);
@@ -119,91 +130,107 @@ lazy_static! {
};
}
-fn framework() -> StandardFramework {
+async fn framework() -> StandardFramework {
+ let builder = BucketBuilder::default().delay(1).limit(20).time_span(60);
+
let framework = StandardFramework::new()
- .configure(|c| c
- .allow_dm(false)
- .with_whitespace(true)
- .prefixes(ALL_PREFIXES.iter())
- .ignore_bots(true)
- .on_mention(None)
- .owners(vec![CONFIG.discord.owner()].into_iter().collect())
- .case_insensitivity(true)
- )
.before(before_handle)
.after(after_handle)
- .bucket("Standard", |b| {
- b.delay(1).limit(20).time_span(60)
- });
+ .bucket("Standard", builder)
+ .await;
+
+ let config = Configuration::default()
+ .allow_dm(false)
+ .with_whitespace(true)
+ .prefixes(ALL_PREFIXES.iter().map(|x| x.to_string()))
+ .ignore_bots(true)
+ .on_mention(None)
+ .owners(vec![CONFIG.discord.owner()].into_iter().collect())
+ .case_insensitivity(true);
+
+ framework.configure(config);
register_commands(framework)
}
-fn before_handle(ctx: &mut Context, message: &Message, cmd: &str) -> bool {
+fn before_handle(
+ ctx: &Context,
+ message: &Message,
+ cmd: &str,
+) -> Pin<Box<dyn Future<Output = bool> + Send>> {
debug!("got command '{}' from user '{}' ({})", cmd, message.author.name, message.author.id);
- if !message.guild_id.map_or(false, |x| x == CONFIG.discord.guild()) {
- info!("rejecting command '{}' from user '{}': wrong guild", cmd, message.author.name);
- return false;
- }
+ Box::pin(async move {
+ if !message.guild_id.map_or(false, |x| x == CONFIG.discord.guild()) {
+ info!("rejecting command '{}' from user '{}': wrong guild", cmd, message.author.name);
+ return false;
+ }
- if message.author.id == CONFIG.discord.owner() {
- return true;
- }
+ if message.author.id == CONFIG.discord.owner() {
+ return true;
+ }
- let restricted_prefix = RESTRICTED_PREFIXES.iter()
- .any(|prefix| message.content.starts_with(prefix));
+ let restricted_prefix =
+ RESTRICTED_PREFIXES.iter().any(|prefix| message.content.starts_with(prefix));
- if !restricted_prefix {
- return true;
- }
+ if !restricted_prefix {
+ return true;
+ }
- const PERMITTED_WEEKDAY: chrono::Weekday = chrono::Weekday::Tue;
+ const PERMITTED_WEEKDAY: chrono::Weekday = chrono::Weekday::Tue;
- let user_is_restricted = RESTRICT_IDS.contains(&message.author.id.0);
- let restrictions_flipped = chrono::Local::now().weekday() == PERMITTED_WEEKDAY;
+ let user_is_restricted = RESTRICT_IDS.contains(&message.author.id.get());
+ let restrictions_flipped = chrono::Local::now().weekday() == PERMITTED_WEEKDAY;
- if user_is_restricted == restrictions_flipped {
- return true;
- }
+ if user_is_restricted == restrictions_flipped {
+ return true;
+ }
- let reason = if !restrictions_flipped {
- "restricted prefix".to_owned()
- } else {
- format!("it is {:?}", PERMITTED_WEEKDAY)
- };
+ let reason = if !restrictions_flipped {
+ "restricted prefix".to_owned()
+ } else {
+ format!("it is {:?}", PERMITTED_WEEKDAY)
+ };
- info!("rejecting command '{}' from user '{}': {}", cmd, message.author.name, reason);
+ info!("rejecting command '{}' from user '{}': {}", cmd, message.author.name, reason);
- match ctx.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().unwrap();
- mp.insert(message.id, msg_id);
+ match util::send_result(ctx, message.channel_id, "no", message.tts).await {
+ Err(e) => error!("sending restricted prefix response: {}", e),
+ Ok(msg_id) => {
+ let mut mp = MESSAGE_WATCH.lock().unwrap();
+ mp.insert(message.id, msg_id);
+ },
}
- }
- false
+ false
+ })
}
-fn after_handle(ctx: &mut Context, msg: &Message, cmd: &str, err: StdResult<(), Error>) {
- match err {
- Ok(()) => {
- trace!("command '{}' completed successfully", cmd);
- },
+fn after_handle<'fut>(
+ ctx: &'fut Context,
+ msg: &'fut Message,
+ cmd: &'fut str,
+ err: StdResult<(), CommandError>,
+) -> Pin<Box<dyn Future<Output = ()> + Send + 'fut>> {
+ Box::pin(async move {
+ match err {
+ Ok(()) => {
+ trace!("command '{}' completed successfully", cmd);
+ },
- Err(e) => {
- if let Err(e) = msg.react(&ctx, "❌") {
- error!("reacting to failed message: {}", e);
- }
+ Err(e) => {
+ if let Err(e) = msg.react(&ctx, ReactionType::Unicode("❌".to_owned())).await {
+ error!("reacting to failed message: {}", e);
+ }
- if let Err(e) = ctx.send(msg.channel_id, "BANIC", msg.tts) {
- error!("sending BANIC: {}", e);
- }
+ if let Err(e) = util::send(ctx, msg.channel_id, "BANIC", msg.tts).await {
+ error!("sending BANIC: {}", e);
+ }
- error!("error encountered handling command '{}': {:?}", cmd, e);
+ error!("error encountered handling command '{}': {:?}", cmd, e);
+ },
}
- }
+ })
}
pub fn run() -> Result<()> {
@@ -219,7 +246,8 @@ pub fn run() -> Result<()> {
ctrlc::set_handler(move || {
info!("shutting down");
shard_manager.lock().shutdown_all();
- }).expect("unable to create SIGINT/SIGTERM handlers");
+ })
+ .expect("unable to create SIGINT/SIGTERM handlers");
client.start()
}