RMusicBot/src/player/mediadata.rs

193 lines
5.1 KiB
Rust
Raw Normal View History

2018-11-14 14:29:58 +00:00
use serenity;
use serenity::model::id::ChannelId;
2018-11-14 15:43:53 +00:00
use serenity::voice::ffmpeg;
2018-11-15 14:10:27 +00:00
use serenity::voice::LockedAudio;
2018-11-14 14:29:58 +00:00
use std::cell::RefCell;
use std::sync::{Arc, Mutex, MutexGuard};
use super::prelude::*;
pub struct Song {
pub name: String,
}
pub struct MediaData {
playlist: Mutex<RefCell<Vec<Song>>>,
current_song: Mutex<RefCell<Option<LockedAudio>>>,
2018-11-21 08:58:06 +00:00
song_name: Mutex<RefCell<String>>,
2018-11-24 11:52:42 +00:00
pub next_callback: RefCell<Option<Arc<Fn() -> ()>>>,
2018-11-14 14:29:58 +00:00
}
impl MediaData {
pub fn reset(
&self,
ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message,
) -> Result<(), String> {
{
let playlist = self.playlist_mut();
playlist.borrow_mut().clear();
}
{
let song = self.song_mut();
*song.borrow_mut() = None;
}
2018-11-21 08:58:06 +00:00
{
let name = self.name_mut();
*name.borrow_mut() = String::new();
}
2018-11-14 14:29:58 +00:00
{
2018-11-23 21:06:35 +00:00
*self.next_callback.borrow_mut() = None;
}
2018-11-14 14:29:58 +00:00
2018-11-23 21:06:35 +00:00
{
let manager_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
2018-11-14 14:29:58 +00:00
let mut manager = manager_lock.lock();
2018-11-23 21:06:35 +00:00
2018-11-14 14:29:58 +00:00
let guild_id = match guild_id(msg.channel_id) {
Some(guild_id) => guild_id,
None => return Ok(()),
};
2018-11-23 21:06:35 +00:00
{
let handler = match handler(guild_id, &mut manager) {
Some(handler) => handler,
None => return Ok(()),
};
2018-11-14 14:29:58 +00:00
2018-11-23 21:06:35 +00:00
println!("stopped handler");
2018-11-14 14:29:58 +00:00
2018-11-23 21:06:35 +00:00
handler.stop();
}
manager.remove(guild_id);
2018-11-14 14:29:58 +00:00
}
Ok(())
}
pub fn song_mut(&self) -> MutexGuard<RefCell<Option<LockedAudio>>> {
self.current_song.lock().unwrap()
}
pub fn playlist_mut(&self) -> MutexGuard<RefCell<Vec<Song>>> {
self.playlist.lock().unwrap()
}
2018-11-21 08:58:06 +00:00
pub fn name_mut(&self) -> MutexGuard<RefCell<String>> {
self.song_name.lock().unwrap()
}
2018-11-23 21:06:35 +00:00
pub fn start_playing(
mediadata: &Arc<MediaData>,
2018-11-24 11:52:42 +00:00
callback: Arc<Fn() -> ()>,
2018-11-14 14:29:58 +00:00
channel_id: ChannelId,
manager_lock: &Arc<
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
>,
) {
2018-11-23 21:06:35 +00:00
// check if there is already playing
let already_started = {
let song_lock = mediadata.song_mut();
let song = song_lock.borrow();
song.is_some()
};
2018-11-14 14:29:58 +00:00
2018-11-23 21:06:35 +00:00
// if there isnt already a song playing, start a new one
if !already_started {
*mediadata.next_callback.borrow_mut() = Some(callback.clone());
2018-11-14 14:29:58 +00:00
2018-11-23 21:06:35 +00:00
Self::next_song(mediadata, channel_id, manager_lock, callback);
2018-11-14 14:29:58 +00:00
}
}
2018-11-23 21:06:35 +00:00
pub fn next_song(
mediadata: &Arc<MediaData>,
2018-11-14 14:29:58 +00:00
channel_id: ChannelId,
manager_lock: &Arc<
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
>,
2018-11-24 11:52:42 +00:00
callback: Arc<Fn() -> ()>,
2018-11-23 21:06:35 +00:00
) {
2018-11-14 14:29:58 +00:00
let mut manager = manager_lock.lock();
let guild_id = match guild_id(channel_id) {
Some(id) => id,
2018-11-23 21:06:35 +00:00
None => {
println!("error getting guild_id");
return;
}
2018-11-14 14:29:58 +00:00
};
2018-11-23 21:06:35 +00:00
let mut need_to_leave = false;
{
let handler = {
match handler(guild_id, &mut manager) {
Some(handler) => handler,
None => {
println!("error getting handler");
return;
}
}
};
let playlist_lock = mediadata.playlist_mut();
let mut playlist = playlist_lock.borrow_mut();
let song_name_lock = mediadata.name_mut();
let mut name = song_name_lock.borrow_mut();
let song_lock = mediadata.song_mut();
let mut song = song_lock.borrow_mut();
2018-11-14 14:29:58 +00:00
if playlist.is_empty() {
2018-11-23 21:06:35 +00:00
need_to_leave = true;
handler.stop();
*song = None;
*name = String::new();
2018-11-14 14:29:58 +00:00
} else {
handler.stop();
2018-11-14 15:43:53 +00:00
2018-11-17 18:59:10 +00:00
let first = playlist.remove(0);
2018-11-14 15:43:53 +00:00
let source = match ffmpeg(first.name.clone()) {
Ok(mpeg) => mpeg,
Err(_) => {
playlist.clear();
2018-11-23 21:06:35 +00:00
return;
2018-11-14 15:43:53 +00:00
}
};
2018-11-23 21:06:35 +00:00
*song = Some(handler.play_returning_and_callback(source, callback));
2018-11-21 08:58:06 +00:00
*name = first.name.clone();
2018-11-14 14:29:58 +00:00
print_error!(channel_id.say(format!("Playing song: {}", first.name)));
}
}
2018-11-23 21:06:35 +00:00
if need_to_leave {
manager.remove(guild_id);
}
2018-11-14 14:29:58 +00:00
}
}
impl Default for MediaData {
fn default() -> MediaData {
MediaData {
playlist: Mutex::new(RefCell::new(Vec::new())),
current_song: Mutex::new(RefCell::new(None)),
2018-11-21 08:58:06 +00:00
song_name: Mutex::new(RefCell::new(String::new())),
2018-11-23 21:06:35 +00:00
next_callback: RefCell::new(None),
2018-11-14 14:29:58 +00:00
}
}
}
unsafe impl Send for MediaData {}
unsafe impl Sync for MediaData {}