From a27e95a88da188caef1877bb10e95d9aa5a5effa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Czy=C5=BC?= Date: Sat, 10 Feb 2024 22:22:45 +0100 Subject: [PATCH] music commands migrated --- Cargo.lock | 3 +- Cargo.toml | 12 ++++- LICENSE.md | 6 ++- scripts/cross-build.sh | 0 scripts/launch.sh | 2 +- src/commands/misc.rs | 8 --- src/commands/mod.rs | 1 - src/commands/music/deafen.rs | 36 ++++---------- src/commands/music/join.rs | 28 +++++------ src/commands/music/leave.rs | 42 ++++++---------- src/commands/music/loopcurrent.rs | 83 ------------------------------- src/commands/music/misc.rs | 2 +- src/commands/music/mod.rs | 2 +- src/commands/music/mute.rs | 36 ++++---------- src/commands/music/pause.rs | 33 +++--------- src/commands/music/play.rs | 57 ++++++--------------- src/commands/music/queue.rs | 30 +++-------- src/commands/music/repeat.rs | 43 ++++++++++++++++ src/commands/music/resume.rs | 33 +++--------- src/commands/music/skip.rs | 33 +++--------- src/commands/music/stop.rs | 26 +++------- src/http.rs | 8 +++ src/main.rs | 10 +++- 23 files changed, 182 insertions(+), 352 deletions(-) mode change 100644 => 100755 scripts/cross-build.sh mode change 100644 => 100755 scripts/launch.sh delete mode 100644 src/commands/misc.rs delete mode 100644 src/commands/music/loopcurrent.rs create mode 100644 src/commands/music/repeat.rs create mode 100644 src/http.rs diff --git a/Cargo.lock b/Cargo.lock index db60f44..059ef6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -933,7 +933,7 @@ dependencies = [ [[package]] name = "lyra" -version = "0.3.0" +version = "0.4.0" dependencies = [ "dotenv", "openssl", @@ -2338,6 +2338,7 @@ dependencies = [ "libc", "mio", "num_cpus", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", diff --git a/Cargo.toml b/Cargo.toml index 11c90ff..f305a5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,15 @@ [package] name = "lyra" -version = "0.3.0" +version = "0.4.0" +authors = ["Michał Czyż "] edition = "2021" +description = "A featureful Discord bot written in Rust." +documentation = "https://lyra.c2yz.com/docs" +readme = "README.md" +homepage = "https://lyra.c2yz.com" +license-file = "LICENSE.md" +keywords = ["discord", "bot", "rust", "music", "featureful"] + [dependencies] dotenv = "0.15.0" @@ -12,7 +20,7 @@ reqwest = "0.11.23" serenity = { version = "0.12.0", features = ["cache", "framework", "standard_framework", "voice"] } songbird = { version = "0.4.0", features = ["builtin-queue", "serenity"] } symphonia = "0.5.3" -tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread", "signal"] } +tokio = { version = "1.35.1", features = ["macros", "full", "signal"] } tracing = "0.1.40" tracing-futures = "0.2.5" tracing-subscriber = "0.3.18" diff --git a/LICENSE.md b/LICENSE.md index 4c05437..a1332ca 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,5 +1,7 @@ # License -Copyright(c) Michał Czyż 2024 +Copyright (C) 2024 Michał Czyż -[Currently] All Rights Reserved. \ No newline at end of file +All Rights Reserved. + +This build is private and shall not be distributed nor modified without permission. diff --git a/scripts/cross-build.sh b/scripts/cross-build.sh old mode 100644 new mode 100755 diff --git a/scripts/launch.sh b/scripts/launch.sh old mode 100644 new mode 100755 index a0a9c52..d28ad27 --- a/scripts/launch.sh +++ b/scripts/launch.sh @@ -1,3 +1,3 @@ #!/bin/bash -nohup ./lyra > lyra.log 2> lyra.err < /dev/null & +nohup ../lyra > lyra.log 2> lyra.err < /dev/null & diff --git a/src/commands/misc.rs b/src/commands/misc.rs deleted file mode 100644 index faf460a..0000000 --- a/src/commands/misc.rs +++ /dev/null @@ -1,8 +0,0 @@ -use serenity::model::channel::Message; -use serenity::Result as SerenityResult; - -pub fn check_msg(result: SerenityResult) { - if let Err(why) = result { - println!("Error sending message: {:?}", why); - } -} \ No newline at end of file diff --git a/src/commands/mod.rs b/src/commands/mod.rs index c60b84c..08f5ddf 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,4 +1,3 @@ pub mod kashi; -pub mod misc; pub mod music; pub mod tools; diff --git a/src/commands/music/deafen.rs b/src/commands/music/deafen.rs index 7206521..5c8cb8d 100644 --- a/src/commands/music/deafen.rs +++ b/src/commands/music/deafen.rs @@ -1,24 +1,18 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; +#[poise::command(prefix_command, slash_command)] +pub async fn deafen(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); -#[command] -#[only_in(guilds)] -async fn deafen(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed at init") + .expect("Songbird client placed at init") .clone(); let handler_lock = match manager.get(guild_id) { Some(handler) => handler, None => { - check_msg(msg.reply(ctx, "Not in a voice channel").await); + ctx.say("Not in a voice channel").await?; return Ok(()); } @@ -28,24 +22,16 @@ async fn deafen(ctx: &Context, msg: &Message) -> CommandResult { if handler.is_deaf() { if let Err(err) = handler.deafen(false).await { - check_msg( - msg.channel_id - .say(&ctx.http, format!("Failed: {:?}", err)) - .await, - ); + ctx.say(format!("Failed: {:?}", err)).await?; } - check_msg(msg.channel_id.say(&ctx.http, "Undeafened").await); + ctx.say("Undeafened").await?; } else { if let Err(err) = handler.deafen(true).await { - check_msg( - msg.channel_id - .say(&ctx.http, format!("Failed: {:?}", err)) - .await, - ); + ctx.say(format!("Failed: {:?}", err)).await?; } - check_msg(msg.channel_id.say(&ctx.http, "Deafened").await); + ctx.say("Deafened").await?; } Ok(()) diff --git a/src/commands/music/join.rs b/src/commands/music/join.rs index b8cb3f7..f318e3a 100644 --- a/src/commands/music/join.rs +++ b/src/commands/music/join.rs @@ -1,29 +1,23 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; -use songbird::events::TrackEvent; +use crate::{Context, Error}; +use songbird::TrackEvent; +use crate::commands::music::misc::TrackErrorNotifier; -use crate::commands::{misc::check_msg, music::misc::TrackErrorNotifier}; - -#[command] -#[only_in(guilds)] -async fn join(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - let channel_id = msg.guild(&ctx.cache).unwrap().voice_states.get(&msg.author.id).and_then(|voice_state| voice_state.channel_id); +#[poise::command(prefix_command, slash_command)] +pub async fn join(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); + let channel_id = ctx.guild().unwrap().voice_states.get(&ctx.author().id).and_then(|voice_state| voice_state.channel_id); let connect_to = match channel_id { Some(channel) => channel, None => { - check_msg(msg.reply(ctx, "Not in a voice channel").await); - + ctx.say("Not in a voice channel").await?; return Ok(()); } }; - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Songbird Voice placed at init") + .expect("Songbird client placed at init") .clone(); if let Ok(handler_lock) = manager.join(guild_id, connect_to).await { @@ -31,5 +25,7 @@ async fn join(ctx: &Context, msg: &Message) -> CommandResult { handler.add_global_event(TrackEvent::Error.into(), TrackErrorNotifier); } + ctx.say("Joined the voice channel").await?; + Ok(()) } diff --git a/src/commands/music/leave.rs b/src/commands/music/leave.rs index 0db428e..db11552 100644 --- a/src/commands/music/leave.rs +++ b/src/commands/music/leave.rs @@ -1,36 +1,24 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; +#[poise::command(prefix_command, slash_command)] +pub async fn leave(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); -#[command] -#[aliases(q)] -#[only_in(guilds)] -async fn leave(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed in at init") + .expect("Songbird client placed at init") .clone(); - let has_handler = manager.get(guild_id).is_some(); - - if has_handler { - if let Err(err) = manager.remove(guild_id).await { - check_msg( - msg.channel_id - .say(&ctx.http, format!("Failed: {:?}", err)) - .await, - ); - } - - check_msg(msg.channel_id.say(&ctx.http, "Left voice channel").await); - } else { - check_msg(msg.reply(ctx, "Not in a voice channel").await); + if !manager.get(guild_id).is_some() { + ctx.say("Not in a voice channel").await?; + return Ok(()) } + if let Err(err) = manager.remove(guild_id).await { + ctx.say(format!("Failed: {:?}", err)).await?; + } + + ctx.say("Left voice channel").await?; + Ok(()) } diff --git a/src/commands/music/loopcurrent.rs b/src/commands/music/loopcurrent.rs deleted file mode 100644 index e347f09..0000000 --- a/src/commands/music/loopcurrent.rs +++ /dev/null @@ -1,83 +0,0 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::{Args, CommandResult}; -use serenity::model::prelude::*; -use serenity::prelude::*; -use songbird::tracks::LoopState; - -use crate::commands::misc::check_msg; - -#[command] -#[aliases(loop)] -#[only_in(guilds)] -async fn loopcurrent(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - - let manager = songbird::get(ctx) - .await - .expect("Client placed at init") - .clone(); - - - if let Some(handler_lock) = manager.get(guild_id) { - let handler = handler_lock.lock().await; - let queue = handler.queue(); - - let track = queue.current().unwrap().get_info().await; - let is_looped = track.unwrap().loops; - - - let count = match args.single::() { - Ok(count) => count, - Err(_) => 100, - }; - - match is_looped { - LoopState::Infinite => { - let _ = queue.current().unwrap().disable_loop(); - - check_msg( - msg.channel_id - .say( - &ctx.http, - format!("Song unlooped."), - ) - .await, - ); - } - LoopState::Finite(_) => { - if count < 100 { - let _ = queue.current().unwrap().loop_for(count); - check_msg( - msg.channel_id - .say( - &ctx.http, - format!("Song looped forever (a very long time)."), - ) - .await, - ) - } - else { - let _ = queue.current().unwrap().enable_loop(); - - check_msg( - msg.channel_id - .say( - &ctx.http, - format!("Song looped {} times.", count), - ) - .await, - ) - } - - } - } - } else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel to play in") - .await, - ); - } - - Ok(()) -} diff --git a/src/commands/music/misc.rs b/src/commands/music/misc.rs index c9ff161..2a79369 100644 --- a/src/commands/music/misc.rs +++ b/src/commands/music/misc.rs @@ -17,4 +17,4 @@ impl VoiceEventHandler for TrackErrorNotifier { } None } -} \ No newline at end of file +} diff --git a/src/commands/music/mod.rs b/src/commands/music/mod.rs index 342a8fb..f983108 100644 --- a/src/commands/music/mod.rs +++ b/src/commands/music/mod.rs @@ -7,6 +7,6 @@ pub mod play; pub mod queue; pub mod skip; pub mod stop; -pub mod loopcurrent; +pub mod repeat; pub mod pause; pub mod resume; diff --git a/src/commands/music/mute.rs b/src/commands/music/mute.rs index edcf6fa..dca44c3 100644 --- a/src/commands/music/mute.rs +++ b/src/commands/music/mute.rs @@ -1,24 +1,18 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; +#[poise::command(prefix_command, slash_command)] +pub async fn mute(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); -#[command] -#[only_in(guilds)] -async fn mute(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed at init") + .expect("Songbird client placed at init") .clone(); let handler_lock = match manager.get(guild_id) { Some(handler) => handler, None => { - check_msg(msg.reply(ctx, "Not in a voice channel").await); + ctx.say("Not in a voice channel").await?; return Ok(()); } @@ -28,24 +22,16 @@ async fn mute(ctx: &Context, msg: &Message) -> CommandResult { if handler.is_mute() { if let Err(e) = handler.mute(false).await { - check_msg( - msg.channel_id - .say(&ctx.http, format!("failed: {:?}", e)) - .await, - ); + ctx.say(format!("failed: {:?}", e)).await?; } - check_msg(msg.channel_id.say(&ctx.http, "Unmuted").await); + ctx.say("Unmuted").await?; } else { if let Err(err) = handler.mute(true).await { - check_msg( - msg.channel_id - .say(&ctx.http, format!("Failed: {:?}", err)) - .await, - ); + ctx.say(format!("Failed: {:?}", err)).await?; } - check_msg(msg.channel_id.say(&ctx.http, "Muted").await); + ctx.say("Muted").await?; } Ok(()) diff --git a/src/commands/music/pause.rs b/src/commands/music/pause.rs index 02f0c77..b9a9e83 100644 --- a/src/commands/music/pause.rs +++ b/src/commands/music/pause.rs @@ -1,18 +1,12 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; +#[poise::command(prefix_command, slash_command)] +pub async fn pause(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); -#[command] -#[only_in(guilds)] -async fn pause(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed at init") + .expect("Songbird client placed at init") .clone(); if let Some(handler_lock) = manager.get(guild_id) { @@ -20,20 +14,9 @@ async fn pause(ctx: &Context, msg: &Message) -> CommandResult { let queue = handler.queue(); let _ = queue.pause(); - check_msg( - msg.channel_id - .say( - &ctx.http, - format!("Song paused."), - ) - .await, - ); + ctx.say(format!("Song paused.")).await?; } else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel to play in") - .await, - ); + ctx.say("Not in a voice channel to play in").await?; } Ok(()) diff --git a/src/commands/music/play.rs b/src/commands/music/play.rs index b16ccf0..2e456ec 100644 --- a/src/commands/music/play.rs +++ b/src/commands/music/play.rs @@ -1,58 +1,35 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::{Args, CommandResult}; -use serenity::model::prelude::*; -use serenity::prelude::*; -use reqwest::Client as HttpClient; +use crate::{Context, Error}; + use songbird::input::{Compose, YoutubeDl}; use songbird::events::TrackEvent; -use crate::commands::{misc::check_msg, music::misc::TrackErrorNotifier}; - -pub struct HttpKey; - -impl TypeMapKey for HttpKey { - type Value = HttpClient; -} - -#[command] -#[aliases(p)] -#[only_in(guilds)] -async fn play(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { - let url = match args.single::() { - Ok(url) => url, - Err(_) => { - check_msg( - msg.channel_id - .say(&ctx.http, "Must provide a URL to a video or audio") - .await, - ); - - return Ok(()); - } - }; +use crate::commands::music::misc::TrackErrorNotifier; +use crate::http::HttpKey; +#[poise::command(prefix_command, slash_command)] +pub async fn play(ctx: Context<'_>, url: String) -> Result<(), Error> { let is_search = !url.starts_with("http"); - let guild_id = msg.guild_id.unwrap(); - let channel_id = msg.guild(&ctx.cache).unwrap().voice_states.get(&msg.author.id).and_then(|voice_state| voice_state.channel_id); + let guild_id = ctx.guild_id().unwrap(); + let channel_id = ctx.guild().unwrap().voice_states.get(&ctx.author().id).and_then(|voice_state| voice_state.channel_id); let connect_to = match channel_id { Some(channel) => channel, None => { - check_msg(msg.reply(ctx, "Not in a voice channel").await); + ctx.say("Not in a voice channel").await?; return Ok(()); } }; let http_client = { - let data = ctx.data.read().await; + let data = ctx.serenity_context().data.read().await; data.get::() .cloned() .expect("Guaranteed to exist in the typemap.") }; - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await .expect("Songbird Voice placed at init") .clone(); @@ -65,22 +42,18 @@ async fn play(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { let mut src = if is_search { println!("ytsearch:{}", url); - YoutubeDl::new_ytdl_like("yt-dlp", http_client, format!("ytsearch:{}", args.clone().message())) + YoutubeDl::new_ytdl_like("yt-dlp", http_client, format!("ytsearch:{}", url)) } else { YoutubeDl::new_ytdl_like("yt-dlp", http_client, url) }; let _ = handler.enqueue_input(src.clone().into()).await; - let metadata = src.aux_metadata().await.unwrap(); + let _metadata = src.aux_metadata().await.unwrap(); - check_msg(msg.channel_id.say(&ctx.http, format!("Playing song: {}", metadata.title.unwrap())).await); + // ctx.say(format!("Playing song: {}", metadata.title.unwrap())).await?; } else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel to play in") - .await, - ); + ctx.say("Not in a voice channel to play in").await?; } Ok(()) diff --git a/src/commands/music/queue.rs b/src/commands/music/queue.rs index 9cc9c78..acc71bf 100644 --- a/src/commands/music/queue.rs +++ b/src/commands/music/queue.rs @@ -1,18 +1,12 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; - -#[command] -#[only_in(guilds)] -async fn queue(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); +#[poise::command(prefix_command, slash_command)] +pub async fn queue(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed at init") + .expect("Songbird client placed at init") .clone(); if let Some(handler_lock) = manager.get(guild_id) { @@ -30,18 +24,10 @@ async fn queue(ctx: &Context, msg: &Message) -> CommandResult { )); } - check_msg( - msg.channel_id - .say(&ctx.http, queue_res) - .await, - ); + ctx.say(queue_res).await?; } else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel!") - .await, - ); + ctx.say("Not in a voice channel!").await?; } Ok(()) diff --git a/src/commands/music/repeat.rs b/src/commands/music/repeat.rs new file mode 100644 index 0000000..41a2cd7 --- /dev/null +++ b/src/commands/music/repeat.rs @@ -0,0 +1,43 @@ +use crate::{Context, Error}; +use songbird::tracks::LoopState; + +#[poise::command(prefix_command, slash_command)] +pub async fn repeat(ctx: Context<'_>, times: usize) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); + + let manager = songbird::get(&ctx.serenity_context()) + .await + .expect("Songbird client placed at init") + .clone(); + + + if let Some(handler_lock) = manager.get(guild_id) { + let handler = handler_lock.lock().await; + let queue = handler.queue(); + + let track = queue.current().unwrap().get_info().await; + let is_looped = track.unwrap().loops; + + match is_looped { + LoopState::Infinite => { + let _ = queue.current().unwrap().disable_loop(); + + ctx.say("Song unlooped.").await?; + } + LoopState::Finite(_) => { + if times < 100 { + let _ = queue.current().unwrap().loop_for(times); + ctx.say("Song looped forever (a very long time)").await?; + } + else { + let _ = queue.current().unwrap().enable_loop(); + ctx.say(format!("Song looped {} times.", times)).await?; + } + } + } + } else { + ctx.say("Not in a voice channel to play in").await?; + } + + Ok(()) +} diff --git a/src/commands/music/resume.rs b/src/commands/music/resume.rs index a569bf5..864dea8 100644 --- a/src/commands/music/resume.rs +++ b/src/commands/music/resume.rs @@ -1,18 +1,12 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; +#[poise::command(prefix_command, slash_command)] +pub async fn resume(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); -#[command] -#[only_in(guilds)] -async fn resume(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed at init") + .expect("Songbird client placed at init") .clone(); if let Some(handler_lock) = manager.get(guild_id) { @@ -20,20 +14,9 @@ async fn resume(ctx: &Context, msg: &Message) -> CommandResult { let queue = handler.queue(); let _ = queue.resume(); - check_msg( - msg.channel_id - .say( - &ctx.http, - format!("Song resumed."), - ) - .await, - ); + ctx.say(format!("Song resumed.")).await?; } else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel to play in") - .await, - ); + ctx.say("Not in a voice channel to play in").await?; } Ok(()) diff --git a/src/commands/music/skip.rs b/src/commands/music/skip.rs index f6efc5a..d0abbd4 100644 --- a/src/commands/music/skip.rs +++ b/src/commands/music/skip.rs @@ -1,18 +1,12 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; +#[poise::command(prefix_command, slash_command)] +pub async fn skip(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); -#[command] -#[only_in(guilds)] -async fn skip(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); - - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed at init") + .expect("Songbird client placed at init") .clone(); if let Some(handler_lock) = manager.get(guild_id) { @@ -20,20 +14,9 @@ async fn skip(ctx: &Context, msg: &Message) -> CommandResult { let queue = handler.queue(); let _ = queue.skip(); - check_msg( - msg.channel_id - .say( - &ctx.http, - format!("Song skipped: {} in queue.", queue.len()), - ) - .await, - ); + ctx.say(format!("Song skipped: {} in queue.", queue.len())).await?; } else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel to play in") - .await, - ); + ctx.say("Not in a voice channel to play in").await?; } Ok(()) diff --git a/src/commands/music/stop.rs b/src/commands/music/stop.rs index 426737d..39e2067 100644 --- a/src/commands/music/stop.rs +++ b/src/commands/music/stop.rs @@ -1,18 +1,12 @@ -use serenity::framework::standard::macros::command; -use serenity::framework::standard::CommandResult; -use serenity::model::prelude::*; -use serenity::prelude::*; +use crate::{Context, Error}; -use crate::commands::misc::check_msg; - -#[command] -#[only_in(guilds)] -async fn stop(ctx: &Context, msg: &Message) -> CommandResult { - let guild_id = msg.guild_id.unwrap(); +#[poise::command(prefix_command, slash_command)] +pub async fn stop(ctx: Context<'_>) -> Result<(), Error> { + let guild_id = ctx.guild_id().unwrap(); - let manager = songbird::get(ctx) + let manager = songbird::get(&ctx.serenity_context()) .await - .expect("Client placed at init") + .expect("Songbird client placed at init") .clone(); if let Some(handler_lock) = manager.get(guild_id) { @@ -20,13 +14,9 @@ async fn stop(ctx: &Context, msg: &Message) -> CommandResult { let queue = handler.queue(); queue.stop(); - check_msg(msg.channel_id.say(&ctx.http, "Playback stopped!").await); + ctx.say("Playback stopped!").await?; } else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel!") - .await, - ); + ctx.say("Not in a voice channel!").await?; } Ok(()) diff --git a/src/http.rs b/src/http.rs new file mode 100644 index 0000000..e2b18b0 --- /dev/null +++ b/src/http.rs @@ -0,0 +1,8 @@ +use reqwest::Client as HttpClient; +use poise::serenity_prelude::prelude::TypeMapKey; + +pub struct HttpKey; + +impl TypeMapKey for HttpKey { + type Value = HttpClient; +} diff --git a/src/main.rs b/src/main.rs index 575860f..7911ef2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,9 +4,14 @@ use poise::serenity_prelude::{self as serenity, ActivityData}; use std::sync::Arc; use std::time::Duration; use tracing::{info, warn, error}; +use reqwest::Client as HttpClient; +mod http; mod commands; +// http typemap for handling requests +use crate::http::HttpKey; + // commands: music use crate::commands::music::deafen::*; use crate::commands::music::join::*; @@ -16,7 +21,7 @@ use crate::commands::music::play::*; use crate::commands::music::queue::*; use crate::commands::music::skip::*; use crate::commands::music::stop::*; -use crate::commands::music::loopcurrent::*; +use crate::commands::music::repeat::*; use crate::commands::music::pause::*; use crate::commands::music::resume::*; @@ -66,7 +71,7 @@ async fn main() { deafen(), join(), leave(), - loopcurrent(), + repeat(), mute(), pause(), play(), @@ -144,6 +149,7 @@ async fn main() { let mut client = serenity::ClientBuilder::new(token, intents) .framework(framework) .register_songbird() + .type_map_insert::(HttpClient::new()) .await .expect("Error creating client");