use std::sync::Arc; use twilight_model::{ application::interaction::application_command::{CommandData, CommandOptionValue}, gateway::payload::incoming::InteractionCreate, http::interaction::InteractionResponseData, id::{ Id, marker::{GuildMarker, UserMarker}, }, }; use twilight_util::builder::{InteractionResponseDataBuilder, embed::EmbedBuilder}; use crate::{ bail, brain::Brain, database::{BoardRow, Error as DbError, PermissionSetting}, success, util, }; pub async fn add_points( brain: Arc, guild: Id, create: &InteractionCreate, data: &CommandData, ) -> InteractionResponseData { let mut points = None; let mut users: Vec> = vec![]; for opt in &data.options { match opt.name.as_str() { "points" => match opt.value { CommandOptionValue::Integer(num) => points = Some(num), _ => unreachable!(), }, "users" => match &opt.value { CommandOptionValue::String(raw) => { let mentions = util::extract_user_mentions(&raw); users = mentions; } _ => unreachable!(), }, _ => unreachable!(), } } if users.len() == 0 { bail!("No users mentioned! Who do we add points to?") } let (points, points_display, points_verb) = match points { Some(p) if p > 0 => (p, p, "added to"), Some(p) if p < 0 => (p, -p, "removed from"), Some(0) => { return success!("adding 0 points is a no-operation! I won't do anything :)"); } Some(_) | None => unreachable!(), }; brain.create_leaderboard_if_not_exists(guild); let settings = brain.db.get_leaderboard_settings(guild.get()).unwrap(); if let PermissionSetting::RoleRequired = settings.permission { if let Some(role) = settings.role { let member = create.member.clone().unwrap(); let found_role = member.roles.iter().find(|vrole| vrole.get() == role); if found_role.is_none() { bail!("You do not have the right permissions to change the score"); } } else { // Seeing as the role is a required input on the subcommand, this // would only happen with direct database fiddling or like, some // really weird arcane bullshit? bail!( "Permissions set to Role Required, but no role is set. \ This shouldn't be able to happen. \ Maybe try to set the permissions again?" ); } } for user in &users { match brain.db.give_user_points(guild.get(), user.get(), points) { Err(DbError::UserNotExist) => { let member = brain.guild_member(guild, *user).await; let row = BoardRow { user_id: user.get(), user_handle: member.handle, user_nickname: member.nick.or(member.global_name), points, }; brain.db.add_user_to_leaderboard(guild.get(), row).unwrap(); } _ => (), } } let users_string = users .into_iter() .map(|u| format!("<@{u}>")) .collect::>() .join(", "); let msg = format!("{points_display} points {points_verb} {users_string}"); let embed = EmbedBuilder::new().description(msg).build(); InteractionResponseDataBuilder::new() .embeds([embed]) .build() }