Wip commit
This commit is contained in:
parent
cd5651c7f6
commit
07538f3277
1787
Cargo.lock
generated
1787
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
11
Cargo.toml
@ -7,17 +7,17 @@ authors = ["jellywx <judesouthworth@pm.me>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
songbird = { version = "0.3", features = ["builtin-queue"] }
|
||||
poise = "0.5.5"
|
||||
songbird = { version = "0.4", features = ["builtin-queue"] }
|
||||
poise = "0.6.1-rc1"
|
||||
sqlx = { version = "0.5", default-features = false, features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal", "migrate"] }
|
||||
tokio = { version = "1", features = ["fs", "process", "io-util"] }
|
||||
lazy_static = "1.4"
|
||||
reqwest = "0.11"
|
||||
env_logger = "0.10"
|
||||
regex = "1.4"
|
||||
regex = "1.10"
|
||||
log = "0.4"
|
||||
serde_json = "1.0"
|
||||
dashmap = "5.3"
|
||||
dashmap = "5.5"
|
||||
serde = "1.0"
|
||||
dotenv = "0.15.0"
|
||||
prometheus = { version = "0.13.3", optional = true }
|
||||
@ -26,9 +26,6 @@ axum = { version = "0.6.20", optional = true }
|
||||
[features]
|
||||
metrics = ["dep:prometheus", "dep:axum"]
|
||||
|
||||
[patch."https://github.com/serenity-rs/serenity"]
|
||||
serenity = { version = "0.11.6" }
|
||||
|
||||
[package.metadata.deb]
|
||||
features = ["metrics"]
|
||||
depends = "$auto, ffmpeg"
|
||||
|
@ -1,19 +1,23 @@
|
||||
use poise::{
|
||||
serenity_prelude::{CreateEmbed, CreateEmbedFooter},
|
||||
CreateReply,
|
||||
};
|
||||
|
||||
use crate::{consts::THEME_COLOR, Context, Error};
|
||||
|
||||
/// View bot commands
|
||||
#[poise::command(slash_command)]
|
||||
pub async fn help(ctx: Context<'_>) -> Result<(), Error> {
|
||||
ctx.send(|m| {
|
||||
m.ephemeral(true).embed(|e| {
|
||||
e.title("Help")
|
||||
ctx.send(
|
||||
CreateReply::new().ephemeral(true).embed(
|
||||
CreateEmbed::new()
|
||||
.title("Help")
|
||||
.color(THEME_COLOR)
|
||||
.footer(|f| {
|
||||
f.text(concat!(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
" ver ",
|
||||
env!("CARGO_PKG_VERSION")
|
||||
))
|
||||
})
|
||||
.footer(CreateEmbedFooter::new(concat!(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
" ver ",
|
||||
env!("CARGO_PKG_VERSION")
|
||||
)))
|
||||
.description(
|
||||
"__Info Commands__
|
||||
`/help` `/info`
|
||||
@ -49,9 +53,9 @@ __Setting Commands__
|
||||
|
||||
__Advanced Commands__
|
||||
`/soundboard` - Create a soundboard",
|
||||
)
|
||||
})
|
||||
})
|
||||
),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
@ -62,13 +66,17 @@ __Advanced Commands__
|
||||
pub async fn info(ctx: Context<'_>) -> Result<(), Error> {
|
||||
let current_user = ctx.serenity_context().cache.current_user();
|
||||
|
||||
ctx.send(|m| m.ephemeral(true)
|
||||
.embed(|e| e
|
||||
.title("Info")
|
||||
.color(THEME_COLOR)
|
||||
.footer(|f| f
|
||||
.text(concat!(env!("CARGO_PKG_NAME"), " ver ", env!("CARGO_PKG_VERSION"))))
|
||||
.description(format!("Invite me: https://discord.com/api/oauth2/authorize?client_id={}&permissions=3165184&scope=applications.commands%20bot
|
||||
ctx.send(
|
||||
CreateReply::new().ephemeral(true).embed(
|
||||
CreateEmbed::new()
|
||||
.title("Info")
|
||||
.color(THEME_COLOR)
|
||||
.footer(CreateEmbedFooter::new(concat!(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
" ver ",
|
||||
env!("CARGO_PKG_VERSION")
|
||||
)))
|
||||
.description(format!("Invite me: https://discord.com/api/oauth2/authorize?client_id={}&permissions=3165184&scope=applications.commands%20bot
|
||||
|
||||
**Welcome to SoundFX!**
|
||||
Developer: <@203532103185465344>
|
||||
@ -76,7 +84,9 @@ Find me on https://discord.jellywx.com/ and on https://github.com/JellyWX :)
|
||||
|
||||
**An online dashboard is available!** Visit https://soundfx.jellywx.com/dashboard
|
||||
There is a maximum sound limit per user. This can be removed by subscribing at **https://patreon.com/jellywx**",
|
||||
current_user.id.as_u64())))).await?;
|
||||
current_user.id.as_u64())))
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -63,11 +63,12 @@ pub async fn upload_new_sound(
|
||||
|
||||
// need to check if user is Patreon or not
|
||||
if count >= *MAX_SOUNDS {
|
||||
let patreon_guild_member =
|
||||
GuildId(*PATREON_GUILD).member(ctx, ctx.author().id).await;
|
||||
let patreon_guild_member = GuildId::from(*PATREON_GUILD)
|
||||
.member(ctx, ctx.author().id)
|
||||
.await;
|
||||
|
||||
if let Ok(member) = patreon_guild_member {
|
||||
permit_upload = member.roles.contains(&RoleId(*PATREON_ROLE));
|
||||
permit_upload = member.roles.contains(&RoleId::from(*PATREON_ROLE));
|
||||
} else {
|
||||
permit_upload = false;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use poise::serenity_prelude::AutocompleteChoice;
|
||||
|
||||
use crate::{models::sound::SoundCtx, Context};
|
||||
|
||||
pub mod favorite;
|
||||
@ -8,34 +10,22 @@ pub mod search;
|
||||
pub mod settings;
|
||||
pub mod stop;
|
||||
|
||||
pub async fn autocomplete_sound(
|
||||
ctx: Context<'_>,
|
||||
partial: &str,
|
||||
) -> Vec<poise::AutocompleteChoice<String>> {
|
||||
pub async fn autocomplete_sound(ctx: Context<'_>, partial: &str) -> Vec<AutocompleteChoice> {
|
||||
ctx.data()
|
||||
.autocomplete_user_sounds(&partial, ctx.author().id, ctx.guild_id().unwrap())
|
||||
.await
|
||||
.unwrap_or(vec![])
|
||||
.iter()
|
||||
.map(|s| poise::AutocompleteChoice {
|
||||
name: s.name.clone(),
|
||||
value: s.id.to_string(),
|
||||
})
|
||||
.map(|s| AutocompleteChoice::new(s.name.clone(), s.id.to_string()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub async fn autocomplete_favorite(
|
||||
ctx: Context<'_>,
|
||||
partial: &str,
|
||||
) -> Vec<poise::AutocompleteChoice<String>> {
|
||||
pub async fn autocomplete_favorite(ctx: Context<'_>, partial: &str) -> Vec<AutocompleteChoice> {
|
||||
ctx.data()
|
||||
.autocomplete_favorite_sounds(&partial, ctx.author().id)
|
||||
.await
|
||||
.unwrap_or(vec![])
|
||||
.iter()
|
||||
.map(|s| poise::AutocompleteChoice {
|
||||
name: s.name.clone(),
|
||||
value: s.id.to_string(),
|
||||
})
|
||||
.map(|s| AutocompleteChoice::new(s.name.clone(), s.id.to_string()))
|
||||
.collect()
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use poise::serenity_prelude::{
|
||||
builder::CreateActionRow, model::application::component::ButtonStyle, GuildChannel,
|
||||
ReactionType,
|
||||
};
|
||||
use poise::serenity_prelude::{builder::CreateActionRow, ButtonStyle, GuildChannel, ReactionType};
|
||||
|
||||
#[cfg(feature = "metrics")]
|
||||
use crate::metrics::PLAY_COUNTER;
|
||||
|
@ -1,10 +1,8 @@
|
||||
use poise::{
|
||||
serenity_prelude,
|
||||
serenity_prelude::{
|
||||
application::component::ButtonStyle,
|
||||
constants::MESSAGE_CODE_LIMIT,
|
||||
interaction::{message_component::MessageComponentInteraction, InteractionResponseType},
|
||||
CreateActionRow, CreateEmbed, GuildId, UserId,
|
||||
constants::MESSAGE_CODE_LIMIT, ButtonStyle, ComponentInteraction, CreateActionRow,
|
||||
CreateEmbed, EditInteractionResponse, GuildId, UserId,
|
||||
},
|
||||
CreateReply,
|
||||
};
|
||||
@ -16,7 +14,7 @@ use crate::{
|
||||
Context, Data, Error,
|
||||
};
|
||||
|
||||
fn format_search_results<'a>(search_results: Vec<Sound>) -> CreateReply<'a> {
|
||||
fn format_search_results(search_results: Vec<Sound>) -> CreateReply {
|
||||
let mut builder = CreateReply::default();
|
||||
|
||||
let mut current_character_count = 0;
|
||||
@ -213,7 +211,7 @@ impl SoundPager {
|
||||
pub async fn handle_interaction(
|
||||
ctx: &serenity_prelude::Context,
|
||||
data: &Data,
|
||||
interaction: &MessageComponentInteraction,
|
||||
interaction: &ComponentInteraction,
|
||||
) -> Result<(), Error> {
|
||||
let user_id = interaction.user.id;
|
||||
let guild_id = interaction.guild_id.unwrap();
|
||||
@ -226,18 +224,11 @@ impl SoundPager {
|
||||
ListContext::Guild => data.count_guild_sounds(guild_id).await?,
|
||||
};
|
||||
|
||||
interaction
|
||||
.create_interaction_response(&ctx, |r| {
|
||||
r.kind(InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.ephemeral(true)
|
||||
.add_embed(pager.embed(&sounds, count))
|
||||
.components(|c| c.add_action_row(pager.create_action_row(count / 25)))
|
||||
})
|
||||
})
|
||||
.await?;
|
||||
let response = EditInteractionResponse::default()
|
||||
.add_embed(pager.embed(&sounds, count))
|
||||
.components(|c| c.add_action_row(pager.create_action_row(count / 25)));
|
||||
|
||||
Ok(())
|
||||
interaction.Ok(())
|
||||
}
|
||||
|
||||
async fn reply(&self, ctx: Context<'_>) -> Result<(), Error> {
|
||||
|
@ -1,9 +1,6 @@
|
||||
use poise::serenity_prelude::{
|
||||
model::{
|
||||
application::interaction::{Interaction, InteractionResponseType},
|
||||
channel::Channel,
|
||||
},
|
||||
ActionRowComponent, Activity, Context, CreateActionRow, CreateComponents,
|
||||
model::channel::Channel, ActionRowComponent, Activity, Context, CreateActionRow, FullEvent,
|
||||
Interaction,
|
||||
};
|
||||
|
||||
#[cfg(feature = "metrics")]
|
||||
@ -19,16 +16,18 @@ use crate::{
|
||||
Data, Error,
|
||||
};
|
||||
|
||||
pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> Result<(), Error> {
|
||||
pub async fn listener(ctx: &Context, event: &FullEvent, data: &Data) -> Result<(), Error> {
|
||||
match event {
|
||||
poise::Event::Ready { .. } => {
|
||||
FullEvent::Ready { .. } => {
|
||||
ctx.set_activity(Activity::watching("for /play")).await;
|
||||
}
|
||||
poise::Event::VoiceStateUpdate { old, new, .. } => {
|
||||
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) {
|
||||
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();
|
||||
|
||||
@ -93,7 +92,7 @@ pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> R
|
||||
}
|
||||
}
|
||||
}
|
||||
poise::Event::InteractionCreate { interaction } => match interaction {
|
||||
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 {
|
||||
|
33
src/main.rs
33
src/main.rs
@ -13,13 +13,11 @@ mod utils;
|
||||
use std::{env, path::Path, sync::Arc};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use poise::serenity_prelude::{
|
||||
builder::CreateApplicationCommands,
|
||||
model::{
|
||||
gateway::GatewayIntents,
|
||||
id::{GuildId, UserId},
|
||||
},
|
||||
use poise::serenity_prelude::model::{
|
||||
gateway::GatewayIntents,
|
||||
id::{GuildId, UserId},
|
||||
};
|
||||
use serde_json::Value;
|
||||
use songbird::SerenityInit;
|
||||
use sqlx::{MySql, Pool};
|
||||
use tokio::sync::RwLock;
|
||||
@ -40,29 +38,20 @@ type Context<'a> = poise::Context<'a, Data, Error>;
|
||||
pub async fn register_application_commands(
|
||||
ctx: &poise::serenity_prelude::Context,
|
||||
framework: &poise::Framework<Data, Error>,
|
||||
guild_id: Option<GuildId>,
|
||||
) -> Result<(), poise::serenity_prelude::Error> {
|
||||
let mut commands_builder = CreateApplicationCommands::default();
|
||||
let mut commands_builder = vec![];
|
||||
let commands = &framework.options().commands;
|
||||
for command in commands {
|
||||
if let Some(slash_command) = command.create_as_slash_command() {
|
||||
commands_builder.add_application_command(slash_command);
|
||||
commands_builder.push(slash_command.into());
|
||||
}
|
||||
if let Some(context_menu_command) = command.create_as_context_menu_command() {
|
||||
commands_builder.add_application_command(context_menu_command);
|
||||
commands_builder.push(context_menu_command.into());
|
||||
}
|
||||
}
|
||||
let commands_builder = poise::serenity_prelude::json::Value::Array(commands_builder.0);
|
||||
let commands_builder = Value::Array(commands_builder);
|
||||
|
||||
if let Some(guild_id) = guild_id {
|
||||
ctx.http
|
||||
.create_guild_application_commands(guild_id.0, &commands_builder)
|
||||
.await?;
|
||||
} else {
|
||||
ctx.http
|
||||
.create_global_application_commands(&commands_builder)
|
||||
.await?;
|
||||
}
|
||||
ctx.http.create_global_commands(&commands_builder).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -153,9 +142,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
.token(discord_token)
|
||||
.setup(move |ctx, _bot, framework| {
|
||||
Box::pin(async move {
|
||||
register_application_commands(ctx, framework, None)
|
||||
.await
|
||||
.unwrap();
|
||||
register_application_commands(ctx, framework).await.unwrap();
|
||||
|
||||
Ok(Data {
|
||||
database,
|
||||
|
@ -78,12 +78,10 @@ impl GuildData {
|
||||
|
||||
let guild_data = sqlx::query_as_unchecked!(
|
||||
GuildData,
|
||||
"
|
||||
SELECT id, prefix, volume, allow_greets, allowed_role
|
||||
FROM servers
|
||||
WHERE id = ?
|
||||
",
|
||||
guild_id.as_u64()
|
||||
"SELECT id, prefix, volume, allow_greets, allowed_role
|
||||
FROM servers
|
||||
WHERE id = ?",
|
||||
guild_id
|
||||
)
|
||||
.fetch_one(db_pool)
|
||||
.await;
|
||||
@ -104,17 +102,15 @@ SELECT id, prefix, volume, allow_greets, allowed_role
|
||||
let guild_id = guild_id.into();
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
INSERT INTO servers (id)
|
||||
VALUES (?)
|
||||
",
|
||||
guild_id.as_u64()
|
||||
"INSERT INTO servers (id)
|
||||
VALUES (?)",
|
||||
guild_id
|
||||
)
|
||||
.execute(db_pool)
|
||||
.await?;
|
||||
|
||||
Ok(GuildData {
|
||||
id: guild_id.as_u64().to_owned(),
|
||||
id: guild_id.get(),
|
||||
prefix: String::from("?"),
|
||||
volume: 100,
|
||||
allow_greets: AllowGreet::Enabled,
|
||||
|
@ -47,13 +47,12 @@ impl JoinSoundCtx for Data {
|
||||
sqlx::query_as!(
|
||||
JoinSound,
|
||||
"
|
||||
SELECT join_sound_id
|
||||
FROM join_sounds
|
||||
WHERE user = ?
|
||||
AND guild = ?
|
||||
ORDER BY guild IS NULL
|
||||
",
|
||||
user_id.as_u64(),
|
||||
SELECT join_sound_id
|
||||
FROM join_sounds
|
||||
WHERE user = ?
|
||||
AND guild = ?
|
||||
ORDER BY guild IS NULL",
|
||||
user_id,
|
||||
guild_id.map(|g| g.0)
|
||||
)
|
||||
.fetch_one(&self.database)
|
||||
@ -62,13 +61,12 @@ SELECT join_sound_id
|
||||
sqlx::query_as!(
|
||||
JoinSound,
|
||||
"
|
||||
SELECT join_sound_id
|
||||
FROM join_sounds
|
||||
WHERE user = ?
|
||||
AND (guild IS NULL OR guild = ?)
|
||||
ORDER BY guild IS NULL
|
||||
",
|
||||
user_id.as_u64(),
|
||||
SELECT join_sound_id
|
||||
FROM join_sounds
|
||||
WHERE user = ?
|
||||
AND (guild IS NULL OR guild = ?)
|
||||
ORDER BY guild IS NULL",
|
||||
user_id,
|
||||
guild_id.map(|g| g.0)
|
||||
)
|
||||
.fetch_one(&self.database)
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::{env, path::Path};
|
||||
|
||||
use poise::serenity_prelude::async_trait;
|
||||
use songbird::input::restartable::Restartable;
|
||||
use songbird::input::Input;
|
||||
use sqlx::Executor;
|
||||
use tokio::{fs::File, io::AsyncWriteExt, process::Command};
|
||||
|
||||
@ -441,12 +441,10 @@ impl Sound {
|
||||
pub async fn playable(
|
||||
&self,
|
||||
db_pool: impl Executor<'_, Database = Database>,
|
||||
) -> Result<Restartable, Box<dyn std::error::Error + Send + Sync>> {
|
||||
) -> Result<Input, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let path_name = self.store_sound_source(db_pool).await?;
|
||||
|
||||
Ok(Restartable::ffmpeg(path_name, false)
|
||||
.await
|
||||
.expect("FFMPEG ERROR!"))
|
||||
Ok(Input::from(path_name))
|
||||
}
|
||||
|
||||
pub async fn count_user_sounds<U: Into<u64>>(
|
||||
|
57
src/utils.rs
57
src/utils.rs
@ -1,11 +1,14 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use poise::serenity_prelude::model::{
|
||||
channel::Channel,
|
||||
guild::Guild,
|
||||
id::{ChannelId, UserId},
|
||||
use poise::serenity_prelude::{
|
||||
model::{
|
||||
channel::Channel,
|
||||
guild::Guild,
|
||||
id::{ChannelId, UserId},
|
||||
},
|
||||
GuildRef,
|
||||
};
|
||||
use songbird::{create_player, error::JoinResult, tracks::TrackHandle, Call};
|
||||
use songbird::{error::JoinResult, tracks::TrackHandle, Call};
|
||||
use sqlx::Executor;
|
||||
use tokio::sync::{Mutex, MutexGuard};
|
||||
|
||||
@ -24,19 +27,18 @@ pub async fn play_audio(
|
||||
db_pool: impl Executor<'_, Database = Database>,
|
||||
r#loop: bool,
|
||||
) -> Result<TrackHandle, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let (track, track_handler) = create_player(sound.playable(db_pool).await?.into());
|
||||
let track = sound.playable(db_pool).await?;
|
||||
let handle = call_handler.play_source(track);
|
||||
|
||||
let _ = track_handler.set_volume(volume as f32 / 100.0);
|
||||
handle.set_volume(volume as f32 / 100.0)?;
|
||||
|
||||
if r#loop {
|
||||
let _ = track_handler.enable_loop();
|
||||
handle.enable_loop()?;
|
||||
} else {
|
||||
let _ = track_handler.disable_loop();
|
||||
handle.disable_loop()?;
|
||||
}
|
||||
|
||||
call_handler.play(track);
|
||||
|
||||
Ok(track_handler)
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
pub async fn queue_audio(
|
||||
@ -46,11 +48,10 @@ pub async fn queue_audio(
|
||||
db_pool: impl Executor<'_, Database = Database> + Copy,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
for sound in sounds {
|
||||
let (a, b) = create_player(sound.playable(db_pool).await?.into());
|
||||
let track = sound.playable(db_pool).await?;
|
||||
let handle = call_handler.enqueue_source(track);
|
||||
|
||||
let _ = b.set_volume(volume as f32 / 100.0);
|
||||
|
||||
call_handler.enqueue(a);
|
||||
handle.set_volume(volume as f32 / 100.0)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -58,31 +59,28 @@ pub async fn queue_audio(
|
||||
|
||||
pub async fn join_channel(
|
||||
ctx: &poise::serenity_prelude::Context,
|
||||
guild: Guild,
|
||||
guild: impl AsRef<Guild>,
|
||||
channel_id: ChannelId,
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<()>) {
|
||||
) -> Arc<Mutex<Call>> {
|
||||
let songbird = songbird::get(ctx).await.unwrap();
|
||||
let current_user = ctx.cache.current_user_id();
|
||||
|
||||
let current_voice_state = guild
|
||||
.as_ref()
|
||||
.voice_states
|
||||
.get(¤t_user)
|
||||
.and_then(|voice_state| voice_state.channel_id);
|
||||
|
||||
let (call, res) = if current_voice_state == Some(channel_id) {
|
||||
let call_opt = songbird.get(guild.id);
|
||||
let call = if current_voice_state == Some(channel_id) {
|
||||
let call_opt = songbird.get(guild.as_ref().id);
|
||||
|
||||
if let Some(call) = call_opt {
|
||||
(call, Ok(()))
|
||||
Ok(call)
|
||||
} else {
|
||||
let (call, res) = songbird.join(guild.id, channel_id).await;
|
||||
|
||||
(call, res)
|
||||
songbird.join(guild.as_ref().id, channel_id).await
|
||||
}
|
||||
} else {
|
||||
let (call, res) = songbird.join(guild.id, channel_id).await;
|
||||
|
||||
(call, res)
|
||||
songbird.join(guild.as_ref().id, channel_id).await
|
||||
};
|
||||
|
||||
{
|
||||
@ -96,7 +94,7 @@ pub async fn join_channel(
|
||||
.await;
|
||||
}
|
||||
|
||||
(call, res)
|
||||
call
|
||||
}
|
||||
|
||||
pub async fn play_from_query(
|
||||
@ -129,8 +127,7 @@ pub async fn play_from_query(
|
||||
match sound_res {
|
||||
Some(sound) => {
|
||||
{
|
||||
let (call_handler, _) =
|
||||
join_channel(ctx, guild.clone(), user_channel).await;
|
||||
let call_handler = join_channel(ctx, guild.clone(), user_channel).await;
|
||||
|
||||
let guild_data = data.guild_data(guild_id).await.unwrap();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user