aboutsummaryrefslogtreecommitdiff
path: root/src/bot.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bot.rs')
-rw-r--r--src/bot.rs77
1 files changed, 52 insertions, 25 deletions
diff --git a/src/bot.rs b/src/bot.rs
index 2c9f73b..5d52259 100644
--- a/src/bot.rs
+++ b/src/bot.rs
@@ -5,7 +5,7 @@ use std::{
pin::Pin,
result::Result as StdResult,
str::FromStr,
- sync::Mutex,
+ sync::Arc,
};
use chrono::Datelike;
@@ -26,6 +26,7 @@ use serenity::{
GuildId,
ReactionType,
},
+ async_trait,
framework::{
standard::{
BucketBuilder,
@@ -45,7 +46,15 @@ use serenity::{
},
prelude::*,
};
-use songbird::SerenityInit;
+use songbird::{
+ Call,
+ CoreEvent,
+ Event,
+ EventContext,
+ SerenityInit,
+ TrackEvent,
+};
+use tokio::sync::Mutex;
use crate::{
commands::register_commands,
@@ -82,14 +91,20 @@ impl EventHandler for Handler {
#[cfg(not(debug_assertions))]
let botname = "thulani";
- use serenity::futures::StreamExt;
- serenity::futures::stream::iter(guild.iter())
- .for_each(|g| async move {
- if let Err(e) = g.id.edit_nickname(&ctx, Some(botname)).await {
- error!("changing nickname: {:?}", e);
- }
- })
- .await;
+ if let Some(guild) = guild {
+ if let Err(e) = guild.id.edit_nickname(&ctx, Some(botname)).await {
+ error!("changing nickname: {:?}", e);
+ }
+ }
+
+ let sb = songbird::get(&ctx).await.unwrap();
+
+ let c = sb.get_or_insert(CONFIG.discord.guild());
+ let mut call = c.lock().await;
+
+ call.remove_all_global_events();
+
+ call.add_global_event(Event::Track(TrackEvent::End), SongbirdHandler(c.clone()));
}
async fn resume(&self, _ctx: Context, _resume: ResumedEvent) {
@@ -103,7 +118,21 @@ impl EventHandler for Handler {
deleted_message_id: MessageId,
_: Option<GuildId>,
) {
- MESSAGE_WATCH.lock().unwrap().remove(&deleted_message_id);
+ MESSAGE_WATCH.lock().await.remove(&deleted_message_id);
+ }
+}
+
+struct SongbirdHandler(Arc<Mutex<Call>>);
+
+#[async_trait]
+impl songbird::events::EventHandler for SongbirdHandler {
+ async fn act(&self, _ctx: &EventContext<'_>) -> Option<Event> {
+ let mut call = self.0.lock().await;
+ if call.queue().is_empty() {
+ let _ = call.leave().await;
+ }
+
+ None
}
}
@@ -162,11 +191,11 @@ async fn framework() -> StandardFramework {
register_commands(framework)
}
-fn before_handle(
- ctx: &Context,
- message: &Message,
- cmd: &str,
-) -> Pin<Box<dyn Future<Output = bool> + Send>> {
+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);
Box::pin(async move {
@@ -206,7 +235,7 @@ fn before_handle(
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();
+ let mut mp = MESSAGE_WATCH.lock().await;
mp.insert(message.id, msg_id);
},
}
@@ -257,15 +286,13 @@ pub async fn run() -> Result<()> {
let shard_manager = client.shard_manager.clone();
- ctrlc::set_handler(move || {
- info!("shutting down");
+ tokio::spawn(async move {
+ tokio::signal::ctrl_c().await.unwrap();
+ warn!("got ctrl c");
- let shard_manager = shard_manager.clone();
- tokio::task::spawn(async move {
- shard_manager.shutdown_all().await;
- });
- })
- .expect("unable to create SIGINT/SIGTERM handlers");
+ shard_manager.shutdown_all().await;
+ info!("shutdown");
+ });
client.start().await?;