Apply serenity 0.6 api

This commit is contained in:
hodasemi 2019-07-12 14:41:51 +02:00
parent 4276428a8b
commit f89c8706eb
16 changed files with 335 additions and 316 deletions

View file

@ -10,4 +10,5 @@ serde_json = "*"
rand = "0.6"
rusqlite = { version = "*", features = ["bundled"] }
serenity = { version = "0.6", default-features = false, features = [ "builder", "cache", "client", "framework", "gateway", "model", "standard_framework", "utils", "voice", "rustls_backend"]}
parking_lot = { version = "*" }
lock_api = "0.2.0"
parking_lot = "*"

Binary file not shown.

BIN
Penis1 Normal file

Binary file not shown.

View file

@ -25,6 +25,20 @@ macro_rules! check_result_return {
};
}
/// check result macro, where the Ok() is the type which should be returned, else print error and return
#[macro_export]
macro_rules! check_result_return_ok {
($v:expr) => {
match $v {
Ok(t) => t,
Err(msg) => {
println!("{}", msg);
return Ok(());
}
}
};
}
// check result macro, where the Ok() is void
#[macro_export]
macro_rules! check_error {
@ -46,6 +60,17 @@ macro_rules! display_error {
};
}
/// check result macro, where the Ok() is void, but just print the error message
#[macro_export]
macro_rules! display_error_ok {
($v:expr) => {
if let Err(msg) = $v {
println!("{}", msg);
return Ok(());
};
};
}
macro_rules! print_error {
($v:expr) => {
if let Err(msg) = $v {

View file

@ -33,6 +33,7 @@ use std::sync::Arc;
use confighandler::*;
use player::prelude::*;
use std::collections::HashSet;
struct Config {
token: String,
@ -51,7 +52,7 @@ impl Default for Config {
group!({
name: "general",
options: {},
commands: [ip]
commands: [ip, list, pause, play, remove, skip, stop]
});
fn main() {
@ -95,10 +96,36 @@ fn main() {
{
let mut data = client.data.write();
data.insert::<VoiceManager>(Arc::clone(&client.voice_manager));
data.insert::<Media>(MediaData::new("Penis1").expect("failed to create media data handle"));
}
let media_data =
Arc::new(MediaData::new("Penis1").expect("failed to create media data handle"));
// We will fetch your bot's owners and id
let (owners, bot_id) = match client.cache_and_http.http.get_current_application_info() {
Ok(info) => {
let mut owners = HashSet::new();
owners.insert(info.owner.id);
(owners, info.id)
}
Err(why) => panic!("Could not access application info: {:?}", why),
};
client.with_framework(
// Configures the client, allowing for options to mutate how the
// framework functions.
//
// Refer to the documentation for
// `serenity::ext::framework::Configuration` for all available
// configurations.
StandardFramework::new()
.configure(|c| {
c.with_whitespace(true)
.on_mention(Some(bot_id))
.prefix(&config.prefix)
.owners(owners)
})
.group(&GENERAL_GROUP),
);
/*
@ -129,10 +156,9 @@ fn main() {
.cmd("ip", IP::new())
.cmd("remove", Remove::new(media_data.clone())),
);
*/
let _ = client
.start()
.map_err(|why| println!("Client ended: {:?}", why));
*/
}

View file

@ -10,7 +10,7 @@ use std::process::{Command, Stdio};
use std::str::from_utf8;
#[command]
fn ip(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
fn ip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
let args = ["ifconfig.me"];
let out = match Command::new("curl")
@ -27,8 +27,8 @@ fn ip(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
}
match from_utf8(out.stdout.as_slice()) {
Ok(string) => print_error!(msg.author.direct_message(|m| m.content(string))),
Err(_) => print_error!(msg.channel_id.say("error getting IP string")),
Ok(string) => print_error!(msg.author.direct_message(&ctx, |m| m.content(string))),
Err(_) => print_error!(msg.channel_id.say(&ctx.http, "error getting IP string")),
};
Ok(())

View file

@ -19,10 +19,10 @@ fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
let mut output = String::new();
let data = ctx.data.read();
let media = match data.get::<MediaData>() {
Ok(media) => media,
Err(_) => {
msg.channel_id.say("could not find media data");
let media = match data.get::<Media>() {
Some(media) => media,
None => {
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
return Ok(());
}
};
@ -46,7 +46,7 @@ fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
}
}
print_error!(msg.channel_id.say(output));
print_error!(msg.channel_id.say(&ctx.http, output));
Ok(())
}

View file

@ -19,15 +19,18 @@ fn pause(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
}
let data = ctx.data.read();
let media = match data.get::<MediaData>() {
Ok(media) => media,
Err(_) => {
msg.channel_id.say("could not find media data");
let media = match data.get::<Media>() {
Some(media) => media,
None => {
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
return Ok(());
}
};
media.song().pause();
if let Some(song) = media.song() {
let mut lock = song.lock();
lock.pause();
}
Ok(())
}

View file

@ -1,8 +1,6 @@
use parking_lot;
use lock_api::RawMutex;
use std::cell::RefCell;
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, MutexGuard};
use std::sync::Arc;
use rand::{seq::SliceRandom, thread_rng};
@ -18,7 +16,7 @@ use serenity::{
};
#[command]
fn play(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
if !channel_contains_author(ctx, msg) {
println!(
"user {} is not in the same voice channel as the bot",
@ -27,18 +25,20 @@ fn play(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
return Ok(());
}
let data = ctx.data.read();
let mut media = match data.get_mut::<MediaData>() {
Ok(media) => media,
Err(_) => {
msg.channel_id.say("could not find media data");
let mut data = ctx.data.write();
let media = match data.get_mut::<Media>() {
Some(media) => media,
None => {
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
return Ok(());
}
};
if args.len() == 0 {
if !Self::check_for_continue(self.media.song_mut()?) {
print_error!(msg.channel_id.say("Must provide a URL to a video or audio"));
if !check_for_continue(media.song_mut()) {
print_error!(msg
.channel_id
.say(&ctx.http, "Must provide a URL to a video or audio"));
}
} else if args.len() == 1 {
let arg = match args.single::<String>() {
@ -48,21 +48,21 @@ fn play(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
};
if arg == "--local" {
self.handle_local_request(ctx, msg)?;
handle_local_request(media, ctx, msg)?;
} else if arg.starts_with("http") {
self.handle_http_request(ctx, msg, &arg)?;
handle_http_request(media, ctx, msg, &arg)?;
} else {
self.handle_song_request(ctx, msg, &arg)?;
handle_song_request(media, ctx, msg, &arg)?;
}
} else {
print_error!(msg.channel_id.say("Unsupported argument list"));
print_error!(msg.channel_id.say(&ctx.http, "Unsupported argument list"));
}
Ok(())
}
fn check_for_continue(song_lock: MutexGuard<RefCell<Option<LockedAudio>>>) -> bool {
match song_lock.borrow_mut().deref_mut() {
fn check_for_continue(song_lock: &Option<LockedAudio>) -> bool {
match song_lock {
Some(song) => {
let song_clone = song.clone();
let mut audio_lock = song_clone.lock();
@ -74,20 +74,13 @@ fn check_for_continue(song_lock: MutexGuard<RefCell<Option<LockedAudio>>>) -> bo
}
}
fn check_join_channel(
manager_lock: &Arc<parking_lot::Mutex<serenity::client::bridge::voice::ClientVoiceManager>>,
msg: &serenity::model::channel::Message,
fn check_join_channel<T: RawMutex>(
manager_lock: &Arc<lock_api::Mutex<T, serenity::client::bridge::voice::ClientVoiceManager>>,
ctx: &Context,
msg: &Message,
) {
let guild = match msg.guild() {
Some(guild) => guild,
None => {
display_error!(msg.channel_id.say("Groups and DMs not supported"));
return;
}
};
let guild_id = guild.read().id;
let guild = check_result_return!(guild(ctx, msg));
let guild_id = check_result_return!(guild_id(ctx, msg));
let channel_id = guild
.read()
@ -98,50 +91,45 @@ fn check_join_channel(
let connect_to = match channel_id {
Some(channel) => channel,
None => {
display_error!(msg.reply("Not in a voice channel"));
display_error!(msg.reply(ctx, "Not in a voice channel"));
return;
}
};
let mut manager = manager_lock.lock();
manager.join(guild_id, connect_to);
}
fn append_songs(
media: &mut MediaData,
ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message,
ctx: &Context,
msg: &Message,
mut source: Vec<Song>,
) -> Result<(), String> {
{
let playlist_mutex = self.media.playlist_mut()?;
playlist_mutex.borrow_mut().append(&mut source);
}
media.playlist_mut().append(&mut source);
if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
Self::check_join_channel(&manager_lock, msg);
if let Some(manager_lock) = ctx.data.read().get::<VoiceManager>().cloned() {
check_join_channel(&manager_lock, ctx, msg);
let check_finished = {
let media_clone = self.media.clone();
let channel_id = msg.channel_id;
let manager_lock_clone = manager_lock.clone();
// let check_finished = {
// let channel_id = msg.channel_id;
// let manager_lock_clone = manager_lock.clone();
Arc::new(move || {
let callback = match media_clone.next_callback.borrow().deref() {
Some(callback) => callback.clone(),
None => {
println!("next_callback not set!");
return;
}
};
// Arc::new(move || {
// let callback = match media.next_callback.borrow().deref() {
// Some(callback) => callback.clone(),
// None => {
// println!("next_callback not set!");
// return;
// }
// };
MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback);
})
};
// MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback);
// })
// };
MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock);
MediaData::start_playing(ctx, media, msg, &manager_lock);
}
Ok(())
@ -149,160 +137,172 @@ fn append_songs(
fn handle_http_request(
media: &mut MediaData,
ctx: &mut serenity::client::Context,
ctx: &serenity::client::Context,
msg: &serenity::model::channel::Message,
url: &String,
) -> Result<(), String> {
let sql = self.media.lock_db()?;
let mut stmt = match sql.prepare("SELECT name FROM Vulva3 WHERE link = ?") {
Ok(statement) => statement,
Err(_) => return Err("failed preparing data base access".to_string()),
};
let rows = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
Err(_) => return Err("failed querying rows".to_string()),
};
let mut names = Vec::new();
for name_result in rows {
let name = match name_result {
Ok(name) => name,
Err(_) => return Err("failed getting name from row".to_string()),
{
let sql = media.db();
let mut stmt = match sql.prepare("SELECT name FROM Vulva3 WHERE link = ?") {
Ok(statement) => statement,
Err(_) => return Err("failed preparing data base access".to_string()),
};
names.push(name);
let rows = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
Err(_) => return Err("failed querying rows".to_string()),
};
for name_result in rows {
let name = match name_result {
Ok(name) => name,
Err(_) => return Err("failed getting name from row".to_string()),
};
names.push(name);
}
}
if names.len() > 0 {
print_error!(msg.channel_id.say("song already loaded!"));
print_error!(msg.channel_id.say(&ctx.http, "song already loaded!"));
self.append_songs(
append_songs(
media,
ctx,
msg,
names.iter().map(|n| Song { name: n.clone() }).collect(),
)?;
return Ok(());
}
let source = match youtube_dl(&url) {
Ok(source) => source,
Err(why) => {
println!("Err starting source: {:?}", why);
print_error!(msg
.channel_id
.say(format!("Error using youtube-dl: {}", why)));
return Ok(());
}
};
let mut info = if source.len() == 1 {
"Finished downloading song:".to_string()
} else {
"Finished downloading songs:".to_string()
};
let source = match youtube_dl(&url) {
Ok(source) => source,
Err(why) => {
println!("Err starting source: {:?}", why);
for song in &source {
info = format!("{}\n\t{}", info, song.name);
print_error!(msg
.channel_id
.say(&ctx.http, format!("Error using youtube-dl: {}", why)));
return Ok(());
}
};
let mut info = if source.len() == 1 {
"Finished downloading song:".to_string()
} else {
"Finished downloading songs:".to_string()
};
if sql
.execute(
"INSERT INTO Vulva3 (name, link)
VALUES (?1, ?2)",
params![song.name, url],
)
.is_err()
{
return Err("failed inserting songs into db".to_string());
let sql = media.db();
for song in &source {
info = format!("{}\n\t{}", info, song.name);
if sql
.execute(
"INSERT INTO Vulva3 (name, link)
VALUES (?1, ?2)",
params![song.name, url],
)
.is_err()
{
return Err("failed inserting songs into db".to_string());
}
}
}
print_error!(msg.channel_id.say(&ctx.http, info));
append_songs(media, ctx, msg, source)?;
}
print_error!(msg.channel_id.say(info));
self.append_songs(ctx, msg, source)?;
Ok(())
}
fn handle_local_request(
media: &mut MediaData,
ctx: &mut serenity::client::Context,
ctx: &serenity::client::Context,
msg: &serenity::model::channel::Message,
) -> Result<(), String> {
let sql = self.media.lock_db()?;
let mut stmt = match sql.prepare("SELECT name FROM Vulva3") {
Ok(statement) => statement,
Err(_) => return Err("failed preparing data base access".to_string()),
};
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
Err(_) => return Err("failed querying rows".to_string()),
};
let mut songs = Vec::new();
for name_result in rows {
let name = match name_result {
Ok(name) => name,
Err(_) => return Err("failed getting name from row".to_string()),
{
let sql = media.db();
let mut stmt = match sql.prepare("SELECT name FROM Vulva3") {
Ok(statement) => statement,
Err(_) => return Err("failed preparing data base access".to_string()),
};
songs.push(Song { name });
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
Err(_) => return Err("failed querying rows".to_string()),
};
for name_result in rows {
let name = match name_result {
Ok(name) => name,
Err(_) => return Err("failed getting name from row".to_string()),
};
songs.push(Song { name });
}
}
let mut rng = thread_rng();
songs.shuffle(&mut rng);
self.append_songs(ctx, msg, songs)?;
append_songs(media, ctx, msg, songs)?;
Ok(())
}
fn handle_song_request(
media: &mut MediaData,
ctx: &mut serenity::client::Context,
ctx: &serenity::client::Context,
msg: &serenity::model::channel::Message,
pattern: &str,
) -> Result<(), String> {
let sql = self.media.lock_db()?;
let mut stmt = match sql.prepare(&format!(
"SELECT name FROM Vulva3 WHERE name LIKE '%{}%'",
pattern
)) {
Ok(statement) => statement,
Err(_) => return Err("failed preparing data base access".to_string()),
};
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
Err(_) => return Err("failed querying rows".to_string()),
};
let mut songs = Vec::new();
for name_result in rows {
let name = match name_result {
Ok(name) => name,
Err(_) => return Err("failed getting name from row".to_string()),
{
let sql = media.db();
let mut stmt = match sql.prepare(&format!(
"SELECT name FROM Vulva3 WHERE name LIKE '%{}%'",
pattern
)) {
Ok(statement) => statement,
Err(_) => return Err("failed preparing data base access".to_string()),
};
songs.push(Song { name });
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
Err(_) => return Err("failed querying rows".to_string()),
};
for name_result in rows {
let name = match name_result {
Ok(name) => name,
Err(_) => return Err("failed getting name from row".to_string()),
};
songs.push(Song { name });
}
}
if !songs.is_empty() {
let mut rng = thread_rng();
songs.shuffle(&mut rng);
self.append_songs(ctx, msg, songs)?;
append_songs(media, ctx, msg, songs)?;
} else {
print_error!(msg
.channel_id
.say(format!("no song found with pattern {}", pattern)));
.say(&ctx.http, format!("no song found with pattern {}", pattern)));
}
Ok(())

View file

@ -15,10 +15,10 @@ use serenity::{
#[command]
fn remove(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
let data = ctx.data.read();
let media = match data.get::<MediaData>() {
Ok(media) => media,
Err(_) => {
msg.channel_id.say("could not find media data");
let media = match data.get::<Media>() {
Some(media) => media,
None => {
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
return Ok(());
}
};
@ -34,15 +34,14 @@ fn remove(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
if !song_name.is_empty() {
match fs::remove_file(&song_name) {
Ok(_) => print_error!(msg.channel_id.say(format!(
"Remove current song ({}) from local disk",
song_name
))),
Err(err) => print_error!(msg.channel_id.say(format!(
"Error removing file ({}): {:?}",
song_name,
err.kind()
))),
Ok(_) => print_error!(msg.channel_id.say(
&ctx.http,
format!("Remove current song ({}) from local disk", song_name)
)),
Err(err) => print_error!(msg.channel_id.say(
&ctx.http,
format!("Error removing file ({}): {:?}", song_name, err.kind())
)),
};
}

View file

@ -19,42 +19,32 @@ fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
return Ok(());
}
if let Some(mut manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
let mut data = ctx.data.write();
if let Some(manager_lock) = data.get_mut::<VoiceManager>().cloned() {
let mut manager = manager_lock.lock();
let guild_id = match guild_id(msg.channel_id) {
Some(id) => id,
None => {
println!("error getting guild id");
print_error!(msg.channel_id.say("error getting guild id"));
return Ok(());
}
};
let guild_id = check_result_return_ok!(guild_id(ctx, msg));
if let Some(handler) = handler(guild_id, &mut manager) {
let data = ctx.data.read();
let mut media = match data.get_mut::<MediaData>() {
Ok(media) => media,
Err(_) => {
msg.channel_id.say("could not find media data");
let media = match data.get_mut::<Media>() {
Some(media) => media,
None => {
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
return Ok(());
}
};
let mut playlist = media.playlist_mut();
let mut song = media.song_mut();
// if current song is the last song in this playlist, just return
if playlist.is_empty() {
if media.playlist().is_empty() {
print_error!(msg
.channel_id
.say("playlist is empty, no next song available"));
.say(&ctx.http, "playlist is empty, no next song available"));
return Ok(());
} else {
// remove the current song from the playlist
let first = playlist.remove(0);
let first = media.playlist_mut().remove(0);
// stop the current song from playing
handler.stop();
@ -63,8 +53,8 @@ fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
let source = match ffmpeg(first.name.clone()) {
Ok(mpeg) => mpeg,
Err(_) => {
playlist.clear();
*song = None;
media.playlist_mut().clear();
*media.song_mut() = None;
return Ok(());
}
@ -85,12 +75,13 @@ fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
None => println!("error getting callback from media"),
}
*/
*song = Some(handler.play_returning(source));
*media.song_mut() = Some(handler.play_returning(source));
*media.song_name_mut() = first.name.clone();
print_error!(msg
.channel_id
.say(format!("Skipped current song, now playing: {}", first.name)));
print_error!(msg.channel_id.say(
&ctx.http,
format!("Skipped current song, now playing: {}", first.name)
));
}
}
}

View file

@ -16,16 +16,16 @@ fn stop(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
return Ok(());
}
let data = ctx.data.read();
let mut media = match data.get_mut::<MediaData>() {
Ok(media) => media,
Err(_) => {
msg.channel_id.say("could not find media data");
let mut data = ctx.data.write();
let media = match data.get_mut::<Media>() {
Some(media) => media,
None => {
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
return Ok(());
}
};
print_error!(data.reset(ctx, msg));
print_error!(media.reset(ctx, msg));
Ok(())
}

View file

@ -1,5 +1,6 @@
use serenity;
use serenity::model::id::ChannelId;
use serenity::model::channel::Message;
use serenity::prelude::*;
use serenity::voice::ffmpeg;
use serenity::voice::LockedAudio;
@ -55,21 +56,18 @@ impl MediaData {
pub fn reset(
&mut self,
ctx: &mut serenity::client::Context,
ctx: &serenity::client::Context,
msg: &serenity::model::channel::Message,
) -> Result<(), String> {
self.playlist().clear();
self.song = None;
self.name = String::new();
self.next_callback = None();
self.playlist.clear();
self.current_song = None;
self.song_name = String::new();
self.next_callback = None;
if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
if let Some(manager_lock) = ctx.data.read().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 guild_id = guild_id(ctx, msg)?;
{
let handler = match handler(guild_id, &mut manager) {
@ -109,60 +107,41 @@ impl MediaData {
}
pub fn song_name(&self) -> &String {
&self.name
&self.song_name
}
pub fn song_name_mut(&mut self) -> &mut String {
&mut self.name
&mut self.song_name
}
pub fn start_playing(
mediadata: &Arc<MediaData>,
callback: Arc<Fn() -> ()>,
channel_id: ChannelId,
ctx: &Context,
mediadata: &mut MediaData,
msg: &Message,
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()
};
let already_started = { mediadata.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);
Self::next_song(ctx, mediadata, msg, manager_lock);
}
}
pub fn next_song(
mediadata: &Arc<MediaData>,
channel_id: ChannelId,
ctx: &Context,
mediadata: &mut MediaData,
msg: &Message,
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 guild_id = check_result_return!(guild_id(ctx, msg));
let mut need_to_leave = false;
@ -177,56 +156,31 @@ impl MediaData {
}
};
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() {
if mediadata.playlist().is_empty() {
need_to_leave = true;
handler.stop();
*song = None;
*name = String::new();
*mediadata.song_mut() = None;
*mediadata.song_name_mut() = String::new();
} else {
handler.stop();
let first = playlist.remove(0);
let first = mediadata.playlist_mut().remove(0);
let source = match ffmpeg(first.name.clone()) {
Ok(mpeg) => mpeg,
Err(_) => {
playlist.clear();
mediadata.playlist_mut().clear();
return;
}
};
*song = Some(handler.play_returning_and_callback(source, callback));
*name = first.name.clone();
*mediadata.song_mut() = Some(handler.play_returning(source));
*mediadata.song_name_mut() = first.name.clone();
print_error!(channel_id.say(format!("Playing song: {}", first.name)));
print_error!(msg
.channel_id
.say(&ctx.http, format!("Playing song: {}", first.name)));
}
}
@ -238,3 +192,9 @@ impl MediaData {
unsafe impl Send for MediaData {}
unsafe impl Sync for MediaData {}
pub struct Media;
impl TypeMapKey for Media {
type Value = MediaData;
}

View file

@ -1,26 +1,43 @@
use parking_lot::MutexGuard;
use lock_api::{MutexGuard, RawMutex};
use serenity;
use serenity::model::id::{ChannelId, GuildId};
use serenity::model::channel::Message;
use serenity::model::guild::Guild;
use serenity::model::id::GuildId;
use serenity::prelude::RwLock as SerRwLock;
use serenity::voice::Handler;
use std::sync::Arc;
// This imports `typemap`'s `Key` as `TypeMapKey`.
use serenity::prelude::*;
use super::prelude::*;
pub fn guild_id(channel_id: ChannelId) -> Option<GuildId> {
/*
match CACHE.read().guild_channel(channel_id) {
Some(channel) => Some(channel.read().guild_id),
pub fn guild(ctx: &Context, msg: &Message) -> Result<Arc<SerRwLock<Guild>>, String> {
match msg.guild(&ctx.cache) {
Some(guild) => Ok(guild),
None => {
print_error!(channel_id.say("Error finding channel info"));
None
if msg
.channel_id
.say(&ctx.http, "Groups and DMs not supported")
.is_err()
{}
Err("failed getting Guild".to_string())
}
}
*/
None
}
pub fn handler<'a>(
pub fn guild_id(ctx: &Context, msg: &Message) -> Result<GuildId, String> {
let guild = guild(ctx, msg)?;
let guild_read = guild.read();
Ok(guild_read.id)
}
pub fn handler<'a, T: RawMutex>(
guild_id: GuildId,
manager: &'a mut MutexGuard<'_, serenity::client::bridge::voice::ClientVoiceManager>,
manager: &'a mut MutexGuard<'_, T, serenity::client::bridge::voice::ClientVoiceManager>,
) -> Option<&'a mut Handler> {
manager.get_mut(guild_id)
}
@ -33,12 +50,9 @@ pub fn channel_contains_author(
match ctx.data.read().get::<VoiceManager>().cloned() {
Some(manager_lock) => {
let mut manager = manager_lock.lock();
let guild_id = match guild_id(msg.channel_id) {
Some(guild_id) => guild_id,
None => {
println!("error getting guild_id");
return true;
}
let guild_id = match guild_id(ctx, msg) {
Ok(id) => id,
Err(_) => return true,
};
let handler = match handler(guild_id, &mut manager) {

View file

@ -1,4 +1,4 @@
pub use super::mediadata::{MediaData, Song};
pub use super::mediadata::{Media, MediaData, Song};
pub use super::commands::ip::*;
pub use super::commands::list::*;
@ -13,4 +13,4 @@ pub use super::voicemanager::VoiceManager;
pub use super::youtube::youtube_dl;
pub use super::player::{channel_contains_author, guild_id, handler};
pub use super::player::{channel_contains_author, guild, guild_id, handler};

View file

@ -1,5 +1,5 @@
use parking_lot::Mutex;
use serenity::client::bridge::voice::ClientVoiceManager;
use serenity::prelude::Mutex;
use std::sync::Arc;
use typemap::Key;