diff --git a/.gitignore b/.gitignore index 69c6a79..4f12ed8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ -/target +target/ **/*.rs.bk +bot/ + *.webm diff --git a/Cargo.toml b/Cargo.toml index 0b107c0..821c891 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ authors = ["hodasemi "] [dependencies] typemap = "~0.3" serde_json = "*" +rand = "0.6" [dependencies.serenity] default-features = false diff --git a/src/main.rs b/src/main.rs index 28d47e6..16e1d5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ extern crate serenity; extern crate parking_lot; +extern crate rand; extern crate serde_json; extern crate typemap; diff --git a/src/player/commands/play.rs b/src/player/commands/play.rs index 818cea2..4dcfbf9 100644 --- a/src/player/commands/play.rs +++ b/src/player/commands/play.rs @@ -4,9 +4,12 @@ use serenity; use serenity::voice::LockedAudio; use std::cell::RefCell; +use std::fs; use std::ops::DerefMut; use std::sync::{Arc, MutexGuard}; +use rand::{seq::SliceRandom, thread_rng}; + use super::super::prelude::*; pub struct Play { @@ -66,6 +69,24 @@ impl Play { manager.join(guild_id, connect_to); } + fn append_songs( + &self, + ctx: &mut serenity::client::Context, + msg: &serenity::model::channel::Message, + mut source: Vec, + ) { + { + let playlist_mutex = self.media.playlist_mut(); + playlist_mutex.borrow_mut().append(&mut source); + } + + let manager_lock = ctx.data.lock().get::().cloned().unwrap(); + + Self::check_join_channel(&manager_lock, msg); + + MediaData::start_thread(&self.media, msg.channel_id, &manager_lock); + } + fn handle_http_request( &self, ctx: &mut serenity::client::Context, @@ -98,16 +119,7 @@ impl Play { print_error!(msg.channel_id.say(info)); - { - let playlist_mutex = self.media.playlist_mut(); - playlist_mutex.borrow_mut().append(&mut source); - } - - let manager_lock = ctx.data.lock().get::().cloned().unwrap(); - - Self::check_join_channel(&manager_lock, msg); - - MediaData::start_thread(&self.media, msg.channel_id, &manager_lock); + self.append_songs(ctx, msg, source); } fn handle_local_request( @@ -117,7 +129,25 @@ impl Play { ) { print_error!(self.media.reset(ctx, msg)); - // TODO: read local file directory and play songs in arbitrary order + let files = fs::read_dir("./").unwrap(); + + let mut songs = Vec::new(); + + for file in files { + let os_name = file.unwrap().file_name(); + let name = os_name.to_str().unwrap(); + + if name != "RMusicBot" && name != "bot.conf" { + songs.push(Song { + name: name.to_string(), + }); + } + } + + let mut rng = thread_rng(); + songs.shuffle(&mut rng); + + self.append_songs(ctx, msg, songs); } } diff --git a/src/player/commands/skip.rs b/src/player/commands/skip.rs index 3b912e5..f5d3596 100644 --- a/src/player/commands/skip.rs +++ b/src/player/commands/skip.rs @@ -1,4 +1,5 @@ use serenity; +use serenity::voice::ffmpeg; use std::sync::Arc; @@ -54,7 +55,18 @@ impl serenity::framework::standard::Command for Skip { let first = playlist.remove(0); handler.stop(); - *song = Some(handler.play_returning(first.source)); + + let source = match ffmpeg(first.name.clone()) { + Ok(mpeg) => mpeg, + Err(_) => { + playlist.clear(); + *song = None; + + return Ok(()); + } + }; + + *song = Some(handler.play_returning(source)); print_error!( msg.channel_id diff --git a/src/player/mediadata.rs b/src/player/mediadata.rs index e5b1cf2..783dd40 100644 --- a/src/player/mediadata.rs +++ b/src/player/mediadata.rs @@ -1,5 +1,6 @@ use serenity; use serenity::model::id::ChannelId; +use serenity::voice::ffmpeg; use serenity::voice::{AudioSource, LockedAudio}; use std::cell::RefCell; @@ -12,7 +13,6 @@ use std::time; use super::prelude::*; pub struct Song { - pub source: Box, pub name: String, } @@ -92,6 +92,7 @@ impl MediaData { let song_lock = media_clone.song_mut(); let mut borrow = song_lock.borrow_mut(); + // if there is currently something playing if let Some(ref mut song) = borrow.deref_mut() { let song_lock = song.clone(); let audio = song_lock.lock(); @@ -120,6 +121,7 @@ impl MediaData { continue; } + // nothing is playing { let playlist_mutex = media_clone.playlist_mut(); let mut playlist = playlist_mutex.borrow_mut(); @@ -132,7 +134,19 @@ impl MediaData { { let first = playlist.remove(0); - *borrow = Some(handler.play_returning(first.source)); + let source = match ffmpeg(first.name.clone()) { + Ok(mpeg) => mpeg, + Err(_) => { + playlist.clear(); + *borrow = None; + handler.stop(); + media_clone.reset_thread(); + + return; + } + }; + + *borrow = Some(handler.play_returning(source)); print_error!( channel_id.say(format!("Playing song: {}", first.name)) @@ -182,7 +196,17 @@ impl MediaData { let first = playlist.remove(0); handler.stop(); - *song = handler.play_returning(first.source); + + let source = match ffmpeg(first.name.clone()) { + Ok(mpeg) => mpeg, + Err(_) => { + playlist.clear(); + + return false; + } + }; + + *song = handler.play_returning(source); print_error!(channel_id.say(format!("Playing song: {}", first.name))); diff --git a/src/player/youtube.rs b/src/player/youtube.rs index f7e09bf..5d475bb 100644 --- a/src/player/youtube.rs +++ b/src/player/youtube.rs @@ -1,4 +1,3 @@ -use serenity::voice::ffmpeg; use std::process::{Command, Output, Stdio}; use std::str::from_utf8; @@ -66,17 +65,11 @@ pub fn youtube_dl(uri: &str) -> Result, String> { println!("file: {}", file); } - let mut ffmpegs = Vec::new(); + let mut songs = Vec::new(); for file in files { - match ffmpeg(&file) { - Ok(mpeg) => ffmpegs.push(Song { - source: mpeg, - name: file, - }), - Err(_) => return Err("ffmpeg error".to_string()), - } + songs.push(Song { name: file }) } - Ok(ffmpegs) + Ok(songs) }