aboutsummaryrefslogtreecommitdiff
path: root/src/bot.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bot.rs')
-rw-r--r--src/bot.rs169
1 files changed, 89 insertions, 80 deletions
diff --git a/src/bot.rs b/src/bot.rs
index db37754..c8b01ab 100644
--- a/src/bot.rs
+++ b/src/bot.rs
@@ -1,9 +1,9 @@
use std::{
+ collections::HashSet,
fs::File,
future::Future,
path::PathBuf,
pin::Pin,
- result::Result as StdResult,
str::FromStr,
sync::Arc,
};
@@ -21,22 +21,16 @@ use log::{
trace,
warn,
};
+use poise::{
+ BoxFuture,
+ FrameworkError,
+};
use serenity::{
all::{
GuildId,
ReactionType,
},
- async_trait,
- framework::{
- standard::{
- BucketBuilder,
- CommandError,
- Configuration,
- },
- StandardFramework,
- },
model::{
- channel::Message,
event::ResumedEvent,
gateway::Ready,
id::{
@@ -56,11 +50,13 @@ use songbird::{
use tokio::sync::Mutex;
use crate::{
- commands::register_commands,
+ commands,
config::CONFIG,
util,
util::OAUTH_URL,
Error,
+ PoiseContext,
+ PoiseData,
Result,
};
@@ -123,7 +119,7 @@ impl EventHandler for Handler {
struct SongbirdHandler(Arc<Mutex<Call>>);
-#[async_trait]
+#[serenity::async_trait]
impl songbird::events::EventHandler for SongbirdHandler {
async fn act(&self, _ctx: &EventContext<'_>) -> Option<Event> {
let mut call = self.0.lock().await;
@@ -161,112 +157,125 @@ lazy_static! {
let result = restrict_ids.unwrap_or_default().into_iter().collect::<FnvHashSet<_>>();
- info!("restricted ids: {:?}", result);
+ info!("restricted ids: {result:?}");
result
};
}
-async fn framework() -> StandardFramework {
- let builder = BucketBuilder::default().delay(1).limit(20).time_span(60);
+fn on_err(err: FrameworkError<PoiseData, anyhow::Error>) -> BoxFuture<()> {
+ Box::pin(async move {
+ error!("error encountered: {err:?}");
- let framework = StandardFramework::new()
- .before(before_handle)
- .after(after_handle)
- .bucket("Standard", builder)
- .await;
+ if let Some(ctx) = err.ctx() {
+ if let Err(e) = util::react(ctx, ReactionType::Unicode("❌".to_owned())).await {
+ error!("reacting to failed message: {e}");
+ }
- 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);
+ if let Err(e) = util::reply(ctx, "BANIC").await {
+ error!("sending BANIC: {e}");
+ }
+ }
+ })
+}
- framework.configure(config);
+async fn framework() -> poise::Framework<PoiseData, anyhow::Error> {
+ let additional_prefixes =
+ ALL_PREFIXES.iter().skip(1).map(|x| poise::Prefix::Literal(x.to_owned())).collect();
- register_commands(framework)
-}
+ let framework = poise::Framework::builder()
+ .options(poise::FrameworkOptions {
+ pre_command: before_handle,
+ post_command: after_handle,
+ on_error: on_err,
+
+ command_check: Some(check),
+
+ prefix_options: poise::PrefixFrameworkOptions {
+ prefix: ALL_PREFIXES.get(0).map(|&x| x.to_owned()),
+ additional_prefixes,
+ case_insensitive_commands: true,
+ mention_as_prefix: false,
+ ignore_bots: true,
+ ..Default::default()
+ },
+
+ commands: commands::commands(),
+ owners: HashSet::from_iter([CONFIG.discord.owner()]),
+ initialize_owners: false,
+ skip_checks_for_owners: true,
-fn before_handle<'fut>(
- ctx: &'fut Context,
- message: &'fut Message,
- cmd: &'fut str,
-) -> Pin<Box<dyn Future<Output = bool> + Send + 'fut>> {
- debug!("got command '{}' from user '{}' ({})", cmd, message.author.name, message.author.id);
+ ..Default::default()
+ })
+ .setup(|_ctx, _ready, _framework| Box::pin(async move { Ok(()) }))
+ .build();
+
+ framework
+}
+fn check(ctx: PoiseContext) -> BoxFuture<anyhow::Result<bool>> {
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 !ctx.guild_id().map_or(false, |x| x == CONFIG.discord.guild()) {
+ info!(
+ "rejecting command '{}' from user '{}': wrong guild",
+ ctx.command().name,
+ ctx.author().name
+ );
+ return Ok(false);
}
- if message.author.id == CONFIG.discord.owner() {
- return true;
+ if ctx.author().id == CONFIG.discord.owner() {
+ return Ok(true);
}
- let restricted_prefix =
- RESTRICTED_PREFIXES.iter().any(|prefix| message.content.starts_with(prefix));
+ let restricted_prefix = RESTRICTED_PREFIXES.iter().any(|&prefix| ctx.prefix() == prefix);
if !restricted_prefix {
- return true;
+ return Ok(true);
}
const PERMITTED_WEEKDAY: chrono::Weekday = chrono::Weekday::Tue;
- let user_is_restricted = RESTRICT_IDS.contains(&message.author.id.get());
+ let user_is_restricted = RESTRICT_IDS.contains(&ctx.author().id.get());
let restrictions_flipped = chrono::Local::now().weekday() == PERMITTED_WEEKDAY;
if user_is_restricted == restrictions_flipped {
- return true;
+ return Ok(true);
}
let reason = if !restrictions_flipped {
"restricted prefix".to_owned()
} else {
- format!("it is {:?}", PERMITTED_WEEKDAY)
+ format!("it is {PERMITTED_WEEKDAY:?}")
};
- info!("rejecting command '{}' from user '{}': {}", cmd, message.author.name, reason);
+ info!(
+ "rejecting command '{}' from user '{}': {}",
+ ctx.command().name,
+ ctx.author().name,
+ reason
+ );
- 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().await;
- mp.insert(message.id, msg_id);
- },
- }
+ util::reply(ctx, "no").await?;
- false
+ Ok(false)
})
}
-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, ReactionType::Unicode("❌".to_owned())).await {
- error!("reacting to failed message: {}", e);
- }
+fn before_handle<'fut>(ctx: PoiseContext<'fut>) -> Pin<Box<dyn Future<Output = ()> + Send + 'fut>> {
+ debug!(
+ "got command '{}' from user '{}' ({})",
+ ctx.command().name,
+ ctx.author().name,
+ ctx.author().id
+ );
- if let Err(e) = util::send(ctx, msg.channel_id, "BANIC", msg.tts).await {
- error!("sending BANIC: {}", e);
- }
+ Box::pin(async {})
+}
- error!("error encountered handling command '{}': {:?}", cmd, e);
- },
- }
+fn after_handle(ctx: PoiseContext) -> BoxFuture<()> {
+ Box::pin(async move {
+ trace!("command '{}' completed successfully", ctx.command().name);
})
}