222 lines
11 KiB
Rust
222 lines
11 KiB
Rust
use poise::serenity_prelude::{
|
|
model::channel::Channel, ActionRowComponent, Activity, Context, CreateActionRow, FullEvent,
|
|
Interaction,
|
|
};
|
|
|
|
#[cfg(feature = "metrics")]
|
|
use crate::metrics::GREET_COUNTER;
|
|
use crate::{
|
|
cmds::search::SoundPager,
|
|
models::{
|
|
guild_data::{AllowGreet, CtxGuildData},
|
|
join_sound::JoinSoundCtx,
|
|
sound::Sound,
|
|
},
|
|
utils::{join_channel, play_audio, play_from_query},
|
|
Data, Error,
|
|
};
|
|
|
|
pub async fn listener(ctx: &Context, event: &FullEvent, data: &Data) -> Result<(), Error> {
|
|
match event {
|
|
FullEvent::Ready { .. } => {
|
|
ctx.set_activity(Activity::watching("for /play")).await;
|
|
}
|
|
FullEvent::VoiceStateUpdate { old, new, .. } => {
|
|
if let Some(past_state) = old {
|
|
if let (Some(guild_id), None) = (past_state.guild_id, new.channel_id) {
|
|
if let Some(channel_id) = past_state.channel_id {
|
|
if let Some(Channel::Guild(channel)) =
|
|
channel_id.to_channel_cached(&ctx.cache)
|
|
{
|
|
if channel.members(&ctx).await.map(|m| m.len()).unwrap_or(0) <= 1 {
|
|
let songbird = songbird::get(ctx).await.unwrap();
|
|
|
|
let _ = songbird.remove(guild_id).await;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if let (Some(guild_id), Some(user_channel)) = (new.guild_id, new.channel_id) {
|
|
if let Some(guild) = ctx.cache.guild(guild_id) {
|
|
let guild_data_opt = data.guild_data(guild.id).await;
|
|
|
|
if let Ok(guild_data) = guild_data_opt {
|
|
let volume;
|
|
let allowed_greets;
|
|
|
|
{
|
|
let read = guild_data.read().await;
|
|
|
|
volume = read.volume;
|
|
allowed_greets = read.allow_greets;
|
|
}
|
|
|
|
if allowed_greets != AllowGreet::Disabled {
|
|
if let Some(join_id) = data
|
|
.join_sound(
|
|
new.user_id,
|
|
new.guild_id,
|
|
allowed_greets == AllowGreet::GuildOnly,
|
|
)
|
|
.await
|
|
{
|
|
let mut sound = sqlx::query_as_unchecked!(
|
|
Sound,
|
|
"
|
|
SELECT name, id, public, server_id, uploader_id
|
|
FROM sounds
|
|
WHERE id = ?",
|
|
join_id
|
|
)
|
|
.fetch_one(&data.database)
|
|
.await
|
|
.unwrap();
|
|
|
|
let (handler, _) = join_channel(&ctx, guild, user_channel).await;
|
|
|
|
#[cfg(feature = "metrics")]
|
|
GREET_COUNTER.inc();
|
|
|
|
play_audio(
|
|
&mut sound,
|
|
volume,
|
|
&mut handler.lock().await,
|
|
&data.database,
|
|
false,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
FullEvent::InteractionCreate { interaction } => match interaction {
|
|
Interaction::MessageComponent(component) => {
|
|
if let Some(guild_id) = component.guild_id {
|
|
if let Ok(()) = SoundPager::handle_interaction(ctx, &data, component).await {
|
|
} else {
|
|
let mode = component.data.custom_id.as_str();
|
|
match mode {
|
|
"#stop" => {
|
|
component
|
|
.create_interaction_response(ctx, |r| {
|
|
r.kind(InteractionResponseType::DeferredUpdateMessage)
|
|
})
|
|
.await
|
|
.unwrap();
|
|
|
|
let songbird = songbird::get(ctx).await.unwrap();
|
|
let call_opt = songbird.get(guild_id);
|
|
|
|
if let Some(call) = call_opt {
|
|
let mut lock = call.lock().await;
|
|
|
|
lock.stop();
|
|
}
|
|
}
|
|
|
|
"#loop" | "#queue" | "#instant" => {
|
|
component
|
|
.create_interaction_response(ctx, |r| {
|
|
r.kind(InteractionResponseType::UpdateMessage)
|
|
.interaction_response_data(|d| {
|
|
let mut c = vec![];
|
|
|
|
for action_row in &component.message.components {
|
|
let mut a: CreateActionRow = Default::default();
|
|
// These are always buttons
|
|
for component in &action_row.components {
|
|
match component {
|
|
ActionRowComponent::Button(button) => {
|
|
a.create_button(|b| {
|
|
if let Some(label) =
|
|
&button.label
|
|
{
|
|
b.label(label);
|
|
}
|
|
if let Some(emoji) =
|
|
&button.emoji
|
|
{
|
|
b.emoji(emoji.clone());
|
|
}
|
|
if let Some(custom_id) =
|
|
&button.custom_id
|
|
{
|
|
if custom_id
|
|
.starts_with('#')
|
|
{
|
|
b.custom_id(custom_id)
|
|
.disabled(
|
|
custom_id
|
|
== "#mode"
|
|
|| custom_id
|
|
== mode,
|
|
);
|
|
} else {
|
|
b.custom_id(format!(
|
|
"{}{}",
|
|
custom_id
|
|
.split('#')
|
|
.next()
|
|
.unwrap(),
|
|
mode
|
|
));
|
|
}
|
|
}
|
|
|
|
b.style(button.style);
|
|
|
|
b
|
|
});
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
c.push(a);
|
|
}
|
|
|
|
d.set_components(c)
|
|
})
|
|
})
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
id_mode => {
|
|
component
|
|
.create_interaction_response(ctx, |r| {
|
|
r.kind(InteractionResponseType::DeferredUpdateMessage)
|
|
})
|
|
.await
|
|
.unwrap();
|
|
|
|
let mut it = id_mode.split('#');
|
|
let id = it.next().unwrap();
|
|
let mode = it.next().unwrap_or("instant");
|
|
|
|
play_from_query(
|
|
&ctx,
|
|
&data,
|
|
guild_id.to_guild_cached(&ctx).unwrap(),
|
|
component.user.id,
|
|
None,
|
|
id.split('#').next().unwrap(),
|
|
mode == "loop",
|
|
)
|
|
.await;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
},
|
|
_ => {}
|
|
}
|
|
|
|
Ok(())
|
|
}
|