From 647c45a0e7fd233360e3ee503845aa8fbfe3ac9c Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Mon, 9 Dec 2019 16:22:01 -0500 Subject: [PATCH] Choose --- youmubot/src/commands/community/mod.rs | 92 +++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/youmubot/src/commands/community/mod.rs b/youmubot/src/commands/community/mod.rs index 4ddad82..620e09b 100644 --- a/youmubot/src/commands/community/mod.rs +++ b/youmubot/src/commands/community/mod.rs @@ -1,4 +1,19 @@ -use serenity::framework::standard::macros::group; +use rand::{ + distributions::{Distribution, Uniform}, + thread_rng, +}; +use serenity::prelude::*; +use serenity::{ + framework::standard::{ + macros::{command, group}, + Args, CommandError as Error, CommandResult, + }, + model::{ + channel::{Channel, Message}, + user::OnlineStatus, + }, + utils::MessageBuilder, +}; mod votes; @@ -7,7 +22,80 @@ use votes::VOTE_COMMAND; group!({ name: "community", options: { + only_in: "guilds", description: "Community related commands. Usually comes with some sort of delays, since it involves pinging", }, - commands: [vote], + commands: [choose, vote], }); + +#[command] +#[description = r"👑 Randomly choose an active member and mention them! +Note that only online/idle users in the channel are chosen from."] +#[usage = "[title = the chosen one]"] +#[example = "the strongest in Gensokyo"] +#[max_args(1)] +pub fn choose(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult { + let title = if args.is_empty() { + "the chosen one".to_owned() + } else { + args.single::()? + }; + + let users: Result, Error> = { + let guild = m.guild(&ctx).unwrap(); + let guild = guild.read(); + let presences = &guild.presences; + let channel = m.channel_id.to_channel(&ctx)?; + if let Channel::Guild(channel) = channel { + let channel = channel.read(); + Ok(channel + .members(&ctx)? + .into_iter() + .filter(|v| !v.user.read().bot) + .map(|v| v.user_id()) + .filter(|v| { + presences + .get(v) + .map(|presence| { + presence.status == OnlineStatus::Online + || presence.status == OnlineStatus::Idle + }) + .unwrap_or(false) + }) + .collect()) + } else { + panic!() + } + }; + let users = users?; + + if users.len() < 2 { + m.reply( + &ctx, + "🍰 Have this cake for yourself because no-one is here for the gods to pick.", + )?; + return Ok(()); + } + + let winner = { + let uniform = Uniform::from(0..users.len()); + let mut rng = thread_rng(); + &users[uniform.sample(&mut rng)] + }; + + m.channel_id.send_message(&ctx, |c| { + c.content( + MessageBuilder::new() + .push("👑 The Gensokyo gods have gathered around and decided, out of ") + .push_bold(format!("{}", users.len())) + .push(" potential prayers, ") + .push(winner.mention()) + .push(" will be ") + .push_bold_safe(title) + .push(". Congrats! 🎉 🎊 🥳") + .build(), + ) + })?; + + Ok(()) +}