|
@@ -1,40 +1,36 @@
|
|
|
-use std::{
|
|
|
- sync::Arc,
|
|
|
- collections::HashMap,
|
|
|
-};
|
|
|
+use super::audio_state::AudioState;
|
|
|
+use lazy_static::lazy_static;
|
|
|
use serenity::{
|
|
|
- client::Context,
|
|
|
+ client::Context,
|
|
|
framework::standard::{
|
|
|
- Args, CommandResult,
|
|
|
macros::{command, group},
|
|
|
+ Args, CommandResult,
|
|
|
},
|
|
|
- model::{channel::Message, id::GuildId}
|
|
|
+ model::{channel::Message, id::GuildId},
|
|
|
};
|
|
|
use songbird::tracks::TrackCommand;
|
|
|
-use tokio::{
|
|
|
- sync::Mutex,
|
|
|
-};
|
|
|
-use lazy_static::lazy_static;
|
|
|
-use super::{
|
|
|
- audio_state::AudioState,
|
|
|
-};
|
|
|
+use std::{collections::HashMap, sync::Arc};
|
|
|
+use tokio::sync::Mutex;
|
|
|
|
|
|
-use super::config::audio as config_audio;
|
|
|
-
|
|
|
-use crate::util::{
|
|
|
- send_message,
|
|
|
- send_embed,
|
|
|
- message_react,
|
|
|
-};
|
|
|
+use crate::util::{message_react, send_embed};
|
|
|
|
|
|
#[group]
|
|
|
-#[commands(join,disconnect,play,splay,cure,extend,skip,pause,resume,change_loop,shuffle,clear,queue)]
|
|
|
+#[commands(
|
|
|
+ join,
|
|
|
+ disconnect,
|
|
|
+ play,
|
|
|
+ skip,
|
|
|
+ pause,
|
|
|
+ resume,
|
|
|
+ change_loop,
|
|
|
+ shuffle,
|
|
|
+ clear,
|
|
|
+ queue
|
|
|
+)]
|
|
|
struct Audio;
|
|
|
|
|
|
lazy_static! {
|
|
|
- static ref AUDIO_STATES: Mutex<HashMap<GuildId, Arc<AudioState>>> = {
|
|
|
- Mutex::new(HashMap::new())
|
|
|
- };
|
|
|
+ static ref AUDIO_STATES: Mutex<HashMap<GuildId, Arc<AudioState>>> = Mutex::new(HashMap::new());
|
|
|
}
|
|
|
|
|
|
async fn get_audio_state(ctx: &Context, msg: &Message) -> Option<Arc<AudioState>> {
|
|
@@ -54,19 +50,16 @@ async fn get_audio_state(ctx: &Context, msg: &Message) -> Option<Arc<AudioState>
|
|
|
.voice_states
|
|
|
.get(&msg.author.id)
|
|
|
.and_then(|voice_state| voice_state.channel_id);
|
|
|
- let channel_id = match channel_id{
|
|
|
+ let channel_id = match channel_id {
|
|
|
Some(channel_id) => channel_id,
|
|
|
None => {
|
|
|
send_embed(ctx, msg, "Error: please be in a voice channel").await;
|
|
|
return None;
|
|
|
}
|
|
|
};
|
|
|
- let manager = songbird::get(ctx)
|
|
|
- .await
|
|
|
- .unwrap()
|
|
|
- .clone();
|
|
|
+ let manager = songbird::get(ctx).await.unwrap().clone();
|
|
|
let (handle_lock, success) = manager.join(guild_id, channel_id).await;
|
|
|
- if let Err(err) = success{
|
|
|
+ if let Err(err) = success {
|
|
|
println!("Error: {:?}", err);
|
|
|
return None;
|
|
|
}
|
|
@@ -84,19 +77,30 @@ async fn remove_audio_state(ctx: &Context, msg: &Message) -> Result<(), String>
|
|
|
let guild_id = guild.id;
|
|
|
|
|
|
let mut audio_states = AUDIO_STATES.lock().await;
|
|
|
+ let manager = songbird::get(ctx).await.unwrap();
|
|
|
+ if manager
|
|
|
+ .get(guild_id)
|
|
|
+ .unwrap()
|
|
|
+ .lock()
|
|
|
+ .await
|
|
|
+ .leave()
|
|
|
+ .await
|
|
|
+ .is_err()
|
|
|
+ {
|
|
|
+ return Err("Could not leave channel".to_string());
|
|
|
+ }
|
|
|
|
|
|
- if let Some(state) = audio_states.remove(&guild_id){
|
|
|
- AudioState::cleanup(state).await;
|
|
|
+ if audio_states.remove(&guild_id).is_some() {
|
|
|
Ok(())
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
Err("bot is not currently active".to_string())
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn join(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn join(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- if audio_state.is_some(){
|
|
|
+ if audio_state.is_some() {
|
|
|
message_react(ctx, msg, "🥳").await;
|
|
|
}
|
|
|
|
|
@@ -105,8 +109,8 @@ async fn join(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
|
|
|
#[command]
|
|
|
#[aliases("leave")]
|
|
|
-async fn disconnect(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
- match remove_audio_state(ctx, msg).await{
|
|
|
+async fn disconnect(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
+ match remove_audio_state(ctx, msg).await {
|
|
|
Ok(()) => message_react(ctx, msg, "👋").await,
|
|
|
Err(why) => send_embed(ctx, msg, &format!("Error: {}", why)).await,
|
|
|
};
|
|
@@ -115,175 +119,99 @@ async fn disconnect(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn play(ctx: &Context, msg: &Message, args: Args) -> CommandResult{
|
|
|
- let query = args.rest();
|
|
|
-
|
|
|
- let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
- Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
- };
|
|
|
-
|
|
|
- AudioState::add_audio(audio_state, query, false).await;
|
|
|
-
|
|
|
- message_react(ctx, msg, "🎶").await;
|
|
|
-
|
|
|
- Ok(())
|
|
|
-}
|
|
|
-
|
|
|
-#[command]
|
|
|
-async fn splay(ctx: &Context, msg: &Message, args: Args) -> CommandResult{
|
|
|
+async fn play(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
|
let query = args.rest();
|
|
|
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
- Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
- };
|
|
|
-
|
|
|
- AudioState::add_audio(audio_state, query, true).await;
|
|
|
-
|
|
|
- message_react(ctx, msg, "🔀").await;
|
|
|
- message_react(ctx, msg, "🎶").await;
|
|
|
-
|
|
|
- Ok(())
|
|
|
-}
|
|
|
-
|
|
|
-#[command]
|
|
|
-async fn cure(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult{
|
|
|
- let query= match args.single::<String>(){
|
|
|
- Ok(query) => query,
|
|
|
- Err(_) => {
|
|
|
- send_embed(ctx, msg, "Error: invalid Spotify playlist").await;
|
|
|
- return Ok(())
|
|
|
- }
|
|
|
- };
|
|
|
- let amount = match args.single::<usize>(){
|
|
|
- Ok(amount) => amount,
|
|
|
- Err(_) => {
|
|
|
- 20
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
- AudioState::add_recommended_songs(audio_state, &query, amount).await;
|
|
|
-
|
|
|
- message_react(ctx, msg, "🍻").await;
|
|
|
message_react(ctx, msg, "🎶").await;
|
|
|
|
|
|
- Ok(())
|
|
|
-}
|
|
|
-
|
|
|
-#[command]
|
|
|
-async fn extend(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult{
|
|
|
- let query= match args.single::<String>(){
|
|
|
- Ok(query) => query,
|
|
|
- Err(_) => {
|
|
|
- send_embed(ctx, msg, "Error: invalid Spotify playlist").await;
|
|
|
- return Ok(())
|
|
|
- }
|
|
|
- };
|
|
|
- let extend_ratio = match args.single::<f64>(){
|
|
|
- Ok(amount) => amount,
|
|
|
- Err(_) => {
|
|
|
- config_audio::EXTEND_RATIO
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
- Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
- };
|
|
|
+ AudioState::add_audio(audio_state, query).await;
|
|
|
|
|
|
- AudioState::extend_songs(audio_state, &query, extend_ratio).await;
|
|
|
-
|
|
|
- message_react(ctx, msg, "🍻").await;
|
|
|
- message_react(ctx, msg, "🎶").await;
|
|
|
+ message_react(ctx, msg, "✅").await;
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn skip(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn skip(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
if let Err(why) = AudioState::send_track_command(audio_state, TrackCommand::Stop).await {
|
|
|
send_embed(ctx, msg, &format!("Error: {}", why)).await;
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
message_react(ctx, msg, "↪").await;
|
|
|
};
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn pause(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn pause(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
if let Err(why) = AudioState::send_track_command(audio_state, TrackCommand::Pause).await {
|
|
|
send_embed(ctx, msg, &format!("Error: {}", why)).await;
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
message_react(ctx, msg, "⏸").await;
|
|
|
};
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn resume(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn resume(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
if let Err(why) = AudioState::send_track_command(audio_state, TrackCommand::Play).await {
|
|
|
send_embed(ctx, msg, &format!("Error: {}", why)).await;
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
message_react(ctx, msg, "▶").await;
|
|
|
};
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn shuffle(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn shuffle(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
if let Err(why) = AudioState::shuffle(audio_state).await {
|
|
|
send_embed(ctx, msg, &format!("Error: {}", why)).await;
|
|
|
- } else{
|
|
|
+ } else {
|
|
|
message_react(ctx, msg, "🔀").await;
|
|
|
};
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn clear(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn clear(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
if let Err(why) = AudioState::clear(audio_state.clone()).await {
|
|
|
send_embed(ctx, msg, &format!("Error: {}", why)).await;
|
|
|
- } else{
|
|
|
+ } else {
|
|
|
message_react(ctx, msg, "🗑").await;
|
|
|
};
|
|
|
|
|
@@ -292,11 +220,11 @@ async fn clear(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
|
|
|
#[command]
|
|
|
#[aliases("loop")]
|
|
|
-async fn change_loop(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn change_loop(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
match AudioState::change_looping(audio_state).await {
|
|
@@ -308,48 +236,14 @@ async fn change_loop(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
}
|
|
|
|
|
|
#[command]
|
|
|
-async fn queue(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
+async fn queue(ctx: &Context, msg: &Message) -> CommandResult {
|
|
|
let audio_state = get_audio_state(ctx, msg).await;
|
|
|
- let audio_state = match audio_state{
|
|
|
+ let audio_state = match audio_state {
|
|
|
Some(audio_state) => audio_state,
|
|
|
- None => return Ok(())
|
|
|
+ None => return Ok(()),
|
|
|
};
|
|
|
|
|
|
- send_embed(ctx, msg,&AudioState::get_string(audio_state).await).await;
|
|
|
+ send_embed(ctx, msg, &AudioState::get_string(audio_state).await).await;
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
-/*
|
|
|
-#[command]
|
|
|
-async fn start(ctx: &Context, msg: &Message) -> CommandResult{
|
|
|
- let c_id = msg.channel_id;
|
|
|
- let b = ctx.clone();
|
|
|
- println!("start command");
|
|
|
- //let a= a.clone();
|
|
|
- {
|
|
|
- let b = b.clone();
|
|
|
- tokio::spawn(async move {
|
|
|
- spam(c_id, b, 3).await
|
|
|
- }
|
|
|
- );
|
|
|
- }
|
|
|
- {
|
|
|
- let b = b.clone();
|
|
|
- tokio::spawn(async move {
|
|
|
- spam(c_id, b, 5).await
|
|
|
- }
|
|
|
- );
|
|
|
- }
|
|
|
- Ok(())
|
|
|
-}
|
|
|
-
|
|
|
-async fn spam(c_id: ChannelId, ctx: Context, duration: u64){
|
|
|
- loop {
|
|
|
- let result = c_id.say(&ctx.http, format!("{} seconds passed", duration)).await;
|
|
|
- if let Err(why) = result {
|
|
|
- println!("Error sending message {:?}", why);
|
|
|
- }
|
|
|
- sleep(Duration::from_secs(duration)).await;
|
|
|
- }
|
|
|
-}
|
|
|
-*/
|