-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathBanInteractions.cs
193 lines (177 loc) · 9.41 KB
/
BanInteractions.cs
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
using static Cliptok.Helpers.BanHelpers;
namespace Cliptok.Commands.InteractionCommands
{
internal class BanInteractions : ApplicationCommandModule
{
[SlashCommand("ban", "Bans a user from the server, either permanently or temporarily.", defaultPermission: false)]
[SlashRequireHomeserverPerm(ServerPermLevel.Moderator), SlashCommandPermissions(permissions: DiscordPermission.BanMembers)]
public async Task BanSlashCommand(InteractionContext ctx,
[Option("user", "The user to ban")] DiscordUser user,
[Option("reason", "The reason the user is being banned")] string reason,
[Option("keep_messages", "Whether to keep the users messages when banning")] bool keepMessages = false,
[Option("time", "The length of time the user is banned for")] string time = null,
[Option("appeal_link", "Whether to show the user an appeal URL in the DM")] bool appealable = false,
[Option("compromised_account", "Whether to include special instructions for compromised accounts")] bool compromisedAccount = false
)
{
// Initial response to avoid the 3 second timeout, will edit later.
var eout = new DiscordInteractionResponseBuilder().AsEphemeral(true);
await ctx.CreateResponseAsync(DiscordInteractionResponseType.DeferredChannelMessageWithSource, eout);
// Edits need a webhook rather than interaction..?
DiscordWebhookBuilder webhookOut = new();
int messageDeleteDays = 7;
if (keepMessages)
messageDeleteDays = 0;
if (user.IsBot)
{
webhookOut.Content = $"{Program.cfgjson.Emoji.Error} To prevent accidents, I won't ban bots. If you really need to do this, do it manually in Discord.";
await ctx.EditResponseAsync(webhookOut);
return;
}
DiscordMember targetMember;
try
{
targetMember = await ctx.Guild.GetMemberAsync(user.Id);
if ((await GetPermLevelAsync(ctx.Member)) == ServerPermLevel.TrialModerator && ((await GetPermLevelAsync(targetMember)) >= ServerPermLevel.TrialModerator))
{
webhookOut.Content = $"{Program.cfgjson.Emoji.Error} As a Trial Moderator you cannot perform moderation actions on other staff members.";
await ctx.EditResponseAsync(webhookOut);
return;
}
}
catch
{
// do nothing :/
}
TimeSpan banDuration;
if (time is null)
banDuration = default;
else
{
try
{
banDuration = HumanDateParser.HumanDateParser.Parse(time).Subtract(ctx.Interaction.CreationTimestamp.DateTime);
}
catch
{
webhookOut.Content = $"{Program.cfgjson.Emoji.Error} There was an error parsing your supplied ban length!";
await ctx.EditResponseAsync(webhookOut);
return;
}
}
DiscordMember member;
try
{
member = await ctx.Guild.GetMemberAsync(user.Id);
}
catch
{
member = null;
}
if (member is null)
{
await BanFromServerAsync(user.Id, reason, ctx.User.Id, ctx.Guild, messageDeleteDays, ctx.Channel, banDuration, appealable, compromisedAccount);
}
else
{
if (DiscordHelpers.AllowedToMod(ctx.Member, member))
{
if (DiscordHelpers.AllowedToMod(await ctx.Guild.GetMemberAsync(ctx.Client.CurrentUser.Id), member))
{
await BanFromServerAsync(user.Id, reason, ctx.User.Id, ctx.Guild, messageDeleteDays, ctx.Channel, banDuration, appealable, compromisedAccount);
}
else
{
webhookOut.Content = $"{Program.cfgjson.Emoji.Error} I don't have permission to ban **{DiscordHelpers.UniqueUsername(user)}**!";
await ctx.EditResponseAsync(webhookOut);
return;
}
}
else
{
webhookOut.Content = $"{Program.cfgjson.Emoji.Error} You don't have permission to ban **{DiscordHelpers.UniqueUsername(user)}**!";
await ctx.EditResponseAsync(webhookOut);
return;
}
}
reason = reason.Replace("`", "\\`").Replace("*", "\\*");
if (banDuration == default)
await ctx.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} {user.Mention} has been banned: **{reason}**");
else
await ctx.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} {user.Mention} has been banned for **{TimeHelpers.TimeToPrettyFormat(banDuration, false)}**: **{reason}**");
webhookOut.Content = $"{Program.cfgjson.Emoji.Success} User was successfully bonked.";
await ctx.EditResponseAsync(webhookOut);
}
[SlashCommand("unban", "Unbans a user who has been previously banned.", defaultPermission: false)]
[SlashRequireHomeserverPerm(ServerPermLevel.Moderator), SlashCommandPermissions(permissions: DiscordPermission.BanMembers)]
public async Task SlashUnbanCommand(InteractionContext ctx, [Option("user", "The ID or mention of the user to unban. Ignore the suggestions, IDs work.")] SnowflakeObject userId, [Option("reason", "Used in audit log only currently")] string reason = "No reason specified.")
{
DiscordUser targetUser = default;
try
{
targetUser = await ctx.Client.GetUserAsync(userId.Id);
}
catch (Exception ex)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} Exception of type `{ex.GetType()}` thrown fetching user:\n```\n{ex.Message}\n{ex.StackTrace}```", ephemeral: true);
return;
}
if ((await Program.db.HashExistsAsync("bans", targetUser.Id)))
{
await UnbanUserAsync(ctx.Guild, targetUser, $"[Unban by {DiscordHelpers.UniqueUsername(ctx.User)}]: {reason}");
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Unbanned} Successfully unbanned **{DiscordHelpers.UniqueUsername(targetUser)}**.");
}
else
{
bool banSuccess = await UnbanUserAsync(ctx.Guild, targetUser);
if (banSuccess)
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Unbanned} Successfully unbanned **{DiscordHelpers.UniqueUsername(targetUser)}**.");
else
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} That user doesn't appear to be banned, *and* an error occurred while attempting to unban them anyway.\nPlease contact the bot owner if this wasn't expected, the error has been logged.");
}
}
}
[SlashCommand("kick", "Kicks a user, removing them from the server until they rejoin.", defaultPermission: false)]
[SlashRequireHomeserverPerm(ServerPermLevel.Moderator), SlashCommandPermissions(permissions: DiscordPermission.KickMembers)]
public async Task KickCmd(InteractionContext ctx, [Option("user", "The user you want to kick from the server.")] DiscordUser target, [Option("reason", "The reason for kicking this user.")] string reason = "No reason specified.")
{
if (target.IsBot)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} To prevent accidents, I won't kick bots. If you really need to do this, do it manually in Discord.");
return;
}
reason = reason.Replace("`", "\\`").Replace("*", "\\*");
DiscordMember member;
try
{
member = await ctx.Guild.GetMemberAsync(target.Id);
}
catch
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} That user doesn't appear to be in the server!");
return;
}
if (DiscordHelpers.AllowedToMod(ctx.Member, member))
{
if (DiscordHelpers.AllowedToMod(await ctx.Guild.GetMemberAsync(ctx.Client.CurrentUser.Id), member))
{
await Kick.KickAndLogAsync(member, reason, ctx.Member);
await ctx.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Ejected} {target.Mention} has been kicked: **{reason}**");
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Success} Done!", ephemeral: true);
return;
}
else
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} I don't have permission to kick **{DiscordHelpers.UniqueUsername(target)}**!", ephemeral: true);
return;
}
}
else
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} You aren't allowed to kick **{DiscordHelpers.UniqueUsername(target)}**!", ephemeral: true);
return;
}
}
}
}