WIP: continued working on play and stop command, there are still errors and it does not work, it does compile though

This commit is contained in:
moonleay 2024-02-24 03:05:27 +01:00
parent a1a78d6598
commit 50202dfdf5
Signed by: moonleay
GPG key ID: 82667543CCD715FB
5 changed files with 132 additions and 27 deletions

4
.gitignore vendored
View file

@ -1,3 +1,5 @@
/target /target
/data /data
config.json config.json
.idea/

View file

@ -3,22 +3,24 @@ use serenity::all::{CommandDataOption, CommandDataOptionValue, CommandInteractio
use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter};
use serenity::model::application::CommandOptionType; use serenity::model::application::CommandOptionType;
use crate::util::user_util;
pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed {
let username = command.user.name.as_str(); let username = command.user.name.as_str();
let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S");
let options = &command.data.options; let options = &command.data.options;
let query = if let Some(CommandDataOption { let query = if let Some(CommandDataOption {
value: CommandDataOptionValue::String(query), .. value: CommandDataOptionValue::String(query), ..
}) = &options.first() }) = &options.first()
{ {
query query
} else { } else {
return CreateEmbed::new() return CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo")) .author(CreateEmbedAuthor::new("Rustendo"))
.title("Error 400") .title("Error 400")
.description("There is no query provied.") .description("There is no query provied.")
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username)))
}; };
let guild_id = match &command.guild_id { let guild_id = match &command.guild_id {
@ -26,14 +28,14 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed {
None => { None => {
return CreateEmbed::new() return CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo")) .author(CreateEmbedAuthor::new("Rustendo"))
.title("guildid not found") .title("GuildId not found")
.description("Could not find guild id.") .description("Could not find guild id.")
.footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username))); .footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username)));
} }
}; };
let (guild_id, channel_id) = { let (guild_id, channel_id) = {
let guild = &ctx.cache.guild(guild_id).unwrap(); let guild = &ctx.cache.guild(guild_id).unwrap(); // TODO: This unwrap throws errors.
// This may be unsafe, idk not sure yet // This may be unsafe, idk not sure yet
let channel_id = guild let channel_id = guild
.voice_states .voice_states
@ -52,26 +54,40 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed {
.footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username))); .footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username)));
}, },
}; };
let manager = &songbird::get(ctx) let manager = &songbird::get(ctx)
.await .await
.expect("") .expect("Cannot get Songbird.")
.clone(); .clone();
manager.join(guild_id, connect_to).await.expect("Cannot connect>..."); if !user_util::is_self_connected_to_vc(&ctx, &guild_id) {
// self is connected to vc, check if user is in same vc
let self_channel = user_util::get_self_vc_id(&ctx, &guild_id);
// Check if user is in the same VC as the bot
if self_channel != connect_to {
return CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo"))
.title("You are not in my VC.")
.description("Connect to my VC to control the music.")
.footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username)));
}
// Connect to VC
manager.join(guild_id, connect_to).await.expect("Cannot connect>...");
}
CreateEmbed::new() CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo")) .author(CreateEmbedAuthor::new("Rustendo"))
.title(format!("Searching for {}", query)) .title("Searching...")
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) .description(format!("Looking for {}", query))
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username)))
} }
pub fn register() -> CreateCommand { pub fn register() -> CreateCommand {
CreateCommand::new("play") CreateCommand::new("play")
.description("Play music") .description("Play music")
.add_option( .add_option(
CreateCommandOption::new(CommandOptionType::String, "query", "Link or search term") CreateCommandOption::new(CommandOptionType::String, "query", "Link or search term")
.required(true) .required(true)
) )
} }

View file

@ -2,13 +2,57 @@ use chrono::Local;
use serenity::all::{CommandInteraction, Context}; use serenity::all::{CommandInteraction, Context};
use serenity::builder::{CreateCommand, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; use serenity::builder::{CreateCommand, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter};
pub async fn run(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { use crate::util::user_util;
pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed {
let username = command.user.name.as_str(); let username = command.user.name.as_str();
let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S");
let guild_id = match &command.guild_id {
Some(guild_id) => guild_id,
None => {
return CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo"))
.title("GuildId not found")
.description("Could not find guild id.")
.footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username)));
}
};
if !user_util::is_self_connected_to_vc(&ctx, guild_id) {
// Bot is not connectd to vc; no need to dc
return CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo"))
.title("Bot is not connected")
.description("And therefore I cannot stop playing.")
.footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username)));
}
let manager = songbird::get(&ctx)
.await
.expect("Cannot get Songbird")
.clone();
let has_handler = manager.get(guild_id.clone()).is_some();
if has_handler {
if let Err(e) = manager.remove(guild_id.clone()).await {
return CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo"))
.title("There was an error")
.description(format!("Failed: {:?}", e))
.footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username)));
}
return CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo"))
.title("I stopped and left\nJust like your girlfriend.")
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username)))
}
CreateEmbed::new() CreateEmbed::new()
.author(CreateEmbedAuthor::new("Rustendo")) .author(CreateEmbedAuthor::new("Rustendo"))
.title("I stopped and left\nJust like your girlfriend.") .title("Bot is not connected")
.footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) .description("And therefore I cannot stop playing.\nSomething happend, which shouldn't have.")
.footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username)))
} }
@ -17,4 +61,4 @@ pub fn register() -> CreateCommand {
} }
// >18/02/2024 @ 19:01:59 - bartlo // >18/02/2024 @ 19:01:59 - bartlo
// >2024-02-19 17:58:39 | moonleay // >2024-02-19 17:58:39 | moonleay

View file

@ -1 +1,2 @@
pub mod config; pub mod config;
pub mod user_util;

42
src/util/user_util.rs Normal file
View file

@ -0,0 +1,42 @@
use serenity::all::{ChannelId, Context, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, GuildId};
pub fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool {
let self_id = &ctx.cache.current_user().id;
let (_guild_id, channel_id) = {
let guild = &ctx.cache.guild(guild_id).unwrap();
// This may be unsafe, idk not sure yet
let channel_id = guild
.voice_states
.get(self_id)
.and_then(|voice_state| voice_state.channel_id);
(guild.id, channel_id)
};
// TODO: There has to be a way to improve this. This is bad code and it should be optimized.
let connect_to = match channel_id {
Some(channel) => channel,
None => {
return false
},
};
true
}
// This whole file is jank. I have to rewrite this once I know Rust better
pub fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> ChannelId {
let self_id = &ctx.cache.current_user().id;
let (guild_id, channel_id) = {
let guild = &ctx.cache.guild(guild_id).unwrap();
// This may be unsafe, idk not sure yet
let channel_id = guild
.voice_states
.get(&self_id)
.and_then(|voice_state| voice_state.channel_id);
(guild.id, channel_id)
};
channel_id.unwrap()
}