Connect and play works again
This commit is contained in:
parent
f89c8706eb
commit
53798b050d
18 changed files with 165 additions and 550 deletions
|
@ -7,8 +7,8 @@ authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
typemap = "~0.3"
|
typemap = "~0.3"
|
||||||
serde_json = "*"
|
serde_json = "*"
|
||||||
rand = "0.6"
|
utilities = { git = "http://dimov.cloud/hodasemi/utilities" }
|
||||||
rusqlite = { version = "*", features = ["bundled"] }
|
rusqlite = { version = "*", features = ["bundled"] }
|
||||||
serenity = { version = "0.6", default-features = false, features = [ "builder", "cache", "client", "framework", "gateway", "model", "standard_framework", "utils", "voice", "rustls_backend"]}
|
serenity = { version = "0.7", default-features = false, features = [ "builder", "cache", "client", "framework", "gateway", "model", "standard_framework", "utils", "voice", "rustls_backend"]}
|
||||||
lock_api = "0.2.0"
|
|
||||||
parking_lot = "*"
|
parking_lot = "*"
|
||||||
|
failure = "*"
|
||||||
|
|
BIN
Penis1
BIN
Penis1
Binary file not shown.
|
@ -1,204 +0,0 @@
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{BufRead, BufReader, Write};
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum Value {
|
|
||||||
Value(String),
|
|
||||||
Array(Vec<String>),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ConfigSection {
|
|
||||||
header: String,
|
|
||||||
body: HashMap<String, Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Value {
|
|
||||||
pub fn empty() -> Value {
|
|
||||||
Value::Value("".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn value<T>(value: &T) -> Value
|
|
||||||
where
|
|
||||||
T: Display,
|
|
||||||
{
|
|
||||||
Value::Value(format!("{}", value))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn array<T>(array: &Vec<T>) -> Value
|
|
||||||
where
|
|
||||||
T: Display,
|
|
||||||
{
|
|
||||||
Value::Array(array.iter().map(|v| format!("{}", v)).collect())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_value<T>(&self, value: &mut T) -> Result<(), String>
|
|
||||||
where
|
|
||||||
T: FromStr,
|
|
||||||
{
|
|
||||||
match self {
|
|
||||||
Value::Value(value_string) => match value_string.parse::<T>() {
|
|
||||||
Ok(val) => *value = val,
|
|
||||||
Err(_) => return Err(format!("error parsing value {}", value_string)),
|
|
||||||
},
|
|
||||||
_ => return Err("key_value has wrong format".to_string()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_array<T>(&self, array: &mut Vec<T>) -> Result<(), String>
|
|
||||||
where
|
|
||||||
T: FromStr,
|
|
||||||
{
|
|
||||||
match self {
|
|
||||||
Value::Array(value_array) => {
|
|
||||||
for value_string in value_array {
|
|
||||||
match value_string.parse::<T>() {
|
|
||||||
Ok(val) => array.push(val),
|
|
||||||
Err(_) => return Err(format!("error parsing value {}", value_string)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => return Err("key_value has wrong format".to_string()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_config(file_name: &str) -> Result<HashMap<String, HashMap<String, Value>>, String> {
|
|
||||||
let file = match File::open(file_name) {
|
|
||||||
Ok(file) => file,
|
|
||||||
Err(msg) => return Err(format!("error opening config file({}): {}", file_name, msg)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut infos = HashMap::new();
|
|
||||||
let mut current_section: Option<ConfigSection> = None;
|
|
||||||
|
|
||||||
for line_res in BufReader::new(file).lines() {
|
|
||||||
if let Ok(line) = line_res {
|
|
||||||
let mut trimmed = line.trim().to_string();
|
|
||||||
|
|
||||||
if trimmed.starts_with("#") || trimmed.is_empty() {
|
|
||||||
continue;
|
|
||||||
} else if trimmed.starts_with("[") && trimmed.ends_with("]") {
|
|
||||||
trimmed.remove(0);
|
|
||||||
trimmed.pop();
|
|
||||||
|
|
||||||
if let Some(ref section) = current_section {
|
|
||||||
infos.insert(section.header.clone(), section.body.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
current_section = Some(ConfigSection {
|
|
||||||
header: trimmed,
|
|
||||||
body: HashMap::new(),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
let mut split = trimmed.split("=");
|
|
||||||
|
|
||||||
let key = match split.nth(0) {
|
|
||||||
Some(key) => key.trim().to_string(),
|
|
||||||
None => {
|
|
||||||
println!("cannot get key from line: {}", trimmed);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let value = match split.last() {
|
|
||||||
Some(value) => value.trim().to_string(),
|
|
||||||
None => {
|
|
||||||
println!("cannot get value from line: {}", trimmed);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if value.starts_with("[") && value.ends_with("]") {
|
|
||||||
let mut trimmed_value = value;
|
|
||||||
trimmed_value.remove(0);
|
|
||||||
trimmed_value.pop();
|
|
||||||
|
|
||||||
let value_split = trimmed_value.split(";");
|
|
||||||
let value_array = value_split.map(|v| v.trim().to_string()).collect();
|
|
||||||
|
|
||||||
if let Some(ref mut section) = current_section {
|
|
||||||
section.body.insert(key, Value::Array(value_array));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Some(ref mut section) = current_section {
|
|
||||||
section.body.insert(key, Value::Value(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// also push the last section
|
|
||||||
if let Some(section) = current_section {
|
|
||||||
infos.insert(section.header, section.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(infos)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_config(
|
|
||||||
file_name: &str,
|
|
||||||
sections: &Vec<(String, Vec<(String, Value)>)>,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
let mut file = match File::create(file_name) {
|
|
||||||
Ok(file) => file,
|
|
||||||
Err(msg) => {
|
|
||||||
return Err(format!(
|
|
||||||
"error creating config file({}): {}",
|
|
||||||
file_name, msg
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (header, body) in sections {
|
|
||||||
let fmt_header = format!("[{}]\n", header);
|
|
||||||
|
|
||||||
if let Err(_) = file.write_all(fmt_header.as_bytes()) {
|
|
||||||
return Err(format!("failed writing section: {}", fmt_header));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (key, value) in body {
|
|
||||||
let fmt_key_value = format!(
|
|
||||||
"{} = {}\n",
|
|
||||||
key,
|
|
||||||
match value {
|
|
||||||
Value::Value(val) => val.clone(),
|
|
||||||
Value::Array(array) => {
|
|
||||||
let mut array_value = "[".to_string();
|
|
||||||
|
|
||||||
for (i, val) in array.iter().enumerate() {
|
|
||||||
// if element is not the last one
|
|
||||||
if i != array.len() - 1 {
|
|
||||||
array_value = format!("{}{}, ", array_value, val);
|
|
||||||
} else {
|
|
||||||
array_value = format!("{}{}", array_value, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
format!("{}]", array_value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(_) = file.write_all(fmt_key_value.as_bytes()) {
|
|
||||||
return Err(format!("failed writing key value: {}", fmt_key_value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(_) = file.write_all("\n".as_bytes()) {
|
|
||||||
return Err("failed writing new line".to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
#![macro_use]
|
|
||||||
|
|
||||||
/// check result macro, where the Ok() is the type which should be returned
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! check_result {
|
|
||||||
($v:expr) => {
|
|
||||||
match $v {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(msg) => return Err(msg),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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 {
|
|
||||||
($v:expr) => {
|
|
||||||
match $v {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(msg) => {
|
|
||||||
println!("{}", msg);
|
|
||||||
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 {
|
|
||||||
($v:expr) => {
|
|
||||||
if let Err(msg) = $v {
|
|
||||||
return Err(msg);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// check result macro, where the Ok() is void, but just print the error message
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! display_error {
|
|
||||||
($v:expr) => {
|
|
||||||
if let Err(msg) = $v {
|
|
||||||
println!("{}", msg);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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 {
|
|
||||||
println!("{}", msg);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
31
src/main.rs
31
src/main.rs
|
@ -3,12 +3,9 @@
|
||||||
extern crate serenity;
|
extern crate serenity;
|
||||||
|
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
extern crate rand;
|
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate typemap;
|
extern crate typemap;
|
||||||
|
|
||||||
mod confighandler;
|
|
||||||
mod macros;
|
|
||||||
mod player;
|
mod player;
|
||||||
|
|
||||||
use serenity::{
|
use serenity::{
|
||||||
|
@ -31,10 +28,11 @@ use serenity::prelude::*;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use confighandler::*;
|
|
||||||
use player::prelude::*;
|
use player::prelude::*;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use utilities::prelude::*;
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
token: String,
|
token: String,
|
||||||
prefix: String,
|
prefix: String,
|
||||||
|
@ -55,9 +53,9 @@ group!({
|
||||||
commands: [ip, list, pause, play, remove, skip, stop]
|
commands: [ip, list, pause, play, remove, skip, stop]
|
||||||
});
|
});
|
||||||
|
|
||||||
fn main() {
|
fn main() -> VerboseResult<()> {
|
||||||
// read config file
|
// read config file
|
||||||
let config_file = check_result_return!(read_config("bot.conf"));
|
let config_file = ConfigHandler::read_config("bot.conf")?;
|
||||||
|
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
|
@ -65,26 +63,23 @@ fn main() {
|
||||||
Some(info) => {
|
Some(info) => {
|
||||||
match info.get("token") {
|
match info.get("token") {
|
||||||
Some(token_pair) => {
|
Some(token_pair) => {
|
||||||
display_error!(token_pair.set_value(&mut config.token));
|
token_pair.set_value(&mut config.token)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
println!("couldn't find token inside meta section");
|
create_error!("couldn't find token inside meta section");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match info.get("prefix") {
|
match info.get("prefix") {
|
||||||
Some(prefix_pair) => {
|
Some(prefix_pair) => {
|
||||||
display_error!(prefix_pair.set_value(&mut config.prefix));
|
prefix_pair.set_value(&mut config.prefix)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
println!("couldn't find prefix inside meta section");
|
create_error!("couldn't find prefix inside meta section");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
println!("couldn't find Meta section in config file");
|
create_error!("couldn't find Meta section in config file");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,8 +90,10 @@ fn main() {
|
||||||
// event handlers and framework commands.
|
// event handlers and framework commands.
|
||||||
{
|
{
|
||||||
let mut data = client.data.write();
|
let mut data = client.data.write();
|
||||||
data.insert::<VoiceManager>(Arc::clone(&client.voice_manager));
|
data.insert::<Media>(
|
||||||
data.insert::<Media>(MediaData::new("Penis1").expect("failed to create media data handle"));
|
MediaData::new("Penis1", Arc::clone(&client.voice_manager))
|
||||||
|
.expect("failed to create media data handle"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We will fetch your bot's owners and id
|
// We will fetch your bot's owners and id
|
||||||
|
@ -161,4 +158,6 @@ fn main() {
|
||||||
let _ = client
|
let _ = client
|
||||||
.start()
|
.start()
|
||||||
.map_err(|why| println!("Client ended: {:?}", why));
|
.map_err(|why| println!("Client ended: {:?}", why));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ fn ip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
match from_utf8(out.stdout.as_slice()) {
|
match from_utf8(out.stdout.as_slice()) {
|
||||||
Ok(string) => print_error!(msg.author.direct_message(&ctx, |m| m.content(string))),
|
Ok(string) => msg.author.direct_message(&ctx, |m| m.content(string))?,
|
||||||
Err(_) => print_error!(msg.channel_id.say(&ctx.http, "error getting IP string")),
|
Err(_) => msg.channel_id.say(&ctx.http, "error getting IP string")?,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -8,11 +8,8 @@ use serenity::{
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
if !channel_contains_author(ctx, msg) {
|
if let Err(err) = channel_contains_author(ctx, msg) {
|
||||||
println!(
|
msg.channel_id.say(&ctx.http, err)?;
|
||||||
"user {} is not in the same voice channel as the bot",
|
|
||||||
msg.author.name
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +19,7 @@ fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
let media = match data.get::<Media>() {
|
let media = match data.get::<Media>() {
|
||||||
Some(media) => media,
|
Some(media) => media,
|
||||||
None => {
|
None => {
|
||||||
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
|
msg.channel_id.say(&ctx.http, "could not find media data")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -46,7 +43,7 @@ fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_error!(msg.channel_id.say(&ctx.http, output));
|
msg.channel_id.say(&ctx.http, output)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,8 @@ use serenity::{
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
fn pause(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
fn pause(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
if !channel_contains_author(ctx, msg) {
|
if let Err(err) = channel_contains_author(ctx, msg) {
|
||||||
println!(
|
msg.channel_id.say(&ctx.http, err)?;
|
||||||
"user {} is not in the same voice channel as the bot",
|
|
||||||
msg.author.name
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +19,7 @@ fn pause(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
let media = match data.get::<Media>() {
|
let media = match data.get::<Media>() {
|
||||||
Some(media) => media,
|
Some(media) => media,
|
||||||
None => {
|
None => {
|
||||||
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
|
msg.channel_id.say(&ctx.http, "could not find media data")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
use lock_api::RawMutex;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use rand::{seq::SliceRandom, thread_rng};
|
|
||||||
|
|
||||||
use super::super::prelude::*;
|
use super::super::prelude::*;
|
||||||
|
|
||||||
use rusqlite::params;
|
use rusqlite::params;
|
||||||
|
|
||||||
|
use rand::{seq::SliceRandom, thread_rng};
|
||||||
|
|
||||||
use serenity::prelude::*;
|
use serenity::prelude::*;
|
||||||
use serenity::voice::LockedAudio;
|
use serenity::voice::LockedAudio;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
|
@ -15,13 +11,12 @@ use serenity::{
|
||||||
model::channel::Message,
|
model::channel::Message,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use utilities::prelude::*;
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
|
fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||||
if !channel_contains_author(ctx, msg) {
|
if let Err(err) = channel_contains_author(ctx, msg) {
|
||||||
println!(
|
msg.channel_id.say(&ctx.http, err)?;
|
||||||
"user {} is not in the same voice channel as the bot",
|
|
||||||
msg.author.name
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,33 +24,32 @@ fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||||
let media = match data.get_mut::<Media>() {
|
let media = match data.get_mut::<Media>() {
|
||||||
Some(media) => media,
|
Some(media) => media,
|
||||||
None => {
|
None => {
|
||||||
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
|
msg.channel_id.say(&ctx.http, "could not find media data")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if args.len() == 0 {
|
if args.len() == 0 {
|
||||||
if !check_for_continue(media.song_mut()) {
|
if !check_for_continue(media.song_mut()) {
|
||||||
print_error!(msg
|
msg.channel_id
|
||||||
.channel_id
|
.say(&ctx.http, "Must provide a URL to a video or audio")?;
|
||||||
.say(&ctx.http, "Must provide a URL to a video or audio"));
|
|
||||||
}
|
|
||||||
} else if args.len() == 1 {
|
|
||||||
let arg = match args.single::<String>() {
|
|
||||||
Ok(arg) => arg,
|
|
||||||
// can't happen, since we tested for length == 1
|
|
||||||
Err(_) => return Ok(()),
|
|
||||||
};
|
|
||||||
|
|
||||||
if arg == "--local" {
|
|
||||||
handle_local_request(media, ctx, msg)?;
|
|
||||||
} else if arg.starts_with("http") {
|
|
||||||
handle_http_request(media, ctx, msg, &arg)?;
|
|
||||||
} else {
|
|
||||||
handle_song_request(media, ctx, msg, &arg)?;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print_error!(msg.channel_id.say(&ctx.http, "Unsupported argument list"));
|
let first_arg = args.current().unwrap();
|
||||||
|
|
||||||
|
if first_arg == "--local" {
|
||||||
|
handle_local_request(media, ctx, msg)?;
|
||||||
|
} else if first_arg.starts_with("http") {
|
||||||
|
handle_http_request(media, ctx, msg, first_arg)?;
|
||||||
|
} else {
|
||||||
|
let mut arg_list = String::new();
|
||||||
|
|
||||||
|
for arg in args.iter::<String>() {
|
||||||
|
arg_list += &format!(" {}", arg?.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_song_request(media, ctx, msg, &arg_list)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -74,63 +68,15 @@ fn check_for_continue(song_lock: &Option<LockedAudio>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_join_channel<T: RawMutex>(
|
|
||||||
manager_lock: &Arc<lock_api::Mutex<T, serenity::client::bridge::voice::ClientVoiceManager>>,
|
|
||||||
ctx: &Context,
|
|
||||||
msg: &Message,
|
|
||||||
) {
|
|
||||||
let guild = check_result_return!(guild(ctx, msg));
|
|
||||||
let guild_id = check_result_return!(guild_id(ctx, msg));
|
|
||||||
|
|
||||||
let channel_id = guild
|
|
||||||
.read()
|
|
||||||
.voice_states
|
|
||||||
.get(&msg.author.id)
|
|
||||||
.and_then(|voice_state| voice_state.channel_id);
|
|
||||||
|
|
||||||
let connect_to = match channel_id {
|
|
||||||
Some(channel) => channel,
|
|
||||||
None => {
|
|
||||||
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(
|
fn append_songs(
|
||||||
media: &mut MediaData,
|
media: &mut MediaData,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
msg: &Message,
|
msg: &Message,
|
||||||
mut source: Vec<Song>,
|
mut source: Vec<Song>,
|
||||||
) -> Result<(), String> {
|
) -> VerboseResult<()> {
|
||||||
media.playlist_mut().append(&mut source);
|
media.playlist_mut().append(&mut source);
|
||||||
|
|
||||||
if let Some(manager_lock) = ctx.data.read().get::<VoiceManager>().cloned() {
|
MediaData::start_playing(ctx, media, msg)?;
|
||||||
check_join_channel(&manager_lock, ctx, msg);
|
|
||||||
|
|
||||||
// let check_finished = {
|
|
||||||
// let channel_id = msg.channel_id;
|
|
||||||
// let manager_lock_clone = manager_lock.clone();
|
|
||||||
|
|
||||||
// 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::start_playing(ctx, media, msg, &manager_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -139,8 +85,8 @@ fn handle_http_request(
|
||||||
media: &mut MediaData,
|
media: &mut MediaData,
|
||||||
ctx: &serenity::client::Context,
|
ctx: &serenity::client::Context,
|
||||||
msg: &serenity::model::channel::Message,
|
msg: &serenity::model::channel::Message,
|
||||||
url: &String,
|
url: &str,
|
||||||
) -> Result<(), String> {
|
) -> VerboseResult<()> {
|
||||||
let mut names = Vec::new();
|
let mut names = Vec::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -148,18 +94,18 @@ fn handle_http_request(
|
||||||
|
|
||||||
let mut stmt = match sql.prepare("SELECT name FROM Vulva3 WHERE link = ?") {
|
let mut stmt = match sql.prepare("SELECT name FROM Vulva3 WHERE link = ?") {
|
||||||
Ok(statement) => statement,
|
Ok(statement) => statement,
|
||||||
Err(_) => return Err("failed preparing data base access".to_string()),
|
Err(_) => create_error!("failed preparing data base access"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let rows = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
|
let rows = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
|
||||||
Ok(rows) => rows,
|
Ok(rows) => rows,
|
||||||
Err(_) => return Err("failed querying rows".to_string()),
|
Err(_) => create_error!("failed querying rows"),
|
||||||
};
|
};
|
||||||
|
|
||||||
for name_result in rows {
|
for name_result in rows {
|
||||||
let name = match name_result {
|
let name = match name_result {
|
||||||
Ok(name) => name,
|
Ok(name) => name,
|
||||||
Err(_) => return Err("failed getting name from row".to_string()),
|
Err(_) => create_error!("failed getting name from row"),
|
||||||
};
|
};
|
||||||
|
|
||||||
names.push(name);
|
names.push(name);
|
||||||
|
@ -167,7 +113,9 @@ fn handle_http_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if names.len() > 0 {
|
if names.len() > 0 {
|
||||||
print_error!(msg.channel_id.say(&ctx.http, "song already loaded!"));
|
msg.channel_id
|
||||||
|
.say(&ctx.http, "song already loaded!")
|
||||||
|
.map_err(|err| format!("{}", err))?;
|
||||||
|
|
||||||
append_songs(
|
append_songs(
|
||||||
media,
|
media,
|
||||||
|
@ -181,9 +129,9 @@ fn handle_http_request(
|
||||||
Err(why) => {
|
Err(why) => {
|
||||||
println!("Err starting source: {:?}", why);
|
println!("Err starting source: {:?}", why);
|
||||||
|
|
||||||
print_error!(msg
|
msg.channel_id
|
||||||
.channel_id
|
.say(&ctx.http, format!("Error using youtube-dl: {}", why))
|
||||||
.say(&ctx.http, format!("Error using youtube-dl: {}", why)));
|
.map_err(|err| format!("{}", err))?;
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -209,12 +157,14 @@ fn handle_http_request(
|
||||||
)
|
)
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
return Err("failed inserting songs into db".to_string());
|
create_error!("failed inserting songs into db");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_error!(msg.channel_id.say(&ctx.http, info));
|
msg.channel_id
|
||||||
|
.say(&ctx.http, info)
|
||||||
|
.map_err(|err| format!("{}", err))?;
|
||||||
|
|
||||||
append_songs(media, ctx, msg, source)?;
|
append_songs(media, ctx, msg, source)?;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +176,7 @@ fn handle_local_request(
|
||||||
media: &mut MediaData,
|
media: &mut MediaData,
|
||||||
ctx: &serenity::client::Context,
|
ctx: &serenity::client::Context,
|
||||||
msg: &serenity::model::channel::Message,
|
msg: &serenity::model::channel::Message,
|
||||||
) -> Result<(), String> {
|
) -> VerboseResult<()> {
|
||||||
let mut songs = Vec::new();
|
let mut songs = Vec::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -234,18 +184,18 @@ fn handle_local_request(
|
||||||
|
|
||||||
let mut stmt = match sql.prepare("SELECT name FROM Vulva3") {
|
let mut stmt = match sql.prepare("SELECT name FROM Vulva3") {
|
||||||
Ok(statement) => statement,
|
Ok(statement) => statement,
|
||||||
Err(_) => return Err("failed preparing data base access".to_string()),
|
Err(_) => create_error!("failed preparing data base access"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
||||||
Ok(rows) => rows,
|
Ok(rows) => rows,
|
||||||
Err(_) => return Err("failed querying rows".to_string()),
|
Err(_) => create_error!("failed querying rows"),
|
||||||
};
|
};
|
||||||
|
|
||||||
for name_result in rows {
|
for name_result in rows {
|
||||||
let name = match name_result {
|
let name = match name_result {
|
||||||
Ok(name) => name,
|
Ok(name) => name,
|
||||||
Err(_) => return Err("failed getting name from row".to_string()),
|
Err(_) => create_error!("failed getting name from row"),
|
||||||
};
|
};
|
||||||
|
|
||||||
songs.push(Song { name });
|
songs.push(Song { name });
|
||||||
|
@ -265,7 +215,7 @@ fn handle_song_request(
|
||||||
ctx: &serenity::client::Context,
|
ctx: &serenity::client::Context,
|
||||||
msg: &serenity::model::channel::Message,
|
msg: &serenity::model::channel::Message,
|
||||||
pattern: &str,
|
pattern: &str,
|
||||||
) -> Result<(), String> {
|
) -> VerboseResult<()> {
|
||||||
let mut songs = Vec::new();
|
let mut songs = Vec::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -276,18 +226,18 @@ fn handle_song_request(
|
||||||
pattern
|
pattern
|
||||||
)) {
|
)) {
|
||||||
Ok(statement) => statement,
|
Ok(statement) => statement,
|
||||||
Err(_) => return Err("failed preparing data base access".to_string()),
|
Err(_) => create_error!("failed preparing data base access"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
||||||
Ok(rows) => rows,
|
Ok(rows) => rows,
|
||||||
Err(_) => return Err("failed querying rows".to_string()),
|
Err(_) => create_error!("failed querying rows"),
|
||||||
};
|
};
|
||||||
|
|
||||||
for name_result in rows {
|
for name_result in rows {
|
||||||
let name = match name_result {
|
let name = match name_result {
|
||||||
Ok(name) => name,
|
Ok(name) => name,
|
||||||
Err(_) => return Err("failed getting name from row".to_string()),
|
Err(_) => create_error!("failed getting name from row"),
|
||||||
};
|
};
|
||||||
|
|
||||||
songs.push(Song { name });
|
songs.push(Song { name });
|
||||||
|
@ -300,9 +250,9 @@ fn handle_song_request(
|
||||||
|
|
||||||
append_songs(media, ctx, msg, songs)?;
|
append_songs(media, ctx, msg, songs)?;
|
||||||
} else {
|
} else {
|
||||||
print_error!(msg
|
msg.channel_id
|
||||||
.channel_id
|
.say(&ctx.http, format!("no song found with pattern {}", pattern))
|
||||||
.say(&ctx.http, format!("no song found with pattern {}", pattern)));
|
.map_err(|err| format!("{}", err))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -18,7 +18,7 @@ fn remove(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
let media = match data.get::<Media>() {
|
let media = match data.get::<Media>() {
|
||||||
Some(media) => media,
|
Some(media) => media,
|
||||||
None => {
|
None => {
|
||||||
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
|
msg.channel_id.say(&ctx.http, "could not find media data")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -34,14 +34,14 @@ fn remove(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
|
|
||||||
if !song_name.is_empty() {
|
if !song_name.is_empty() {
|
||||||
match fs::remove_file(&song_name) {
|
match fs::remove_file(&song_name) {
|
||||||
Ok(_) => print_error!(msg.channel_id.say(
|
Ok(_) => msg.channel_id.say(
|
||||||
&ctx.http,
|
&ctx.http,
|
||||||
format!("Remove current song ({}) from local disk", song_name)
|
format!("Remove current song ({}) from local disk", song_name),
|
||||||
)),
|
)?,
|
||||||
Err(err) => print_error!(msg.channel_id.say(
|
Err(err) => msg.channel_id.say(
|
||||||
&ctx.http,
|
&ctx.http,
|
||||||
format!("Error removing file ({}): {:?}", song_name, err.kind())
|
format!("Error removing file ({}): {:?}", song_name, err.kind()),
|
||||||
)),
|
)?,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,35 +11,24 @@ use serenity::{
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
if !channel_contains_author(ctx, msg) {
|
if let Err(err) = channel_contains_author(ctx, msg) {
|
||||||
println!(
|
msg.channel_id.say(&ctx.http, err)?;
|
||||||
"user {} is not in the same voice channel as the bot",
|
|
||||||
msg.author.name
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut data = ctx.data.write();
|
let mut data = ctx.data.write();
|
||||||
|
|
||||||
if let Some(manager_lock) = data.get_mut::<VoiceManager>().cloned() {
|
if let Some(media) = data.get_mut::<Media>() {
|
||||||
let mut manager = manager_lock.lock();
|
let voice_manager = media.voice_manager.clone();
|
||||||
|
let mut manager = voice_manager.lock();
|
||||||
|
|
||||||
let guild_id = check_result_return_ok!(guild_id(ctx, msg));
|
let guild_id = guild_id(ctx, msg)?;
|
||||||
|
|
||||||
if let Some(handler) = handler(guild_id, &mut manager) {
|
if let Some(handler) = handler(guild_id, &mut manager) {
|
||||||
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 current song is the last song in this playlist, just return
|
// if current song is the last song in this playlist, just return
|
||||||
if media.playlist().is_empty() {
|
if media.playlist().is_empty() {
|
||||||
print_error!(msg
|
msg.channel_id
|
||||||
.channel_id
|
.say(&ctx.http, "playlist is empty, no next song available")?;
|
||||||
.say(&ctx.http, "playlist is empty, no next song available"));
|
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,10 +67,10 @@ fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
*media.song_mut() = Some(handler.play_returning(source));
|
*media.song_mut() = Some(handler.play_returning(source));
|
||||||
*media.song_name_mut() = first.name.clone();
|
*media.song_name_mut() = first.name.clone();
|
||||||
|
|
||||||
print_error!(msg.channel_id.say(
|
msg.channel_id.say(
|
||||||
&ctx.http,
|
&ctx.http,
|
||||||
format!("Skipped current song, now playing: {}", first.name)
|
format!("Skipped current song, now playing: {}", first.name),
|
||||||
));
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,8 @@ use serenity::{
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
fn stop(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
fn stop(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
if !channel_contains_author(ctx, msg) {
|
if let Err(err) = channel_contains_author(ctx, msg) {
|
||||||
println!(
|
msg.channel_id.say(&ctx.http, err)?;
|
||||||
"user {} is not in the same voice channel as the bot",
|
|
||||||
msg.author.name
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +17,12 @@ fn stop(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||||
let media = match data.get_mut::<Media>() {
|
let media = match data.get_mut::<Media>() {
|
||||||
Some(media) => media,
|
Some(media) => media,
|
||||||
None => {
|
None => {
|
||||||
display_error_ok!(msg.channel_id.say(&ctx.http, "could not find media data"));
|
msg.channel_id.say(&ctx.http, "could not find media data")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
print_error!(media.reset(ctx, msg));
|
media.reset(ctx, msg)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,16 @@ use serenity::prelude::*;
|
||||||
use serenity::voice::ffmpeg;
|
use serenity::voice::ffmpeg;
|
||||||
use serenity::voice::LockedAudio;
|
use serenity::voice::LockedAudio;
|
||||||
|
|
||||||
|
use serenity::client::bridge::voice::ClientVoiceManager;
|
||||||
|
use serenity::prelude::Mutex;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::prelude::*;
|
use super::prelude::*;
|
||||||
|
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection};
|
||||||
|
|
||||||
|
use utilities::prelude::*;
|
||||||
|
|
||||||
pub struct Song {
|
pub struct Song {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
@ -18,13 +22,18 @@ pub struct MediaData {
|
||||||
playlist: Vec<Song>,
|
playlist: Vec<Song>,
|
||||||
current_song: Option<LockedAudio>,
|
current_song: Option<LockedAudio>,
|
||||||
song_name: String,
|
song_name: String,
|
||||||
pub next_callback: Option<Arc<Fn() -> ()>>,
|
pub next_callback: Option<Arc<dyn Fn() -> ()>>,
|
||||||
|
|
||||||
sql_data_base: Connection,
|
sql_data_base: Connection,
|
||||||
|
|
||||||
|
pub voice_manager: Arc<Mutex<ClientVoiceManager>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MediaData {
|
impl MediaData {
|
||||||
pub fn new(file: &str) -> Result<MediaData, String> {
|
pub fn new(
|
||||||
|
file: &str,
|
||||||
|
voice_manager: Arc<Mutex<ClientVoiceManager>>,
|
||||||
|
) -> Result<MediaData, String> {
|
||||||
let connection = match Connection::open(file) {
|
let connection = match Connection::open(file) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(_) => return Err(format!("can't open {}", file)),
|
Err(_) => return Err(format!("can't open {}", file)),
|
||||||
|
@ -51,6 +60,8 @@ impl MediaData {
|
||||||
next_callback: None,
|
next_callback: None,
|
||||||
|
|
||||||
sql_data_base: connection,
|
sql_data_base: connection,
|
||||||
|
|
||||||
|
voice_manager,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,8 +75,8 @@ impl MediaData {
|
||||||
self.song_name = String::new();
|
self.song_name = String::new();
|
||||||
self.next_callback = None;
|
self.next_callback = None;
|
||||||
|
|
||||||
if let Some(manager_lock) = ctx.data.read().get::<VoiceManager>().cloned() {
|
if let Some(media) = ctx.data.read().get::<Media>() {
|
||||||
let mut manager = manager_lock.lock();
|
let mut manager = media.voice_manager.lock();
|
||||||
|
|
||||||
let guild_id = guild_id(ctx, msg)?;
|
let guild_id = guild_id(ctx, msg)?;
|
||||||
|
|
||||||
|
@ -118,30 +129,23 @@ impl MediaData {
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
mediadata: &mut MediaData,
|
mediadata: &mut MediaData,
|
||||||
msg: &Message,
|
msg: &Message,
|
||||||
manager_lock: &Arc<
|
) -> VerboseResult<()> {
|
||||||
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
|
|
||||||
>,
|
|
||||||
) {
|
|
||||||
// check if there is already playing
|
// check if there is already playing
|
||||||
let already_started = { mediadata.song().is_some() };
|
let already_started = mediadata.song().is_some();
|
||||||
|
|
||||||
// if there isnt already a song playing, start a new one
|
// if there isnt already a song playing, start a new one
|
||||||
if !already_started {
|
if !already_started {
|
||||||
Self::next_song(ctx, mediadata, msg, manager_lock);
|
Self::next_song(ctx, mediadata, msg)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_song(
|
pub fn next_song(ctx: &Context, mediadata: &mut MediaData, msg: &Message) -> VerboseResult<()> {
|
||||||
ctx: &Context,
|
let voice_manager = mediadata.voice_manager.clone();
|
||||||
mediadata: &mut MediaData,
|
let mut manager = voice_manager.lock();
|
||||||
msg: &Message,
|
|
||||||
manager_lock: &Arc<
|
|
||||||
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
|
|
||||||
>,
|
|
||||||
) {
|
|
||||||
let mut manager = manager_lock.lock();
|
|
||||||
|
|
||||||
let guild_id = check_result_return!(guild_id(ctx, msg));
|
let guild_id = guild_id(ctx, msg)?;
|
||||||
|
|
||||||
let mut need_to_leave = false;
|
let mut need_to_leave = false;
|
||||||
|
|
||||||
|
@ -150,8 +154,7 @@ impl MediaData {
|
||||||
match handler(guild_id, &mut manager) {
|
match handler(guild_id, &mut manager) {
|
||||||
Some(handler) => handler,
|
Some(handler) => handler,
|
||||||
None => {
|
None => {
|
||||||
println!("error getting handler");
|
create_error!("error getting handler");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -171,22 +174,24 @@ impl MediaData {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
mediadata.playlist_mut().clear();
|
mediadata.playlist_mut().clear();
|
||||||
|
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*mediadata.song_mut() = Some(handler.play_returning(source));
|
*mediadata.song_mut() = Some(handler.play_returning(source));
|
||||||
*mediadata.song_name_mut() = first.name.clone();
|
*mediadata.song_name_mut() = first.name.clone();
|
||||||
|
|
||||||
print_error!(msg
|
msg.channel_id
|
||||||
.channel_id
|
.say(&ctx.http, format!("Playing song: {}", first.name))
|
||||||
.say(&ctx.http, format!("Playing song: {}", first.name)));
|
.map_err(|err| format!("{}", err))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if need_to_leave {
|
if need_to_leave {
|
||||||
manager.remove(guild_id);
|
manager.remove(guild_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
pub mod eventhandler;
|
pub mod eventhandler;
|
||||||
pub mod mediadata;
|
pub mod mediadata;
|
||||||
pub mod player;
|
pub mod player;
|
||||||
pub mod voicemanager;
|
|
||||||
mod youtube;
|
mod youtube;
|
||||||
|
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use lock_api::{MutexGuard, RawMutex};
|
use parking_lot::lock_api::{MutexGuard, RawMutex};
|
||||||
use serenity;
|
use serenity;
|
||||||
use serenity::model::channel::Message;
|
use serenity::model::channel::Message;
|
||||||
use serenity::model::guild::Guild;
|
use serenity::model::guild::Guild;
|
||||||
|
@ -8,6 +8,8 @@ use serenity::voice::Handler;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use utilities::prelude::*;
|
||||||
|
|
||||||
// This imports `typemap`'s `Key` as `TypeMapKey`.
|
// This imports `typemap`'s `Key` as `TypeMapKey`.
|
||||||
use serenity::prelude::*;
|
use serenity::prelude::*;
|
||||||
|
|
||||||
|
@ -45,64 +47,39 @@ pub fn handler<'a, T: RawMutex>(
|
||||||
pub fn channel_contains_author(
|
pub fn channel_contains_author(
|
||||||
ctx: &mut serenity::client::Context,
|
ctx: &mut serenity::client::Context,
|
||||||
msg: &serenity::model::channel::Message,
|
msg: &serenity::model::channel::Message,
|
||||||
) -> bool {
|
) -> VerboseResult<()> {
|
||||||
let (guild_id, voice_channel_id_bot) = {
|
let guild = guild(ctx, msg)?;
|
||||||
match ctx.data.read().get::<VoiceManager>().cloned() {
|
let guild_id = guild.read().id;
|
||||||
Some(manager_lock) => {
|
|
||||||
let mut manager = manager_lock.lock();
|
|
||||||
let guild_id = match guild_id(ctx, msg) {
|
|
||||||
Ok(id) => id,
|
|
||||||
Err(_) => return true,
|
|
||||||
};
|
|
||||||
|
|
||||||
let handler = match handler(guild_id, &mut manager) {
|
let author_channel_id = match guild
|
||||||
Some(handler) => handler,
|
.read()
|
||||||
None => {
|
.voice_states
|
||||||
println!("error getting handler");
|
.get(&msg.author.id)
|
||||||
return true;
|
.and_then(|voice_state| voice_state.channel_id)
|
||||||
|
{
|
||||||
|
Some(channel) => channel,
|
||||||
|
None => create_error!("author is not in a voice channel!"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(media) = ctx.data.read().get::<Media>() {
|
||||||
|
let mut manager = media.voice_manager.lock();
|
||||||
|
|
||||||
|
match manager.get(guild_id) {
|
||||||
|
Some(handler) => match handler.channel_id {
|
||||||
|
Some(bot_channel_id) => {
|
||||||
|
if bot_channel_id != author_channel_id {
|
||||||
|
create_error!("author is not in the same voice channel as the bot!");
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
None => {
|
||||||
(
|
manager.join(guild_id, author_channel_id);
|
||||||
guild_id,
|
}
|
||||||
match handler.channel_id {
|
},
|
||||||
Some(id) => id,
|
None => {
|
||||||
None => {
|
manager.join(guild_id, author_channel_id);
|
||||||
println!("error getting channel_id for bot");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
None => return false,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let author = &msg.author;
|
|
||||||
|
|
||||||
let guild = match guild_id.to_guild_cached(&ctx) {
|
|
||||||
Some(guild) => guild,
|
|
||||||
None => {
|
|
||||||
println!("error getting guild from cache");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let guild_lock = guild.read();
|
|
||||||
|
|
||||||
let voice_state = match guild_lock.voice_states.get(&author.id) {
|
|
||||||
Some(state) => state,
|
|
||||||
None => {
|
|
||||||
println!("error getting voice state from user {}", author.name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(voice_channel_id_user) = voice_state.channel_id {
|
|
||||||
if voice_channel_id_bot != voice_channel_id_user {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ pub use super::commands::skip::*;
|
||||||
pub use super::commands::stop::*;
|
pub use super::commands::stop::*;
|
||||||
|
|
||||||
pub use super::eventhandler::Handler;
|
pub use super::eventhandler::Handler;
|
||||||
pub use super::voicemanager::VoiceManager;
|
|
||||||
|
|
||||||
pub use super::youtube::youtube_dl;
|
pub use super::youtube::youtube_dl;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
use serenity::client::bridge::voice::ClientVoiceManager;
|
|
||||||
use serenity::prelude::Mutex;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use typemap::Key;
|
|
||||||
|
|
||||||
pub struct VoiceManager;
|
|
||||||
|
|
||||||
impl Key for VoiceManager {
|
|
||||||
type Value = Arc<Mutex<ClientVoiceManager>>;
|
|
||||||
}
|
|
|
@ -72,7 +72,7 @@ pub fn youtube_dl(uri: &str) -> Result<Vec<Song>, String> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let files = check_result!(convert_output(&out));
|
let files = convert_output(&out)?;
|
||||||
|
|
||||||
for file in &files {
|
for file in &files {
|
||||||
println!("file: {}", file);
|
println!("file: {}", file);
|
||||||
|
|
Loading…
Reference in a new issue