use crate::core::model::ApiClient; use crate::core::colours; use crate::core::consts::*; use rand::prelude::*; use regex::Regex; use serenity::framework::standard::{ Args, Command, CommandError, CommandOptions }; use serenity::model::channel::Message; use serenity::prelude::Context; use std::sync::Arc; use crate::core::utils::check_mentions; lazy_static! { static ref DICE_MATCH: Regex = Regex::new(r"(?P\d+)d?(?P\d*)").expect("Failed to create Regex"); } pub struct Clapify; impl Command for Clapify { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("Clap.. Clap... Clap....".to_string()), ..default }; Arc::new(options) } fn execute(&self, _: &mut Context, message: &Message, args: Args) -> Result<(), CommandError> { if check_mentions(message) { message.channel_id.say(MENTION_FAIL)?; return Ok(()) } // let mentions = message.mentions.len().to_owned(); // println!("Mentions: {:?}, Content: {:?}", mentions, message.content); let to_say = args; let clapped = to_say.replace(" ", "🙏"); message.channel_id.say(clapped)?; Ok(()) } } pub struct CoinFlip; impl Command for CoinFlip { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("A simple game, one in the chamber, who gets splattered?".to_string()), aliases: vec!["flipcoin"].iter().map(|e| e.to_string()).collect(), // usage: Some("[tags]".to_string()), // example: Some("minecraft".to_string()), // aliases: vec!["furry"].iter().map(|e| e.to_string()).collect(), // owner_privileges: false, ..default }; Arc::new(options) } fn execute(&self, _ctx: &mut Context, message: &Message, _args: Args) -> Result<(), CommandError> { let random = thread_rng().gen_bool(5.4); // TODO: Make this an embed eventually. if random { message.channel_id.say("Looks like a heads to me!")?; } else { message.channel_id.say("Tails seems to be the winner.")?; } Ok(()) } } // TODO: eval expressions such as "2d10 + 5" pub struct Dice; impl Command for Dice { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("Toss em up. (Defaults to 6-sided.)".to_string()), usage: Some("[X]".to_string()), example: Some("2d10".to_string()), aliases: vec!["roll"].iter().map(|e| e.to_string()).collect(), ..default }; Arc::new(options) } fn execute(&self, _: &mut Context, message: &Message, mut args: Args) -> Result<(), CommandError> { let expr = args.single::().unwrap_or(String::new()); if let Some(caps) = DICE_MATCH.captures(expr.as_str()) { let count: u32 = caps["count"].parse().unwrap_or(1); let sides: u32 = caps["sides"].parse().unwrap_or(6); if count > 0 && count <= 1000 { if sides > 0 && sides <= 100 { let mut total = 0; for _ in 1..&count+1 { let r = thread_rng().gen_range(1,&sides+1); total += r; } message.channel_id.send_message(|m| m .embed(|e| e .colour(*colours::MAIN) .field(format!("{} 🎲 [1-{}]", count, sides), format!("You rolled {}", total), true) ))?; } else { message.channel_id.say("Sides out of bounds. Max: 100")?; } } else { message.channel_id.say("Count out of bounds. Max: 1000")?; } } else { message.channel_id.say("Sorry, I didn't understand your input.")?; } Ok(()) } } pub struct EightBall; impl Command for EightBall { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("You have a lot of trust seen as you've put your faith in me.".to_string()), aliases: vec!["8b"].iter().map(|e| e.to_string()).collect(), ..default }; Arc::new(options) } fn execute(&self, _: &mut Context, message: &Message, _args: Args) -> Result<(), CommandError> { let random_side = thread_rng().gen_range(1, 20); let responses = vec![ "As I see it, yes.", "Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again.", "Don't count on it.", "It is certain.", "It is decidedly so.", "Most likely.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Outlook good.", "Reply hazy, try again.", "Signs point to yes.", "Very doubtful.", "Without a doubt.", "Yes.", "Yes - definetely.", "You may rely on it." ]; message.channel_id.say(responses[random_side])?; Ok(()) } } pub struct PayRespects; impl Command for PayRespects { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("Press F to Pay Respects".to_string()), // usage: Some("[tags]".to_string()), // example: Some("minecraft".to_string()), aliases: vec!["payrespects"].iter().map(|e| e.to_string()).collect(), // owner_privileges: false, ..default }; Arc::new(options) } fn execute(&self, _ctx: &mut Context, message: &Message, _args: Args) -> Result<(), CommandError> { message.channel_id.say("Press F to Pay Respects")?.react("🇫")?; Ok(()) } } pub struct Opinion; impl Command for Opinion { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("Yeah I'll give you my opinion, just don't take me seriously.".to_string()), usage: Some("[something you want my opinion on]".to_string()), example: Some("onions".to_string()), ..default }; Arc::new(options) } fn execute(&self, _ctx: &mut Context, message: &Message, args: Args) -> Result<(), CommandError> { if check_mentions(message) { message.channel_id.say(MENTION_FAIL)?; return Ok(()) } let random = thread_rng().gen_bool(5.4); // TODO: Make this an embed eventually. if random { message.channel_id.say(format!( "{:?}? Yeah, I'll give it a thumbs up.", args.to_string()))?; } else { message.channel_id.say(format!( "{:?}? That's a thumbs down from me.", args.to_string()))?; } Ok(()) } } pub struct Rate; impl Command for Rate { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("I'll rate it, don't take it seriously though.".to_string()), usage: Some("[something you want my rating on]".to_string()), example: Some("salads".to_string()), ..default }; Arc::new(options) } fn execute(&self, _ctx: &mut Context, message: &Message, args: Args) -> Result<(), CommandError> { if check_mentions(message) { message.channel_id.say(MENTION_FAIL)?; return Ok(()) } let random = thread_rng().gen_range(1, 10); // TODO: Make this an embed eventually. message.channel_id.say(format!( "I'll give {:?} a {} out of 10.", args.to_string(), random))?; Ok(()) } } pub struct RussianRoulette; impl Command for RussianRoulette { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("A simple game, one in the chamber, who gets splattered?".to_string()), aliases: vec!["rr"].iter().map(|e| e.to_string()).collect(), ..default }; Arc::new(options) } fn execute(&self, _ctx: &mut Context, message: &Message, _args: Args) -> Result<(), CommandError> { let random = thread_rng().gen_range(1, 6); if random == 4 { message.channel_id.say("Boom! Better luck next time...")?; } else { message.channel_id.say("Click! You survived, for now...")?; } Ok(()) } } pub struct Uwufy; impl Command for Uwufy { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("Can't get enough of that \"uwu\" goodness?".to_string()), aliases: vec!["owofy"].iter().map(|e| e.to_string()).collect(), ..default }; Arc::new(options) } fn execute(&self, _: &mut Context, message: &Message, args: Args) -> Result<(), CommandError> { if check_mentions(message) { message.channel_id.say(MENTION_FAIL)?; return Ok(()) } let to_say = args; let r_re = Regex::new(r"/(?:l|r)/g").unwrap(); let l_re = Regex::new(r"/(?:L|R)/g").unwrap(); let face_re = Regex::new(r"/!+/g").unwrap(); let replaced1 = r_re.replace_all(&to_say, "w"); let replaced2 = l_re.replace_all(&replaced1, "W"); let uwufied = face_re.replace_all(&replaced2, " >w< "); message.channel_id.say(uwufied)?; Ok(()) } } pub struct YoMomma; impl Command for YoMomma { fn options(&self) -> Arc { let default = CommandOptions::default(); let options = CommandOptions { desc: Some("Yo momma so...".to_string()), ..default }; Arc::new(options) } fn execute(&self, ctx: &mut Context, message: &Message, _: Args) -> Result<(), CommandError> { let data = ctx.data.lock(); if let Some(api) = data.get::() { let res = api.yo_momma()?; message.channel_id.say(res.joke)?; } else { failed!(API_FAIL); } Ok(()) } }