1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
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<Brain>,
guild: Id<GuildMarker>,
create: &InteractionCreate,
data: &CommandData,
) -> InteractionResponseData {
let mut points = None;
let mut users: Vec<Id<UserMarker>> = 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::<Vec<String>>()
.join(", ");
let msg = format!("{points_display} points {points_verb} {users_string}");
let embed = EmbedBuilder::new().description(msg).build();
InteractionResponseDataBuilder::new()
.embeds([embed])
.build()
}
|