use serenity; use serenity::model::id::ChannelId; use serenity::voice::ffmpeg; use serenity::voice::LockedAudio; use std::sync::Arc; use super::prelude::*; use rusqlite::{params, Connection}; pub struct Song { pub name: String, } pub struct MediaData { playlist: Vec<Song>, current_song: Option<LockedAudio>, song_name: String, pub next_callback: Option<Arc<Fn() -> ()>>, sql_data_base: Connection, } impl MediaData { pub fn new(file: &str) -> Result<MediaData, String> { let connection = match Connection::open(file) { Ok(file) => file, Err(_) => return Err(format!("can't open {}", file)), }; match connection.execute( "CREATE TABLE IF NOT EXISTS Vulva3 ( name TEXT PRIMARY KEY, link TEXT NOT NULL )", params![], ) { Ok(_) => (), Err(err) => { println!("{}", err); return Err(format!("can't create table")); } }; Ok(MediaData { playlist: Vec::new(), current_song: None, song_name: String::new(), next_callback: None, sql_data_base: connection, }) } pub fn reset( &mut self, ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, ) -> Result<(), String> { self.playlist().clear(); self.song = None; self.name = String::new(); self.next_callback = None(); if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() { let mut manager = manager_lock.lock(); let guild_id = match guild_id(msg.channel_id) { Some(guild_id) => guild_id, None => return Ok(()), }; { let handler = match handler(guild_id, &mut manager) { Some(handler) => handler, None => return Ok(()), }; println!("stopped handler"); handler.stop(); } manager.remove(guild_id); } Ok(()) } pub fn db(&self) -> &Connection { &self.sql_data_base } pub fn song(&self) -> &Option<LockedAudio> { &self.current_song } pub fn song_mut(&mut self) -> &mut Option<LockedAudio> { &mut self.current_song } pub fn playlist(&self) -> &Vec<Song> { &self.playlist } pub fn playlist_mut(&mut self) -> &mut Vec<Song> { &mut self.playlist } pub fn song_name(&self) -> &String { &self.name } pub fn song_name_mut(&mut self) -> &mut String { &mut self.name } pub fn start_playing( mediadata: &Arc<MediaData>, callback: Arc<Fn() -> ()>, channel_id: ChannelId, manager_lock: &Arc< serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>, >, ) { // check if there is already playing let already_started = { let song_lock = match mediadata.song_mut() { Ok(song) => song, Err(msg) => { println!("{}", msg); return; } }; let song = song_lock.borrow(); song.is_some() }; // if there isnt already a song playing, start a new one if !already_started { *mediadata.next_callback.borrow_mut() = Some(callback.clone()); Self::next_song(mediadata, channel_id, manager_lock, callback); } } pub fn next_song( mediadata: &Arc<MediaData>, channel_id: ChannelId, manager_lock: &Arc< serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>, >, callback: Arc<Fn() -> ()>, ) { let mut manager = manager_lock.lock(); let guild_id = match guild_id(channel_id) { Some(id) => id, None => { println!("error getting guild_id"); return; } }; 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 = match mediadata.playlist_mut() { Ok(playlist) => playlist, Err(msg) => { println!("{}", msg); return; } }; let mut playlist = playlist_lock.borrow_mut(); let song_name_lock = match mediadata.name_mut() { Ok(name) => name, Err(msg) => { println!("{}", msg); return; } }; let mut name = song_name_lock.borrow_mut(); let song_lock = match mediadata.song_mut() { Ok(song) => song, Err(msg) => { println!("{}", msg); return; } }; let mut song = song_lock.borrow_mut(); if playlist.is_empty() { need_to_leave = true; handler.stop(); *song = None; *name = String::new(); } else { handler.stop(); let first = playlist.remove(0); let source = match ffmpeg(first.name.clone()) { Ok(mpeg) => mpeg, Err(_) => { playlist.clear(); return; } }; *song = Some(handler.play_returning_and_callback(source, callback)); *name = first.name.clone(); print_error!(channel_id.say(format!("Playing song: {}", first.name))); } } if need_to_leave { manager.remove(guild_id); } } } unsafe impl Send for MediaData {} unsafe impl Sync for MediaData {}