add more commands
This commit is contained in:
@@ -9,18 +9,18 @@ use serenity::{
|
|||||||
model::channel::Message,
|
model::channel::Message,
|
||||||
utils::MessageBuilder,
|
utils::MessageBuilder,
|
||||||
};
|
};
|
||||||
use songbird::input::Input;
|
use songbird::input::{Input, Metadata};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use sunk::{
|
use sunk::{
|
||||||
search::{self, SearchPage},
|
search::{self, SearchPage},
|
||||||
song::Song,
|
song::Song,
|
||||||
Streamable,
|
Media, Streamable,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::MusicClient;
|
use crate::MusicClient;
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[commands(song, random)]
|
#[commands(song, random, skip, stop, pause, resume, queue, now_playing, remove)]
|
||||||
pub struct General;
|
pub struct General;
|
||||||
|
|
||||||
pub struct Handler;
|
pub struct Handler;
|
||||||
@@ -29,10 +29,8 @@ pub struct Handler;
|
|||||||
impl EventHandler for Handler {}
|
impl EventHandler for Handler {}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[only_in(guilds)]
|
|
||||||
#[aliases(s, p, play)]
|
#[aliases(s, p, play)]
|
||||||
#[example("~song Down Under")]
|
/// Play a named song
|
||||||
#[description("Play a named song")]
|
|
||||||
async fn song(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
async fn song(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
let music_client = data
|
let music_client = data
|
||||||
@@ -61,10 +59,8 @@ async fn song(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[only_in(guilds)]
|
#[aliases(r, rand)]
|
||||||
#[aliases(r, random, rand)]
|
/// Play a random song
|
||||||
#[example("~random")]
|
|
||||||
#[description("Play a random song")]
|
|
||||||
async fn random(ctx: &Context, msg: &Message) -> CommandResult {
|
async fn random(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
let music_client = data
|
let music_client = data
|
||||||
@@ -86,6 +82,184 @@ async fn random(ctx: &Context, msg: &Message) -> CommandResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[aliases(pl)]
|
||||||
|
/// Play a playlist
|
||||||
|
async fn playlist(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let data = ctx.data.read().await;
|
||||||
|
let music_client = data
|
||||||
|
.get::<MusicClient>()
|
||||||
|
.expect("Couldn't retrieve music client");
|
||||||
|
|
||||||
|
let result = Song::random(&music_client, 1).await?;
|
||||||
|
|
||||||
|
match result.first() {
|
||||||
|
Some(song) => {
|
||||||
|
queue_song(ctx, msg, &song, &music_client).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let text = "No song found";
|
||||||
|
msg.reply(&ctx.http, text).await?;
|
||||||
|
Err(anyhow!(text).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
/// Skip current song
|
||||||
|
async fn skip(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
|
let handler = call.lock().await;
|
||||||
|
|
||||||
|
let queue = handler.queue();
|
||||||
|
queue.skip()?;
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, "Song skipped").await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
/// Clear queue and stop playing
|
||||||
|
async fn stop(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
|
let handler = call.lock().await;
|
||||||
|
|
||||||
|
let queue = handler.queue();
|
||||||
|
queue.stop();
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, "Stopped playing").await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
/// Pause playing current song
|
||||||
|
async fn pause(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
|
let handler = call.lock().await;
|
||||||
|
|
||||||
|
let queue = handler.queue();
|
||||||
|
let current = match queue.current() {
|
||||||
|
Some(channel) => channel,
|
||||||
|
None => {
|
||||||
|
let text = "Not currently playing";
|
||||||
|
msg.reply(ctx, text).await?;
|
||||||
|
return Err(anyhow!(text).into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
current.pause()?;
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, "Paused playing").await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[aliases(resume)]
|
||||||
|
/// Resume playing current song
|
||||||
|
async fn resume(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
|
let handler = call.lock().await;
|
||||||
|
|
||||||
|
let queue = handler.queue();
|
||||||
|
queue.resume()?;
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, "Resumed playing").await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[aliases(now_playing, now, np, playing)]
|
||||||
|
/// Show currently playing song
|
||||||
|
async fn now_playing(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
|
let handler = call.lock().await;
|
||||||
|
|
||||||
|
let queue = handler.queue();
|
||||||
|
let current = match queue.current() {
|
||||||
|
Some(channel) => channel,
|
||||||
|
None => {
|
||||||
|
let text = "Not currently playing";
|
||||||
|
msg.reply(ctx, text).await?;
|
||||||
|
return Err(anyhow!(text).into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let text = song_message(None, current.metadata());
|
||||||
|
msg.reply(&ctx.http, text).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[aliases(q)]
|
||||||
|
/// Show song queue
|
||||||
|
async fn queue(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
|
let handler = call.lock().await;
|
||||||
|
|
||||||
|
let current_queue = handler.queue().current_queue();
|
||||||
|
|
||||||
|
let text = if current_queue.is_empty() {
|
||||||
|
"No songs queued".into()
|
||||||
|
} else {
|
||||||
|
let mut text = String::new();
|
||||||
|
for (i, track) in current_queue.iter().enumerate() {
|
||||||
|
text.push_str(&song_message(Some(i), track.metadata()));
|
||||||
|
text.push_str("\n");
|
||||||
|
}
|
||||||
|
text
|
||||||
|
};
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, text).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
/// Remove song from queue, given id
|
||||||
|
async fn remove(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||||
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
|
let handler = call.lock().await;
|
||||||
|
|
||||||
|
let index = args.single()?;
|
||||||
|
|
||||||
|
let queue = handler.queue();
|
||||||
|
let text = if let Some(track) = queue.current_queue().get(index) {
|
||||||
|
queue.dequeue(index);
|
||||||
|
let metadata = track.metadata();
|
||||||
|
format!(
|
||||||
|
"Removed track: {} - {} ",
|
||||||
|
metadata.artist.to_owned().unwrap_or_default(),
|
||||||
|
metadata.track.to_owned().unwrap_or_default(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
"No song with that index".into()
|
||||||
|
};
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, text).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn song_message(index: Option<usize>, metadata: &Metadata) -> String {
|
||||||
|
let prefix = match index {
|
||||||
|
Some(i) => format!("- {}: ", i),
|
||||||
|
None => "Current: ".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let song_info = format!(
|
||||||
|
"{} - {} ",
|
||||||
|
metadata.artist.to_owned().unwrap_or_default(),
|
||||||
|
metadata.track.to_owned().unwrap_or_default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
MessageBuilder::new()
|
||||||
|
.push_bold(prefix)
|
||||||
|
.push(song_info)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
async fn queue_song(
|
async fn queue_song(
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
msg: &Message,
|
msg: &Message,
|
||||||
@@ -98,10 +272,9 @@ async fn queue_song(
|
|||||||
handler.enqueue_source(input);
|
handler.enqueue_source(input);
|
||||||
|
|
||||||
let song_info = format!(
|
let song_info = format!(
|
||||||
"{} - {} ({}) ",
|
"{} - {} ",
|
||||||
song.artist.clone().unwrap_or_default(),
|
song.artist.to_owned().unwrap_or_default(),
|
||||||
song.title,
|
song.title,
|
||||||
song.album.clone().unwrap_or_default(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
msg.reply(
|
msg.reply(
|
||||||
@@ -110,6 +283,8 @@ async fn queue_song(
|
|||||||
.push("Added ")
|
.push("Added ")
|
||||||
.push_bold_safe(song_info)
|
.push_bold_safe(song_info)
|
||||||
.push("to the queue")
|
.push("to the queue")
|
||||||
|
.push("\n")
|
||||||
|
.push(song.cover_art_url(client, 256)?)
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -117,7 +292,7 @@ async fn queue_song(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn join_channel<'a>(
|
async fn join_channel(
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
msg: &Message,
|
msg: &Message,
|
||||||
) -> Result<Arc<serenity::prelude::Mutex<songbird::Call>>> {
|
) -> Result<Arc<serenity::prelude::Mutex<songbird::Call>>> {
|
||||||
|
|||||||
Reference in New Issue
Block a user