1
+ /* members: Handlers for events involving server members
2
+ * Copyright 2025 Ben Westover <[email protected] >
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it
5
+ * under the terms of the GNU General Public License as published by the Free
6
+ * Software Foundation, either version 3 of the License, or (at your option)
7
+ * any later version. This program is distributed in the hope that it will be
8
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
10
+ * Public License for more details.
11
+ *
12
+ * You should have received a copy of the GNU General Public License along with
13
+ * this program. If not, see <https://www.gnu.org/licenses/>.
14
+ */
15
+ #include " members.h"
16
+ #include " ../util.h"
17
+
18
+ dpp::task<dpp::invite> members::findinvite (dpp::cluster* bot, const dpp::snowflake guild, std::vector<dpp::invite>& invites) {
19
+ dpp::invite invite_used = dpp::invite ();
20
+ invite_used.code = " unknown" ;
21
+
22
+ // Get current invite list
23
+ dpp::confirmation_callback_t invites_conf = co_await bot->co_guild_get_invites (guild);
24
+ if (invites_conf.is_error ()) {
25
+ co_return invite_used;
26
+ }
27
+ // Look for any invite with more uses than the cache has
28
+ for (size_t i = 0 ; i < invites.size (); i++) {
29
+ for (const dpp::invite& invite : std::get<dpp::invite_map>(invites_conf.value ) | std::views::values) {
30
+ if (invite.code == invites[i].code && invite.uses > invites[i].uses ) {
31
+ // Update invite in cache
32
+ invites[i] = invite;
33
+
34
+ invite_used = invite;
35
+ co_return invite_used;
36
+ }
37
+ }
38
+ }
39
+ co_return invite_used;
40
+ }
41
+
42
+ dpp::task<> members::on_kick (const dpp::guild_audit_log_entry_create_t & event, const nlohmann::json& config) {
43
+ dpp::confirmation_callback_t user_conf = co_await event.owner ->co_user_get_cached (event.entry .target_id );
44
+ dpp::confirmation_callback_t mod_conf = co_await event.owner ->co_user_get_cached (event.entry .user_id );
45
+
46
+ dpp::embed embed = dpp::embed ().set_color (dpp::colors::red).set_title (" Manual Kick" );
47
+ if (!user_conf.is_error ()) {
48
+ dpp::user_identified user = std::get<dpp::user_identified>(user_conf.value );
49
+ embed.set_thumbnail (user.get_avatar_url ()).add_field (" User kicked" , user.username , true );
50
+ }
51
+ embed.add_field (" User ID" , event.entry .target_id .str (), true );
52
+
53
+ if (mod_conf.is_error ()) {
54
+ embed.add_field (" Moderator ID" , event.entry .user_id .str (), false );
55
+ } else {
56
+ dpp::user_identified mod = std::get<dpp::user_identified>(mod_conf.value );
57
+ embed.add_field (" Kicked by" , mod.global_name , false );
58
+ }
59
+
60
+ if (!event.entry .reason .empty ()) {
61
+ embed.add_field (" Reason" , event.entry .reason , false );
62
+ }
63
+ event.owner ->message_create (dpp::message (config[" log_channel_ids" ][" mod_log" ], embed));
64
+ }
65
+
66
+ dpp::task<> members::on_ban (const dpp::guild_audit_log_entry_create_t & event, const nlohmann::json& config) {
67
+ dpp::confirmation_callback_t user_conf = co_await event.owner ->co_user_get_cached (event.entry .target_id );
68
+ dpp::confirmation_callback_t mod_conf = co_await event.owner ->co_user_get_cached (event.entry .user_id );
69
+
70
+ dpp::embed embed = dpp::embed ().set_color (dpp::colors::red).set_title (" Manual Ban" );
71
+ if (!user_conf.is_error ()) {
72
+ dpp::user_identified user = std::get<dpp::user_identified>(user_conf.value );
73
+ embed.set_thumbnail (user.get_avatar_url ()).add_field (" User banned" , user.username , true );
74
+ }
75
+ embed.add_field (" User ID" , event.entry .target_id .str (), true );
76
+
77
+ if (mod_conf.is_error ()) {
78
+ embed.add_field (" Moderator ID" , event.entry .user_id .str (), false );
79
+ } else {
80
+ dpp::user_identified mod = std::get<dpp::user_identified>(mod_conf.value );
81
+ embed.add_field (" Banned by" , mod.global_name , false );
82
+ }
83
+
84
+ if (!event.entry .reason .empty ()) {
85
+ embed.add_field (" Reason" , event.entry .reason , false );
86
+ }
87
+ event.owner ->message_create (dpp::message (config[" log_channel_ids" ][" mod_log" ], embed));
88
+ }
89
+
90
+ dpp::task<> members::on_unban (const dpp::guild_audit_log_entry_create_t & event, const nlohmann::json& config) {
91
+ dpp::confirmation_callback_t user_conf = co_await event.owner ->co_user_get_cached (event.entry .target_id );
92
+ dpp::confirmation_callback_t mod_conf = co_await event.owner ->co_user_get_cached (event.entry .user_id );
93
+
94
+ dpp::embed embed = dpp::embed ().set_color (dpp::colors::green).set_title (" Ban Manually Removed" );
95
+ if (!user_conf.is_error ()) {
96
+ dpp::user_identified user = std::get<dpp::user_identified>(user_conf.value );
97
+ embed.set_thumbnail (user.get_avatar_url ()).add_field (" User unbanned" , user.username , true );
98
+ }
99
+ embed.add_field (" User ID" , event.entry .target_id .str (), true );
100
+
101
+ if (mod_conf.is_error ()) {
102
+ embed.add_field (" Moderator ID" , event.entry .user_id .str (), false );
103
+ } else {
104
+ dpp::user_identified mod = std::get<dpp::user_identified>(mod_conf.value );
105
+ embed.add_field (" Ban removed by" , mod.global_name , false );
106
+ }
107
+
108
+ if (!event.entry .reason .empty ()) {
109
+ embed.add_field (" Reason" , event.entry .reason , false );
110
+ }
111
+ event.owner ->message_create (dpp::message (config[" log_channel_ids" ][" mod_log" ], embed));
112
+ }
113
+
114
+ dpp::task<> members::on_join (const dpp::guild_member_add_t & event, const nlohmann::json& config, std::vector<dpp::invite>& invites) {
115
+ dpp::embed welcome_embed = dpp::embed ().set_color (dpp::colors::green).set_title (" New Member" )
116
+ .set_thumbnail (event.added .get_user ()->get_avatar_url ())
117
+ .set_description (event.added .get_user ()->global_name + " has joined Tech Support Central!" );
118
+ event.owner ->message_create (dpp::message (config[" log_channel_ids" ][" welcome" ], welcome_embed));
119
+
120
+ dpp::embed log_embed = dpp::embed ().set_color (dpp::colors::green).set_title (" Member Joined" )
121
+ .set_thumbnail (event.added .get_user ()->get_avatar_url ())
122
+ .set_description (event.added .get_user ()->username )
123
+ .add_field (" User ID" , event.added .user_id .str (), false )
124
+ .add_field (" Account Created:" , std::format (" <t:{}>" ,
125
+ static_cast <time_t >(event.added .get_user ()->get_creation_time ())), false );
126
+ dpp::invite invite_used = co_await findinvite (event.owner , event.adding_guild .id , invites);
127
+ if (invite_used.code != " unknown" ) {
128
+ log_embed.add_field (" Invite code" , invite_used.code , false );
129
+ if (invite_used.code == " 2vwUBmhM8U" ) {
130
+ log_embed.add_field (" Invite creator" , " top.gg" , true );
131
+ } else {
132
+ log_embed.add_field (" Invite creator" , invite_used.inviter .username , true );
133
+ }
134
+ log_embed.add_field (" Invite uses" , std::to_string (invite_used.uses ), true );
135
+ }
136
+ event.owner ->message_create (dpp::message (config[" log_channel_ids" ][" member_log" ], log_embed));
137
+ }
138
+
139
+ void members::on_leave (const dpp::guild_member_remove_t & event, const nlohmann::json& config) {
140
+ dpp::embed embed = dpp::embed ().set_color (dpp::colors::red).set_title (" Member Left" )
141
+ .set_thumbnail (event.removed .get_avatar_url ())
142
+ .set_description (event.removed .username + " has left Tech Support Central." )
143
+ .set_footer (dpp::embed_footer ().set_text (std::string (" User ID: " ) + event.removed .id .str ()));
144
+ event.owner ->message_create (dpp::message (config[" log_channel_ids" ][" member_log" ], embed));
145
+ }
0 commit comments