Fix join behaviour

This commit is contained in:
hodasemi 2019-09-15 13:19:32 +02:00
parent 53798b050d
commit b5f2221379
6 changed files with 168 additions and 85 deletions

View file

@ -12,3 +12,5 @@ rusqlite = { version = "*", features = ["bundled"] }
serenity = { version = "0.7", default-features = false, features = [ "builder", "cache", "client", "framework", "gateway", "model", "standard_framework", "utils", "voice", "rustls_backend"]}
parking_lot = "*"
failure = "*"
hey_listen = "*"
white_rabbit = "*"

View file

@ -1,3 +1,4 @@
[Meta]
token = NDc4NTQ1NzY1MDc4MjY5OTU2.DlMQjQ.lqep6rd5w-uBOGst_cuEOQptt84
prefix = !
volume = 0.1

View file

@ -36,6 +36,7 @@ use utilities::prelude::*;
struct Config {
token: String,
prefix: String,
volume: f32,
}
impl Default for Config {
@ -43,6 +44,7 @@ impl Default for Config {
Self {
token: String::new(),
prefix: String::new(),
volume: 1.0,
}
}
}
@ -53,6 +55,18 @@ group!({
commands: [ip, list, pause, play, remove, skip, stop]
});
#[help]
fn my_help(
context: &mut Context,
msg: &Message,
args: Args,
help_options: &'static HelpOptions,
groups: &[&'static CommandGroup],
owners: HashSet<UserId>,
) -> CommandResult {
help_commands::with_embeds(context, msg, args, &help_options, groups, owners)
}
fn main() -> VerboseResult<()> {
// read config file
let config_file = ConfigHandler::read_config("bot.conf")?;
@ -77,6 +91,10 @@ fn main() -> VerboseResult<()> {
create_error!("couldn't find prefix inside meta section");
}
}
if let Some(volume) = info.get("volume") {
volume.set_value(&mut config.volume)?;
}
}
None => {
create_error!("couldn't find Meta section in config file");
@ -91,7 +109,7 @@ fn main() -> VerboseResult<()> {
{
let mut data = client.data.write();
data.insert::<Media>(
MediaData::new("Penis1", Arc::clone(&client.voice_manager))
MediaData::new("Penis1", Arc::clone(&client.voice_manager), config.volume)
.expect("failed to create media data handle"),
);
}
@ -121,40 +139,10 @@ fn main() -> VerboseResult<()> {
.prefix(&config.prefix)
.owners(owners)
})
.group(&GENERAL_GROUP),
.group(&GENERAL_GROUP)
.help(&MY_HELP),
);
/*
client.with_framework(
StandardFramework::new()
.configure(|c| c.prefix(&config.prefix).on_mention(true))
.cmd("play", Play::new(media_data.clone()))
.cmd("pause", Pause::new(media_data.clone()))
.cmd(
"help",
Help::new(
&config.prefix,
vec![
"play".to_string(),
"pause".to_string(),
"stop".to_string(),
"help".to_string(),
"list".to_string(),
"skip".to_string(),
"remove".to_string(),
"ip".to_string(),
],
),
)
.cmd("stop", Stop::new(media_data.clone()))
.cmd("list", List::new(media_data.clone()))
.cmd("skip", Skip::new(media_data.clone()))
.cmd("ip", IP::new())
.cmd("remove", Remove::new(media_data.clone())),
);
*/
let _ = client
.start()
.map_err(|why| println!("Client ended: {:?}", why));

View file

@ -42,13 +42,13 @@ fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
} else if first_arg.starts_with("http") {
handle_http_request(media, ctx, msg, first_arg)?;
} else {
let mut arg_list = String::new();
let mut arg_list = args.single::<String>()?;
for arg in args.iter::<String>() {
arg_list += &format!(" {}", arg?.trim());
}
handle_song_request(media, ctx, msg, &arg_list)?;
handle_song_request(media, ctx, msg, &arg_list)?
}
}
@ -76,6 +76,7 @@ fn append_songs(
) -> VerboseResult<()> {
media.playlist_mut().append(&mut source);
println!("start playing");
MediaData::start_playing(ctx, media, msg)?;
Ok(())
@ -216,6 +217,8 @@ fn handle_song_request(
msg: &serenity::model::channel::Message,
pattern: &str,
) -> VerboseResult<()> {
println!("song request ({})", pattern);
let mut songs = Vec::new();
{
@ -244,10 +247,14 @@ fn handle_song_request(
}
}
println!("{:?}", &songs);
if !songs.is_empty() {
let mut rng = thread_rng();
songs.shuffle(&mut rng);
println!("append songs");
append_songs(media, ctx, msg, songs)?;
} else {
msg.channel_id

View file

@ -4,21 +4,26 @@ use serenity::prelude::*;
use serenity::voice::ffmpeg;
use serenity::voice::LockedAudio;
use parking_lot::lock_api::{MutexGuard, RawMutex};
use serenity::client::bridge::voice::ClientVoiceManager;
use serenity::prelude::Mutex;
use std::sync::Arc;
use super::prelude::*;
use std::fs;
use rusqlite::{params, Connection};
use utilities::prelude::*;
#[derive(Debug)]
pub struct Song {
pub name: String,
}
pub struct MediaData {
volume: f32,
playlist: Vec<Song>,
current_song: Option<LockedAudio>,
song_name: String,
@ -33,6 +38,7 @@ impl MediaData {
pub fn new(
file: &str,
voice_manager: Arc<Mutex<ClientVoiceManager>>,
volume: f32,
) -> Result<MediaData, String> {
let connection = match Connection::open(file) {
Ok(file) => file,
@ -54,6 +60,7 @@ impl MediaData {
};
Ok(MediaData {
volume,
playlist: Vec::new(),
current_song: None,
song_name: String::new(),
@ -75,12 +82,10 @@ impl MediaData {
self.song_name = String::new();
self.next_callback = None;
if let Some(media) = ctx.data.read().get::<Media>() {
let mut manager = media.voice_manager.lock();
let mut manager = self.voice_manager.lock();
let guild_id = guild_id(ctx, msg)?;
{
let handler = match handler(guild_id, &mut manager) {
Some(handler) => handler,
None => return Ok(()),
@ -89,10 +94,7 @@ impl MediaData {
println!("stopped handler");
handler.stop();
}
manager.remove(guild_id);
}
Ok(())
}
@ -135,62 +137,152 @@ impl MediaData {
// if there isnt already a song playing, start a new one
if !already_started {
println!("next song");
Self::next_song(ctx, mediadata, msg)?;
}
Ok(())
}
fn check_for_next(&mut self, ctx: &Context, msg: &Message) -> VerboseResult<String> {
println!("check for next");
while !self.playlist().is_empty() {
let first = self.playlist_mut().remove(0).name;
println!("check: {} ({})", &first, self.playlist().len());
if fs::metadata(&first).is_err() {
msg.channel_id
.say(
&ctx.http,
format!(
"\"{}\" doesn't exist locally anymore and will be removed from data base",
&first
),
)
.map_err(|err| format!("{}", err))?;
let sql = self.db();
if let Err(_) = sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![&first]) {
create_error!("failed executing sql delete");
}
} else {
return Ok(first);
}
}
println!("no song found!");
create_error!("no suitable song found!")
}
fn check_for_channel<T: RawMutex>(
manager: &mut MutexGuard<T, ClientVoiceManager>,
ctx: &Context,
msg: &Message,
) -> VerboseResult<()> {
println!("check for channel!");
let guild = guild(ctx, msg)?;
let guild_id = guild.read().id;
println!("got guild id");
let author_channel_id = match guild
.read()
.voice_states
.get(&msg.author.id)
.and_then(|voice_state| voice_state.channel_id)
{
Some(channel) => channel,
None => create_error!("author is not in a voice channel!"),
};
println!("got author channel");
match manager.get(guild_id) {
Some(handler) => {
// check if the bot is in a channel
if let None = handler.channel_id {
println!("handler had no channel");
manager.join(guild_id, author_channel_id);
}
}
None => {
println!("manager had no handler");
manager.join(guild_id, author_channel_id);
}
}
Ok(())
}
pub fn next_song(ctx: &Context, mediadata: &mut MediaData, msg: &Message) -> VerboseResult<()> {
println!("start next song");
let voice_manager = mediadata.voice_manager.clone();
let mut manager = voice_manager.lock();
println!("got manager lock");
let guild_id = guild_id(ctx, msg)?;
println!("got guild id");
let mut need_to_leave = false;
{
if mediadata.playlist().is_empty() {
need_to_leave = true;
*mediadata.song_mut() = None;
*mediadata.song_name_mut() = String::new();
if let Some(handler) = handler(guild_id, &mut manager) {
handler.stop();
}
} else {
let first = mediadata.check_for_next(ctx, msg)?;
Self::check_for_channel(&mut manager, ctx, msg)?;
let handler = {
match handler(guild_id, &mut manager) {
Some(handler) => handler,
None => {
println!("failed getting handler");
create_error!("error getting handler");
}
}
};
if mediadata.playlist().is_empty() {
need_to_leave = true;
handler.stop();
*mediadata.song_mut() = None;
*mediadata.song_name_mut() = String::new();
} else {
handler.stop();
println!("got handler");
let first = mediadata.playlist_mut().remove(0);
let source = match ffmpeg(first.name.clone()) {
let source = match ffmpeg(first.clone()) {
Ok(mpeg) => mpeg,
Err(_) => {
mediadata.playlist_mut().clear();
return Ok(());
}
Err(_) => create_error!(format!("failed loading: {}", &first)),
};
*mediadata.song_mut() = Some(handler.play_returning(source));
*mediadata.song_name_mut() = first.name.clone();
handler.stop();
let song = handler.play_returning(source);
{
let mut song_lock = song.lock();
song_lock.volume(mediadata.volume);
}
*mediadata.song_mut() = Some(song);
*mediadata.song_name_mut() = first.clone();
msg.channel_id
.say(&ctx.http, format!("Playing song: {}", first.name))
.say(&ctx.http, format!("Playing song: {}", first))
.map_err(|err| format!("{}", err))?;
}
}
if need_to_leave {
manager.remove(guild_id);
}
println!("successfully started next song");
Ok(())
}
}

View file

@ -62,23 +62,16 @@ pub fn channel_contains_author(
};
if let Some(media) = ctx.data.read().get::<Media>() {
let mut manager = media.voice_manager.lock();
let manager = media.voice_manager.lock();
match manager.get(guild_id) {
Some(handler) => match handler.channel_id {
Some(bot_channel_id) => {
if let Some(handler) = manager.get(guild_id) {
// check if the bot is in a channel
if let Some(bot_channel_id) = handler.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);
}
},
None => {
manager.join(guild_id, author_channel_id);
}
}
};
}
Ok(())