From ba42e009f4ea6e43f417d3eda2efed84f0869bf3 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Fri, 23 Feb 2024 19:22:19 +0100 Subject: [PATCH 01/41] fix: `interaction_create` event --- src/main.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/main.rs b/src/main.rs index 725a7a0..a65cf25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,12 +41,12 @@ struct Handler; impl EventHandler for Handler { async fn interaction_create(&self, ctx: Context, interaction: Interaction) { if let Interaction::Command(command) = interaction { - let content = match command.data.name.as_str() { - "info" => Some(commands::info::run(&ctx, &command)), - "play" => Some(commands::play::run(&ctx, &command)), - "stop" => Some(commands::stop::run(&ctx, &command)), - _ => Some(respond_with_error(&ctx, &command)), - }; + let content = Some(match command.data.name.as_str() { + "info" => commands::info::run(&ctx, &command).await, + "play" => commands::play::run(&ctx, &command).await, + "stop" => commands::stop::run(&ctx, &command).await, + _ => respond_with_error(&ctx, &command).await, + }); if let Some(embed) = content { let data = CreateInteractionResponseMessage::new().embed(embed); @@ -72,25 +72,24 @@ impl EventHandler for Handler { pub async fn respond_with_error(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = &command.user.name.as_str(); let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); - + CreateEmbed::new() .author(CreateEmbedAuthor::new("Rustendo")) .title("Command not found") .description("Cannot find the executed command") - .footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username))) + .footer(CreateEmbedFooter::new(format!( + "> {} | {}", + current_time, username } #[tokio::main] async fn main() { - println!(r"__________ __ .___ -\______ \__ __ _______/ |_ ____ ____ __| _/____ - | _/ | | ___/\ __\_/ __ \ / \ / __ |/ _ \ + println!( | | \ | |___ \ | | \ ___/ | | | /_/ ( <_> ) |____|_ /____/____ > |__| \___ >|___| |____ |\____/ \/ \/ \/ \/ \/ "); - // Load config let config = config::load().unwrap(); // Set status @@ -111,9 +110,7 @@ async fn main() { // // Shards will automatically attempt to reconnect, and will perform exponential backoff until // it reconnects. - if let Err(why) = client - .start() - .await { + if let Err(why) = client.start().await { println!("Client error: {why:?}"); } } From 1fd1bc893c10f5929c8abb477d4b6c0068ce10a6 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Fri, 23 Feb 2024 19:25:19 +0100 Subject: [PATCH 02/41] chore: formatting --- src/main.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main.rs b/src/main.rs index a65cf25..6f003ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,14 @@ mod commands; -mod util; mod handler; +mod util; -use std::thread::current; use chrono::Local; use serenity::all::{CommandInteraction, OnlineStatus}; use serenity::async_trait; -use serenity::builder::{CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, CreateInteractionResponse, CreateInteractionResponseMessage}; +use serenity::builder::{ + CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, CreateInteractionResponse, + CreateInteractionResponseMessage, +}; use serenity::gateway::ActivityData; use serenity::model::application::{Command, Interaction}; use serenity::model::gateway::Ready; @@ -18,18 +20,9 @@ use util::config; // The voice client can be retrieved in any command using `songbird::get(ctx).await`. use songbird::SerenityInit; -// Event related imports to detect track creation failures. -use songbird::events::{Event, EventContext, EventHandler as VoiceEventHandler, TrackEvent}; - -// To turn user URLs into playable audio, we'll use yt-dlp. -use songbird::input::YoutubeDl; - // YtDl requests need an HTTP client to operate -- we'll create and store our own. use reqwest::Client as HttpClient; -// Import the `Context` to handle commands. -use serenity::client::Context; - struct HttpKey; impl TypeMapKey for HttpKey { type Value = HttpClient; @@ -80,15 +73,20 @@ pub async fn respond_with_error(_ctx: &Context, command: &CommandInteraction) -> .footer(CreateEmbedFooter::new(format!( "> {} | {}", current_time, username + ))) } #[tokio::main] async fn main() { println!( + r"__________ __ .___ +\______ \__ __ _______/ |_ ____ ____ __| _/____ + | _/ | | ___/\ __\_/ __ \ / \ / __ |/ _ \ | | \ | |___ \ | | \ ___/ | | | /_/ ( <_> ) - |____|_ /____/____ > |__| \___ >|___| |____ |\____/ - \/ \/ \/ \/ \/ -"); + |____|_ /____/____ > |__| \___ >|___| |____ |\____/ + \/ \/ \/ \/ \/ +" + ); // Load config let config = config::load().unwrap(); From 50202dfdf58da7c21fe05421380d6e874cea64d3 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sat, 24 Feb 2024 03:05:27 +0100 Subject: [PATCH 03/41] WIP: continued working on play and stop command, there are still errors and it does not work, it does compile though --- .gitignore | 4 +++- src/commands/play.rs | 56 +++++++++++++++++++++++++++---------------- src/commands/stop.rs | 54 +++++++++++++++++++++++++++++++++++++---- src/util/mod.rs | 3 ++- src/util/user_util.rs | 42 ++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 27 deletions(-) create mode 100644 src/util/user_util.rs diff --git a/.gitignore b/.gitignore index f680304..5de384b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /target /data -config.json \ No newline at end of file +config.json + +.idea/ diff --git a/src/commands/play.rs b/src/commands/play.rs index 874c8e9..9d536ea 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -3,22 +3,24 @@ use serenity::all::{CommandDataOption, CommandDataOptionValue, CommandInteractio use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; use serenity::model::application::CommandOptionType; +use crate::util::user_util; + pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); let options = &command.data.options; let query = if let Some(CommandDataOption { - value: CommandDataOptionValue::String(query), .. - }) = &options.first() + value: CommandDataOptionValue::String(query), .. + }) = &options.first() { query } else { return CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("Error 400") - .description("There is no query provied.") - .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) + .author(CreateEmbedAuthor::new("Rustendo")) + .title("Error 400") + .description("There is no query provied.") + .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) }; let guild_id = match &command.guild_id { @@ -26,14 +28,14 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { None => { return CreateEmbed::new() .author(CreateEmbedAuthor::new("Rustendo")) - .title("guildid not found") + .title("GuildId not found") .description("Could not find guild id.") .footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username))); } }; - + 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 let channel_id = guild .voice_states @@ -52,26 +54,40 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { .footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username))); }, }; - + let manager = &songbird::get(ctx) .await - .expect("") + .expect("Cannot get Songbird.") .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() - .author(CreateEmbedAuthor::new("Rustendo")) - .title(format!("Searching for {}", query)) - .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) + .author(CreateEmbedAuthor::new("Rustendo")) + .title("Searching...") + .description(format!("Looking for {}", query)) + .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) } pub fn register() -> CreateCommand { CreateCommand::new("play") - .description("Play music") - .add_option( - CreateCommandOption::new(CommandOptionType::String, "query", "Link or search term") - .required(true) - ) + .description("Play music") + .add_option( + CreateCommandOption::new(CommandOptionType::String, "query", "Link or search term") + .required(true) + ) } diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 261934a..c7333dc 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -2,13 +2,57 @@ use chrono::Local; use serenity::all::{CommandInteraction, Context}; 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 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() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("I stopped and left\nJust like your girlfriend.") - .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) + .author(CreateEmbedAuthor::new("Rustendo")) + .title("Bot is not connected") + .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 -// >2024-02-19 17:58:39 | moonleay \ No newline at end of file +// >2024-02-19 17:58:39 | moonleay diff --git a/src/util/mod.rs b/src/util/mod.rs index a105933..1a9154c 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1 +1,2 @@ -pub mod config; \ No newline at end of file +pub mod config; +pub mod user_util; \ No newline at end of file diff --git a/src/util/user_util.rs b/src/util/user_util.rs new file mode 100644 index 0000000..4ea3778 --- /dev/null +++ b/src/util/user_util.rs @@ -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() + +} From 2c82dbb0196bd06c2d5677ac5ea92e01fcd9080e Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 3 Mar 2024 23:30:31 +0100 Subject: [PATCH 04/41] fix: several improvements --- .gitignore | 3 + Cargo.lock | 326 +++++++++++++++++++++++++++--------------- src/commands/info.rs | 19 +-- src/commands/play.rs | 115 ++++++++------- src/commands/stop.rs | 58 ++++---- src/main.rs | 24 +--- src/util/config.rs | 12 +- src/util/embed.rs | 29 ++++ src/util/mod.rs | 3 +- src/util/user_util.rs | 64 ++++----- 10 files changed, 384 insertions(+), 269 deletions(-) create mode 100644 src/util/embed.rs diff --git a/.gitignore b/.gitignore index 5de384b..53fe865 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ config.json .idea/ +.zed + +.DS_Store diff --git a/Cargo.lock b/Cargo.lock index 0f40128..cd4694e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -208,9 +208,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" [[package]] name = "cfg-if" @@ -230,7 +230,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.3", + "windows-targets 0.52.4", ] [[package]] @@ -266,9 +266,9 @@ dependencies = [ [[package]] name = "confy" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d296c475c6ed4093824c28e222420831d27577aaaf0a1163a3b7fc35b248a5" +checksum = "45b1f4c00870f07dc34adcac82bb6a72cc5aabca8536ba1797e01df51d2ce9a0" dependencies = [ "directories", "serde", @@ -312,9 +312,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ "crossbeam-utils", ] @@ -467,6 +467,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "extended" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" + [[package]] name = "fastrand" version = "2.0.1" @@ -581,7 +587,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -625,11 +631,12 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +checksum = "b5b25e5b3e733153bcab35ee4671b46604b42516163cae442d1601cb716f2ac5" dependencies = [ "cc", + "cfg-if", "libc", "log", "rustversion", @@ -683,7 +690,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.11", "indexmap", "slab", "tokio", @@ -699,9 +706,9 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hermit-abi" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "http" @@ -714,6 +721,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -721,7 +739,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.11", "pin-project-lite", ] @@ -748,7 +766,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", + "http 0.2.11", "http-body", "httparse", "httpdate", @@ -768,7 +786,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", + "http 0.2.11", "hyper", "rustls 0.21.10", "tokio", @@ -799,7 +817,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -823,9 +841,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown", @@ -908,9 +926,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "loom" @@ -984,9 +1002,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", @@ -1102,9 +1120,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" @@ -1129,7 +1147,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -1217,7 +1235,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -1256,7 +1274,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -1444,7 +1462,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", + "http 0.2.11", "http-body", "hyper", "hyper-rustls", @@ -1475,7 +1493,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 0.25.4", "winreg", ] @@ -1603,10 +1621,24 @@ checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring 0.17.8", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -1628,6 +1660,12 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pki-types" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -1638,6 +1676,17 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -1792,7 +1841,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -1814,7 +1863,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -1840,9 +1889,9 @@ dependencies = [ [[package]] name = "serenity" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385647faa24a889929028973650a4f158fb1b4272b2fcf94feb9fcc3c009e813" +checksum = "c64da29158bb55d70677cacd4f4f8eab1acef005fb830d9c3bea411b090e96a9" dependencies = [ "arrayvec", "async-trait", @@ -1866,7 +1915,7 @@ dependencies = [ "static_assertions", "time", "tokio", - "tokio-tungstenite 0.20.1", + "tokio-tungstenite 0.21.0", "tracing", "typemap_rev", "typesize", @@ -1958,9 +2007,9 @@ dependencies = [ [[package]] name = "songbird" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b905d2cdd4becf0e643a4aa5491cdfe8f193d5676b5bae7c0460e0e3c6358d63" +checksum = "54d70e66a385ea8f732afac37b6ff2a8334eccac9aeed3d162a3c550b059233a" dependencies = [ "async-trait", "audiopus", @@ -1990,7 +2039,7 @@ dependencies = [ "symphonia", "symphonia-core", "tokio", - "tokio-tungstenite 0.20.1", + "tokio-tungstenite 0.21.0", "tokio-util", "tracing", "tracing-futures", @@ -2046,9 +2095,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "symphonia" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e48dba70095f265fdb269b99619b95d04c89e619538138383e63310b14d941" +checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9" dependencies = [ "lazy_static", "symphonia-bundle-flac", @@ -2058,15 +2107,15 @@ dependencies = [ "symphonia-core", "symphonia-format-mkv", "symphonia-format-ogg", - "symphonia-format-wav", + "symphonia-format-riff", "symphonia-metadata", ] [[package]] name = "symphonia-bundle-flac" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f23b0482a7cb18fcdf9981ab0b78df800ef0080187d294650023c462439058d" +checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97" dependencies = [ "log", "symphonia-core", @@ -2076,9 +2125,9 @@ dependencies = [ [[package]] name = "symphonia-codec-adpcm" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870e7dc1865d818c7b6318879d060553a73a3b2a3b8443dff90910f10ac41150" +checksum = "c94e1feac3327cd616e973d5be69ad36b3945f16b06f19c6773fc3ac0b426a0f" dependencies = [ "log", "symphonia-core", @@ -2086,9 +2135,9 @@ dependencies = [ [[package]] name = "symphonia-codec-pcm" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47f1fbd220a06a641c8ce2ddad10f5ef6ee5cc0c54d9044d25d43b0d3119deaa" +checksum = "f395a67057c2ebc5e84d7bb1be71cce1a7ba99f64e0f0f0e303a03f79116f89b" dependencies = [ "log", "symphonia-core", @@ -2096,9 +2145,9 @@ dependencies = [ [[package]] name = "symphonia-codec-vorbis" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3953397e3506aa01350c4205817e4f95b58d476877a42f0458d07b665749e203" +checksum = "5a98765fb46a0a6732b007f7e2870c2129b6f78d87db7987e6533c8f164a9f30" dependencies = [ "log", "symphonia-core", @@ -2107,9 +2156,9 @@ dependencies = [ [[package]] name = "symphonia-core" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c73eb88fee79705268cc7b742c7bc93a7b76e092ab751d0833866970754142" +checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3" dependencies = [ "arrayvec", "bitflags 1.3.2", @@ -2120,9 +2169,9 @@ dependencies = [ [[package]] name = "symphonia-format-mkv" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5c61dfc851ad25d4043d8c231d8617e8f7cd02a6cc0edad21ade21848d58895" +checksum = "1bb43471a100f7882dc9937395bd5ebee8329298e766250b15b3875652fe3d6f" dependencies = [ "lazy_static", "log", @@ -2133,9 +2182,9 @@ dependencies = [ [[package]] name = "symphonia-format-ogg" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf1a00ccd11452d44048a0368828040f778ae650418dbd9d8765b7ee2574c8d" +checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931" dependencies = [ "log", "symphonia-core", @@ -2144,11 +2193,12 @@ dependencies = [ ] [[package]] -name = "symphonia-format-wav" -version = "0.5.3" +name = "symphonia-format-riff" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da76614728fa27c003bdcdfbac51396bd8fcbf94c95fe8e62f1d2bac58ef03a4" +checksum = "05f7be232f962f937f4b7115cbe62c330929345434c834359425e043bfd15f50" dependencies = [ + "extended", "log", "symphonia-core", "symphonia-metadata", @@ -2156,9 +2206,9 @@ dependencies = [ [[package]] name = "symphonia-metadata" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c3e1937e31d0e068bbe829f66b2f2bfaa28d056365279e0ef897172c3320c0" +checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c" dependencies = [ "encoding_rs", "lazy_static", @@ -2168,9 +2218,9 @@ dependencies = [ [[package]] name = "symphonia-utils-xiph" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a450ca645b80d69aff8b35576cbfdc7f20940b29998202aab910045714c951f8" +checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe" dependencies = [ "symphonia-core", "symphonia-metadata", @@ -2189,9 +2239,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.50" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -2233,9 +2283,9 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", @@ -2260,7 +2310,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -2345,7 +2395,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -2379,6 +2429,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.2", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-tungstenite" version = "0.18.0" @@ -2397,17 +2458,18 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", - "rustls 0.21.10", + "rustls 0.22.2", + "rustls-pki-types", "tokio", - "tokio-rustls 0.24.1", - "tungstenite 0.20.1", - "webpki-roots", + "tokio-rustls 0.25.0", + "tungstenite 0.21.0", + "webpki-roots 0.26.1", ] [[package]] @@ -2484,7 +2546,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -2567,7 +2629,7 @@ dependencies = [ "base64 0.13.1", "byteorder", "bytes", - "http", + "http 0.2.11", "httparse", "log", "rand", @@ -2581,18 +2643,19 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.0.0", "httparse", "log", "rand", - "rustls 0.21.10", + "rustls 0.22.2", + "rustls-pki-types", "sha1", "thiserror", "url", @@ -2680,7 +2743,7 @@ checksum = "0b122284365ba8497be951b9a21491f70c9688eb6fddc582931a0703f6a00ece" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", ] [[package]] @@ -2788,9 +2851,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -2832,7 +2895,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", "wasm-bindgen-shared", ] @@ -2866,7 +2929,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2916,6 +2979,15 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2949,11 +3021,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.48.0" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538" dependencies = [ - "windows-targets 0.48.5", + "windows-core 0.53.0", + "windows-targets 0.52.4", ] [[package]] @@ -2962,7 +3035,26 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-core" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd" +dependencies = [ + "windows-result", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-result" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" +dependencies = [ + "windows-targets 0.52.4", ] [[package]] @@ -2980,7 +3072,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.4", ] [[package]] @@ -3000,17 +3092,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.3", - "windows_aarch64_msvc 0.52.3", - "windows_i686_gnu 0.52.3", - "windows_i686_msvc 0.52.3", - "windows_x86_64_gnu 0.52.3", - "windows_x86_64_gnullvm 0.52.3", - "windows_x86_64_msvc 0.52.3", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -3021,9 +3113,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -3033,9 +3125,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -3045,9 +3137,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -3057,9 +3149,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -3069,9 +3161,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -3081,9 +3173,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -3093,15 +3185,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winnow" -version = "0.6.2" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4191c47f15cc3ec71fcb4913cb83d58def65dd3787610213c649283b5ce178" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" dependencies = [ "memchr", ] diff --git a/src/commands/info.rs b/src/commands/info.rs index df43b6b..4dc5807 100644 --- a/src/commands/info.rs +++ b/src/commands/info.rs @@ -1,20 +1,21 @@ -use chrono::Local; use serenity::all::{CommandInteraction, Context}; -use serenity::builder::{CreateCommand, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; +use serenity::builder::{CreateCommand, CreateEmbed}; + +use crate::util::embed::Embed; pub async fn run(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); - let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); - CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .description("Botendo v7\ndeveloped by [moonleay](https://moonleay.net)\n\nCheck out the repository: https://git.moonleay.net/DiscordBots/Rustendo") - .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) -} + Embed::create( + username, + "", + "Botendo v7\ndeveloped by [moonleay](https://moonleay.net)\n\nCheck out the repository: https://git.moonleay.net/DiscordBots/Rustendo", + ) +} pub fn register() -> CreateCommand { CreateCommand::new("info").description("Infos about the bot") } // >18/02/2024 @ 19:01:59 - bartlo -// >2024-02-19 17:58:39 | moonleay \ No newline at end of file +// >2024-02-19 17:58:39 | moonleay diff --git a/src/commands/play.rs b/src/commands/play.rs index 9d536ea..3791885 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -1,93 +1,104 @@ -use chrono::Local; -use serenity::all::{CommandDataOption, CommandDataOptionValue, CommandInteraction, Context, ResolvedOption, ResolvedValue}; -use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; +use serenity::all::{CommandDataOption, CommandDataOptionValue, CommandInteraction, Context}; +use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed}; use serenity::model::application::CommandOptionType; -use crate::util::user_util; +use crate::util::embed::Embed; +use crate::util::user_util::{self, get_guild}; pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); - let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); let options = &command.data.options; - let query = if let Some(CommandDataOption { - value: CommandDataOptionValue::String(query), .. - }) = &options.first() - { - query - } else { - return CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("Error 400") - .description("There is no query provied.") - .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) - }; + let query = command.data.options.first().and_then(|option| { + if let CommandDataOptionValue::String(query) = &option.value { + Some(query) + } else { + None + } + }); + + if query.is_none() { + return Embed::create(username, "Error 400", "There is no query provided"); + } 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))); + return Embed::create(username, "GuildId not found", "Could not find guild id."); } }; let (guild_id, channel_id) = { - let guild = &ctx.cache.guild(guild_id).unwrap(); // TODO: This unwrap throws errors. - // This may be unsafe, idk not sure yet - let channel_id = guild - .voice_states - .get(&command.user.id) - .and_then(|voice_state| voice_state.channel_id); - (guild.id, channel_id) + let guild = get_guild(ctx, guild_id); + + match guild { + Some(guild) => { + let channel_id = guild + .voice_states + .get(&command.user.id) + .and_then(|voice_state| voice_state.channel_id); + + (guild.id, channel_id) + } + None => { + return Embed::create(username, "Guild not found", "Could not find guild."); + } + } }; let connect_to = match channel_id { Some(channel) => channel, None => { - return CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("You are not in a VC.") - .description("Join one to start playing music.") - .footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username))); - }, + return Embed::create( + username, + "You are not in a VC.", + "Join one to start playing music.", + ); + } }; - + let manager = &songbird::get(ctx) .await .expect("Cannot get Songbird.") .clone(); - if !user_util::is_self_connected_to_vc(&ctx, &guild_id) { + 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); + let self_channel = user_util::get_self_vc_id(ctx, &guild_id); + + if self_channel.is_none() { + return Embed::create( + username, + "I am not in a VC.", + "Connect me to a VC to start playing music.", + ); + } + + let self_channel = self_channel.unwrap(); + // 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))); + return Embed::create( + username, + "You are not in my VC.", + "Connect to my VC to control the music.", + ); } // Connect to VC - manager.join(guild_id, connect_to).await.expect("Cannot connect>..."); + manager + .join(guild_id, connect_to) + .await + .expect("Cannot connect>..."); } - - CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("Searching...") - .description(format!("Looking for {}", query)) - .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) -} + Embed::create(username, "Searching...", format!("Looking for {}", query)) +} pub fn register() -> CreateCommand { CreateCommand::new("play") .description("Play music") .add_option( CreateCommandOption::new(CommandOptionType::String, "query", "Link or search term") - .required(true) + .required(true), ) } diff --git a/src/commands/stop.rs b/src/commands/stop.rs index c7333dc..aeb7715 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -1,60 +1,52 @@ -use chrono::Local; use serenity::all::{CommandInteraction, Context}; -use serenity::builder::{CreateCommand, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; +use serenity::builder::{CreateCommand, CreateEmbed}; +use crate::util::embed::Embed; use crate::util::user_util; + pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); - 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))); + return Embed::create(username, "GuildId not found", "Could not find guild id."); } }; - if !user_util::is_self_connected_to_vc(&ctx, guild_id) { + 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))); + return Embed::create( + username, + "Bot is not connected", + "And therefore I cannot stop playing.", + ); } - let manager = songbird::get(&ctx) + let manager = songbird::get(ctx) .await .expect("Cannot get Songbird") .clone(); - let has_handler = manager.get(guild_id.clone()).is_some(); + let has_handler = manager.get(*guild_id).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))); + if let Err(e) = manager.remove(*guild_id).await { + return Embed::create(username, "There was an error", format!("Failed: {:?}", e)); } - return CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("I stopped and left\nJust like your girlfriend.") - .footer(CreateEmbedFooter::new(format!(">{} | {}", current_time, username))) + return Embed::create( + username, + "I stopped and left\nJust like your girlfriend.", + "", + ); } - - CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("Bot is not connected") - .description("And therefore I cannot stop playing.\nSomething happend, which shouldn't have.") - .footer(CreateEmbedFooter::new(format!("> {} | {}", current_time, username))) -} + Embed::create( + username, + "Bot is not connected", + "And therefore I cannot stop playing.\nSomething happend, which shouldn't have.", + ) +} pub fn register() -> CreateCommand { CreateCommand::new("stop").description("Stop playing and start leavin'") diff --git a/src/main.rs b/src/main.rs index 6f003ef..cbc9c4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,18 +2,14 @@ mod commands; mod handler; mod util; -use chrono::Local; use serenity::all::{CommandInteraction, OnlineStatus}; use serenity::async_trait; -use serenity::builder::{ - CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, CreateInteractionResponse, - CreateInteractionResponseMessage, -}; +use serenity::builder::{CreateEmbed, CreateInteractionResponse, CreateInteractionResponseMessage}; use serenity::gateway::ActivityData; use serenity::model::application::{Command, Interaction}; use serenity::model::gateway::Ready; use serenity::prelude::*; -use util::config; +use util::{config, error::Embed}; // This trait adds the `register_songbird` and `register_songbird_with` methods // to the client builder below, making it easy to install this voice client. @@ -63,17 +59,11 @@ impl EventHandler for Handler { } pub async fn respond_with_error(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { - let username = &command.user.name.as_str(); - let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); - - CreateEmbed::new() - .author(CreateEmbedAuthor::new("Rustendo")) - .title("Command not found") - .description("Cannot find the executed command") - .footer(CreateEmbedFooter::new(format!( - "> {} | {}", - current_time, username - ))) + Embed::create( + command.user.name.to_owned(), + "Command not found", + "Cannot find the executed command", + ) } #[tokio::main] diff --git a/src/util/config.rs b/src/util/config.rs index 24b216b..f3e4cb9 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -8,7 +8,7 @@ pub struct Config { pub discord_token: String, pub lavalink_address: String, pub lavalink_password: String, - pub user_id: u64 + pub user_id: u64, } const CONFIG_FILE: &str = "./data/config.json"; @@ -17,23 +17,23 @@ pub fn load() -> Result> { // TODO: load config, create empty config if there is no config, stop if there is no complete config let config_file = match fs::File::open(CONFIG_FILE) { Ok(file) => file, - Err(_) => create_empty() + Err(_) => create_empty(), }; let config_file = serde_json::from_reader(config_file).unwrap(); Ok(config_file) } -fn create_empty() -> fs::File{ +fn create_empty() -> fs::File { let example_config = Config { discord_token: "paste_your_token".to_string(), lavalink_address: "paste_your_lavalink_address".to_string(), lavalink_password: "paste_your_lavalink_password".to_string(), - user_id: 1 + user_id: 1, }; let mut config_file = fs::File::create(CONFIG_FILE).unwrap(); let file_content = serde_json::to_string(&example_config).unwrap(); - config_file.write_all(&file_content.as_bytes()).unwrap(); + config_file.write_all(file_content.as_bytes()).unwrap(); panic!("There is no config. But now there is a template.") -} \ No newline at end of file +} diff --git a/src/util/embed.rs b/src/util/embed.rs new file mode 100644 index 0000000..47a7d0c --- /dev/null +++ b/src/util/embed.rs @@ -0,0 +1,29 @@ +use std::fmt::Display; + +use chrono::Local; +use serenity::all::{CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; + +pub struct Embed; + +impl Embed { + pub fn create< + S: Into + Display, + T: Into + Display, + U: Into + Display, + >( + username: S, + title: T, + message: U, + ) -> CreateEmbed { + let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); + + CreateEmbed::new() + .author(CreateEmbedAuthor::new(username.to_string())) + .title(title) + .description(message) + .footer(CreateEmbedFooter::new(format!( + "> {} | {}", + current_time, username + ))) + } +} diff --git a/src/util/mod.rs b/src/util/mod.rs index 1a9154c..654a104 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,2 +1,3 @@ pub mod config; -pub mod user_util; \ No newline at end of file +pub mod embed; +pub mod user_util; diff --git a/src/util/user_util.rs b/src/util/user_util.rs index 4ea3778..ad88d02 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -1,42 +1,38 @@ -use serenity::all::{ChannelId, Context, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, GuildId}; +use serenity::all::{ChannelId, Context, Guild, GuildId}; + +/// Get a guild by id +pub fn get_guild(ctx: &Context, guild_id: &GuildId) -> Option { + let guild = ctx.cache.guild(guild_id)?; + + Some(guild.clone()) +} + +/// Get the current channel id of the bot +pub fn get_channel_id(ctx: &Context, guild_id: &GuildId) -> Option { + let guild = get_guild(ctx, guild_id)?; + + let channel_id = guild + .voice_states + .get(&ctx.cache.current_user().id) + .and_then(|voice_state| voice_state.channel_id); + + Some(channel_id.unwrap()) +} 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) - }; + let channel_id = get_channel_id(ctx, guild_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 + if channel_id.is_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() - +pub fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> Option { + let channel_id = get_channel_id(ctx, guild_id)?; + + Some(channel_id) } From 4d6e665a3b31ac6479a8e10b4ec4124523cc669a Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 4 Mar 2024 23:39:36 +0100 Subject: [PATCH 05/41] fix: fixed import errors feat: removed unneeded functions, added logging to user_util --- src/commands/play.rs | 39 ++++++----------------------- src/main.rs | 2 +- src/util/user_util.rs | 58 ++++++++++++++++++++++++++----------------- 3 files changed, 43 insertions(+), 56 deletions(-) diff --git a/src/commands/play.rs b/src/commands/play.rs index 3791885..fffaf21 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -1,9 +1,9 @@ -use serenity::all::{CommandDataOption, CommandDataOptionValue, CommandInteraction, Context}; +use serenity::all::{CommandDataOptionValue, CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed}; use serenity::model::application::CommandOptionType; use crate::util::embed::Embed; -use crate::util::user_util::{self, get_guild}; +use crate::util::user_util::{self, get_vc_id}; pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); @@ -27,35 +27,10 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { return Embed::create(username, "GuildId not found", "Could not find guild id."); } }; + + println!("Guild ID: {:?}", guild_id); - let (guild_id, channel_id) = { - let guild = get_guild(ctx, guild_id); - - match guild { - Some(guild) => { - let channel_id = guild - .voice_states - .get(&command.user.id) - .and_then(|voice_state| voice_state.channel_id); - - (guild.id, channel_id) - } - None => { - return Embed::create(username, "Guild not found", "Could not find guild."); - } - } - }; - - let connect_to = match channel_id { - Some(channel) => channel, - None => { - return Embed::create( - username, - "You are not in a VC.", - "Join one to start playing music.", - ); - } - }; + let connect_to = get_vc_id(ctx, &guild_id, &command.user.id).expect("Cannot get channel id"); let manager = &songbird::get(ctx) .await @@ -86,12 +61,12 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { } // Connect to VC manager - .join(guild_id, connect_to) + .join(*guild_id, connect_to) .await .expect("Cannot connect>..."); } - Embed::create(username, "Searching...", format!("Looking for {}", query)) + Embed::create(username, "Searching...", format!("Looking for {:?}", query)) } pub fn register() -> CreateCommand { diff --git a/src/main.rs b/src/main.rs index cbc9c4f..5c533d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use serenity::gateway::ActivityData; use serenity::model::application::{Command, Interaction}; use serenity::model::gateway::Ready; use serenity::prelude::*; -use util::{config, error::Embed}; +use util::{config, embed::Embed}; // This trait adds the `register_songbird` and `register_songbird_with` methods // to the client builder below, making it easy to install this voice client. diff --git a/src/util/user_util.rs b/src/util/user_util.rs index ad88d02..46a91b0 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -1,38 +1,50 @@ -use serenity::all::{ChannelId, Context, Guild, GuildId}; +use serenity::all::{ChannelId, Context, Guild, GuildId, UserId}; /// Get a guild by id pub fn get_guild(ctx: &Context, guild_id: &GuildId) -> Option { - let guild = ctx.cache.guild(guild_id)?; + let guild = match ctx.cache.guild(guild_id) { + Some(guild) => guild, + None => { + println!("Cannot get guild!"); + return None + } + }; // TODO This is always None for some reason + + println!("Got guild: {:?}", guild.name); Some(guild.clone()) } /// Get the current channel id of the bot -pub fn get_channel_id(ctx: &Context, guild_id: &GuildId) -> Option { - let guild = get_guild(ctx, guild_id)?; +pub fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { + let guild = match get_guild(&ctx, guild_id){ + Some(guild) => guild, + None => { + println!("Cannot get guild while getting channel id!"); + return None + } + }; let channel_id = guild .voice_states - .get(&ctx.cache.current_user().id) - .and_then(|voice_state| voice_state.channel_id); + .get(user_id) + .and_then(|voice_state| voice_state.channel_id)?; - Some(channel_id.unwrap()) -} - -pub fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { - let channel_id = get_channel_id(ctx, guild_id); - - // TODO: There has to be a way to improve this. This is bad code and it should be optimized. - if channel_id.is_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) -> Option { - let channel_id = get_channel_id(ctx, guild_id)?; + println!("Got vc with id: {:?}", channel_id); + + Some(channel_id) +} + +/// Check if the bot is connected to a voice channel +pub fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { + let channel_id = get_self_vc_id(ctx, guild_id); + + !channel_id.is_none() +} + +/// Get the current channel id of the bot +pub fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> Option { + let channel_id = get_vc_id(ctx, guild_id, &ctx.cache.current_user().id)?; Some(channel_id) } From cfd051be3fa3ed25de2a8dd82673c6888ba9d9f1 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 5 Mar 2024 12:08:19 +0100 Subject: [PATCH 06/41] feat: added getting data from discord --- src/commands/play.rs | 8 ++--- src/commands/stop.rs | 2 +- src/util/user_util.rs | 68 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/commands/play.rs b/src/commands/play.rs index fffaf21..feb170d 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -30,18 +30,18 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { println!("Guild ID: {:?}", guild_id); - let connect_to = get_vc_id(ctx, &guild_id, &command.user.id).expect("Cannot get channel id"); + let connect_to = get_vc_id(ctx, &guild_id, &command.user.id).await.expect("Cannot get channel id"); let manager = &songbird::get(ctx) .await .expect("Cannot get Songbird.") .clone(); - if !user_util::is_self_connected_to_vc(ctx, &guild_id) { + if !user_util::is_self_connected_to_vc(ctx, &guild_id).await { // self is connected to vc, check if user is in same vc - let self_channel = user_util::get_self_vc_id(ctx, &guild_id); + let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await; - if self_channel.is_none() { + if self_channel.is_err() { return Embed::create( username, "I am not in a VC.", diff --git a/src/commands/stop.rs b/src/commands/stop.rs index aeb7715..002d6f9 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -14,7 +14,7 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { } }; - if !user_util::is_self_connected_to_vc(ctx, guild_id) { + if !user_util::is_self_connected_to_vc_cached(ctx, guild_id) { // Bot is not connectd to vc; no need to dc return Embed::create( username, diff --git a/src/util/user_util.rs b/src/util/user_util.rs index 46a91b0..8bfd6ad 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -1,23 +1,48 @@ -use serenity::all::{ChannelId, Context, Guild, GuildId, UserId}; +use futures::future::BoxFuture; +use serenity::all::{ChannelId, Context, Guild, GuildId, PartialGuild, UserId}; +use serenity::Error; /// Get a guild by id -pub fn get_guild(ctx: &Context, guild_id: &GuildId) -> Option { +pub fn get_guild_cached(ctx: &Context, guild_id: &GuildId) -> Option { let guild = match ctx.cache.guild(guild_id) { Some(guild) => guild, None => { - println!("Cannot get guild!"); + println!("Cannot get guild with id {:?}!", guild_id); return None } - }; // TODO This is always None for some reason + }; println!("Got guild: {:?}", guild.name); Some(guild.clone()) } +pub async fn request_guild(ctx: &Context, guild_id: &GuildId) -> Result { + let guild = match ctx.http.get_guild(*guild_id).await { + Ok(guild) => guild, + Err(error) => { + return Err(error); + } + }; + + Ok(guild.id.to_guild_cached(ctx).unwrap().clone()) +} + +/// Request a guild by id, get it from Discord, not from cache, this is a partial guild +pub async fn request_partial_guild(ctx: &Context, guild_id: &GuildId) -> PartialGuild { + let guild = match ctx.http.get_guild(*guild_id).await { + Ok(guild) => guild, + Err(error) => { + panic!("error whilest getting guild from Discord {}", error); + } + }; + + guild +} + /// Get the current channel id of the bot -pub fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { - let guild = match get_guild(&ctx, guild_id){ +pub fn get_vc_id_cached(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { + let guild = match get_guild_cached(&ctx, guild_id){ Some(guild) => guild, None => { println!("Cannot get guild while getting channel id!"); @@ -35,16 +60,39 @@ pub fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option< Some(channel_id) } +pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Result { + let guild = request_guild(&ctx, guild_id).await?; + + let channel_id = guild + .voice_states + .get(user_id) + .and_then(|voice_state| voice_state.channel_id) + .expect("Cannot get channel id"); + + Ok(channel_id) +} + /// Check if the bot is connected to a voice channel -pub fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { - let channel_id = get_self_vc_id(ctx, guild_id); +pub fn is_self_connected_to_vc_cached(ctx: &Context, guild_id: &GuildId) -> bool { + let channel_id = get_self_vc_id_cached(ctx, guild_id); !channel_id.is_none() } +pub async fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { + let channel_id = get_self_vc_id(ctx, guild_id); + + !channel_id.await.is_err() +} + /// Get the current channel id of the bot -pub fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> Option { - let channel_id = get_vc_id(ctx, guild_id, &ctx.cache.current_user().id)?; +pub fn get_self_vc_id_cached(ctx: &Context, guild_id: &GuildId) -> Option { + let channel_id = get_vc_id_cached(ctx, guild_id, &ctx.cache.current_user().id)?; Some(channel_id) } + +pub async fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> Result { + let channel_id = get_vc_id(ctx, guild_id, &ctx.cache.current_user().id).await; + channel_id // This throws errors in main.rs for some reason +} From af50d5472957bca7fe0c42dfb5aa4d7dfe16dba6 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Wed, 6 Mar 2024 09:13:23 +0100 Subject: [PATCH 07/41] fix: `get_self_vc_id` throws an error The problem was that `ctx.cache.current_user()` uses an Arc and needs to get the value first before passing it to as a parameter. Assigning it to a variable first and referencing it, fixes the issue --- src/util/user_util.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/util/user_util.rs b/src/util/user_util.rs index 8bfd6ad..3f70c58 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -93,6 +93,7 @@ pub fn get_self_vc_id_cached(ctx: &Context, guild_id: &GuildId) -> Option Result { - let channel_id = get_vc_id(ctx, guild_id, &ctx.cache.current_user().id).await; - channel_id // This throws errors in main.rs for some reason + let user_id = ctx.cache.current_user().id; + + get_vc_id(ctx, guild_id, &user_id).await } From d72577c2456db107b774a53fd918b1adeb4662d9 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Wed, 6 Mar 2024 10:06:31 +0100 Subject: [PATCH 08/41] fix: improvements by clippy --- src/commands/play.rs | 11 ++++++----- src/util/user_util.rs | 28 +++++++++++++++------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/commands/play.rs b/src/commands/play.rs index feb170d..acff8ef 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -7,7 +7,6 @@ use crate::util::user_util::{self, get_vc_id}; pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); - let options = &command.data.options; let query = command.data.options.first().and_then(|option| { if let CommandDataOptionValue::String(query) = &option.value { @@ -27,19 +26,21 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { return Embed::create(username, "GuildId not found", "Could not find guild id."); } }; - + println!("Guild ID: {:?}", guild_id); - let connect_to = get_vc_id(ctx, &guild_id, &command.user.id).await.expect("Cannot get channel id"); + let connect_to = get_vc_id(ctx, guild_id, &command.user.id) + .await + .expect("Cannot get channel id"); let manager = &songbird::get(ctx) .await .expect("Cannot get Songbird.") .clone(); - if !user_util::is_self_connected_to_vc(ctx, &guild_id).await { + if !user_util::is_self_connected_to_vc(ctx, guild_id).await { // self is connected to vc, check if user is in same vc - let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await; + let self_channel = user_util::get_self_vc_id(ctx, guild_id).await; if self_channel.is_err() { return Embed::create( diff --git a/src/util/user_util.rs b/src/util/user_util.rs index 3f70c58..40ec889 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -1,4 +1,3 @@ -use futures::future::BoxFuture; use serenity::all::{ChannelId, Context, Guild, GuildId, PartialGuild, UserId}; use serenity::Error; @@ -8,10 +7,10 @@ pub fn get_guild_cached(ctx: &Context, guild_id: &GuildId) -> Option { Some(guild) => guild, None => { println!("Cannot get guild with id {:?}!", guild_id); - return None + return None; } }; - + println!("Got guild: {:?}", guild.name); Some(guild.clone()) @@ -29,24 +28,23 @@ pub async fn request_guild(ctx: &Context, guild_id: &GuildId) -> Result PartialGuild { - let guild = match ctx.http.get_guild(*guild_id).await { + match ctx.http.get_guild(*guild_id).await { Ok(guild) => guild, Err(error) => { panic!("error whilest getting guild from Discord {}", error); } - }; - - guild + } } /// Get the current channel id of the bot pub fn get_vc_id_cached(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { - let guild = match get_guild_cached(&ctx, guild_id){ + let guild = match get_guild_cached(ctx, guild_id) { Some(guild) => guild, None => { println!("Cannot get guild while getting channel id!"); - return None + return None; } }; @@ -60,8 +58,12 @@ pub fn get_vc_id_cached(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Some(channel_id) } -pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Result { - let guild = request_guild(&ctx, guild_id).await?; +pub async fn get_vc_id( + ctx: &Context, + guild_id: &GuildId, + user_id: &UserId, +) -> Result { + let guild = request_guild(ctx, guild_id).await?; let channel_id = guild .voice_states @@ -76,13 +78,13 @@ pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> R pub fn is_self_connected_to_vc_cached(ctx: &Context, guild_id: &GuildId) -> bool { let channel_id = get_self_vc_id_cached(ctx, guild_id); - !channel_id.is_none() + channel_id.is_some() } pub async fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { let channel_id = get_self_vc_id(ctx, guild_id); - !channel_id.await.is_err() + channel_id.await.is_ok() } /// Get the current channel id of the bot From b2ba381e44c617d8896197650c2e605f98f28121 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Mar 2024 23:30:39 +0100 Subject: [PATCH 09/41] fix: fixed not being able to get guild struct, continued work on play command --- src/commands/play.rs | 39 +++++++++++++++++---------------------- src/main.rs | 1 + src/util/user_util.rs | 30 +++++++++++++----------------- 3 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/commands/play.rs b/src/commands/play.rs index feb170d..3102f5a 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -16,7 +16,7 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { None } }); - + if query.is_none() { return Embed::create(username, "Error 400", "There is no query provided"); } @@ -37,33 +37,28 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { .expect("Cannot get Songbird.") .clone(); + let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await; if !user_util::is_self_connected_to_vc(ctx, &guild_id).await { // self is connected to vc, check if user is in same vc - let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await; - if self_channel.is_err() { - return Embed::create( - username, - "I am not in a VC.", - "Connect me to a VC to start playing music.", - ); + if self_channel.is_none() { + // Connect to VC + manager + .join(*guild_id, connect_to) + .await + .expect("Cannot connect>..."); } - let self_channel = self_channel.unwrap(); + } + let self_channel = self_channel.expect("Cannot get self channel"); - // Check if user is in the same VC as the bot - if self_channel != connect_to { - return Embed::create( - username, - "You are not in my VC.", - "Connect to my VC to control the music.", - ); - } - // Connect to VC - manager - .join(*guild_id, connect_to) - .await - .expect("Cannot connect>..."); + // Check if user is in the same VC as the bot + if self_channel != connect_to { + return Embed::create( + username, + "You are not in my VC.", + "Connect to my VC to control the music.", + ); } Embed::create(username, "Searching...", format!("Looking for {:?}", query)) diff --git a/src/main.rs b/src/main.rs index 5c533d4..ed4f368 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,6 +91,7 @@ async fn main() { .activity(activity) .register_songbird() .type_map_insert::(HttpClient::new()) + .intents(GatewayIntents::all()) .await .expect("Error creating client"); diff --git a/src/util/user_util.rs b/src/util/user_util.rs index 3f70c58..ef0c742 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -1,5 +1,4 @@ -use futures::future::BoxFuture; -use serenity::all::{ChannelId, Context, Guild, GuildId, PartialGuild, UserId}; +use serenity::all::{CacheHttp, ChannelId, Context, Guild, GuildId, GuildRef, PartialGuild, UserId}; use serenity::Error; /// Get a guild by id @@ -17,15 +16,15 @@ pub fn get_guild_cached(ctx: &Context, guild_id: &GuildId) -> Option { Some(guild.clone()) } -pub async fn request_guild(ctx: &Context, guild_id: &GuildId) -> Result { - let guild = match ctx.http.get_guild(*guild_id).await { - Ok(guild) => guild, - Err(error) => { - return Err(error); +pub fn request_guild(ctx: &Context, guild_id: &GuildId) -> Guild { + let guild = match guild_id.to_guild_cached(&ctx.cache) { + Some(guild) => guild.clone(), + None => { + panic!("Cannot get guild with id {:?}!", guild_id); } }; - - Ok(guild.id.to_guild_cached(ctx).unwrap().clone()) + + guild } /// Request a guild by id, get it from Discord, not from cache, this is a partial guild @@ -60,16 +59,13 @@ pub fn get_vc_id_cached(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Some(channel_id) } -pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Result { - let guild = request_guild(&ctx, guild_id).await?; - - let channel_id = guild +pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { + let guild = request_guild(&ctx, guild_id); + guild .voice_states .get(user_id) .and_then(|voice_state| voice_state.channel_id) - .expect("Cannot get channel id"); - Ok(channel_id) } /// Check if the bot is connected to a voice channel @@ -82,7 +78,7 @@ pub fn is_self_connected_to_vc_cached(ctx: &Context, guild_id: &GuildId) -> bool pub async fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { let channel_id = get_self_vc_id(ctx, guild_id); - !channel_id.await.is_err() + !channel_id.await.is_none() } /// Get the current channel id of the bot @@ -92,7 +88,7 @@ pub fn get_self_vc_id_cached(ctx: &Context, guild_id: &GuildId) -> Option Result { +pub async fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> Option { let user_id = ctx.cache.current_user().id; get_vc_id(ctx, guild_id, &user_id).await From a16d8a6b60e2c19adbb4ce85c66a2e4ef6cf6e6d Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 8 Mar 2024 01:18:30 +0100 Subject: [PATCH 10/41] feat: bot now plays songs, started to work on queue system --- Cargo.lock | 8 ++ Cargo.toml | 2 + src/commands/info.rs | 4 +- src/commands/play.rs | 41 +-------- src/commands/stop.rs | 36 +------- src/handler/mod.rs | 0 src/main.rs | 35 ++++++-- src/music/mod.rs | 2 + src/music/music_events.rs | 42 +++++++++ src/music/music_manager.rs | 173 +++++++++++++++++++++++++++++++++++++ src/util/embed.rs | 2 +- src/util/user_util.rs | 74 ++++++---------- 12 files changed, 289 insertions(+), 130 deletions(-) delete mode 100644 src/handler/mod.rs create mode 100644 src/music/mod.rs create mode 100644 src/music/music_events.rs create mode 100644 src/music/music_manager.rs diff --git a/Cargo.lock b/Cargo.lock index cd4694e..55d56bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1338,6 +1338,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "queues" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1475abae4f8ad4998590fe3acfe20104f0a5d48fc420c817cd2c09c3f56151f0" + [[package]] name = "quote" version = "1.0.35" @@ -1561,6 +1567,8 @@ dependencies = [ "chrono", "confy", "futures", + "once_cell", + "queues", "reqwest", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 8cd9d80..02c692f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,5 @@ tracing = "0.1.40" tracing-subscriber = "0.3.18" tracing-futures = "0.2.5" futures = "0.3.1" +queues = "1" +once_cell = "1" diff --git a/src/commands/info.rs b/src/commands/info.rs index 4dc5807..2c93d36 100644 --- a/src/commands/info.rs +++ b/src/commands/info.rs @@ -7,9 +7,9 @@ pub async fn run(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); Embed::create( - username, "", - "Botendo v7\ndeveloped by [moonleay](https://moonleay.net)\n\nCheck out the repository: https://git.moonleay.net/DiscordBots/Rustendo", + "Botendo v7", + "developed by [moonleay](https://moonleay.net)\n\nCheck out the repository: https://git.moonleay.net/DiscordBots/Rustendo", ) } diff --git a/src/commands/play.rs b/src/commands/play.rs index 3102f5a..1df5511 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -1,15 +1,15 @@ use serenity::all::{CommandDataOptionValue, CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed}; use serenity::model::application::CommandOptionType; +use crate::music::music_manager; use crate::util::embed::Embed; -use crate::util::user_util::{self, get_vc_id}; pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let options = &command.data.options; - - let query = command.data.options.first().and_then(|option| { + + let query = options.first().and_then(|option| { if let CommandDataOptionValue::String(query) = &option.value { Some(query) } else { @@ -28,40 +28,7 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { } }; - println!("Guild ID: {:?}", guild_id); - - let connect_to = get_vc_id(ctx, &guild_id, &command.user.id).await.expect("Cannot get channel id"); - - let manager = &songbird::get(ctx) - .await - .expect("Cannot get Songbird.") - .clone(); - - let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await; - if !user_util::is_self_connected_to_vc(ctx, &guild_id).await { - // self is connected to vc, check if user is in same vc - - if self_channel.is_none() { - // Connect to VC - manager - .join(*guild_id, connect_to) - .await - .expect("Cannot connect>..."); - } - - } - let self_channel = self_channel.expect("Cannot get self channel"); - - // Check if user is in the same VC as the bot - if self_channel != connect_to { - return Embed::create( - username, - "You are not in my VC.", - "Connect to my VC to control the music.", - ); - } - - Embed::create(username, "Searching...", format!("Looking for {:?}", query)) + music_manager::attempt_to_queue_song(&ctx, &guild_id, &command.user.id, &command.user.name, query.unwrap()).await } pub fn register() -> CreateCommand { diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 002d6f9..2f0600a 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -1,8 +1,7 @@ use serenity::all::{CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateEmbed}; - +use crate::music::music_manager; use crate::util::embed::Embed; -use crate::util::user_util; pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); @@ -14,38 +13,7 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { } }; - if !user_util::is_self_connected_to_vc_cached(ctx, guild_id) { - // Bot is not connectd to vc; no need to dc - return Embed::create( - username, - "Bot is not connected", - "And therefore I cannot stop playing.", - ); - } - - let manager = songbird::get(ctx) - .await - .expect("Cannot get Songbird") - .clone(); - - let has_handler = manager.get(*guild_id).is_some(); - - if has_handler { - if let Err(e) = manager.remove(*guild_id).await { - return Embed::create(username, "There was an error", format!("Failed: {:?}", e)); - } - return Embed::create( - username, - "I stopped and left\nJust like your girlfriend.", - "", - ); - } - - Embed::create( - username, - "Bot is not connected", - "And therefore I cannot stop playing.\nSomething happend, which shouldn't have.", - ) + music_manager::attempt_to_stop(&ctx, &guild_id, &command.user.id, &command.user.name).await } pub fn register() -> CreateCommand { diff --git a/src/handler/mod.rs b/src/handler/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/main.rs b/src/main.rs index ed4f368..7e36070 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,15 @@ mod commands; -mod handler; mod util; +mod music; -use serenity::all::{CommandInteraction, OnlineStatus}; +use serenity::all::{CommandInteraction, CreateInteractionResponseFollowup, OnlineStatus, VoiceState}; use serenity::async_trait; -use serenity::builder::{CreateEmbed, CreateInteractionResponse, CreateInteractionResponseMessage}; +use serenity::builder::{CreateEmbed}; use serenity::gateway::ActivityData; use serenity::model::application::{Command, Interaction}; use serenity::model::gateway::Ready; use serenity::prelude::*; -use util::{config, embed::Embed}; +use util::{config, embed::Embed, user_util}; // This trait adds the `register_songbird` and `register_songbird_with` methods // to the client builder below, making it easy to install this voice client. @@ -30,6 +30,8 @@ struct Handler; impl EventHandler for Handler { async fn interaction_create(&self, ctx: Context, interaction: Interaction) { if let Interaction::Command(command) = interaction { + let _ = &command.defer(&ctx.http()).await.expect("Cannot defer"); + let content = Some(match command.data.name.as_str() { "info" => commands::info::run(&ctx, &command).await, "play" => commands::play::run(&ctx, &command).await, @@ -38,10 +40,9 @@ impl EventHandler for Handler { }); if let Some(embed) = content { - let data = CreateInteractionResponseMessage::new().embed(embed); - let builder = CreateInteractionResponse::Message(data); - if let Err(why) = command.create_response(&ctx.http, builder).await { - println!("Cannot respond to slash command: {why}"); + let followup = CreateInteractionResponseFollowup::new().embed(embed); + if let Err(why) = command.create_followup(&ctx.http, followup).await { + println!("Cannot followup to slash command: {why}") } } } @@ -53,8 +54,24 @@ impl EventHandler for Handler { let _command = Command::create_global_command(&ctx.http, commands::info::register()).await; let _command = Command::create_global_command(&ctx.http, commands::stop::register()).await; let _command = Command::create_global_command(&ctx.http, commands::play::register()).await; + println!("Commands are registered and Rustendo is ready for Freddy."); + } - println!("Created all public / commands"); + async fn voice_state_update(&self, ctx: Context, old: Option, new: VoiceState) { + if !new.channel_id.is_none() { + return; // User did not leave, ignore + } + if let Some(old) = old { + if !user_util::is_self_connected_to_vc(&ctx, &old.guild_id.unwrap()).await { + return; // Bot is not connected to a VC, ignore + } + if user_util::get_amount_of_members_in_vc(&ctx, &old.guild_id.unwrap(), &old.channel_id.unwrap()).await < 2 { + let manager = songbird::get(&ctx).await.expect("Cannot get Songbird"); + if let Err(e) = manager.remove(old.guild_id.unwrap()).await { + println!("Failed to remove handler: {:?}", e); + } + } + } // else: new user joined, ignore } } diff --git a/src/music/mod.rs b/src/music/mod.rs new file mode 100644 index 0000000..f16ee08 --- /dev/null +++ b/src/music/mod.rs @@ -0,0 +1,2 @@ +pub mod music_manager; +pub mod music_events; \ No newline at end of file diff --git a/src/music/music_events.rs b/src/music/music_events.rs new file mode 100644 index 0000000..ca48045 --- /dev/null +++ b/src/music/music_events.rs @@ -0,0 +1,42 @@ +use std::sync::Arc; +use queues::IsQueue; +use serenity::all::{ChannelId, GuildId, Http}; +use serenity::async_trait; +use songbird::{Event, EventContext, EventHandler}; +use crate::music::music_manager; + +pub struct TrackEndNotifier { + pub guild_id: GuildId, + pub channel_id: ChannelId, + pub http: Arc, + pub cmdctx: Arc, +} + +#[async_trait] +impl EventHandler for TrackEndNotifier { + async fn act(&self, ctx: &EventContext<'_>) -> Option { + unsafe { // TODO: Does this need to be unsafe? + if let EventContext::Track(track_list) = ctx { + println!("The track ended!"); + let queue = music_manager::get_queue(&self.guild_id); + if queue.size() == 0 { + let stopped = match music_manager::stop(&self.cmdctx, &self.guild_id).await { + Ok(stopped) => stopped, + Err(e) => { + println!("Cannot stop: {:?}", e); + return None; + } + }; + if stopped { + println!("Stopped playing successfully."); + } else { + println!("Failed to stop playing."); + } + return None; + } + } + } + + None + } +} diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs new file mode 100644 index 0000000..7781b98 --- /dev/null +++ b/src/music/music_manager.rs @@ -0,0 +1,173 @@ +use std::collections::{HashMap}; +use std::sync::{Arc, Mutex}; +use std::time::Duration; +use once_cell::sync::Lazy; +use queues::Queue; +use serenity::all::{Context, CreateEmbed, GuildId, UserId}; +use songbird::{Event, TrackEvent}; +use songbird::error::JoinError; +use songbird::input::{Compose, YoutubeDl}; +use crate::HttpKey; +use crate::music::music_events; +use crate::util::embed::Embed; +use crate::util::user_util; +use crate::util::user_util::get_vc_id; + +/// pub static mut MUSIC_QUEUE: HashMap> = HashMap::new(); +pub static mut MUSIC_QUEUE: Lazy>>> = Lazy::new(|| { + Mutex::new(HashMap::new()) +}); // TODO: This does not work and this is not the way to do it. This is a placeholder for now. + +pub unsafe fn get_queue(guild_id: &GuildId) -> &Queue { + MUSIC_QUEUE.lock().unwrap().entry(*guild_id).or_insert_with(Queue::new) +} + +pub async fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str, query: &str) -> CreateEmbed { + if !user_util::is_user_connected_to_vc(ctx, guild_id, user_id).await { + return Embed::create(username, "You are not connected to a VC", "Connect to my VC to control the music."); + } + + let connect_to = match get_vc_id(ctx, &guild_id, &user_id).await { + Some(channel_id) => channel_id, + None => { + return Embed::create(username, "Error", "Cannot get channel id"); + } + + }; + + let manager = &songbird::get(ctx) + .await + .expect("Cannot get Songbird.") + .clone(); + + let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await; + if !user_util::is_self_connected_to_vc(ctx, &guild_id).await { + // self is connected to vc, check if user is in same vc + + if self_channel.is_none() { // TODO This could maybe be removed? + // Connect to VC + manager + .join(*guild_id, connect_to) + .await + .expect("Cannot connect>..."); + } + + } else { + let self_channel = self_channel.expect("Cannot get self channel"); + + // Check if user is in the same VC as the bot + if self_channel != connect_to { + return Embed::create( + username, + "You are not in my VC.", + "Connect to my VC to control the music.", + ); + } + } + + // Get query + let do_search = !query.starts_with("http"); + let http_client = { + let data = ctx.data.read().await; + data.get::() + .cloned() + .expect("Guaranteed to exist in the typemap.") + }; + + // Create source + let mut src = if do_search { + YoutubeDl::new_search(http_client, query.to_string()) + } else { + YoutubeDl::new(http_client, query.to_string()) + }; + let handler_lock = match manager.get(*guild_id) { + Some(handler) => handler, + None => { + return Embed::create(username, "Error", "Cannot get handler"); + }, + }; + + // Start playing + let mut handler = handler_lock.lock().await; + let track_handle = handler.play_input(src.clone().into()); // TODO: Add event handlers + handler.add_global_event( + Event::Track(TrackEvent::End), + music_events::TrackEndNotifier { + guild_id: *guild_id, + channel_id: connect_to, + http: Arc::clone(&ctx.http), + cmdctx: Arc::new(ctx.clone()), + }, + ); + + // Get metadata + let metadata = src.aux_metadata().await.expect("Cannot get metadata"); + let title = metadata.title.unwrap_or("Unknown title".to_string()); + let author = metadata.artist.unwrap_or("Unknown artist".to_string()); + let duration = metadata.duration.unwrap_or(Duration::from_millis(0)); + let thumbnail = metadata.thumbnail.unwrap_or("https://http.cat/images/404.jpg".to_string()); + let link = metadata.source_url.unwrap_or("https://piped.moonleay.net/404".to_string()); + + Embed::create(username, "Added to queue", format!("{} by {} ({}min {}sec) was added to the queue.\n [[Link]({})]", + title, author, duration.as_secs() / 60, duration.as_secs() % 60, link)) + .thumbnail(thumbnail) +} + + +pub async fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str) -> CreateEmbed { + if !user_util::is_self_connected_to_vc(ctx, guild_id).await { + // Bot is not connectd to vc; no need to dc + return Embed::create( + username, + "Bot is not connected", + "And therefore there is no need to do anything.", + ); + } + let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await.expect("Cannot get self channel"); + let connect_to = get_vc_id(ctx, &guild_id, &user_id).await.expect("Cannot get channel id"); + + // Check if user is in the same VC as the bot + if self_channel != connect_to { + return Embed::create( + username, + "You are not in my VC.", + "Connect to my VC to control the music.", + ); + } + + let stopped = match stop(ctx, guild_id).await { + Ok(stopped) => stopped, + Err(e) => { + println!("Error while stopping: {:?}", e); + return Embed::create(username, "There was an error", "Tell moonleay to check the logs.".to_string()); + } + }; + + if !stopped { + return Embed::create(username, "Can't stop, what ain't running.", "I am not connected. I cant stop doing something, when I'm not doing it".to_string()); + } else { + return Embed::create( + username, + "I stopped and left", + "Just like your girlfriend.", + ); + } +} + +// Make the bot leave the voice channel. Returns Ok(true) if bot was connected, returns Ok(false) if bot was not connected. Returns Err if something went wrong. +pub async fn stop(ctx: &Context, guild_id: &GuildId) -> Result { + let manager = songbird::get(ctx) + .await + .expect("Cannot get Songbird") + .clone(); + + let has_handler = manager.get(*guild_id).is_some(); + + if has_handler { + if let Err(e) = manager.remove(*guild_id).await { + return Err(e); // Failed to remove handler + } + return Ok(true) // Handler removed + } + Ok(false) // No handler, so it's already stopped +} diff --git a/src/util/embed.rs b/src/util/embed.rs index 47a7d0c..bfdb2f1 100644 --- a/src/util/embed.rs +++ b/src/util/embed.rs @@ -22,7 +22,7 @@ impl Embed { .title(title) .description(message) .footer(CreateEmbedFooter::new(format!( - "> {} | {}", + "> {} - {}", current_time, username ))) } diff --git a/src/util/user_util.rs b/src/util/user_util.rs index ef0c742..8e7bf74 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -1,21 +1,7 @@ -use serenity::all::{CacheHttp, ChannelId, Context, Guild, GuildId, GuildRef, PartialGuild, UserId}; -use serenity::Error; - -/// Get a guild by id -pub fn get_guild_cached(ctx: &Context, guild_id: &GuildId) -> Option { - let guild = match ctx.cache.guild(guild_id) { - Some(guild) => guild, - None => { - println!("Cannot get guild with id {:?}!", guild_id); - return None - } - }; - - println!("Got guild: {:?}", guild.name); - - Some(guild.clone()) -} +use std::collections::HashMap; +use serenity::all::{ChannelId, Context, Guild, GuildId, PartialGuild, UserId, VoiceState}; +/// Request a guild by id, get it from cache pub fn request_guild(ctx: &Context, guild_id: &GuildId) -> Guild { let guild = match guild_id.to_guild_cached(&ctx.cache) { Some(guild) => guild.clone(), @@ -39,26 +25,7 @@ pub async fn request_partial_guild(ctx: &Context, guild_id: &GuildId) -> Partial guild } -/// Get the current channel id of the bot -pub fn get_vc_id_cached(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { - let guild = match get_guild_cached(&ctx, guild_id){ - Some(guild) => guild, - None => { - println!("Cannot get guild while getting channel id!"); - return None - } - }; - - let channel_id = guild - .voice_states - .get(user_id) - .and_then(|voice_state| voice_state.channel_id)?; - - println!("Got vc with id: {:?}", channel_id); - - Some(channel_id) -} - +/// Get the voice channel id of a user pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { let guild = request_guild(&ctx, guild_id); guild @@ -69,27 +36,40 @@ pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> O } /// Check if the bot is connected to a voice channel -pub fn is_self_connected_to_vc_cached(ctx: &Context, guild_id: &GuildId) -> bool { - let channel_id = get_self_vc_id_cached(ctx, guild_id); - - !channel_id.is_none() -} - pub async fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { let channel_id = get_self_vc_id(ctx, guild_id); !channel_id.await.is_none() } -/// Get the current channel id of the bot -pub fn get_self_vc_id_cached(ctx: &Context, guild_id: &GuildId) -> Option { - let channel_id = get_vc_id_cached(ctx, guild_id, &ctx.cache.current_user().id)?; +/// Check if a user is connected to a voice channel +pub async fn is_user_connected_to_vc(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> bool { + let channel_id = get_vc_id(ctx, guild_id, user_id).await; - Some(channel_id) + !channel_id.is_none() } +/// Get the voice channel id of the bot pub async fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> Option { let user_id = ctx.cache.current_user().id; get_vc_id(ctx, guild_id, &user_id).await } + +/// Get all voice states of a guild +pub async fn get_voice_states(ctx: &Context, guild_id: &GuildId) -> HashMap{ + let guild = request_guild(ctx, guild_id); + let voice_states = guild.voice_states.clone(); + voice_states +} + + +/// Get the amount of members in a voice channel +pub async fn get_amount_of_members_in_vc(ctx: &Context, guild_id: &GuildId, channel_id: &ChannelId,) -> usize { + let voice_states = get_voice_states(ctx, guild_id).await; + let amount = voice_states + .iter() + .filter(|(_, voice_state)| voice_state.channel_id == Some(*channel_id)) + .count(); + amount +} From a06299fb6fe7e3e78a59be9dfeeacb586e3ba479 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sat, 9 Mar 2024 00:25:12 +0100 Subject: [PATCH 11/41] feat: started to impl queue system --- Cargo.lock | 8 ----- Cargo.toml | 4 +-- src/commands/play.rs | 2 +- src/commands/stop.rs | 2 +- src/main.rs | 26 ++++++++------- src/music/mod.rs | 3 +- src/music/music_events.rs | 22 ++++++++++--- src/music/music_manager.rs | 56 ++++++++++++++++++-------------- src/music/music_queue.rs | 65 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 134 insertions(+), 54 deletions(-) create mode 100644 src/music/music_queue.rs diff --git a/Cargo.lock b/Cargo.lock index 55d56bf..cd4694e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1338,12 +1338,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "queues" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1475abae4f8ad4998590fe3acfe20104f0a5d48fc420c817cd2c09c3f56151f0" - [[package]] name = "quote" version = "1.0.35" @@ -1567,8 +1561,6 @@ dependencies = [ "chrono", "confy", "futures", - "once_cell", - "queues", "reqwest", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 02c692f..394638a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustendo" version = "0.1.0" -authors = ["moonleay "] +authors = ["moonleay ", "migueldamota "] edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -21,5 +21,3 @@ tracing = "0.1.40" tracing-subscriber = "0.3.18" tracing-futures = "0.2.5" futures = "0.3.1" -queues = "1" -once_cell = "1" diff --git a/src/commands/play.rs b/src/commands/play.rs index 1df5511..8fceb13 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -5,7 +5,7 @@ use crate::music::music_manager; use crate::util::embed::Embed; -pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { +pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let options = &command.data.options; diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 2f0600a..beee7ea 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -3,7 +3,7 @@ use serenity::builder::{CreateCommand, CreateEmbed}; use crate::music::music_manager; use crate::util::embed::Embed; -pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { +pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let guild_id = match &command.guild_id { diff --git a/src/main.rs b/src/main.rs index 7e36070..090a238 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,20 +29,22 @@ struct Handler; #[async_trait] impl EventHandler for Handler { async fn interaction_create(&self, ctx: Context, interaction: Interaction) { - if let Interaction::Command(command) = interaction { - let _ = &command.defer(&ctx.http()).await.expect("Cannot defer"); + unsafe { + if let Interaction::Command(command) = interaction { + let _ = &command.defer(&ctx.http()).await.expect("Cannot defer"); - let content = Some(match command.data.name.as_str() { - "info" => commands::info::run(&ctx, &command).await, - "play" => commands::play::run(&ctx, &command).await, - "stop" => commands::stop::run(&ctx, &command).await, - _ => respond_with_error(&ctx, &command).await, - }); + let content = Some(match command.data.name.as_str() { + "info" => commands::info::run(&ctx, &command).await, + "play" => commands::play::run(&ctx, &command).await, + "stop" => commands::stop::run(&ctx, &command).await, + _ => respond_with_error(&ctx, &command).await, + }); - if let Some(embed) = content { - let followup = CreateInteractionResponseFollowup::new().embed(embed); - if let Err(why) = command.create_followup(&ctx.http, followup).await { - println!("Cannot followup to slash command: {why}") + if let Some(embed) = content { + let followup = CreateInteractionResponseFollowup::new().embed(embed); + if let Err(why) = command.create_followup(&ctx.http, followup).await { + println!("Cannot followup to slash command: {why}") + } } } } diff --git a/src/music/mod.rs b/src/music/mod.rs index f16ee08..28737b1 100644 --- a/src/music/mod.rs +++ b/src/music/mod.rs @@ -1,2 +1,3 @@ pub mod music_manager; -pub mod music_events; \ No newline at end of file +pub mod music_events; +mod music_queue; \ No newline at end of file diff --git a/src/music/music_events.rs b/src/music/music_events.rs index ca48045..6358fd4 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -1,9 +1,8 @@ use std::sync::Arc; -use queues::IsQueue; use serenity::all::{ChannelId, GuildId, Http}; use serenity::async_trait; use songbird::{Event, EventContext, EventHandler}; -use crate::music::music_manager; +use crate::music::{music_manager, music_queue}; pub struct TrackEndNotifier { pub guild_id: GuildId, @@ -18,8 +17,10 @@ impl EventHandler for TrackEndNotifier { unsafe { // TODO: Does this need to be unsafe? if let EventContext::Track(track_list) = ctx { println!("The track ended!"); - let queue = music_manager::get_queue(&self.guild_id); - if queue.size() == 0 { + let music_queue = music_queue::get_queue(&self.guild_id); + let q = &music_queue.queue; + if q.len() == 0 { + // No more songs in queue, exit the vc let stopped = match music_manager::stop(&self.cmdctx, &self.guild_id).await { Ok(stopped) => stopped, Err(e) => { @@ -34,6 +35,19 @@ impl EventHandler for TrackEndNotifier { } return None; } + let head = music_queue::get_head(&self.guild_id); + if head.is_none() { + println!("Cannot get head of queue"); + return None; + } + let head = head.unwrap(); + /*let started = match music_manager::play(&self.cmdctx, &self.guild_id, &head).await { + Ok(started) => started, + Err(e) => { + println!("Cannot play: {:?}", e); + return None; + } + }; */ } } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 7781b98..64a2063 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -1,28 +1,16 @@ -use std::collections::{HashMap}; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc}; use std::time::Duration; -use once_cell::sync::Lazy; -use queues::Queue; use serenity::all::{Context, CreateEmbed, GuildId, UserId}; use songbird::{Event, TrackEvent}; use songbird::error::JoinError; use songbird::input::{Compose, YoutubeDl}; use crate::HttpKey; -use crate::music::music_events; +use crate::music::{music_events, music_queue}; use crate::util::embed::Embed; use crate::util::user_util; use crate::util::user_util::get_vc_id; -/// pub static mut MUSIC_QUEUE: HashMap> = HashMap::new(); -pub static mut MUSIC_QUEUE: Lazy>>> = Lazy::new(|| { - Mutex::new(HashMap::new()) -}); // TODO: This does not work and this is not the way to do it. This is a placeholder for now. - -pub unsafe fn get_queue(guild_id: &GuildId) -> &Queue { - MUSIC_QUEUE.lock().unwrap().entry(*guild_id).or_insert_with(Queue::new) -} - -pub async fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str, query: &str) -> CreateEmbed { +pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str, query: &str) -> CreateEmbed { if !user_util::is_user_connected_to_vc(ctx, guild_id, user_id).await { return Embed::create(username, "You are not connected to a VC", "Connect to my VC to control the music."); } @@ -35,7 +23,7 @@ pub async fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: & }; - let manager = &songbird::get(ctx) + let manager = &songbird::get(ctx) // TODO match .await .expect("Cannot get Songbird.") .clone(); @@ -64,6 +52,16 @@ pub async fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: & ); } } + + let currently_playing = music_queue::get_now_playing(&guild_id); + music_queue::add_to_queue(&guild_id, query.to_string()); + if currently_playing != "".to_string() { + // Add to queue + return Embed::create(username, "Added to queue", "The song was added to the queue."); + } + + let query = music_queue::get_head(&guild_id).expect("Cannot get head of queue"); + music_queue::set_now_playing(&guild_id, query.clone()); // Get query let do_search = !query.starts_with("http"); @@ -83,13 +81,13 @@ pub async fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: & let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => { - return Embed::create(username, "Error", "Cannot get handler"); + return Embed::create("", "Error", "Cannot get handler"); }, }; // Start playing let mut handler = handler_lock.lock().await; - let track_handle = handler.play_input(src.clone().into()); // TODO: Add event handlers + let _ = handler.play_input(src.clone().into()); // TODO: Add event handlers handler.add_global_event( Event::Track(TrackEvent::End), music_events::TrackEndNotifier { @@ -113,8 +111,11 @@ pub async fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: & .thumbnail(thumbnail) } +pub async unsafe fn play() { + +} -pub async fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str) -> CreateEmbed { +pub async unsafe fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str) -> CreateEmbed { if !user_util::is_self_connected_to_vc(ctx, guild_id).await { // Bot is not connectd to vc; no need to dc return Embed::create( @@ -142,18 +143,25 @@ pub async fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: &UserId return Embed::create(username, "There was an error", "Tell moonleay to check the logs.".to_string()); } }; - - if !stopped { - return Embed::create(username, "Can't stop, what ain't running.", "I am not connected. I cant stop doing something, when I'm not doing it".to_string()); + + return if !stopped { + Embed::create(username, "Can't stop, what ain't running.", "I am not connected. I cant stop doing something, when I'm not doing it".to_string()) } else { - return Embed::create( + music_queue::delete_queue(guild_id); // Clear queue + + Embed::create( username, "I stopped and left", "Just like your girlfriend.", - ); + ) } } +/// pub async unsafe fn play_song(ctx: &Context, guild_id: &GuildId, query: String) -> Result { + +/// } + + // Make the bot leave the voice channel. Returns Ok(true) if bot was connected, returns Ok(false) if bot was not connected. Returns Err if something went wrong. pub async fn stop(ctx: &Context, guild_id: &GuildId) -> Result { let manager = songbird::get(ctx) diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs new file mode 100644 index 0000000..182a8ee --- /dev/null +++ b/src/music/music_queue.rs @@ -0,0 +1,65 @@ +use serenity::all::GuildId; + +pub struct MusicQueue { // God this sucks. This needs to be reprogrammed properly. + guild_id: GuildId, + pub queue: Vec, + pub now_playing: String, +} + +static mut MUSIC_QUEUE: Vec = Vec::new(); + +pub unsafe fn get_queue(guild_id: &GuildId) -> &MusicQueue { + let queue = MUSIC_QUEUE.iter().find(|q| q.guild_id == *guild_id); + match queue { + Some(queue) => queue, + None => { + let new_queue = MusicQueue { + guild_id: *guild_id, + queue: Vec::new(), + now_playing: "".to_string(), + }; + MUSIC_QUEUE.push(new_queue); + MUSIC_QUEUE.iter().find(|q| q.guild_id == *guild_id).expect("Cannot get queue") + } + } +} + +unsafe fn update_queue(guild_id: &GuildId, queue: Vec, now_playing: String) { + let index = MUSIC_QUEUE.iter().position(|q| q.guild_id == *guild_id).expect("Cannot get index"); + MUSIC_QUEUE[index] = MusicQueue{ + guild_id: *guild_id, + queue, + now_playing, + }; +} + +pub unsafe fn delete_queue(guild_id: &GuildId) { + let index = MUSIC_QUEUE.iter().position(|q| q.guild_id == *guild_id).expect("Cannot get index"); + MUSIC_QUEUE.remove(index); +} + +pub unsafe fn add_to_queue(guild_id: &GuildId, input: String) { + let queue = get_queue(guild_id); + let mut new_queue = queue.queue.clone(); + new_queue.push(input); + update_queue(guild_id, new_queue, queue.now_playing.clone()); +} + +pub unsafe fn get_head(guild_id: &GuildId) -> Option { + let queue = get_queue(guild_id); + let mut q = queue.queue.clone(); + let result = q.first().map(|s| s.clone()); + q.remove(0); + update_queue(guild_id, q, queue.now_playing.clone()); + result +} + +pub unsafe fn set_now_playing(guild_id: &GuildId, now_playing: String) { + let queue = get_queue(guild_id); + update_queue(guild_id, queue.queue.clone(), now_playing); +} + +pub unsafe fn get_now_playing(guild_id: &GuildId) -> String { + let queue = get_queue(guild_id); + queue.now_playing.clone() +} \ No newline at end of file From b493209a3648a9d2bd3222171b5a76d890ec81d1 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sat, 9 Mar 2024 20:05:20 +0100 Subject: [PATCH 12/41] chore!: removed .vscode --- .vscode/settings.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 285dc0b..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rust-analyzer.linkedProjects": [ - ".\\Cargo.toml" - ], - "rust-analyzer.showUnlinkedFileNotification": false -} \ No newline at end of file From ef06cbc90bdaddce79f49d7e16d03c4c0b09a7d3 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sat, 9 Mar 2024 20:05:49 +0100 Subject: [PATCH 13/41] feat: added lazy_static --- Cargo.lock | 1 + Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index cd4694e..4391254 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1561,6 +1561,7 @@ dependencies = [ "chrono", "confy", "futures", + "lazy_static", "reqwest", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 394638a..cb0a401 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,4 @@ tracing = "0.1.40" tracing-subscriber = "0.3.18" tracing-futures = "0.2.5" futures = "0.3.1" +lazy_static = "1.4.0" From e1cf394362cd909aa682909acbd03bc194f3b1a4 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sat, 9 Mar 2024 20:06:08 +0100 Subject: [PATCH 14/41] WIP: continued work on queue --- src/main.rs | 4 +-- src/music/music_events.rs | 8 +----- src/music/music_manager.rs | 52 +++++++++++++++++++++++++------------- src/music/music_queue.rs | 19 +++++++------- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/main.rs b/src/main.rs index 090a238..6f32485 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,8 +59,8 @@ impl EventHandler for Handler { println!("Commands are registered and Rustendo is ready for Freddy."); } - async fn voice_state_update(&self, ctx: Context, old: Option, new: VoiceState) { - if !new.channel_id.is_none() { + async fn voice_state_update(&self, ctx: Context, old: Option, new: VoiceState) { // FIXME: This does not work, when switching channels + if new.channel_id.is_some() { return; // User did not leave, ignore } if let Some(old) = old { diff --git a/src/music/music_events.rs b/src/music/music_events.rs index 6358fd4..dbf84a0 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -41,13 +41,7 @@ impl EventHandler for TrackEndNotifier { return None; } let head = head.unwrap(); - /*let started = match music_manager::play(&self.cmdctx, &self.guild_id, &head).await { - Ok(started) => started, - Err(e) => { - println!("Cannot play: {:?}", e); - return None; - } - }; */ + music_manager::play_song(&self.cmdctx, &self.guild_id, head).await; } } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 64a2063..26c0496 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -53,16 +53,6 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use } } - let currently_playing = music_queue::get_now_playing(&guild_id); - music_queue::add_to_queue(&guild_id, query.to_string()); - if currently_playing != "".to_string() { - // Add to queue - return Embed::create(username, "Added to queue", "The song was added to the queue."); - } - - let query = music_queue::get_head(&guild_id).expect("Cannot get head of queue"); - music_queue::set_now_playing(&guild_id, query.clone()); - // Get query let do_search = !query.starts_with("http"); let http_client = { @@ -71,13 +61,25 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use .cloned() .expect("Guaranteed to exist in the typemap.") }; - + // Create source let mut src = if do_search { YoutubeDl::new_search(http_client, query.to_string()) } else { YoutubeDl::new(http_client, query.to_string()) }; + + let currently_playing = music_queue::get_now_playing(&guild_id); + music_queue::add_to_queue(&guild_id, src.clone()); + if currently_playing.is_some() { + // Add to queue + return Embed::create(username, "Added to queue", "The song was added to the queue."); + } + + let query = music_queue::get_head(&guild_id).expect("Cannot get head of queue"); + music_queue::set_now_playing(&guild_id, Some(src.clone())); + + let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => { @@ -97,7 +99,7 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use cmdctx: Arc::new(ctx.clone()), }, ); - + // Get metadata let metadata = src.aux_metadata().await.expect("Cannot get metadata"); let title = metadata.title.unwrap_or("Unknown title".to_string()); @@ -111,8 +113,27 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use .thumbnail(thumbnail) } -pub async unsafe fn play() { +pub async unsafe fn play_song(ctx: &Context, guild_id: &GuildId, target: YoutubeDl) { + let manager = &songbird::get(ctx) // TODO match + .await + .expect("Cannot get Songbird.") + .clone(); + if !user_util::is_self_connected_to_vc(ctx, guild_id).await { + println!("Bot is not connected to a VC, cannot play."); + return; + } + + music_queue::set_now_playing(&guild_id, Some(target.clone())); + let handler_lock = match manager.get(*guild_id) { + Some(handler) => handler, + None => { + return + }, + }; + + let mut handler = handler_lock.lock().await; + let _ = handler.play_input(target.into()); // TODO: Add event handlers } pub async unsafe fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str) -> CreateEmbed { @@ -157,11 +178,6 @@ pub async unsafe fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: } } -/// pub async unsafe fn play_song(ctx: &Context, guild_id: &GuildId, query: String) -> Result { - -/// } - - // Make the bot leave the voice channel. Returns Ok(true) if bot was connected, returns Ok(false) if bot was not connected. Returns Err if something went wrong. pub async fn stop(ctx: &Context, guild_id: &GuildId) -> Result { let manager = songbird::get(ctx) diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index 182a8ee..77b20aa 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -1,9 +1,10 @@ use serenity::all::GuildId; +use songbird::input::YoutubeDl; pub struct MusicQueue { // God this sucks. This needs to be reprogrammed properly. guild_id: GuildId, - pub queue: Vec, - pub now_playing: String, + pub queue: Vec, + pub now_playing: Option, } static mut MUSIC_QUEUE: Vec = Vec::new(); @@ -16,7 +17,7 @@ pub unsafe fn get_queue(guild_id: &GuildId) -> &MusicQueue { let new_queue = MusicQueue { guild_id: *guild_id, queue: Vec::new(), - now_playing: "".to_string(), + now_playing: None, }; MUSIC_QUEUE.push(new_queue); MUSIC_QUEUE.iter().find(|q| q.guild_id == *guild_id).expect("Cannot get queue") @@ -24,7 +25,7 @@ pub unsafe fn get_queue(guild_id: &GuildId) -> &MusicQueue { } } -unsafe fn update_queue(guild_id: &GuildId, queue: Vec, now_playing: String) { +unsafe fn update_queue(guild_id: &GuildId, queue: Vec, now_playing: Option) { let index = MUSIC_QUEUE.iter().position(|q| q.guild_id == *guild_id).expect("Cannot get index"); MUSIC_QUEUE[index] = MusicQueue{ guild_id: *guild_id, @@ -38,14 +39,14 @@ pub unsafe fn delete_queue(guild_id: &GuildId) { MUSIC_QUEUE.remove(index); } -pub unsafe fn add_to_queue(guild_id: &GuildId, input: String) { +pub unsafe fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { let queue = get_queue(guild_id); let mut new_queue = queue.queue.clone(); new_queue.push(input); update_queue(guild_id, new_queue, queue.now_playing.clone()); } -pub unsafe fn get_head(guild_id: &GuildId) -> Option { +pub unsafe fn get_head(guild_id: &GuildId) -> Option { let queue = get_queue(guild_id); let mut q = queue.queue.clone(); let result = q.first().map(|s| s.clone()); @@ -54,12 +55,12 @@ pub unsafe fn get_head(guild_id: &GuildId) -> Option { result } -pub unsafe fn set_now_playing(guild_id: &GuildId, now_playing: String) { +pub unsafe fn set_now_playing(guild_id: &GuildId, now_playing: Option) { let queue = get_queue(guild_id); update_queue(guild_id, queue.queue.clone(), now_playing); } -pub unsafe fn get_now_playing(guild_id: &GuildId) -> String { +pub unsafe fn get_now_playing(guild_id: &GuildId) -> &Option { let queue = get_queue(guild_id); - queue.now_playing.clone() + &queue.now_playing } \ No newline at end of file From 9c1f6bee6dd53e1962596f9758cbb5f8e589a4f6 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sat, 9 Mar 2024 20:09:17 +0100 Subject: [PATCH 15/41] chore: clippy improvements --- src/commands/play.rs | 18 +++-- src/commands/stop.rs | 6 +- src/music/music_events.rs | 13 ++-- src/music/music_manager.rs | 141 +++++++++++++++++++++++-------------- src/music/music_queue.rs | 24 +++++-- src/util/user_util.rs | 33 ++++----- 6 files changed, 143 insertions(+), 92 deletions(-) diff --git a/src/commands/play.rs b/src/commands/play.rs index 8fceb13..8613fd2 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -1,14 +1,15 @@ +use crate::music::music_manager; + use serenity::all::{CommandDataOptionValue, CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateCommandOption, CreateEmbed}; use serenity::model::application::CommandOptionType; -use crate::music::music_manager; use crate::util::embed::Embed; pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let options = &command.data.options; - + let query = options.first().and_then(|option| { if let CommandDataOptionValue::String(query) = &option.value { Some(query) @@ -16,7 +17,7 @@ pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEm None } }); - + if query.is_none() { return Embed::create(username, "Error 400", "There is no query provided"); } @@ -27,8 +28,15 @@ pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEm return Embed::create(username, "GuildId not found", "Could not find guild id."); } }; - - music_manager::attempt_to_queue_song(&ctx, &guild_id, &command.user.id, &command.user.name, query.unwrap()).await + + music_manager::attempt_to_queue_song( + ctx, + guild_id, + &command.user.id, + &command.user.name, + query.unwrap(), + ) + .await } pub fn register() -> CreateCommand { diff --git a/src/commands/stop.rs b/src/commands/stop.rs index beee7ea..8a65e35 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -1,7 +1,7 @@ -use serenity::all::{CommandInteraction, Context}; -use serenity::builder::{CreateCommand, CreateEmbed}; use crate::music::music_manager; use crate::util::embed::Embed; +use serenity::all::{CommandInteraction, Context}; +use serenity::builder::{CreateCommand, CreateEmbed}; pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); @@ -13,7 +13,7 @@ pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEm } }; - music_manager::attempt_to_stop(&ctx, &guild_id, &command.user.id, &command.user.name).await + music_manager::attempt_to_stop(ctx, guild_id, &command.user.id, &command.user.name).await } pub fn register() -> CreateCommand { diff --git a/src/music/music_events.rs b/src/music/music_events.rs index dbf84a0..abde30f 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -1,8 +1,8 @@ -use std::sync::Arc; +use crate::music::{music_manager, music_queue}; use serenity::all::{ChannelId, GuildId, Http}; use serenity::async_trait; use songbird::{Event, EventContext, EventHandler}; -use crate::music::{music_manager, music_queue}; +use std::sync::Arc; pub struct TrackEndNotifier { pub guild_id: GuildId, @@ -14,12 +14,13 @@ pub struct TrackEndNotifier { #[async_trait] impl EventHandler for TrackEndNotifier { async fn act(&self, ctx: &EventContext<'_>) -> Option { - unsafe { // TODO: Does this need to be unsafe? - if let EventContext::Track(track_list) = ctx { + unsafe { + // TODO: Does this need to be unsafe? + if let EventContext::Track(..) = ctx { println!("The track ended!"); let music_queue = music_queue::get_queue(&self.guild_id); let q = &music_queue.queue; - if q.len() == 0 { + if q.is_empty() { // No more songs in queue, exit the vc let stopped = match music_manager::stop(&self.cmdctx, &self.guild_id).await { Ok(stopped) => stopped, @@ -30,7 +31,7 @@ impl EventHandler for TrackEndNotifier { }; if stopped { println!("Stopped playing successfully."); - } else { + } else { println!("Failed to stop playing."); } return None; diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 26c0496..18c1e88 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -1,26 +1,35 @@ -use std::sync::{Arc}; -use std::time::Duration; -use serenity::all::{Context, CreateEmbed, GuildId, UserId}; -use songbird::{Event, TrackEvent}; -use songbird::error::JoinError; -use songbird::input::{Compose, YoutubeDl}; -use crate::HttpKey; use crate::music::{music_events, music_queue}; use crate::util::embed::Embed; use crate::util::user_util; use crate::util::user_util::get_vc_id; +use crate::HttpKey; +use serenity::all::{Context, CreateEmbed, GuildId, UserId}; +use songbird::error::JoinError; +use songbird::input::{Compose, YoutubeDl}; +use songbird::{Event, TrackEvent}; +use std::sync::Arc; +use std::time::Duration; -pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str, query: &str) -> CreateEmbed { +pub async unsafe fn attempt_to_queue_song( + ctx: &Context, + guild_id: &GuildId, + user_id: &UserId, + username: &str, + query: &str, +) -> CreateEmbed { if !user_util::is_user_connected_to_vc(ctx, guild_id, user_id).await { - return Embed::create(username, "You are not connected to a VC", "Connect to my VC to control the music."); + return Embed::create( + username, + "You are not connected to a VC", + "Connect to my VC to control the music.", + ); } - let connect_to = match get_vc_id(ctx, &guild_id, &user_id).await { + let connect_to = match get_vc_id(ctx, guild_id, user_id).await { Some(channel_id) => channel_id, None => { return Embed::create(username, "Error", "Cannot get channel id"); } - }; let manager = &songbird::get(ctx) // TODO match @@ -28,18 +37,18 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use .expect("Cannot get Songbird.") .clone(); - let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await; - if !user_util::is_self_connected_to_vc(ctx, &guild_id).await { + let self_channel = user_util::get_self_vc_id(ctx, guild_id).await; + if !user_util::is_self_connected_to_vc(ctx, guild_id).await { // self is connected to vc, check if user is in same vc - if self_channel.is_none() { // TODO This could maybe be removed? + if self_channel.is_none() { + // TODO This could maybe be removed? // Connect to VC manager .join(*guild_id, connect_to) .await .expect("Cannot connect>..."); } - } else { let self_channel = self_channel.expect("Cannot get self channel"); @@ -52,7 +61,7 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use ); } } - + // Get query let do_search = !query.starts_with("http"); let http_client = { @@ -61,30 +70,33 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use .cloned() .expect("Guaranteed to exist in the typemap.") }; - + // Create source let mut src = if do_search { YoutubeDl::new_search(http_client, query.to_string()) } else { YoutubeDl::new(http_client, query.to_string()) }; - - let currently_playing = music_queue::get_now_playing(&guild_id); - music_queue::add_to_queue(&guild_id, src.clone()); + + let currently_playing = music_queue::get_now_playing(guild_id); + music_queue::add_to_queue(guild_id, src.clone()); if currently_playing.is_some() { // Add to queue - return Embed::create(username, "Added to queue", "The song was added to the queue."); + return Embed::create( + username, + "Added to queue", + "The song was added to the queue.", + ); } - let query = music_queue::get_head(&guild_id).expect("Cannot get head of queue"); - music_queue::set_now_playing(&guild_id, Some(src.clone())); - + let _query = music_queue::get_head(guild_id).expect("Cannot get head of queue"); + music_queue::set_now_playing(guild_id, Some(src.clone())); let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => { return Embed::create("", "Error", "Cannot get handler"); - }, + } }; // Start playing @@ -99,18 +111,32 @@ pub async unsafe fn attempt_to_queue_song(ctx: &Context, guild_id: &GuildId, use cmdctx: Arc::new(ctx.clone()), }, ); - + // Get metadata let metadata = src.aux_metadata().await.expect("Cannot get metadata"); let title = metadata.title.unwrap_or("Unknown title".to_string()); let author = metadata.artist.unwrap_or("Unknown artist".to_string()); let duration = metadata.duration.unwrap_or(Duration::from_millis(0)); - let thumbnail = metadata.thumbnail.unwrap_or("https://http.cat/images/404.jpg".to_string()); - let link = metadata.source_url.unwrap_or("https://piped.moonleay.net/404".to_string()); + let thumbnail = metadata + .thumbnail + .unwrap_or("https://http.cat/images/404.jpg".to_string()); + let link = metadata + .source_url + .unwrap_or("https://piped.moonleay.net/404".to_string()); - Embed::create(username, "Added to queue", format!("{} by {} ({}min {}sec) was added to the queue.\n [[Link]({})]", - title, author, duration.as_secs() / 60, duration.as_secs() % 60, link)) - .thumbnail(thumbnail) + Embed::create( + username, + "Added to queue", + format!( + "{} by {} ({}min {}sec) was added to the queue.\n [[Link]({})]", + title, + author, + duration.as_secs() / 60, + duration.as_secs() % 60, + link + ), + ) + .thumbnail(thumbnail) } pub async unsafe fn play_song(ctx: &Context, guild_id: &GuildId, target: YoutubeDl) { @@ -118,25 +144,28 @@ pub async unsafe fn play_song(ctx: &Context, guild_id: &GuildId, target: Youtube .await .expect("Cannot get Songbird.") .clone(); - + if !user_util::is_self_connected_to_vc(ctx, guild_id).await { println!("Bot is not connected to a VC, cannot play."); return; } - - music_queue::set_now_playing(&guild_id, Some(target.clone())); + + music_queue::set_now_playing(guild_id, Some(target.clone())); let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, - None => { - return - }, + None => return, }; let mut handler = handler_lock.lock().await; let _ = handler.play_input(target.into()); // TODO: Add event handlers } -pub async unsafe fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str) -> CreateEmbed { +pub async unsafe fn attempt_to_stop( + ctx: &Context, + guild_id: &GuildId, + user_id: &UserId, + username: &str, +) -> CreateEmbed { if !user_util::is_self_connected_to_vc(ctx, guild_id).await { // Bot is not connectd to vc; no need to dc return Embed::create( @@ -145,8 +174,12 @@ pub async unsafe fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: "And therefore there is no need to do anything.", ); } - let self_channel = user_util::get_self_vc_id(ctx, &guild_id).await.expect("Cannot get self channel"); - let connect_to = get_vc_id(ctx, &guild_id, &user_id).await.expect("Cannot get channel id"); + let self_channel = user_util::get_self_vc_id(ctx, guild_id) + .await + .expect("Cannot get self channel"); + let connect_to = get_vc_id(ctx, guild_id, user_id) + .await + .expect("Cannot get channel id"); // Check if user is in the same VC as the bot if self_channel != connect_to { @@ -161,20 +194,24 @@ pub async unsafe fn attempt_to_stop(ctx: &Context, guild_id: &GuildId, user_id: Ok(stopped) => stopped, Err(e) => { println!("Error while stopping: {:?}", e); - return Embed::create(username, "There was an error", "Tell moonleay to check the logs.".to_string()); + return Embed::create( + username, + "There was an error", + "Tell moonleay to check the logs.".to_string(), + ); } }; - return if !stopped { - Embed::create(username, "Can't stop, what ain't running.", "I am not connected. I cant stop doing something, when I'm not doing it".to_string()) - } else { - music_queue::delete_queue(guild_id); // Clear queue - + if !stopped { Embed::create( username, - "I stopped and left", - "Just like your girlfriend.", + "Can't stop, what ain't running.", + "I am not connected. I cant stop doing something, when I'm not doing it".to_string(), ) + } else { + music_queue::delete_queue(guild_id); // Clear queue + + Embed::create(username, "I stopped and left", "Just like your girlfriend.") } } @@ -188,10 +225,8 @@ pub async fn stop(ctx: &Context, guild_id: &GuildId) -> Result let has_handler = manager.get(*guild_id).is_some(); if has_handler { - if let Err(e) = manager.remove(*guild_id).await { - return Err(e); // Failed to remove handler - } - return Ok(true) // Handler removed + manager.remove(*guild_id).await?; + return Ok(true); // Handler removed } - Ok(false) // No handler, so it's already stopped + Ok(false) // No handler, so it's already stopped } diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index 77b20aa..3d6a2ff 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -1,7 +1,8 @@ use serenity::all::GuildId; use songbird::input::YoutubeDl; -pub struct MusicQueue { // God this sucks. This needs to be reprogrammed properly. +pub struct MusicQueue { + // God this sucks. This needs to be reprogrammed properly. guild_id: GuildId, pub queue: Vec, pub now_playing: Option, @@ -20,14 +21,20 @@ pub unsafe fn get_queue(guild_id: &GuildId) -> &MusicQueue { now_playing: None, }; MUSIC_QUEUE.push(new_queue); - MUSIC_QUEUE.iter().find(|q| q.guild_id == *guild_id).expect("Cannot get queue") + MUSIC_QUEUE + .iter() + .find(|q| q.guild_id == *guild_id) + .expect("Cannot get queue") } } } unsafe fn update_queue(guild_id: &GuildId, queue: Vec, now_playing: Option) { - let index = MUSIC_QUEUE.iter().position(|q| q.guild_id == *guild_id).expect("Cannot get index"); - MUSIC_QUEUE[index] = MusicQueue{ + let index = MUSIC_QUEUE + .iter() + .position(|q| q.guild_id == *guild_id) + .expect("Cannot get index"); + MUSIC_QUEUE[index] = MusicQueue { guild_id: *guild_id, queue, now_playing, @@ -35,7 +42,10 @@ unsafe fn update_queue(guild_id: &GuildId, queue: Vec, now_playing: O } pub unsafe fn delete_queue(guild_id: &GuildId) { - let index = MUSIC_QUEUE.iter().position(|q| q.guild_id == *guild_id).expect("Cannot get index"); + let index = MUSIC_QUEUE + .iter() + .position(|q| q.guild_id == *guild_id) + .expect("Cannot get index"); MUSIC_QUEUE.remove(index); } @@ -49,7 +59,7 @@ pub unsafe fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { pub unsafe fn get_head(guild_id: &GuildId) -> Option { let queue = get_queue(guild_id); let mut q = queue.queue.clone(); - let result = q.first().map(|s| s.clone()); + let result = q.first().cloned(); q.remove(0); update_queue(guild_id, q, queue.now_playing.clone()); result @@ -63,4 +73,4 @@ pub unsafe fn set_now_playing(guild_id: &GuildId, now_playing: Option pub unsafe fn get_now_playing(guild_id: &GuildId) -> &Option { let queue = get_queue(guild_id); &queue.now_playing -} \ No newline at end of file +} diff --git a/src/util/user_util.rs b/src/util/user_util.rs index 8e7bf74..32c5423 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -1,52 +1,47 @@ -use std::collections::HashMap; use serenity::all::{ChannelId, Context, Guild, GuildId, PartialGuild, UserId, VoiceState}; +use std::collections::HashMap; /// Request a guild by id, get it from cache pub fn request_guild(ctx: &Context, guild_id: &GuildId) -> Guild { - let guild = match guild_id.to_guild_cached(&ctx.cache) { + match guild_id.to_guild_cached(&ctx.cache) { Some(guild) => guild.clone(), None => { panic!("Cannot get guild with id {:?}!", guild_id); } - }; - - guild + } } /// Request a guild by id, get it from Discord, not from cache, this is a partial guild pub async fn request_partial_guild(ctx: &Context, guild_id: &GuildId) -> PartialGuild { - let guild = match ctx.http.get_guild(*guild_id).await { + match ctx.http.get_guild(*guild_id).await { Ok(guild) => guild, Err(error) => { panic!("error whilest getting guild from Discord {}", error); } - }; - - guild + } } /// Get the voice channel id of a user pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> Option { - let guild = request_guild(&ctx, guild_id); + let guild = request_guild(ctx, guild_id); guild .voice_states .get(user_id) .and_then(|voice_state| voice_state.channel_id) - } /// Check if the bot is connected to a voice channel pub async fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { let channel_id = get_self_vc_id(ctx, guild_id); - !channel_id.await.is_none() + channel_id.await.is_some() } /// Check if a user is connected to a voice channel pub async fn is_user_connected_to_vc(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> bool { let channel_id = get_vc_id(ctx, guild_id, user_id).await; - !channel_id.is_none() + channel_id.is_some() } /// Get the voice channel id of the bot @@ -57,15 +52,17 @@ pub async fn get_self_vc_id(ctx: &Context, guild_id: &GuildId) -> Option HashMap{ +pub async fn get_voice_states(ctx: &Context, guild_id: &GuildId) -> HashMap { let guild = request_guild(ctx, guild_id); - let voice_states = guild.voice_states.clone(); - voice_states + guild.voice_states.clone() } - /// Get the amount of members in a voice channel -pub async fn get_amount_of_members_in_vc(ctx: &Context, guild_id: &GuildId, channel_id: &ChannelId,) -> usize { +pub async fn get_amount_of_members_in_vc( + ctx: &Context, + guild_id: &GuildId, + channel_id: &ChannelId, +) -> usize { let voice_states = get_voice_states(ctx, guild_id).await; let amount = voice_states .iter() From c6af238f06d5a26e27d5d1decd041ffdda6423f5 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 10 Mar 2024 15:27:18 +0100 Subject: [PATCH 16/41] WIP: working on removing unsafe from appliction --- src/main.rs | 43 +++++++++++++++++- src/music/mod.rs | 2 +- src/music/music_events.rs | 4 +- src/music/music_manager.rs | 8 ++-- src/music/music_queue.rs | 89 +++++++++++++------------------------- 5 files changed, 77 insertions(+), 69 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6f32485..1422ec3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,9 @@ mod commands; mod util; mod music; -use serenity::all::{CommandInteraction, CreateInteractionResponseFollowup, OnlineStatus, VoiceState}; +use serenity::all::{CommandInteraction, CreateInteractionResponseFollowup, GuildId, OnlineStatus, VoiceState}; use serenity::async_trait; -use serenity::builder::{CreateEmbed}; +use serenity::builder::CreateEmbed; use serenity::gateway::ActivityData; use serenity::model::application::{Command, Interaction}; use serenity::model::gateway::Ready; @@ -24,6 +24,45 @@ impl TypeMapKey for HttpKey { type Value = HttpClient; } + + + +// lazy static stuff. I don't like it, but it has to be here, bc it has to be @ root +#[macro_use] +extern crate lazy_static; + +use std::collections::HashMap; +use crate::music::music_queue::MusicQueue; + +lazy_static! { + static ref HASHMAP: Mutex> = { + Mutex::new(HashMap::new()) + }; +} + +pub async fn get_queue(guild_id: GuildId) -> MusicQueue { + match HASHMAP.lock().await.get(&guild_id) { + Some(music_queue) => music_queue.clone(), + None => { + let q = MusicQueue { + guild_id: guild_id, + queue: Vec::new(), + now_playing: None + }; + HASHMAP.lock().await.insert(guild_id, q.clone()); + q + } + } +} + + +pub async fn set_queue(guild_id: GuildId, queue: MusicQueue) { + HASHMAP.lock().await.insert(guild_id, queue); +} + + + + struct Handler; #[async_trait] diff --git a/src/music/mod.rs b/src/music/mod.rs index 28737b1..8224adc 100644 --- a/src/music/mod.rs +++ b/src/music/mod.rs @@ -1,3 +1,3 @@ pub mod music_manager; pub mod music_events; -mod music_queue; \ No newline at end of file +pub mod music_queue; \ No newline at end of file diff --git a/src/music/music_events.rs b/src/music/music_events.rs index abde30f..a58c78c 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -14,11 +14,10 @@ pub struct TrackEndNotifier { #[async_trait] impl EventHandler for TrackEndNotifier { async fn act(&self, ctx: &EventContext<'_>) -> Option { - unsafe { // TODO: Does this need to be unsafe? if let EventContext::Track(..) = ctx { println!("The track ended!"); - let music_queue = music_queue::get_queue(&self.guild_id); + let music_queue = crate::get_queue(self.guild_id).await; let q = &music_queue.queue; if q.is_empty() { // No more songs in queue, exit the vc @@ -44,7 +43,6 @@ impl EventHandler for TrackEndNotifier { let head = head.unwrap(); music_manager::play_song(&self.cmdctx, &self.guild_id, head).await; } - } None } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 18c1e88..476af45 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -10,7 +10,7 @@ use songbird::{Event, TrackEvent}; use std::sync::Arc; use std::time::Duration; -pub async unsafe fn attempt_to_queue_song( +pub async fn attempt_to_queue_song( ctx: &Context, guild_id: &GuildId, user_id: &UserId, @@ -139,7 +139,7 @@ pub async unsafe fn attempt_to_queue_song( .thumbnail(thumbnail) } -pub async unsafe fn play_song(ctx: &Context, guild_id: &GuildId, target: YoutubeDl) { +pub async fn play_song(ctx: &Context, guild_id: &GuildId, target: &YoutubeDl) { let manager = &songbird::get(ctx) // TODO match .await .expect("Cannot get Songbird.") @@ -157,10 +157,10 @@ pub async unsafe fn play_song(ctx: &Context, guild_id: &GuildId, target: Youtube }; let mut handler = handler_lock.lock().await; - let _ = handler.play_input(target.into()); // TODO: Add event handlers + let _ = handler.play_input(target.clone().into()); // TODO: Add event handlers } -pub async unsafe fn attempt_to_stop( +pub async fn attempt_to_stop( ctx: &Context, guild_id: &GuildId, user_id: &UserId, diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index 3d6a2ff..6862ebd 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -1,76 +1,47 @@ use serenity::all::GuildId; use songbird::input::YoutubeDl; +#[derive(Debug, Clone)] pub struct MusicQueue { // God this sucks. This needs to be reprogrammed properly. - guild_id: GuildId, + pub guild_id: GuildId, pub queue: Vec, pub now_playing: Option, } -static mut MUSIC_QUEUE: Vec = Vec::new(); +pub async fn delete_queue(guild_id: &GuildId) { + let mut queue = crate::get_queue(*guild_id).await; + queue.now_playing = None; + queue.queue = Vec::new(); + crate::set_queue(*guild_id, queue); +} -pub unsafe fn get_queue(guild_id: &GuildId) -> &MusicQueue { - let queue = MUSIC_QUEUE.iter().find(|q| q.guild_id == *guild_id); - match queue { - Some(queue) => queue, - None => { - let new_queue = MusicQueue { - guild_id: *guild_id, - queue: Vec::new(), - now_playing: None, - }; - MUSIC_QUEUE.push(new_queue); - MUSIC_QUEUE - .iter() - .find(|q| q.guild_id == *guild_id) - .expect("Cannot get queue") - } +pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { + let mut queue = crate::get_queue(*guild_id).await; + queue.queue.push(input); + crate::set_queue(*guild_id, queue); +} + +pub async fn get_head(guild_id: &GuildId) -> Option<&YoutubeDl> { + let music_queue = crate::get_queue(*guild_id).await; + if music_queue.queue.is_empty() { + return None; } -} - -unsafe fn update_queue(guild_id: &GuildId, queue: Vec, now_playing: Option) { - let index = MUSIC_QUEUE - .iter() - .position(|q| q.guild_id == *guild_id) - .expect("Cannot get index"); - MUSIC_QUEUE[index] = MusicQueue { - guild_id: *guild_id, - queue, - now_playing, - }; -} - -pub unsafe fn delete_queue(guild_id: &GuildId) { - let index = MUSIC_QUEUE - .iter() - .position(|q| q.guild_id == *guild_id) - .expect("Cannot get index"); - MUSIC_QUEUE.remove(index); -} - -pub unsafe fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { - let queue = get_queue(guild_id); - let mut new_queue = queue.queue.clone(); - new_queue.push(input); - update_queue(guild_id, new_queue, queue.now_playing.clone()); -} - -pub unsafe fn get_head(guild_id: &GuildId) -> Option { - let queue = get_queue(guild_id); - let mut q = queue.queue.clone(); - let result = q.first().cloned(); - q.remove(0); - update_queue(guild_id, q, queue.now_playing.clone()); + let mut queue = music_queue.queue; + let result = queue.first(); + queue.remove(0); + music_queue.queue = queue; + crate::set_queue(*guild_id, music_queue); result } -pub unsafe fn set_now_playing(guild_id: &GuildId, now_playing: Option) { - let queue = get_queue(guild_id); - update_queue(guild_id, queue.queue.clone(), now_playing); +pub fn set_now_playing(guild_id: &GuildId, now_playing: Option) { + let mut queue = crate::get_queue(*guild_id); + queue.now_playing = now_playing; + crate::set_queue(*guild_id, queue) } -pub unsafe fn get_now_playing(guild_id: &GuildId) -> &Option { - let queue = get_queue(guild_id); - &queue.now_playing +pub fn get_now_playing(guild_id: &GuildId) -> Option { + let queue = crate::get_queue(*guild_id); + queue.now_playing } From e79b4142de1669ae560b9ca6967e62508fed1a46 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 15:39:11 +0100 Subject: [PATCH 17/41] [WIP] fix: music queue bugs --- src/main.rs | 43 ++++++++++++++++--------------- src/music/music_events.rs | 52 +++++++++++++++++++------------------- src/music/music_manager.rs | 14 +++++----- src/music/music_queue.rs | 31 ++++++++++------------- 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1422ec3..926461d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,10 @@ mod commands; -mod util; mod music; +mod util; -use serenity::all::{CommandInteraction, CreateInteractionResponseFollowup, GuildId, OnlineStatus, VoiceState}; +use serenity::all::{ + CommandInteraction, CreateInteractionResponseFollowup, GuildId, OnlineStatus, VoiceState, +}; use serenity::async_trait; use serenity::builder::CreateEmbed; use serenity::gateway::ActivityData; @@ -24,45 +26,36 @@ impl TypeMapKey for HttpKey { type Value = HttpClient; } - - - // lazy static stuff. I don't like it, but it has to be here, bc it has to be @ root #[macro_use] extern crate lazy_static; -use std::collections::HashMap; use crate::music::music_queue::MusicQueue; +use std::collections::HashMap; lazy_static! { - static ref HASHMAP: Mutex> = { - Mutex::new(HashMap::new()) - }; + static ref HASHMAP: Mutex> = Mutex::new(HashMap::new()); } -pub async fn get_queue(guild_id: GuildId) -> MusicQueue { +pub async fn get_queue(guild_id: &GuildId) -> MusicQueue { match HASHMAP.lock().await.get(&guild_id) { Some(music_queue) => music_queue.clone(), None => { let q = MusicQueue { - guild_id: guild_id, + guild_id: *guild_id, queue: Vec::new(), - now_playing: None + now_playing: None, }; - HASHMAP.lock().await.insert(guild_id, q.clone()); + HASHMAP.lock().await.insert(*guild_id, q.clone()); q } } } - -pub async fn set_queue(guild_id: GuildId, queue: MusicQueue) { - HASHMAP.lock().await.insert(guild_id, queue); +pub async fn set_queue(guild_id: &GuildId, queue: MusicQueue) { + HASHMAP.lock().await.insert(*guild_id, queue); } - - - struct Handler; #[async_trait] @@ -98,7 +91,8 @@ impl EventHandler for Handler { println!("Commands are registered and Rustendo is ready for Freddy."); } - async fn voice_state_update(&self, ctx: Context, old: Option, new: VoiceState) { // FIXME: This does not work, when switching channels + async fn voice_state_update(&self, ctx: Context, old: Option, new: VoiceState) { + // FIXME: This does not work, when switching channels if new.channel_id.is_some() { return; // User did not leave, ignore } @@ -106,7 +100,14 @@ impl EventHandler for Handler { if !user_util::is_self_connected_to_vc(&ctx, &old.guild_id.unwrap()).await { return; // Bot is not connected to a VC, ignore } - if user_util::get_amount_of_members_in_vc(&ctx, &old.guild_id.unwrap(), &old.channel_id.unwrap()).await < 2 { + if user_util::get_amount_of_members_in_vc( + &ctx, + &old.guild_id.unwrap(), + &old.channel_id.unwrap(), + ) + .await + < 2 + { let manager = songbird::get(&ctx).await.expect("Cannot get Songbird"); if let Err(e) = manager.remove(old.guild_id.unwrap()).await { println!("Failed to remove handler: {:?}", e); diff --git a/src/music/music_events.rs b/src/music/music_events.rs index a58c78c..3b52714 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -14,35 +14,35 @@ pub struct TrackEndNotifier { #[async_trait] impl EventHandler for TrackEndNotifier { async fn act(&self, ctx: &EventContext<'_>) -> Option { - // TODO: Does this need to be unsafe? - if let EventContext::Track(..) = ctx { - println!("The track ended!"); - let music_queue = crate::get_queue(self.guild_id).await; - let q = &music_queue.queue; - if q.is_empty() { - // No more songs in queue, exit the vc - let stopped = match music_manager::stop(&self.cmdctx, &self.guild_id).await { - Ok(stopped) => stopped, - Err(e) => { - println!("Cannot stop: {:?}", e); - return None; - } - }; - if stopped { - println!("Stopped playing successfully."); - } else { - println!("Failed to stop playing."); + // TODO: Does this need to be unsafe? + if let EventContext::Track(..) = ctx { + println!("The track ended!"); + let music_queue = crate::get_queue(&self.guild_id).await; + let q = &music_queue.queue; + if q.is_empty() { + // No more songs in queue, exit the vc + let stopped = match music_manager::stop(&self.cmdctx, &self.guild_id).await { + Ok(stopped) => stopped, + Err(e) => { + println!("Cannot stop: {:?}", e); + return None; } - return None; + }; + if stopped { + println!("Stopped playing successfully."); + } else { + println!("Failed to stop playing."); } - let head = music_queue::get_head(&self.guild_id); - if head.is_none() { - println!("Cannot get head of queue"); - return None; - } - let head = head.unwrap(); - music_manager::play_song(&self.cmdctx, &self.guild_id, head).await; + return None; } + let head = music_queue::get_head(&self.guild_id).await; + if head.is_none() { + println!("Cannot get head of queue"); + return None; + } + let head = head.unwrap(); + music_manager::play_song(&self.cmdctx, &self.guild_id, &head).await; + } None } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 476af45..2f42673 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -78,8 +78,8 @@ pub async fn attempt_to_queue_song( YoutubeDl::new(http_client, query.to_string()) }; - let currently_playing = music_queue::get_now_playing(guild_id); - music_queue::add_to_queue(guild_id, src.clone()); + let currently_playing = music_queue::get_now_playing(guild_id).await; + music_queue::add_to_queue(guild_id, src.clone()).await; if currently_playing.is_some() { // Add to queue return Embed::create( @@ -89,8 +89,10 @@ pub async fn attempt_to_queue_song( ); } - let _query = music_queue::get_head(guild_id).expect("Cannot get head of queue"); - music_queue::set_now_playing(guild_id, Some(src.clone())); + let _query = music_queue::get_head(guild_id) + .await + .expect("Cannot get head of queue"); + music_queue::set_now_playing(guild_id, Some(src.clone())).await; let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, @@ -150,7 +152,7 @@ pub async fn play_song(ctx: &Context, guild_id: &GuildId, target: &YoutubeDl) { return; } - music_queue::set_now_playing(guild_id, Some(target.clone())); + music_queue::set_now_playing(guild_id, Some(target.clone())).await; let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => return, @@ -209,7 +211,7 @@ pub async fn attempt_to_stop( "I am not connected. I cant stop doing something, when I'm not doing it".to_string(), ) } else { - music_queue::delete_queue(guild_id); // Clear queue + music_queue::delete_queue(guild_id).await; // Clear queue Embed::create(username, "I stopped and left", "Just like your girlfriend.") } diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index 6862ebd..c7501f9 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -10,38 +10,35 @@ pub struct MusicQueue { } pub async fn delete_queue(guild_id: &GuildId) { - let mut queue = crate::get_queue(*guild_id).await; + let mut queue = crate::get_queue(guild_id).await; queue.now_playing = None; queue.queue = Vec::new(); - crate::set_queue(*guild_id, queue); + crate::set_queue(guild_id, queue).await; } pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { - let mut queue = crate::get_queue(*guild_id).await; + let mut queue = crate::get_queue(guild_id).await; queue.queue.push(input); - crate::set_queue(*guild_id, queue); + crate::set_queue(guild_id, queue).await; } -pub async fn get_head(guild_id: &GuildId) -> Option<&YoutubeDl> { - let music_queue = crate::get_queue(*guild_id).await; +pub async fn get_head(guild_id: &GuildId) -> Option { + let mut music_queue = crate::get_queue(guild_id).await; if music_queue.queue.is_empty() { return None; } - let mut queue = music_queue.queue; - let result = queue.first(); - queue.remove(0); - music_queue.queue = queue; - crate::set_queue(*guild_id, music_queue); - result + let result = music_queue.queue.remove(0); + crate::set_queue(guild_id, music_queue).await; + Some(result) } -pub fn set_now_playing(guild_id: &GuildId, now_playing: Option) { - let mut queue = crate::get_queue(*guild_id); +pub async fn set_now_playing(guild_id: &GuildId, now_playing: Option) { + let mut queue = crate::get_queue(guild_id).await; queue.now_playing = now_playing; - crate::set_queue(*guild_id, queue) + crate::set_queue(guild_id, queue).await; } -pub fn get_now_playing(guild_id: &GuildId) -> Option { - let queue = crate::get_queue(*guild_id); +pub async fn get_now_playing(guild_id: &GuildId) -> Option { + let queue = crate::get_queue(guild_id).await; queue.now_playing } From fc32017a10bf1b303e056c1ef8513bebe4852a69 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 16:19:19 +0100 Subject: [PATCH 18/41] fix: mutex lock --- src/main.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 926461d..55eeaf4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,7 +38,9 @@ lazy_static! { } pub async fn get_queue(guild_id: &GuildId) -> MusicQueue { - match HASHMAP.lock().await.get(&guild_id) { + let mut queues = HASHMAP.lock().await; + + match queues.get(&guild_id) { Some(music_queue) => music_queue.clone(), None => { let q = MusicQueue { @@ -46,7 +48,7 @@ pub async fn get_queue(guild_id: &GuildId) -> MusicQueue { queue: Vec::new(), now_playing: None, }; - HASHMAP.lock().await.insert(*guild_id, q.clone()); + queues.insert(*guild_id, q.clone()); q } } From 29392dc72d94fefecfb5cbe12198b13bd3eda60c Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 17:46:35 +0100 Subject: [PATCH 19/41] chore: improve checks --- src/commands/info.rs | 4 +--- src/commands/mod.rs | 2 +- src/commands/play.rs | 2 +- src/commands/stop.rs | 2 +- src/main.rs | 26 ++++++++++++-------------- src/music/music_manager.rs | 4 +--- src/util/user_util.rs | 9 +++------ 7 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/commands/info.rs b/src/commands/info.rs index 2c93d36..a708372 100644 --- a/src/commands/info.rs +++ b/src/commands/info.rs @@ -3,9 +3,7 @@ use serenity::builder::{CreateCommand, CreateEmbed}; use crate::util::embed::Embed; -pub async fn run(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { - let username = command.user.name.as_str(); - +pub async fn run(_ctx: &Context, _command: &CommandInteraction) -> CreateEmbed { Embed::create( "", "Botendo v7", diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 6eaf7b9..755a0ee 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,3 +1,3 @@ pub mod info; pub mod play; -pub mod stop; \ No newline at end of file +pub mod stop; diff --git a/src/commands/play.rs b/src/commands/play.rs index 8613fd2..1e05661 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -6,7 +6,7 @@ use serenity::model::application::CommandOptionType; use crate::util::embed::Embed; -pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { +pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let options = &command.data.options; diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 8a65e35..665a24d 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -3,7 +3,7 @@ use crate::util::embed::Embed; use serenity::all::{CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateEmbed}; -pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { +pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let guild_id = match &command.guild_id { diff --git a/src/main.rs b/src/main.rs index 55eeaf4..20611a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,22 +63,20 @@ struct Handler; #[async_trait] impl EventHandler for Handler { async fn interaction_create(&self, ctx: Context, interaction: Interaction) { - unsafe { - if let Interaction::Command(command) = interaction { - let _ = &command.defer(&ctx.http()).await.expect("Cannot defer"); + if let Interaction::Command(command) = interaction { + let _ = &command.defer(&ctx.http()).await.expect("Cannot defer"); - let content = Some(match command.data.name.as_str() { - "info" => commands::info::run(&ctx, &command).await, - "play" => commands::play::run(&ctx, &command).await, - "stop" => commands::stop::run(&ctx, &command).await, - _ => respond_with_error(&ctx, &command).await, - }); + let content = Some(match command.data.name.as_str() { + "info" => commands::info::run(&ctx, &command).await, + "play" => commands::play::run(&ctx, &command).await, + "stop" => commands::stop::run(&ctx, &command).await, + _ => respond_with_error(&ctx, &command).await, + }); - if let Some(embed) = content { - let followup = CreateInteractionResponseFollowup::new().embed(embed); - if let Err(why) = command.create_followup(&ctx.http, followup).await { - println!("Cannot followup to slash command: {why}") - } + if let Some(embed) = content { + let followup = CreateInteractionResponseFollowup::new().embed(embed); + if let Err(why) = command.create_followup(&ctx.http, followup).await { + println!("Cannot followup to slash command: {why}") } } } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 2f42673..e1e9f13 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -224,9 +224,7 @@ pub async fn stop(ctx: &Context, guild_id: &GuildId) -> Result .expect("Cannot get Songbird") .clone(); - let has_handler = manager.get(*guild_id).is_some(); - - if has_handler { + if manager.get(*guild_id).is_some() { manager.remove(*guild_id).await?; return Ok(true); // Handler removed } diff --git a/src/util/user_util.rs b/src/util/user_util.rs index 32c5423..c3ef10a 100644 --- a/src/util/user_util.rs +++ b/src/util/user_util.rs @@ -12,6 +12,7 @@ pub fn request_guild(ctx: &Context, guild_id: &GuildId) -> Guild { } /// Request a guild by id, get it from Discord, not from cache, this is a partial guild +#[allow(dead_code)] pub async fn request_partial_guild(ctx: &Context, guild_id: &GuildId) -> PartialGuild { match ctx.http.get_guild(*guild_id).await { Ok(guild) => guild, @@ -32,16 +33,12 @@ pub async fn get_vc_id(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> O /// Check if the bot is connected to a voice channel pub async fn is_self_connected_to_vc(ctx: &Context, guild_id: &GuildId) -> bool { - let channel_id = get_self_vc_id(ctx, guild_id); - - channel_id.await.is_some() + get_self_vc_id(ctx, guild_id).await.is_some() } /// Check if a user is connected to a voice channel pub async fn is_user_connected_to_vc(ctx: &Context, guild_id: &GuildId, user_id: &UserId) -> bool { - let channel_id = get_vc_id(ctx, guild_id, user_id).await; - - channel_id.is_some() + get_vc_id(ctx, guild_id, user_id).await.is_some() } /// Get the voice channel id of the bot From 1dcd0ab66bcea8e4e79de96a0bd491cead5ad732 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 10 Mar 2024 19:35:08 +0100 Subject: [PATCH 20/41] added .vscode to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 53fe865..d8f4d9c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ config.json .idea/ -.zed +.vscode/ +.zed/ .DS_Store From ba0f1fb959a673c292b040eebbac4b1f087d732a Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 10 Mar 2024 19:36:02 +0100 Subject: [PATCH 21/41] feat: added skip command, reworked embed messages fix: fixed issue with queue not working properly --- src/commands/info.rs | 6 +- src/commands/mod.rs | 3 +- src/commands/play.rs | 4 +- src/commands/skip.rs | 24 ++++++ src/commands/stop.rs | 2 +- src/main.rs | 8 +- src/music/music_events.rs | 7 +- src/music/music_manager.rs | 150 +++++++++++++++++++------------------ src/util/config.rs | 6 -- src/util/embed.rs | 63 +++++++++++----- 10 files changed, 159 insertions(+), 114 deletions(-) create mode 100644 src/commands/skip.rs diff --git a/src/commands/info.rs b/src/commands/info.rs index 2c93d36..0602288 100644 --- a/src/commands/info.rs +++ b/src/commands/info.rs @@ -6,11 +6,7 @@ use crate::util::embed::Embed; pub async fn run(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); - Embed::create( - "", - "Botendo v7", - "developed by [moonleay](https://moonleay.net)\n\nCheck out the repository: https://git.moonleay.net/DiscordBots/Rustendo", - ) + Embed::create_success_response(username, "Botendo v7", "developed by [moonleay](https://moonleay.net)\n\nCheck out the repository: https://git.moonleay.net/DiscordBots/Rustendo") } pub fn register() -> CreateCommand { diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 6eaf7b9..e2ebff8 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,3 +1,4 @@ pub mod info; pub mod play; -pub mod stop; \ No newline at end of file +pub mod stop; +pub mod skip; \ No newline at end of file diff --git a/src/commands/play.rs b/src/commands/play.rs index 8613fd2..35fdc1c 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -19,13 +19,13 @@ pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEm }); if query.is_none() { - return Embed::create(username, "Error 400", "There is no query provided"); + return Embed::create_error_respose(username, "400: Bad request", "There is no query provided"); } let guild_id = match &command.guild_id { Some(guild_id) => guild_id, None => { - return Embed::create(username, "GuildId not found", "Could not find guild id."); + return Embed::create_error_respose(username, "guild_id not found", "Could not find guild id."); } }; diff --git a/src/commands/skip.rs b/src/commands/skip.rs new file mode 100644 index 0000000..3598dc5 --- /dev/null +++ b/src/commands/skip.rs @@ -0,0 +1,24 @@ +use crate::music::music_manager; +use crate::util::embed::Embed; +use serenity::all::{CommandInteraction, Context}; +use serenity::builder::{CreateCommand, CreateEmbed}; + +pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { + let username = command.user.name.as_str(); + + let guild_id = match &command.guild_id { + Some(guild_id) => guild_id, + None => { + return Embed::create_error_respose(username, "guild_id not found", "Could not find guild id."); + } + }; + + music_manager::attempt_to_skip_current_song(ctx, guild_id, &command.user.id, &command.user.name).await +} + +pub fn register() -> CreateCommand { + CreateCommand::new("skip").description("Skip to the next song in queue") +} + +// >18/02/2024 @ 19:01:59 - bartlo +// >2024-02-19 17:58:39 | moonleay diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 8a65e35..f4bc46a 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -9,7 +9,7 @@ pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEm let guild_id = match &command.guild_id { Some(guild_id) => guild_id, None => { - return Embed::create(username, "GuildId not found", "Could not find guild id."); + return Embed::create_error_respose(username, "guild_id not found", "Could not find guild id."); } }; diff --git a/src/main.rs b/src/main.rs index 55eeaf4..6283d41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,6 +71,7 @@ impl EventHandler for Handler { "info" => commands::info::run(&ctx, &command).await, "play" => commands::play::run(&ctx, &command).await, "stop" => commands::stop::run(&ctx, &command).await, + "skip" => commands::skip::run(&ctx, &command).await, _ => respond_with_error(&ctx, &command).await, }); @@ -90,6 +91,7 @@ impl EventHandler for Handler { let _command = Command::create_global_command(&ctx.http, commands::info::register()).await; let _command = Command::create_global_command(&ctx.http, commands::stop::register()).await; let _command = Command::create_global_command(&ctx.http, commands::play::register()).await; + let _command = Command::create_global_command(&ctx.http, commands::skip::register()).await; println!("Commands are registered and Rustendo is ready for Freddy."); } @@ -120,11 +122,7 @@ impl EventHandler for Handler { } pub async fn respond_with_error(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { - Embed::create( - command.user.name.to_owned(), - "Command not found", - "Cannot find the executed command", - ) + Embed::create_error_respose(command.user.name.as_str(), "Command not found", "Cannot find the executed command") } #[tokio::main] diff --git a/src/music/music_events.rs b/src/music/music_events.rs index 3b52714..f9e43cb 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -1,6 +1,7 @@ use crate::music::{music_manager, music_queue}; use serenity::all::{ChannelId, GuildId, Http}; use serenity::async_trait; +use songbird::input::Compose; use songbird::{Event, EventContext, EventHandler}; use std::sync::Arc; @@ -21,7 +22,7 @@ impl EventHandler for TrackEndNotifier { let q = &music_queue.queue; if q.is_empty() { // No more songs in queue, exit the vc - let stopped = match music_manager::stop(&self.cmdctx, &self.guild_id).await { + let stopped = match music_manager::leave(&self.cmdctx, &self.guild_id).await { Ok(stopped) => stopped, Err(e) => { println!("Cannot stop: {:?}", e); @@ -29,6 +30,7 @@ impl EventHandler for TrackEndNotifier { } }; if stopped { + music_queue::delete_queue(&self.guild_id).await; println!("Stopped playing successfully."); } else { println!("Failed to stop playing."); @@ -40,7 +42,8 @@ impl EventHandler for TrackEndNotifier { println!("Cannot get head of queue"); return None; } - let head = head.unwrap(); + let mut head = head.unwrap(); + println!("Now playing: {}", head.aux_metadata().await.unwrap().title.unwrap()); music_manager::play_song(&self.cmdctx, &self.guild_id, &head).await; } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 2f42673..74a1b3c 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -5,11 +5,12 @@ use crate::util::user_util::get_vc_id; use crate::HttpKey; use serenity::all::{Context, CreateEmbed, GuildId, UserId}; use songbird::error::JoinError; -use songbird::input::{Compose, YoutubeDl}; +use songbird::input::YoutubeDl; use songbird::{Event, TrackEvent}; use std::sync::Arc; -use std::time::Duration; + +/// Either queues the song, or start playing it instantly, depending on if there is already a song playing pub async fn attempt_to_queue_song( ctx: &Context, guild_id: &GuildId, @@ -18,21 +19,17 @@ pub async fn attempt_to_queue_song( query: &str, ) -> CreateEmbed { if !user_util::is_user_connected_to_vc(ctx, guild_id, user_id).await { - return Embed::create( - username, - "You are not connected to a VC", - "Connect to my VC to control the music.", - ); + return Embed::create_error_respose(username, "You are not connected to a VC", "Connect to my vc to start controlling the music.") } let connect_to = match get_vc_id(ctx, guild_id, user_id).await { Some(channel_id) => channel_id, None => { - return Embed::create(username, "Error", "Cannot get channel id"); + return Embed::create_error_respose(username, "Error", "Cannot find channel_id."); } }; - let manager = &songbird::get(ctx) // TODO match + let manager: &Arc = &songbird::get(ctx) // TODO match .await .expect("Cannot get Songbird.") .clone(); @@ -42,23 +39,18 @@ pub async fn attempt_to_queue_song( // self is connected to vc, check if user is in same vc if self_channel.is_none() { - // TODO This could maybe be removed? // Connect to VC - manager + manager // TODO match .join(*guild_id, connect_to) .await .expect("Cannot connect>..."); } } else { - let self_channel = self_channel.expect("Cannot get self channel"); + let self_channel = self_channel.expect("Cannot get self channel");// TODO: match // Check if user is in the same VC as the bot if self_channel != connect_to { - return Embed::create( - username, - "You are not in my VC.", - "Connect to my VC to control the music.", - ); + return Embed::create_error_respose(username, "You are not in my VC", "You have to be in my VC in order to controll the music.") } } @@ -72,7 +64,7 @@ pub async fn attempt_to_queue_song( }; // Create source - let mut src = if do_search { + let src = if do_search { YoutubeDl::new_search(http_client, query.to_string()) } else { YoutubeDl::new(http_client, query.to_string()) @@ -82,11 +74,7 @@ pub async fn attempt_to_queue_song( music_queue::add_to_queue(guild_id, src.clone()).await; if currently_playing.is_some() { // Add to queue - return Embed::create( - username, - "Added to queue", - "The song was added to the queue.", - ); + return Embed::create_yt_playing(src, username, "Added to queue").await; } let _query = music_queue::get_head(guild_id) @@ -97,7 +85,7 @@ pub async fn attempt_to_queue_song( let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => { - return Embed::create("", "Error", "Cannot get handler"); + return Embed::create_error_respose(username, "Error", "Cannot get handler of this guild."); } }; @@ -114,33 +102,10 @@ pub async fn attempt_to_queue_song( }, ); - // Get metadata - let metadata = src.aux_metadata().await.expect("Cannot get metadata"); - let title = metadata.title.unwrap_or("Unknown title".to_string()); - let author = metadata.artist.unwrap_or("Unknown artist".to_string()); - let duration = metadata.duration.unwrap_or(Duration::from_millis(0)); - let thumbnail = metadata - .thumbnail - .unwrap_or("https://http.cat/images/404.jpg".to_string()); - let link = metadata - .source_url - .unwrap_or("https://piped.moonleay.net/404".to_string()); - - Embed::create( - username, - "Added to queue", - format!( - "{} by {} ({}min {}sec) was added to the queue.\n [[Link]({})]", - title, - author, - duration.as_secs() / 60, - duration.as_secs() % 60, - link - ), - ) - .thumbnail(thumbnail) + Embed::create_yt_playing(src, username, "Now playing").await } +/// Play the provided song pub async fn play_song(ctx: &Context, guild_id: &GuildId, target: &YoutubeDl) { let manager = &songbird::get(ctx) // TODO match .await @@ -159,9 +124,60 @@ pub async fn play_song(ctx: &Context, guild_id: &GuildId, target: &YoutubeDl) { }; let mut handler = handler_lock.lock().await; + let _ = handler.stop(); // Stop playing the current song let _ = handler.play_input(target.clone().into()); // TODO: Add event handlers } +/// Attempt to skip the song, which is currently playing. Do nothing if there is no next song +pub async fn attempt_to_skip_current_song(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str) -> CreateEmbed { + if !user_util::is_user_connected_to_vc(ctx, guild_id, user_id).await { + return Embed::create_error_respose(username, "You are not connected to a VC", "Connect to my vc to start controlling the music.") + } + + let connect_to = match get_vc_id(ctx, guild_id, user_id).await { + Some(channel_id) => channel_id, + None => { + return Embed::create_error_respose(username, "Error", "Cannot find channel_id."); + } + }; + + let manager: &Arc = &songbird::get(ctx) // TODO match + .await + .expect("Cannot get Songbird.") + .clone(); + + let self_channel = user_util::get_self_vc_id(ctx, guild_id).await; + if !user_util::is_self_connected_to_vc(ctx, guild_id).await { + // self is connected to vc, check if user is in same vc + + if self_channel.is_none() { + // Connect to VC + manager // TODO match + .join(*guild_id, connect_to) + .await + .expect("Cannot connect>..."); + } + } else { + let self_channel = self_channel.expect("Cannot get self channel");// TODO: match + + // Check if user is in the same VC as the bot + if self_channel != connect_to { + return Embed::create_error_respose(username, "You are not in my VC", "You have to be in my VC in order to controll the music.") + } + } + + let head = music_queue::get_head(guild_id).await; // TODO match + if head.is_none() { + return Embed::create_error_respose(username, "Cannot find a song to play", "The queue is empty."); + } + let head = head.unwrap(); + play_song(ctx, guild_id, &head).await; + + Embed::create_yt_playing(head, username, "Song skipped; Now playing").await +} + + +/// Try to clear the queue and stop playing. Also leave the vc pub async fn attempt_to_stop( ctx: &Context, guild_id: &GuildId, @@ -170,11 +186,7 @@ pub async fn attempt_to_stop( ) -> CreateEmbed { if !user_util::is_self_connected_to_vc(ctx, guild_id).await { // Bot is not connectd to vc; no need to dc - return Embed::create( - username, - "Bot is not connected", - "And therefore there is no need to do anything.", - ); + return Embed::create_error_respose(username, "Bot is not connected", "And therefore there is no need to do anything."); } let self_channel = user_util::get_self_vc_id(ctx, guild_id) .await @@ -185,48 +197,38 @@ pub async fn attempt_to_stop( // Check if user is in the same VC as the bot if self_channel != connect_to { - return Embed::create( - username, - "You are not in my VC.", - "Connect to my VC to control the music.", - ); + return Embed::create_error_respose(username, "You are not in my VC.", "Connect to my VC to controll the music."); } - let stopped = match stop(ctx, guild_id).await { + let stopped = match leave(ctx, guild_id).await { Ok(stopped) => stopped, Err(e) => { println!("Error while stopping: {:?}", e); - return Embed::create( - username, - "There was an error", - "Tell moonleay to check the logs.".to_string(), - ); + return Embed::create_error_respose(username, "There was an error", "Tell moonleay to check the logs."); } }; if !stopped { - Embed::create( - username, - "Can't stop, what ain't running.", - "I am not connected. I cant stop doing something, when I'm not doing it".to_string(), - ) + Embed::create_error_respose(username, "Can't stop, what ain't running", "I am not connected.\nI cant stop doing something, when I'm not doing it.") } else { music_queue::delete_queue(guild_id).await; // Clear queue - Embed::create(username, "I stopped and left", "Just like your girlfriend.") + Embed::create_success_response(username, "I stopped and left", "Just like you girlfriend.") } } -// Make the bot leave the voice channel. Returns Ok(true) if bot was connected, returns Ok(false) if bot was not connected. Returns Err if something went wrong. -pub async fn stop(ctx: &Context, guild_id: &GuildId) -> Result { +/// Make the bot leave the voice channel. Returns Ok(true) if bot was connected, returns Ok(false) if bot was not connected. Returns Err if something went wrong. +pub async fn leave(ctx: &Context, guild_id: &GuildId) -> Result { let manager = songbird::get(ctx) .await .expect("Cannot get Songbird") .clone(); - let has_handler = manager.get(*guild_id).is_some(); + let handler = manager.get(*guild_id); + let has_handler = handler.is_some(); if has_handler { + handler.unwrap().lock().await.stop(); manager.remove(*guild_id).await?; return Ok(true); // Handler removed } diff --git a/src/util/config.rs b/src/util/config.rs index f3e4cb9..f5dc260 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -6,9 +6,6 @@ use std::error::Error; #[derive(Deserialize, Serialize)] pub struct Config { pub discord_token: String, - pub lavalink_address: String, - pub lavalink_password: String, - pub user_id: u64, } const CONFIG_FILE: &str = "./data/config.json"; @@ -26,9 +23,6 @@ pub fn load() -> Result> { fn create_empty() -> fs::File { let example_config = Config { discord_token: "paste_your_token".to_string(), - lavalink_address: "paste_your_lavalink_address".to_string(), - lavalink_password: "paste_your_lavalink_password".to_string(), - user_id: 1, }; let mut config_file = fs::File::create(CONFIG_FILE).unwrap(); diff --git a/src/util/embed.rs b/src/util/embed.rs index bfdb2f1..ffb68a5 100644 --- a/src/util/embed.rs +++ b/src/util/embed.rs @@ -1,29 +1,56 @@ -use std::fmt::Display; +use std::time::Duration; use chrono::Local; -use serenity::all::{CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; +use serenity::all::{Color, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter}; +use songbird::input::{Compose, YoutubeDl}; pub struct Embed; impl Embed { - pub fn create< - S: Into + Display, - T: Into + Display, - U: Into + Display, - >( - username: S, - title: T, - message: U, - ) -> CreateEmbed { + pub fn create_success_response(username: &str, title: &str, desc: &str) -> CreateEmbed { let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); CreateEmbed::new() - .author(CreateEmbedAuthor::new(username.to_string())) - .title(title) - .description(message) - .footer(CreateEmbedFooter::new(format!( - "> {} - {}", - current_time, username - ))) + .title(title) + .description(desc) + .color(Color::from_rgb(224, 49, 26)) + .footer(CreateEmbedFooter::new(format!("> {} - {}", current_time, username))) + } + + pub fn create_error_respose(username: &str, error_title: &str, error_desc: &str) -> CreateEmbed { + let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); + + CreateEmbed::new() + .author(CreateEmbedAuthor::new("Oops, something went wrong.")) + .title(error_title) + .description(error_desc) + .color(Color::from_rgb(224, 49, 26)) + .footer(CreateEmbedFooter::new(format!("> {} - {}", current_time, username))) + } + + pub async fn create_yt_playing(mut src: YoutubeDl, username: &str, show_as_author: &str) -> CreateEmbed { + let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); + + // Get metadata + let metadata = src.aux_metadata().await.expect("Cannot get metadata"); + let title = metadata.title.unwrap_or("Unknown title".to_string()); + let artist = metadata.artist.unwrap_or("Unknown artist".to_string()); + let duration = metadata.duration.unwrap_or(Duration::from_millis(0)); + let thumbnail = metadata + .thumbnail + .unwrap_or("https://http.cat/images/403.jpg".to_string()); + let link = metadata + .source_url + .unwrap_or("https://piped.moonleay.net/403".to_string()); + + CreateEmbed::new() + .author(CreateEmbedAuthor::new(show_as_author)) + .title(title) + .url(link) + .thumbnail(thumbnail) + .field("Artist", artist, true) + .field("Duration", format!("{}min {}sec", duration.as_secs() / 58, duration.as_secs() % 59), true) + .color(Color::from_rgb(81, 224, 26)) + .footer(CreateEmbedFooter::new(format!("> {} - {}",current_time, username))) } } From 1879b4ee0f5a9f7ec67c08d9853c3e77745085dc Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 19:36:28 +0100 Subject: [PATCH 22/41] fix: music queue improvements --- src/main.rs | 30 +-------------- src/music/music_events.rs | 21 +++++----- src/music/music_queue.rs | 81 ++++++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 57 deletions(-) diff --git a/src/main.rs b/src/main.rs index 20611a3..4ed6306 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ mod music; mod util; use serenity::all::{ - CommandInteraction, CreateInteractionResponseFollowup, GuildId, OnlineStatus, VoiceState, + CommandInteraction, CreateInteractionResponseFollowup, OnlineStatus, VoiceState, }; use serenity::async_trait; use serenity::builder::CreateEmbed; @@ -30,34 +30,6 @@ impl TypeMapKey for HttpKey { #[macro_use] extern crate lazy_static; -use crate::music::music_queue::MusicQueue; -use std::collections::HashMap; - -lazy_static! { - static ref HASHMAP: Mutex> = Mutex::new(HashMap::new()); -} - -pub async fn get_queue(guild_id: &GuildId) -> MusicQueue { - let mut queues = HASHMAP.lock().await; - - match queues.get(&guild_id) { - Some(music_queue) => music_queue.clone(), - None => { - let q = MusicQueue { - guild_id: *guild_id, - queue: Vec::new(), - now_playing: None, - }; - queues.insert(*guild_id, q.clone()); - q - } - } -} - -pub async fn set_queue(guild_id: &GuildId, queue: MusicQueue) { - HASHMAP.lock().await.insert(*guild_id, queue); -} - struct Handler; #[async_trait] diff --git a/src/music/music_events.rs b/src/music/music_events.rs index 3b52714..905048a 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -1,4 +1,5 @@ use crate::music::{music_manager, music_queue}; + use serenity::all::{ChannelId, GuildId, Http}; use serenity::async_trait; use songbird::{Event, EventContext, EventHandler}; @@ -17,9 +18,8 @@ impl EventHandler for TrackEndNotifier { // TODO: Does this need to be unsafe? if let EventContext::Track(..) = ctx { println!("The track ended!"); - let music_queue = crate::get_queue(&self.guild_id).await; - let q = &music_queue.queue; - if q.is_empty() { + + if music_queue::is_empty(&self.guild_id).await { // No more songs in queue, exit the vc let stopped = match music_manager::stop(&self.cmdctx, &self.guild_id).await { Ok(stopped) => stopped, @@ -35,12 +35,15 @@ impl EventHandler for TrackEndNotifier { } return None; } - let head = music_queue::get_head(&self.guild_id).await; - if head.is_none() { - println!("Cannot get head of queue"); - return None; - } - let head = head.unwrap(); + + let head = match music_queue::get_head(&self.guild_id).await { + Some(head) => head, + None => { + println!("Cannot get head of queue"); + return None; + } + }; + music_manager::play_song(&self.cmdctx, &self.guild_id, &head).await; } diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index c7501f9..741720e 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -1,7 +1,41 @@ use serenity::all::GuildId; use songbird::input::YoutubeDl; +use tokio::sync::{Mutex, MutexGuard}; -#[derive(Debug, Clone)] +use std::collections::HashMap; +use std::sync::Arc; + +type MusicQueueItem = Arc>; + +lazy_static! { + static ref HASHMAP: Mutex> = Mutex::new(HashMap::new()); +} + +async fn get_music_queue(guild_id: &GuildId) -> MusicQueueItem { + let mut queues = HASHMAP.lock().await; + + queues + .entry(*guild_id) + .or_insert(Arc::new(Mutex::new(MusicQueue { + guild_id: *guild_id, + queue: Vec::new(), + now_playing: None, + }))) + .clone() +} + +pub async fn with_music_queue(guild_id: &GuildId, f: F) -> T +where + F: FnOnce(&mut MusicQueue) -> T, + T: Send, +{ + let queue = get_music_queue(guild_id).await; + let mut queue = queue.lock().await; + + f(&mut *queue) +} + +#[derive(Debug)] pub struct MusicQueue { // God this sucks. This needs to be reprogrammed properly. pub guild_id: GuildId, @@ -10,35 +44,44 @@ pub struct MusicQueue { } pub async fn delete_queue(guild_id: &GuildId) { - let mut queue = crate::get_queue(guild_id).await; - queue.now_playing = None; - queue.queue = Vec::new(); - crate::set_queue(guild_id, queue).await; + with_music_queue(guild_id, |queue| { + queue.now_playing = None; + queue.queue.clear(); + }) + .await; } pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { - let mut queue = crate::get_queue(guild_id).await; - queue.queue.push(input); - crate::set_queue(guild_id, queue).await; + with_music_queue(guild_id, |queue| { + queue.queue.push(input); + }) + .await; } pub async fn get_head(guild_id: &GuildId) -> Option { - let mut music_queue = crate::get_queue(guild_id).await; - if music_queue.queue.is_empty() { - return None; - } - let result = music_queue.queue.remove(0); - crate::set_queue(guild_id, music_queue).await; - Some(result) + with_music_queue(guild_id, |queue| { + if queue.queue.is_empty() { + None + } else { + Some(queue.queue.remove(0)) + } + }) + .await } pub async fn set_now_playing(guild_id: &GuildId, now_playing: Option) { - let mut queue = crate::get_queue(guild_id).await; + let queue = get_music_queue(guild_id).await; + let mut queue = queue.lock().await; + queue.now_playing = now_playing; - crate::set_queue(guild_id, queue).await; } pub async fn get_now_playing(guild_id: &GuildId) -> Option { - let queue = crate::get_queue(guild_id).await; - queue.now_playing + let queue = get_queue(guild_id).await; + + queue.now_playing.to_owned() +} + +pub async fn is_empty(guild_id: &GuildId) -> bool { + with_music_queue(guild_id, |queue| queue.queue.is_empty()).await } From 05fae26549bb42b8f01c14f7567c2e92608423bf Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 19:46:27 +0100 Subject: [PATCH 23/41] fix: bug fixes --- src/commands/skip.rs | 11 ++++-- src/music/music_events.rs | 7 +++- src/music/music_manager.rs | 75 ++++++++++++++++++++++++++++++-------- src/music/music_queue.rs | 13 ++----- 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/commands/skip.rs b/src/commands/skip.rs index 3598dc5..ccf8ad6 100644 --- a/src/commands/skip.rs +++ b/src/commands/skip.rs @@ -3,17 +3,22 @@ use crate::util::embed::Embed; use serenity::all::{CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateEmbed}; -pub async unsafe fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { +pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let username = command.user.name.as_str(); let guild_id = match &command.guild_id { Some(guild_id) => guild_id, None => { - return Embed::create_error_respose(username, "guild_id not found", "Could not find guild id."); + return Embed::create_error_respose( + username, + "guild_id not found", + "Could not find guild id.", + ); } }; - music_manager::attempt_to_skip_current_song(ctx, guild_id, &command.user.id, &command.user.name).await + music_manager::attempt_to_skip_current_song(ctx, guild_id, &command.user.id, &command.user.name) + .await } pub fn register() -> CreateCommand { diff --git a/src/music/music_events.rs b/src/music/music_events.rs index acfd813..30abb9a 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -40,11 +40,14 @@ impl EventHandler for TrackEndNotifier { let mut head = match music_queue::get_head(&self.guild_id).await { Some(head) => head, None => { - println!("Cannot get head of queue: {:?}", e); + println!("Cannot get head of queue"); return None; } }; - println!("Now playing: {}", head.aux_metadata().await.unwrap().title.unwrap()); + println!( + "Now playing: {}", + head.aux_metadata().await.unwrap().title.unwrap() + ); music_manager::play_song(&self.cmdctx, &self.guild_id, &head).await; } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 74a1b3c..834cae7 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -9,7 +9,6 @@ use songbird::input::YoutubeDl; use songbird::{Event, TrackEvent}; use std::sync::Arc; - /// Either queues the song, or start playing it instantly, depending on if there is already a song playing pub async fn attempt_to_queue_song( ctx: &Context, @@ -19,7 +18,11 @@ pub async fn attempt_to_queue_song( query: &str, ) -> CreateEmbed { if !user_util::is_user_connected_to_vc(ctx, guild_id, user_id).await { - return Embed::create_error_respose(username, "You are not connected to a VC", "Connect to my vc to start controlling the music.") + return Embed::create_error_respose( + username, + "You are not connected to a VC", + "Connect to my vc to start controlling the music.", + ); } let connect_to = match get_vc_id(ctx, guild_id, user_id).await { @@ -46,11 +49,15 @@ pub async fn attempt_to_queue_song( .expect("Cannot connect>..."); } } else { - let self_channel = self_channel.expect("Cannot get self channel");// TODO: match + let self_channel = self_channel.expect("Cannot get self channel"); // TODO: match // Check if user is in the same VC as the bot if self_channel != connect_to { - return Embed::create_error_respose(username, "You are not in my VC", "You have to be in my VC in order to controll the music.") + return Embed::create_error_respose( + username, + "You are not in my VC", + "You have to be in my VC in order to controll the music.", + ); } } @@ -85,7 +92,11 @@ pub async fn attempt_to_queue_song( let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => { - return Embed::create_error_respose(username, "Error", "Cannot get handler of this guild."); + return Embed::create_error_respose( + username, + "Error", + "Cannot get handler of this guild.", + ); } }; @@ -124,14 +135,23 @@ pub async fn play_song(ctx: &Context, guild_id: &GuildId, target: &YoutubeDl) { }; let mut handler = handler_lock.lock().await; - let _ = handler.stop(); // Stop playing the current song + handler.stop(); // Stop playing the current song let _ = handler.play_input(target.clone().into()); // TODO: Add event handlers } /// Attempt to skip the song, which is currently playing. Do nothing if there is no next song -pub async fn attempt_to_skip_current_song(ctx: &Context, guild_id: &GuildId, user_id: &UserId, username: &str) -> CreateEmbed { +pub async fn attempt_to_skip_current_song( + ctx: &Context, + guild_id: &GuildId, + user_id: &UserId, + username: &str, +) -> CreateEmbed { if !user_util::is_user_connected_to_vc(ctx, guild_id, user_id).await { - return Embed::create_error_respose(username, "You are not connected to a VC", "Connect to my vc to start controlling the music.") + return Embed::create_error_respose( + username, + "You are not connected to a VC", + "Connect to my vc to start controlling the music.", + ); } let connect_to = match get_vc_id(ctx, guild_id, user_id).await { @@ -158,17 +178,25 @@ pub async fn attempt_to_skip_current_song(ctx: &Context, guild_id: &GuildId, use .expect("Cannot connect>..."); } } else { - let self_channel = self_channel.expect("Cannot get self channel");// TODO: match + let self_channel = self_channel.expect("Cannot get self channel"); // TODO: match // Check if user is in the same VC as the bot if self_channel != connect_to { - return Embed::create_error_respose(username, "You are not in my VC", "You have to be in my VC in order to controll the music.") + return Embed::create_error_respose( + username, + "You are not in my VC", + "You have to be in my VC in order to controll the music.", + ); } } let head = music_queue::get_head(guild_id).await; // TODO match if head.is_none() { - return Embed::create_error_respose(username, "Cannot find a song to play", "The queue is empty."); + return Embed::create_error_respose( + username, + "Cannot find a song to play", + "The queue is empty.", + ); } let head = head.unwrap(); play_song(ctx, guild_id, &head).await; @@ -176,7 +204,6 @@ pub async fn attempt_to_skip_current_song(ctx: &Context, guild_id: &GuildId, use Embed::create_yt_playing(head, username, "Song skipped; Now playing").await } - /// Try to clear the queue and stop playing. Also leave the vc pub async fn attempt_to_stop( ctx: &Context, @@ -186,7 +213,11 @@ pub async fn attempt_to_stop( ) -> CreateEmbed { if !user_util::is_self_connected_to_vc(ctx, guild_id).await { // Bot is not connectd to vc; no need to dc - return Embed::create_error_respose(username, "Bot is not connected", "And therefore there is no need to do anything."); + return Embed::create_error_respose( + username, + "Bot is not connected", + "And therefore there is no need to do anything.", + ); } let self_channel = user_util::get_self_vc_id(ctx, guild_id) .await @@ -197,19 +228,31 @@ pub async fn attempt_to_stop( // Check if user is in the same VC as the bot if self_channel != connect_to { - return Embed::create_error_respose(username, "You are not in my VC.", "Connect to my VC to controll the music."); + return Embed::create_error_respose( + username, + "You are not in my VC.", + "Connect to my VC to controll the music.", + ); } let stopped = match leave(ctx, guild_id).await { Ok(stopped) => stopped, Err(e) => { println!("Error while stopping: {:?}", e); - return Embed::create_error_respose(username, "There was an error", "Tell moonleay to check the logs."); + return Embed::create_error_respose( + username, + "There was an error", + "Tell moonleay to check the logs.", + ); } }; if !stopped { - Embed::create_error_respose(username, "Can't stop, what ain't running", "I am not connected.\nI cant stop doing something, when I'm not doing it.") + Embed::create_error_respose( + username, + "Can't stop, what ain't running", + "I am not connected.\nI cant stop doing something, when I'm not doing it.", + ) } else { music_queue::delete_queue(guild_id).await; // Clear queue diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index 741720e..37b76fb 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -1,6 +1,6 @@ use serenity::all::GuildId; use songbird::input::YoutubeDl; -use tokio::sync::{Mutex, MutexGuard}; +use tokio::sync::Mutex; use std::collections::HashMap; use std::sync::Arc; @@ -32,7 +32,7 @@ where let queue = get_music_queue(guild_id).await; let mut queue = queue.lock().await; - f(&mut *queue) + f(&mut queue) } #[derive(Debug)] @@ -70,16 +70,11 @@ pub async fn get_head(guild_id: &GuildId) -> Option { } pub async fn set_now_playing(guild_id: &GuildId, now_playing: Option) { - let queue = get_music_queue(guild_id).await; - let mut queue = queue.lock().await; - - queue.now_playing = now_playing; + with_music_queue(guild_id, |queue| queue.now_playing = now_playing).await; } pub async fn get_now_playing(guild_id: &GuildId) -> Option { - let queue = get_queue(guild_id).await; - - queue.now_playing.to_owned() + with_music_queue(guild_id, |queue| queue.now_playing.to_owned()).await } pub async fn is_empty(guild_id: &GuildId) -> bool { From f3fec5292a5c7b30ccf8b087a5eb3218e3716733 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 20:11:39 +0100 Subject: [PATCH 24/41] chore: use `VecDeque` for music queue --- src/music/music_queue.rs | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index 37b76fb..e4480fe 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -2,11 +2,19 @@ use serenity::all::GuildId; use songbird::input::YoutubeDl; use tokio::sync::Mutex; -use std::collections::HashMap; +use std::collections::{HashMap, VecDeque}; use std::sync::Arc; type MusicQueueItem = Arc>; +#[derive(Debug)] +pub struct MusicQueue { + // God this sucks. This needs to be reprogrammed properly. + pub guild_id: GuildId, + pub queue: VecDeque, + pub now_playing: Option, +} + lazy_static! { static ref HASHMAP: Mutex> = Mutex::new(HashMap::new()); } @@ -18,7 +26,7 @@ async fn get_music_queue(guild_id: &GuildId) -> MusicQueueItem { .entry(*guild_id) .or_insert(Arc::new(Mutex::new(MusicQueue { guild_id: *guild_id, - queue: Vec::new(), + queue: VecDeque::new(), now_playing: None, }))) .clone() @@ -35,14 +43,6 @@ where f(&mut queue) } -#[derive(Debug)] -pub struct MusicQueue { - // God this sucks. This needs to be reprogrammed properly. - pub guild_id: GuildId, - pub queue: Vec, - pub now_playing: Option, -} - pub async fn delete_queue(guild_id: &GuildId) { with_music_queue(guild_id, |queue| { queue.now_playing = None; @@ -52,21 +52,11 @@ pub async fn delete_queue(guild_id: &GuildId) { } pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { - with_music_queue(guild_id, |queue| { - queue.queue.push(input); - }) - .await; + with_music_queue(guild_id, |queue| queue.queue.push_back(input)).await; } pub async fn get_head(guild_id: &GuildId) -> Option { - with_music_queue(guild_id, |queue| { - if queue.queue.is_empty() { - None - } else { - Some(queue.queue.remove(0)) - } - }) - .await + with_music_queue(guild_id, |queue| queue.queue.pop_front()).await } pub async fn set_now_playing(guild_id: &GuildId, now_playing: Option) { From d471bfcb0680b5e77643f9740b13ebe69542b536 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 10 Mar 2024 20:58:05 +0100 Subject: [PATCH 25/41] feat: added nowplaying command --- src/commands/mod.rs | 1 + src/commands/now_playing.rs | 43 +++++++++++++++++++++++++++++++++++++ src/commands/skip.rs | 3 --- src/commands/stop.rs | 3 --- src/main.rs | 2 ++ 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 src/commands/now_playing.rs diff --git a/src/commands/mod.rs b/src/commands/mod.rs index aa38f60..085759c 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -2,3 +2,4 @@ pub mod info; pub mod play; pub mod skip; pub mod stop; +pub mod now_playing; diff --git a/src/commands/now_playing.rs b/src/commands/now_playing.rs new file mode 100644 index 0000000..f506a32 --- /dev/null +++ b/src/commands/now_playing.rs @@ -0,0 +1,43 @@ +use crate::music::{music_queue}; +use crate::util::embed::Embed; +use serenity::all::{CommandInteraction, Context}; +use serenity::builder::{CreateCommand, CreateEmbed}; + +pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { + let username = command.user.name.as_str(); + + let guild_id = match &command.guild_id { + Some(guild_id) => guild_id, + None => { + return Embed::create_error_respose( + username, + "guild_id not found", + "Could not find guild id.", + ); + } + }; + + let now_plaing = match music_queue::get_now_playing(&guild_id).await { + Some(ytdl) => ytdl, + None => { + return Embed::create_error_respose(username, "Not playing", "I'm not playing anything!"); + } + }; + + let manager = songbird::get(ctx) + .await + .expect("Cannot get Songbird") + .clone(); + + let handler = match manager.get(*guild_id) { + Some(handler) => handler, + None => { + return Embed::create_error_respose(username, "Error", "Error while getting the audio handler."); + } + }; + Embed::create_yt_playing(now_plaing, username, "Currently playing").await +} + +pub fn register() -> CreateCommand { + CreateCommand::new("nowplaying").description("Show what is currently playing.") +} diff --git a/src/commands/skip.rs b/src/commands/skip.rs index ccf8ad6..e5609df 100644 --- a/src/commands/skip.rs +++ b/src/commands/skip.rs @@ -24,6 +24,3 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { pub fn register() -> CreateCommand { CreateCommand::new("skip").description("Skip to the next song in queue") } - -// >18/02/2024 @ 19:01:59 - bartlo -// >2024-02-19 17:58:39 | moonleay diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 8800a41..6056141 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -19,6 +19,3 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { pub fn register() -> CreateCommand { CreateCommand::new("stop").description("Stop playing and start leavin'") } - -// >18/02/2024 @ 19:01:59 - bartlo -// >2024-02-19 17:58:39 | moonleay diff --git a/src/main.rs b/src/main.rs index f9ebb10..a5d9f4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,7 @@ impl EventHandler for Handler { "play" => commands::play::run(&ctx, &command).await, "stop" => commands::stop::run(&ctx, &command).await, "skip" => commands::skip::run(&ctx, &command).await, + "nowplaying" => commands::now_playing::run(&ctx, &command).await, _ => respond_with_error(&ctx, &command).await, }); @@ -62,6 +63,7 @@ impl EventHandler for Handler { let _command = Command::create_global_command(&ctx.http, commands::stop::register()).await; let _command = Command::create_global_command(&ctx.http, commands::play::register()).await; let _command = Command::create_global_command(&ctx.http, commands::skip::register()).await; + let _command = Command::create_global_command(&ctx.http, commands::now_playing::register()).await; println!("Commands are registered and Rustendo is ready for Freddy."); } From 59bf59295e072764212805e0706cd820dd67f587 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 21:07:52 +0100 Subject: [PATCH 26/41] chore: rename `music_queue::get_head` to `next` --- src/music/music_events.rs | 2 +- src/music/music_manager.rs | 5 +++-- src/music/music_queue.rs | 5 ++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/music/music_events.rs b/src/music/music_events.rs index 30abb9a..f35abe9 100644 --- a/src/music/music_events.rs +++ b/src/music/music_events.rs @@ -37,7 +37,7 @@ impl EventHandler for TrackEndNotifier { } return None; } - let mut head = match music_queue::get_head(&self.guild_id).await { + let mut head = match music_queue::next(&self.guild_id).await { Some(head) => head, None => { println!("Cannot get head of queue"); diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 834cae7..169bcd2 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -84,7 +84,7 @@ pub async fn attempt_to_queue_song( return Embed::create_yt_playing(src, username, "Added to queue").await; } - let _query = music_queue::get_head(guild_id) + let _query = music_queue::next(guild_id) .await .expect("Cannot get head of queue"); music_queue::set_now_playing(guild_id, Some(src.clone())).await; @@ -103,6 +103,7 @@ pub async fn attempt_to_queue_song( // Start playing let mut handler = handler_lock.lock().await; let _ = handler.play_input(src.clone().into()); // TODO: Add event handlers + handler.add_global_event( Event::Track(TrackEvent::End), music_events::TrackEndNotifier { @@ -190,7 +191,7 @@ pub async fn attempt_to_skip_current_song( } } - let head = music_queue::get_head(guild_id).await; // TODO match + let head = music_queue::next(guild_id).await; // TODO match if head.is_none() { return Embed::create_error_respose( username, diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index e4480fe..fc286e7 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -10,7 +10,6 @@ type MusicQueueItem = Arc>; #[derive(Debug)] pub struct MusicQueue { // God this sucks. This needs to be reprogrammed properly. - pub guild_id: GuildId, pub queue: VecDeque, pub now_playing: Option, } @@ -25,7 +24,6 @@ async fn get_music_queue(guild_id: &GuildId) -> MusicQueueItem { queues .entry(*guild_id) .or_insert(Arc::new(Mutex::new(MusicQueue { - guild_id: *guild_id, queue: VecDeque::new(), now_playing: None, }))) @@ -55,7 +53,8 @@ pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { with_music_queue(guild_id, |queue| queue.queue.push_back(input)).await; } -pub async fn get_head(guild_id: &GuildId) -> Option { +/// Get next track in queue +pub async fn next(guild_id: &GuildId) -> Option { with_music_queue(guild_id, |queue| queue.queue.pop_front()).await } From a72f9753a21e0e780f2283bc1bc3919d9884bfd8 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 10 Mar 2024 21:36:10 +0100 Subject: [PATCH 27/41] feat: added current position to nowplaying command --- src/commands/now_playing.rs | 14 +++++++++++++- src/main.rs | 2 +- src/music/music_manager.rs | 7 +++++-- src/music/music_queue.rs | 12 +++++++++++- src/util/embed.rs | 2 +- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/commands/now_playing.rs b/src/commands/now_playing.rs index f506a32..ed323a7 100644 --- a/src/commands/now_playing.rs +++ b/src/commands/now_playing.rs @@ -1,5 +1,6 @@ -use crate::music::{music_queue}; +use crate::music::music_queue; use crate::util::embed::Embed; +use futures::{FutureExt, TryFutureExt}; use serenity::all::{CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateEmbed}; @@ -24,6 +25,13 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { } }; + let now_handle = match music_queue::get_now_playing_track_handle(&guild_id).await { + Some(handle) => handle, + None => { + return Embed::create_error_respose(username, "Cannot get TrackHandle", "The TrackHandle is empty."); + } + }; + let manager = songbird::get(ctx) .await .expect("Cannot get Songbird") @@ -35,7 +43,11 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { return Embed::create_error_respose(username, "Error", "Error while getting the audio handler."); } }; + + let position = now_handle.get_info().await.unwrap().position; + Embed::create_yt_playing(now_plaing, username, "Currently playing").await + .field("Position", format!("{}min {}sec", position.as_secs() / 60, position.as_secs() % 60), true) } pub fn register() -> CreateCommand { diff --git a/src/main.rs b/src/main.rs index a5d9f4e..ce0fb85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,7 @@ impl EventHandler for Handler { } async fn voice_state_update(&self, ctx: Context, old: Option, new: VoiceState) { - // FIXME: This does not work, when switching channels + // TODO This does not work, when switching channels if new.channel_id.is_some() { return; // User did not leave, ignore } diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index 834cae7..ab6f933 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -89,6 +89,7 @@ pub async fn attempt_to_queue_song( .expect("Cannot get head of queue"); music_queue::set_now_playing(guild_id, Some(src.clone())).await; + let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => { @@ -102,7 +103,8 @@ pub async fn attempt_to_queue_song( // Start playing let mut handler = handler_lock.lock().await; - let _ = handler.play_input(src.clone().into()); // TODO: Add event handlers + let track_handle = handler.play_input(src.clone().into()); // TODO: Add event handlers + music_queue::set_now_playing_track_handle(guild_id, Some(track_handle)).await; handler.add_global_event( Event::Track(TrackEvent::End), music_events::TrackEndNotifier { @@ -136,7 +138,8 @@ pub async fn play_song(ctx: &Context, guild_id: &GuildId, target: &YoutubeDl) { let mut handler = handler_lock.lock().await; handler.stop(); // Stop playing the current song - let _ = handler.play_input(target.clone().into()); // TODO: Add event handlers + let track_handle = handler.play_input(target.clone().into()); // TODO: Add event handlers + music_queue::set_now_playing_track_handle(guild_id, Some(track_handle)).await; } /// Attempt to skip the song, which is currently playing. Do nothing if there is no next song diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index e4480fe..0bcc335 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -1,5 +1,6 @@ use serenity::all::GuildId; use songbird::input::YoutubeDl; +use songbird::tracks::TrackHandle; use tokio::sync::Mutex; use std::collections::{HashMap, VecDeque}; @@ -9,10 +10,10 @@ type MusicQueueItem = Arc>; #[derive(Debug)] pub struct MusicQueue { - // God this sucks. This needs to be reprogrammed properly. pub guild_id: GuildId, pub queue: VecDeque, pub now_playing: Option, + pub now_playing_track_handle: Option } lazy_static! { @@ -28,6 +29,7 @@ async fn get_music_queue(guild_id: &GuildId) -> MusicQueueItem { guild_id: *guild_id, queue: VecDeque::new(), now_playing: None, + now_playing_track_handle: None, }))) .clone() } @@ -67,6 +69,14 @@ pub async fn get_now_playing(guild_id: &GuildId) -> Option { with_music_queue(guild_id, |queue| queue.now_playing.to_owned()).await } +pub async fn set_now_playing_track_handle(guild_id: &GuildId, track_handle: Option) { + with_music_queue(guild_id, |queue| queue.now_playing_track_handle = track_handle).await +} + +pub async fn get_now_playing_track_handle(guild_id: &GuildId) -> Option { + with_music_queue(guild_id, | queue| queue.now_playing_track_handle.to_owned()).await +} + pub async fn is_empty(guild_id: &GuildId) -> bool { with_music_queue(guild_id, |queue| queue.queue.is_empty()).await } diff --git a/src/util/embed.rs b/src/util/embed.rs index ffb68a5..52526a7 100644 --- a/src/util/embed.rs +++ b/src/util/embed.rs @@ -49,7 +49,7 @@ impl Embed { .url(link) .thumbnail(thumbnail) .field("Artist", artist, true) - .field("Duration", format!("{}min {}sec", duration.as_secs() / 58, duration.as_secs() % 59), true) + .field("Duration", format!("{}min {}sec", duration.as_secs() / 60, duration.as_secs() % 60), true) .color(Color::from_rgb(81, 224, 26)) .footer(CreateEmbedFooter::new(format!("> {} - {}",current_time, username))) } From 72a1fe8af3919c8f20a1766997c49a20b7811521 Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Sun, 10 Mar 2024 21:40:52 +0100 Subject: [PATCH 28/41] chore: updates and formatting --- Cargo.lock | 127 +++++++++++++++--------------------- src/commands/mod.rs | 2 +- src/commands/now_playing.rs | 31 +++++++-- src/commands/play.rs | 12 +++- src/commands/stop.rs | 6 +- src/main.rs | 25 ++++--- src/music/mod.rs | 4 +- src/music/music_manager.rs | 1 - src/music/music_queue.rs | 9 ++- src/util/embed.rs | 89 ++++++++++++++++--------- 10 files changed, 175 insertions(+), 131 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4391254..fddf69e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.3" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "bytecount" @@ -208,9 +208,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.88" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -220,9 +220,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "android-tzdata", "iana-time-zone", @@ -631,12 +631,11 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.6" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b25e5b3e733153bcab35ee4671b46604b42516163cae442d1601cb716f2ac5" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" dependencies = [ "cc", - "cfg-if", "libc", "log", "rustversion", @@ -690,7 +689,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.11", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -712,9 +711,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -723,9 +722,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -739,7 +738,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.11", + "http 0.2.12", "pin-project-lite", ] @@ -766,7 +765,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.11", + "http 0.2.12", "http-body", "httparse", "httpdate", @@ -786,7 +785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http 0.2.11", + "http 0.2.12", "hyper", "rustls 0.21.10", "tokio", @@ -817,7 +816,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -872,9 +871,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1220,18 +1219,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", @@ -1414,7 +1413,7 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.6", "regex-syntax 0.8.2", ] @@ -1429,9 +1428,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1452,9 +1451,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.24" +version = "0.11.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" dependencies = [ "base64 0.21.7", "bytes", @@ -1462,7 +1461,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.11", + "http 0.2.12", "http-body", "hyper", "hyper-rustls", @@ -2257,20 +2256,20 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "system-configuration" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ "core-foundation-sys", "libc", @@ -2630,7 +2629,7 @@ dependencies = [ "base64 0.13.1", "byteorder", "bytes", - "http 0.2.11", + "http 0.2.12", "httparse", "log", "rand", @@ -2651,7 +2650,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.0.0", + "http 1.1.0", "httparse", "log", "rand", @@ -2877,9 +2876,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2887,9 +2886,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -2902,9 +2901,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -2914,9 +2913,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2924,9 +2923,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -2937,9 +2936,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-streams" @@ -2956,9 +2955,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -3022,12 +3021,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.53.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-core 0.53.0", - "windows-targets 0.52.4", + "windows-targets 0.48.5", ] [[package]] @@ -3039,25 +3037,6 @@ dependencies = [ "windows-targets 0.52.4", ] -[[package]] -name = "windows-core" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd" -dependencies = [ - "windows-result", - "windows-targets 0.52.4", -] - -[[package]] -name = "windows-result" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" -dependencies = [ - "windows-targets 0.52.4", -] - [[package]] name = "windows-sys" version = "0.48.0" diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 085759c..7ba1a8c 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,5 +1,5 @@ pub mod info; +pub mod now_playing; pub mod play; pub mod skip; pub mod stop; -pub mod now_playing; diff --git a/src/commands/now_playing.rs b/src/commands/now_playing.rs index ed323a7..e3b5a5e 100644 --- a/src/commands/now_playing.rs +++ b/src/commands/now_playing.rs @@ -21,14 +21,22 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let now_plaing = match music_queue::get_now_playing(&guild_id).await { Some(ytdl) => ytdl, None => { - return Embed::create_error_respose(username, "Not playing", "I'm not playing anything!"); + return Embed::create_error_respose( + username, + "Not playing", + "I'm not playing anything!", + ); } }; let now_handle = match music_queue::get_now_playing_track_handle(&guild_id).await { Some(handle) => handle, None => { - return Embed::create_error_respose(username, "Cannot get TrackHandle", "The TrackHandle is empty."); + return Embed::create_error_respose( + username, + "Cannot get TrackHandle", + "The TrackHandle is empty.", + ); } }; @@ -40,14 +48,27 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let handler = match manager.get(*guild_id) { Some(handler) => handler, None => { - return Embed::create_error_respose(username, "Error", "Error while getting the audio handler."); + return Embed::create_error_respose( + username, + "Error", + "Error while getting the audio handler.", + ); } }; let position = now_handle.get_info().await.unwrap().position; - Embed::create_yt_playing(now_plaing, username, "Currently playing").await - .field("Position", format!("{}min {}sec", position.as_secs() / 60, position.as_secs() % 60), true) + Embed::create_yt_playing(now_plaing, username, "Currently playing") + .await + .field( + "Position", + format!( + "{}min {}sec", + position.as_secs() / 60, + position.as_secs() % 60 + ), + true, + ) } pub fn register() -> CreateCommand { diff --git a/src/commands/play.rs b/src/commands/play.rs index bfba14b..78e44d0 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -19,13 +19,21 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { }); if query.is_none() { - return Embed::create_error_respose(username, "400: Bad request", "There is no query provided"); + return Embed::create_error_respose( + username, + "400: Bad request", + "There is no query provided", + ); } let guild_id = match &command.guild_id { Some(guild_id) => guild_id, None => { - return Embed::create_error_respose(username, "guild_id not found", "Could not find guild id."); + return Embed::create_error_respose( + username, + "guild_id not found", + "Could not find guild id.", + ); } }; diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 6056141..5bc6e78 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -9,7 +9,11 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { let guild_id = match &command.guild_id { Some(guild_id) => guild_id, None => { - return Embed::create_error_respose(username, "guild_id not found", "Could not find guild id."); + return Embed::create_error_respose( + username, + "guild_id not found", + "Could not find guild id.", + ); } }; diff --git a/src/main.rs b/src/main.rs index ce0fb85..fb0bd4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,14 +38,14 @@ impl EventHandler for Handler { if let Interaction::Command(command) = interaction { let _ = &command.defer(&ctx.http()).await.expect("Cannot defer"); - let content = Some(match command.data.name.as_str() { - "info" => commands::info::run(&ctx, &command).await, - "play" => commands::play::run(&ctx, &command).await, - "stop" => commands::stop::run(&ctx, &command).await, - "skip" => commands::skip::run(&ctx, &command).await, - "nowplaying" => commands::now_playing::run(&ctx, &command).await, - _ => respond_with_error(&ctx, &command).await, - }); + let content = Some(match command.data.name.as_str() { + "info" => commands::info::run(&ctx, &command).await, + "play" => commands::play::run(&ctx, &command).await, + "stop" => commands::stop::run(&ctx, &command).await, + "skip" => commands::skip::run(&ctx, &command).await, + "nowplaying" => commands::now_playing::run(&ctx, &command).await, + _ => respond_with_error(&ctx, &command).await, + }); if let Some(embed) = content { let followup = CreateInteractionResponseFollowup::new().embed(embed); @@ -63,7 +63,8 @@ impl EventHandler for Handler { let _command = Command::create_global_command(&ctx.http, commands::stop::register()).await; let _command = Command::create_global_command(&ctx.http, commands::play::register()).await; let _command = Command::create_global_command(&ctx.http, commands::skip::register()).await; - let _command = Command::create_global_command(&ctx.http, commands::now_playing::register()).await; + let _command = + Command::create_global_command(&ctx.http, commands::now_playing::register()).await; println!("Commands are registered and Rustendo is ready for Freddy."); } @@ -94,7 +95,11 @@ impl EventHandler for Handler { } pub async fn respond_with_error(_ctx: &Context, command: &CommandInteraction) -> CreateEmbed { - Embed::create_error_respose(command.user.name.as_str(), "Command not found", "Cannot find the executed command") + Embed::create_error_respose( + command.user.name.as_str(), + "Command not found", + "Cannot find the executed command", + ) } #[tokio::main] diff --git a/src/music/mod.rs b/src/music/mod.rs index 8224adc..d99af32 100644 --- a/src/music/mod.rs +++ b/src/music/mod.rs @@ -1,3 +1,3 @@ -pub mod music_manager; pub mod music_events; -pub mod music_queue; \ No newline at end of file +pub mod music_manager; +pub mod music_queue; diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index e4f88c7..df6654c 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -89,7 +89,6 @@ pub async fn attempt_to_queue_song( .expect("Cannot get head of queue"); music_queue::set_now_playing(guild_id, Some(src.clone())).await; - let handler_lock = match manager.get(*guild_id) { Some(handler) => handler, None => { diff --git a/src/music/music_queue.rs b/src/music/music_queue.rs index 4f03040..09a1cb9 100644 --- a/src/music/music_queue.rs +++ b/src/music/music_queue.rs @@ -12,7 +12,7 @@ type MusicQueueItem = Arc>; pub struct MusicQueue { pub queue: VecDeque, pub now_playing: Option, - pub now_playing_track_handle: Option + pub now_playing_track_handle: Option, } lazy_static! { @@ -69,11 +69,14 @@ pub async fn get_now_playing(guild_id: &GuildId) -> Option { } pub async fn set_now_playing_track_handle(guild_id: &GuildId, track_handle: Option) { - with_music_queue(guild_id, |queue| queue.now_playing_track_handle = track_handle).await + with_music_queue(guild_id, |queue| { + queue.now_playing_track_handle = track_handle + }) + .await } pub async fn get_now_playing_track_handle(guild_id: &GuildId) -> Option { - with_music_queue(guild_id, | queue| queue.now_playing_track_handle.to_owned()).await + with_music_queue(guild_id, |queue| queue.now_playing_track_handle.to_owned()).await } pub async fn is_empty(guild_id: &GuildId) -> bool { diff --git a/src/util/embed.rs b/src/util/embed.rs index 52526a7..39a0cbe 100644 --- a/src/util/embed.rs +++ b/src/util/embed.rs @@ -11,46 +11,71 @@ impl Embed { let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); CreateEmbed::new() - .title(title) - .description(desc) - .color(Color::from_rgb(224, 49, 26)) - .footer(CreateEmbedFooter::new(format!("> {} - {}", current_time, username))) + .title(title) + .description(desc) + .color(Color::from_rgb(224, 49, 26)) + .footer(CreateEmbedFooter::new(format!( + "> {} - {}", + current_time, username + ))) } - pub fn create_error_respose(username: &str, error_title: &str, error_desc: &str) -> CreateEmbed { + pub fn create_error_respose( + username: &str, + error_title: &str, + error_desc: &str, + ) -> CreateEmbed { let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); CreateEmbed::new() - .author(CreateEmbedAuthor::new("Oops, something went wrong.")) - .title(error_title) - .description(error_desc) - .color(Color::from_rgb(224, 49, 26)) - .footer(CreateEmbedFooter::new(format!("> {} - {}", current_time, username))) + .author(CreateEmbedAuthor::new("Oops, something went wrong.")) + .title(error_title) + .description(error_desc) + .color(Color::from_rgb(224, 49, 26)) + .footer(CreateEmbedFooter::new(format!( + "> {} - {}", + current_time, username + ))) } - pub async fn create_yt_playing(mut src: YoutubeDl, username: &str, show_as_author: &str) -> CreateEmbed { - let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); + pub async fn create_yt_playing( + mut src: YoutubeDl, + username: &str, + show_as_author: &str, + ) -> CreateEmbed { + let current_time = Local::now().format("%Y-%m-%d @ %H:%M:%S"); - // Get metadata - let metadata = src.aux_metadata().await.expect("Cannot get metadata"); - let title = metadata.title.unwrap_or("Unknown title".to_string()); - let artist = metadata.artist.unwrap_or("Unknown artist".to_string()); - let duration = metadata.duration.unwrap_or(Duration::from_millis(0)); - let thumbnail = metadata - .thumbnail - .unwrap_or("https://http.cat/images/403.jpg".to_string()); - let link = metadata - .source_url - .unwrap_or("https://piped.moonleay.net/403".to_string()); + // Get metadata + let metadata = src.aux_metadata().await.expect("Cannot get metadata"); + let title = metadata.title.unwrap_or("Unknown title".to_string()); + let artist = metadata.artist.unwrap_or("Unknown artist".to_string()); + let duration = metadata.duration.unwrap_or(Duration::from_millis(0)); + let thumbnail = metadata + .thumbnail + .unwrap_or("https://http.cat/images/403.jpg".to_string()); + let link = metadata + .source_url + .unwrap_or("https://piped.moonleay.net/403".to_string()); - CreateEmbed::new() - .author(CreateEmbedAuthor::new(show_as_author)) - .title(title) - .url(link) - .thumbnail(thumbnail) - .field("Artist", artist, true) - .field("Duration", format!("{}min {}sec", duration.as_secs() / 60, duration.as_secs() % 60), true) - .color(Color::from_rgb(81, 224, 26)) - .footer(CreateEmbedFooter::new(format!("> {} - {}",current_time, username))) + CreateEmbed::new() + .author(CreateEmbedAuthor::new(show_as_author)) + .title(title) + .url(link) + .thumbnail(thumbnail) + .field("Artist", artist, true) + .field( + "Duration", + format!( + "{}min {}sec", + duration.as_secs() / 60, + duration.as_secs() % 60 + ), + true, + ) + .color(Color::from_rgb(81, 224, 26)) + .footer(CreateEmbedFooter::new(format!( + "> {} - {}", + current_time, username + ))) } } From cd879e8af9cee9b48166f882816406a87f99a817 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 4 Apr 2024 08:51:49 +0200 Subject: [PATCH 29/41] feat: added docker support, added docker-compose.yml --- .dockerignore | 2 ++ Dockerfile | 10 ++++++++++ docker-compose.yml | 15 +++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f6c313c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +/target +/data \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b48cfa6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM rust:1.77 + +WORKDIR /usr/src/app +COPY . . + +RUN apt-get update +RUN apt-get install -y cmake +RUN cargo build --release + +CMD ["/usr/src/app/target/release/rustendo"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..cb228f1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: "3" +services: + botendo: + container_name: botendo + image: limiteddev/rustendo:0.1.0 + environment: + TZ: "Europe/Berlin" + deploy: + resources: + limits: + cpus: "0.5" + memory: 512M + restart: unless-stopped + volumes: + - ./data:/usr/src/app/data \ No newline at end of file From f1b0e1e3634bc10dca1517050cb0ebbd148bf713 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 4 Apr 2024 09:21:25 +0200 Subject: [PATCH 30/41] fix: added yt-dlp to docker container --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b48cfa6..b94baf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /usr/src/app COPY . . RUN apt-get update -RUN apt-get install -y cmake +RUN apt-get install -y cmake yt-dlp RUN cargo build --release CMD ["/usr/src/app/target/release/rustendo"] \ No newline at end of file From b5888ec441d9e4fd9c1be9c8841ac240777a4960 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 4 Apr 2024 09:21:31 +0200 Subject: [PATCH 31/41] chore: bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fddf69e..b152e8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1555,7 +1555,7 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustendo" -version = "0.1.0" +version = "7.0.0" dependencies = [ "chrono", "confy", diff --git a/Cargo.toml b/Cargo.toml index cb0a401..064eb41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustendo" -version = "0.1.0" +version = "7.0.0" authors = ["moonleay ", "migueldamota "] edition = "2021" From 2b4e21736c068fdc72de7bb8c9c6a2afd99d9052 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 4 Apr 2024 10:07:11 +0200 Subject: [PATCH 32/41] fix: removed warnings --- src/commands/now_playing.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/commands/now_playing.rs b/src/commands/now_playing.rs index e3b5a5e..c90a3f0 100644 --- a/src/commands/now_playing.rs +++ b/src/commands/now_playing.rs @@ -1,6 +1,5 @@ use crate::music::music_queue; use crate::util::embed::Embed; -use futures::{FutureExt, TryFutureExt}; use serenity::all::{CommandInteraction, Context}; use serenity::builder::{CreateCommand, CreateEmbed}; @@ -45,7 +44,7 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) -> CreateEmbed { .expect("Cannot get Songbird") .clone(); - let handler = match manager.get(*guild_id) { + let _ = match manager.get(*guild_id) { Some(handler) => handler, None => { return Embed::create_error_respose( From 078586dd3f78219be8231f1037499c4d06a3bb54 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 4 Apr 2024 10:07:21 +0200 Subject: [PATCH 33/41] chore: upgraded dependencies --- Cargo.lock | 211 ++++++++++++++++++++++++++--------------------------- 1 file changed, 105 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b152e8f..f5d366f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,9 +29,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -62,13 +62,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -93,15 +93,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -132,9 +132,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -159,9 +159,9 @@ checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" [[package]] name = "bytemuck" -version = "1.14.3" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" [[package]] name = "byteorder" @@ -171,9 +171,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "camino" @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -220,9 +220,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", @@ -475,9 +475,9 @@ checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "flate2" @@ -587,7 +587,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -680,9 +680,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -840,9 +840,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -865,9 +865,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" @@ -898,13 +898,12 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "libc", - "redox_syscall", ] [[package]] @@ -955,9 +954,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -1129,7 +1128,7 @@ version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "cfg-if", "foreign-types", "libc", @@ -1146,7 +1145,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -1157,9 +1156,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -1234,14 +1233,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1273,7 +1272,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -1319,9 +1318,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -1332,7 +1331,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "memchr", "unicase", ] @@ -1396,9 +1395,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -1407,14 +1406,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -1434,7 +1433,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -1445,15 +1444,15 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.11.25" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -1590,11 +1589,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -1627,9 +1626,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" dependencies = [ "log", "ring 0.17.8", @@ -1662,9 +1661,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" [[package]] name = "rustls-webpki" @@ -1773,9 +1772,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -1786,9 +1785,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -1841,14 +1840,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -1863,7 +1862,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -1896,7 +1895,7 @@ dependencies = [ "arrayvec", "async-trait", "base64 0.21.7", - "bitflags 2.4.2", + "bitflags 2.5.0", "bytes", "chrono", "command_attr", @@ -1929,7 +1928,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "593682f6155d07c8b331b3d1060f5aab7e6796caca9f2f66bd9e6855c880e06b" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "num-traits", "serde", "serde_json", @@ -1991,9 +1990,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -2239,9 +2238,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -2256,20 +2255,20 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "system-configuration" -version = "0.6.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 2.4.2", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ "core-foundation-sys", "libc", @@ -2295,22 +2294,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2371,9 +2370,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -2395,7 +2394,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2435,7 +2434,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pki-types", "tokio", ] @@ -2464,7 +2463,7 @@ checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", @@ -2488,9 +2487,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.10" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ "serde", "serde_spanned", @@ -2509,9 +2508,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.6" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ "indexmap", "serde", @@ -2546,7 +2545,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2654,7 +2653,7 @@ dependencies = [ "httparse", "log", "rand", - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pki-types", "sha1", "thiserror", @@ -2719,9 +2718,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typesize" -version = "0.1.5" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36924509726e38224322c8c90ddfbf4317324338327b7c11b7cf8672cb786da1" +checksum = "eb704842c709bc76f63e99e704cb208beeccca2abbabd0d9aec02e48ca1cee0f" dependencies = [ "chrono", "dashmap", @@ -2737,13 +2736,13 @@ dependencies = [ [[package]] name = "typesize-derive" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b122284365ba8497be951b9a21491f70c9688eb6fddc582931a0703f6a00ece" +checksum = "905e88c2a4cc27686bd57e495121d451f027e441388a67f773be729ad4be1ea8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2818,9 +2817,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", ] @@ -2895,7 +2894,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -2929,7 +2928,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From 242fa5217093af8db508c9060a7ddd036530ad88 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 16 Apr 2024 02:21:07 +0200 Subject: [PATCH 34/41] chore: added Cargo.lock to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d8f4d9c..a0d34bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /target /data config.json +Cargo.lock .idea/ .vscode/ From 80dc6d05ba873f591bab23f5cd8f67914df6375e Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 26 Jul 2024 16:50:53 +0200 Subject: [PATCH 35/41] chore: bumped dependencies --- Cargo.lock | 765 +++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 6 +- 2 files changed, 512 insertions(+), 259 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5d366f..dd81a9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -62,13 +62,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -93,15 +93,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -124,6 +124,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -132,9 +138,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -147,21 +153,21 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.15.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" [[package]] name = "byteorder" @@ -171,15 +177,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] @@ -208,9 +214,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" [[package]] name = "cfg-if" @@ -220,9 +226,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -230,7 +236,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -255,9 +261,9 @@ dependencies = [ [[package]] name = "command_attr" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f08c85a02e066b7b4f7dcb60eee6ae0793ef7d6452a3547d1f19665df070a9" +checksum = "88da8d7e9fe6f30d8e3fcf72d0f84102b49de70fece952633e8439e89bdc7631" dependencies = [ "proc-macro2", "quote", @@ -276,6 +282,12 @@ dependencies = [ "toml", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "core-foundation" version = "0.9.4" @@ -303,27 +315,27 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -351,6 +363,41 @@ dependencies = [ "zeroize", ] +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -367,9 +414,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "deranged" @@ -392,6 +439,44 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_builder" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" +dependencies = [ + "darling", + "derive_builder_core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.72", +] + [[package]] name = "digest" version = "0.10.7" @@ -435,9 +520,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -450,9 +535,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -475,15 +560,15 @@ checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -531,6 +616,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "from_map" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99f31122ab0445ff8cee420b805f24e07683073815de1dd276ee7d588d301700" +dependencies = [ + "hashmap_derive", +] + [[package]] name = "futures" version = "0.3.30" @@ -587,7 +681,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -655,9 +749,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -668,9 +762,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -699,9 +793,29 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashmap_derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb30bf173e72cc31b5265dac095423ca14e7789ff7c3b0e6096a37a996f12883" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "hermit-abi" @@ -709,6 +823,27 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hls_m3u8" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e2bd2de7f92b5301546ce1ac53a4ae5cf2f6b10751b100ab1efb73c19788fba" +dependencies = [ + "derive_builder", + "derive_more", + "hex", + "shorthand", + "stable-vec", + "strum", + "thiserror", +] + [[package]] name = "http" version = "0.2.12" @@ -744,9 +879,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -756,9 +891,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -787,7 +922,7 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper", - "rustls 0.21.10", + "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", ] @@ -828,6 +963,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -880,9 +1021,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "levenshtein" @@ -892,9 +1033,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libredox" @@ -902,21 +1043,21 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -924,9 +1065,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "loom" @@ -954,9 +1095,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -966,9 +1107,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -991,22 +1132,23 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1020,11 +1162,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1036,6 +1177,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "no-std-compat" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df270209a7f04d62459240d890ecb792714d5db12c92937823574a09930276b4" + [[package]] name = "no-std-net" version = "0.6.0" @@ -1060,9 +1207,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -1084,9 +1231,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -1103,9 +1250,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ "memchr", ] @@ -1124,11 +1271,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -1145,7 +1292,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -1156,9 +1303,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -1189,9 +1336,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1199,15 +1346,24 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "patricia_tree" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f2f4539bffe53fc4b4da301df49d114b845b077bd5727b7fe2bd9d8df2ae68" +dependencies = [ + "bitflags 2.6.0", ] [[package]] @@ -1233,7 +1389,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -1272,7 +1428,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -1309,18 +1465,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "primal-check" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df7f93fd637f083201473dab4fee2db4c429d32e55e3299980ab3957ab916a0" +checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08" dependencies = [ "num-integer", ] [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1331,16 +1487,16 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "memchr", "unicase", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1386,11 +1542,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] @@ -1406,14 +1562,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -1427,13 +1583,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -1444,9 +1600,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -1474,7 +1630,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-pemfile", "serde", "serde_json", @@ -1527,18 +1683,18 @@ dependencies = [ [[package]] name = "ringbuf" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79abed428d1fd2a128201cec72c5f6938e2da607c6f3745f769fabea399d950a" +checksum = "5c65e4c865bc3d2e3294493dff0acf7e6c259d066e34e22059fa9c39645c3636" dependencies = [ "crossbeam-utils", ] [[package]] name = "rubato" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6dd52e80cfc21894deadf554a5673002938ae4625f7a283e536f9cf7c17b0d5" +checksum = "b5d18b486e7d29a408ef3f825bc1327d8f87af091c987ca2f5b734625940e234" dependencies = [ "num-complex", "num-integer", @@ -1548,13 +1704,22 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] [[package]] name = "rustendo" -version = "7.0.0" +version = "7.0.1" dependencies = [ "chrono", "confy", @@ -1589,11 +1754,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1614,9 +1779,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", @@ -1626,14 +1791,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki 0.102.6", "subtle", "zeroize", ] @@ -1661,9 +1826,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.4.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -1677,9 +1842,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -1688,9 +1853,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty_pool" @@ -1707,9 +1872,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "salsa20" @@ -1772,11 +1937,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -1785,9 +1950,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -1795,18 +1960,18 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -1833,21 +1998,30 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.197" +name = "serde_cow" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "1e7bbbec7196bfde255ab54b65e34087c0849629280028238e67ee25d6a4b7da" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -1856,20 +2030,20 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -1888,14 +2062,14 @@ dependencies = [ [[package]] name = "serenity" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64da29158bb55d70677cacd4f4f8eab1acef005fb830d9c3bea411b090e96a9" +checksum = "880a04106592d0a8f5bdacb1d935889bfbccb4a14f7074984d9cd857235d34ac" dependencies = [ "arrayvec", "async-trait", - "base64 0.21.7", - "bitflags 2.5.0", + "base64 0.22.1", + "bitflags 2.6.0", "bytes", "chrono", "command_attr", @@ -1910,6 +2084,7 @@ dependencies = [ "reqwest", "secrecy", "serde", + "serde_cow", "serde_json", "static_assertions", "time", @@ -1928,7 +2103,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "593682f6155d07c8b331b3d1060f5aab7e6796caca9f2f66bd9e6855c880e06b" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "num-traits", "serde", "serde_json", @@ -1956,10 +2131,22 @@ dependencies = [ ] [[package]] -name = "signal-hook-registry" -version = "1.4.1" +name = "shorthand" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "474f77f985d8212610f170332eaf173e768404c0c1d4deb041f32c297cf18931" +dependencies = [ + "from_map", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -1996,9 +2183,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2006,13 +2193,14 @@ dependencies = [ [[package]] name = "songbird" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54d70e66a385ea8f732afac37b6ff2a8334eccac9aeed3d162a3c550b059233a" +checksum = "338dd182f9f084f583c4c0db38588e28a34778ecec288208cf0b61c378ac90d1" dependencies = [ "async-trait", "audiopus", "byteorder", + "bytes", "crypto_secretbox", "dashmap", "derivative", @@ -2034,6 +2222,7 @@ dependencies = [ "serenity", "serenity-voice-model", "socket2", + "stream_lib", "streamcatcher", "symphonia", "symphonia-core", @@ -2063,12 +2252,38 @@ dependencies = [ "lock_api", ] +[[package]] +name = "stable-vec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1dff32a2ce087283bec878419027cebd888760d8760b2941ad0843531dc9ec8" +dependencies = [ + "no-std-compat", +] + [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stream_lib" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3f10eb5a7054e17abf61d310e4e29108187a847591c63c4c79b6a74898a5a7" +dependencies = [ + "bytes", + "futures-core", + "futures-util", + "hls_m3u8", + "patricia_tree", + "reqwest", + "tokio", + "tracing", + "url", +] + [[package]] name = "streamcatcher" version = "1.0.1" @@ -2087,10 +2302,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" [[package]] -name = "subtle" -version = "2.5.0" +name = "strsim" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "strum" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "530efb820d53b712f4e347916c5e7ed20deb76a4f0457943b3182fb889b06d2c" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6e163a520367c465f59e0a61a23cfae3b10b6546d78b6f672a382be79f7110" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symphonia" @@ -2238,9 +2480,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -2294,22 +2536,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -2324,9 +2566,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -2345,9 +2587,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -2355,9 +2597,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2370,31 +2612,30 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -2424,7 +2665,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.12", "tokio", ] @@ -2434,7 +2675,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.3", + "rustls 0.22.4", "rustls-pki-types", "tokio", ] @@ -2463,33 +2704,32 @@ checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", - "rustls 0.22.3", + "rustls 0.22.4", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", "tungstenite 0.21.0", - "webpki-roots 0.26.1", + "webpki-roots 0.26.3", ] [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c" dependencies = [ "serde", "serde_spanned", @@ -2499,18 +2739,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16" dependencies = [ "indexmap", "serde", @@ -2545,7 +2785,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -2609,9 +2849,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" [[package]] name = "try-lock" @@ -2653,7 +2893,7 @@ dependencies = [ "httparse", "log", "rand", - "rustls 0.22.3", + "rustls 0.22.4", "rustls-pki-types", "sha1", "thiserror", @@ -2742,7 +2982,7 @@ checksum = "905e88c2a4cc27686bd57e495121d451f027e441388a67f773be729ad4be1ea8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", ] [[package]] @@ -2775,6 +3015,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "universal-hash" version = "0.5.1" @@ -2799,9 +3045,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -2817,9 +3063,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", ] @@ -2844,9 +3090,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" @@ -2894,7 +3140,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -2928,7 +3174,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2980,9 +3226,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" dependencies = [ "rustls-pki-types", ] @@ -3005,11 +3251,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3033,7 +3279,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -3051,7 +3297,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -3071,17 +3317,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3092,9 +3339,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3104,9 +3351,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3116,9 +3363,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3128,9 +3381,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3140,9 +3393,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3152,9 +3405,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3164,15 +3417,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c" dependencies = [ "memchr", ] @@ -3189,6 +3442,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index 064eb41..7aa2757 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustendo" -version = "7.0.0" +version = "7.0.1" authors = ["moonleay ", "migueldamota "] edition = "2021" @@ -9,13 +9,13 @@ edition = "2021" [dependencies] serenity = "0.12" -tokio = { version = "1.36", features = ["macros", "rt-multi-thread"] } +tokio = { version = "1.39", features = ["macros", "rt-multi-thread"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" confy = "0.6.0" songbird = "0.4" chrono = "0.4" -reqwest = "0.11" +reqwest = "0.11" # 0.12 creates issues; don't update for now, will fix later symphonia = "0.5" tracing = "0.1.40" tracing-subscriber = "0.3.18" From 0c686e551775359a3c8c00537ba8e0eb6fe90062 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 26 Jul 2024 16:54:31 +0200 Subject: [PATCH 36/41] chore: bumped rust version in docker container --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b94baf4..5c8b158 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.77 +FROM rust:1.80 WORKDIR /usr/src/app COPY . . @@ -7,4 +7,4 @@ RUN apt-get update RUN apt-get install -y cmake yt-dlp RUN cargo build --release -CMD ["/usr/src/app/target/release/rustendo"] \ No newline at end of file +CMD ["/usr/src/app/target/release/rustendo"] From 389f61682fe08f6c2139133798a729e40288513c Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 19 Sep 2024 00:21:21 +0200 Subject: [PATCH 37/41] chore: bump dependencies --- Cargo.lock | 331 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 188 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd81a9f..8f4e01d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -53,22 +53,22 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" dependencies = [ "serde", ] [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -99,17 +99,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -165,9 +165,9 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.16.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -177,15 +177,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -214,9 +214,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.6" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -252,9 +255,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.50" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" dependencies = [ "cc", ] @@ -300,15 +303,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -474,7 +477,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -560,15 +563,15 @@ checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", "miniz_oxide", @@ -681,7 +684,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -762,9 +765,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -831,9 +834,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hls_m3u8" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e2bd2de7f92b5301546ce1ac53a4ae5cf2f6b10751b100ab1efb73c19788fba" +checksum = "b906521a5b0e6d2ec07ea0bb855d92a1db30b48812744a645a3b2a1405cb8159" dependencies = [ "derive_builder", "derive_more", @@ -942,9 +945,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -981,9 +984,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", @@ -1000,9 +1003,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "itoa" @@ -1012,9 +1015,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -1033,9 +1036,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libredox" @@ -1132,18 +1135,18 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", @@ -1250,9 +1253,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.2" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -1292,7 +1295,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -1389,7 +1392,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -1428,7 +1431,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -1459,9 +1462,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "primal-check" @@ -1494,9 +1500,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1542,18 +1548,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -1562,9 +1568,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -1683,9 +1689,9 @@ dependencies = [ [[package]] name = "ringbuf" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c65e4c865bc3d2e3294493dff0acf7e6c259d066e34e22059fa9c39645c3636" +checksum = "46f7f1b88601a8ee13cabf203611ccdf64345dc1c5d24de8b11e1a678ee619b6" dependencies = [ "crossbeam-utils", ] @@ -1710,16 +1716,16 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustendo" -version = "7.0.1" +version = "7.0.3" dependencies = [ "chrono", "confy", @@ -1754,9 +1760,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -1798,7 +1804,7 @@ dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] @@ -1826,9 +1832,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" @@ -1842,9 +1848,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -1896,11 +1902,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1969,9 +1975,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -2008,22 +2014,23 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -2036,7 +2043,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -2130,6 +2137,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "shorthand" version = "0.1.1" @@ -2480,9 +2493,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -2524,14 +2537,15 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2551,7 +2565,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -2612,9 +2626,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.1" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -2635,7 +2649,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -2709,14 +2723,14 @@ dependencies = [ "tokio", "tokio-rustls 0.25.0", "tungstenite 0.21.0", - "webpki-roots 0.26.3", + "webpki-roots 0.26.5", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -2727,9 +2741,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -2739,18 +2753,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.17" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap", "serde", @@ -2761,9 +2775,9 @@ dependencies = [ [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -2785,7 +2799,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -2958,9 +2972,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typesize" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb704842c709bc76f63e99e704cb208beeccca2abbabd0d9aec02e48ca1cee0f" +checksum = "5dece5c06268af6a9ff4541788601e560a4284ffebfb357f713d676f13b964db" dependencies = [ "chrono", "dashmap", @@ -2982,7 +2996,7 @@ checksum = "905e88c2a4cc27686bd57e495121d451f027e441388a67f773be729ad4be1ea8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", ] [[package]] @@ -3002,24 +3016,24 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "universal-hash" @@ -3121,34 +3135,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -3158,9 +3173,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3168,22 +3183,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-streams" @@ -3200,9 +3215,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -3226,9 +3241,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.3" +version = "0.26.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" dependencies = [ "rustls-pki-types", ] @@ -3251,11 +3266,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3300,6 +3315,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -3423,9 +3447,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.16" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -3440,6 +3464,27 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "zeroize" version = "1.8.1" From b368a23adfe864ed176751d7544b74a953faa814 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 19 Sep 2024 00:21:29 +0200 Subject: [PATCH 38/41] chore: bump version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7aa2757..98bf2a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustendo" -version = "7.0.1" +version = "7.0.3" authors = ["moonleay ", "migueldamota "] edition = "2021" From e56e83213f242903be4f13c6788f44ff511032ea Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 19 Sep 2024 00:23:20 +0200 Subject: [PATCH 39/41] fix: fixed yt-dlp not working in docker container chore: bump rust version --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5c8b158..9321e7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,11 @@ -FROM rust:1.80 +FROM rust:1.81 WORKDIR /usr/src/app COPY . . +RUN echo 'deb http://deb.debian.org/debian bookworm-backports main' >> /etc/apt/sources.list RUN apt-get update -RUN apt-get install -y cmake yt-dlp +RUN apt-get install -y cmake yt-dlp/bookworm-backports RUN cargo build --release CMD ["/usr/src/app/target/release/rustendo"] From 84048b1b67bbf4c8a563beda0948aa2e9bc20f2a Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 29 Sep 2024 22:41:05 +0200 Subject: [PATCH 40/41] fix: stop bot from loading playlists and crashing itself --- src/music/music_manager.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/music/music_manager.rs b/src/music/music_manager.rs index df6654c..3df3dfc 100644 --- a/src/music/music_manager.rs +++ b/src/music/music_manager.rs @@ -56,7 +56,7 @@ pub async fn attempt_to_queue_song( return Embed::create_error_respose( username, "You are not in my VC", - "You have to be in my VC in order to controll the music.", + "You have to be in my VC in order to control the music.", ); } } @@ -70,6 +70,14 @@ pub async fn attempt_to_queue_song( .expect("Guaranteed to exist in the typemap.") }; + if query.contains("youtu") && query.contains("&list=") { + return Embed::create_error_respose( + username, + "Playlists are not supported", + "I do not support playlists of any kind, please only provide links to videos" + ); + } + // Create source let src = if do_search { YoutubeDl::new_search(http_client, query.to_string()) From 23ff902e01c358ac8af05761214eae010004da2c Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 29 Sep 2024 22:41:22 +0200 Subject: [PATCH 41/41] chore: bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f4e01d..7131277 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1725,7 +1725,7 @@ dependencies = [ [[package]] name = "rustendo" -version = "7.0.3" +version = "7.0.4" dependencies = [ "chrono", "confy", diff --git a/Cargo.toml b/Cargo.toml index 98bf2a8..de15d83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustendo" -version = "7.0.3" +version = "7.0.4" authors = ["moonleay ", "migueldamota "] edition = "2021"