extern crate serenity; extern crate parking_lot; extern crate serde_json; extern crate typemap; mod confighandler; mod macros; // Import the client's bridge to the voice manager. Since voice is a standalone // feature, it's not as ergonomic to work with as it could be. The client // provides a clean bridged integration with voice. use serenity::client::bridge::voice::ClientVoiceManager; use serenity::client::{Client, Context, EventHandler}; use serenity::framework::StandardFramework; use serenity::model::channel::Message; use serenity::model::gateway::Ready; // Import the `Context` from the client and `parking_lot`'s `Mutex`. // // `parking_lot` offers much more efficient implementations of `std::sync`'s // types. You can read more about it here: // // use serenity::prelude::Mutex; use serenity::Result as SerenityResult; use std::sync::Arc; use typemap::Key; use confighandler::*; mod player; mod youtube; use player::*; /* const fn empty_vec() -> Vec { Vec::new() } */ pub struct VoiceManager; impl Key for VoiceManager { type Value = Arc>; } struct Handler; impl EventHandler for Handler { fn ready(&self, _: Context, ready: Ready) { println!("{} is connected!", ready.user.name); } } struct Config { token: String, prefix: String, } impl Default for Config { fn default() -> Self { Self { token: String::new(), prefix: String::new(), } } } fn main() { // read config file let config_file = check_result_return!(read_config("bot.conf")); let mut config = Config::default(); match config_file.get("Meta") { Some(info) => { match info.get("token") { Some(token_pair) => { display_error!(token_pair.set_value(&mut config.token)); } None => { println!("couldn't find token inside meta section"); return; } } match info.get("prefix") { Some(prefix_pair) => { display_error!(prefix_pair.set_value(&mut config.prefix)); } None => { println!("couldn't find prefix inside meta section"); return; } } } None => { println!("couldn't find Meta section in config file"); return; } }; let mut client = Client::new(&config.token, Handler).expect("Err creating client"); // Obtain a lock to the data owned by the client, and insert the client's // voice manager into it. This allows the voice manager to be accessible by // event handlers and framework commands. { let mut data = client.data.lock(); data.insert::(Arc::clone(&client.voice_manager)); } let media_data = Arc::new(MediaData::default()); 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(), "help".to_string(), "skip".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()), ); let _ = client .start() .map_err(|why| println!("Client ended: {:?}", why)); } /// Checks that a message successfully sent; if not, then logs why to stdout. fn check_msg(result: SerenityResult) { if let Err(why) = result { println!("Error sending message: {:?}", why); } }