Apply serenity 0.6 api
This commit is contained in:
parent
4276428a8b
commit
f89c8706eb
16 changed files with 335 additions and 316 deletions
|
@ -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 = "*"
|
||||
|
|
BIN
Gopnik McBlyat - Polski Rave
Normal file
BIN
Gopnik McBlyat - Polski Rave
Normal file
Binary file not shown.
BIN
Penis1
Normal file
BIN
Penis1
Normal file
Binary file not shown.
|
@ -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 {
|
||||
|
|
36
src/main.rs
36
src/main.rs
|
@ -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));
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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())
|
||||
)),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue