DeukBot4/DeukBot4/MessageHandlers/CommandHandler/Commands/ModeratorCommands.cs

315 lines
14 KiB
C#

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DeukBot4.Database;
using DeukBot4.Database.ServerSettings;
using DeukBot4.MessageHandlers.CommandHandler.RequestStructure;
using DeukBot4.MessageHandlers.Permissions;
using DeukBot4.Utilities;
using Discord;
using Discord.WebSocket;
#pragma warning disable 4014
namespace DeukBot4.MessageHandlers.CommandHandler
{
public class ModeratorCommands : CommandContainerBase
{
public override string Name => "Moderator";
[Command("purge", PermissionLevel.Moderator)]
[CommandHelp("Purges a set number of messages",
"Purges a set number of messages. \n" +
"Usage: \n" +
"``!purge {number}`")]
[CommandParameters(ParameterMatcher.ParameterType.Number)]
[BlockUsageInPm, RequireParameterMatch]
public async Task PurgeMessages(CommandRequest request)
{
// get the server channel object out of message. Return if it's somehow not a server channel
if (!(request.OriginalMessage.Channel is ITextChannel channel))
return;
var messageCountParameter = request.Parameters[0].AsInt();
if (!messageCountParameter.HasValue)
return;
var messageCount = messageCountParameter.Value;
var messages = channel.GetMessagesAsync(request.OriginalMessage, Direction.Before, messageCount);
messages.ForEachAsync(x =>
{
foreach (var message in x)
{
message.DeleteAsync();
}
});
}
[Command("kick", PermissionLevel.Moderator)]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Remainder)]
[CommandHelp("Kicks a user from the server",
"Kicks a user from the server. Will not work on people with a helper role, or higher.\n" +
"Usage: \n" +
"``!kick {User Mention} {optional: Reason}``\n" +
"``!kick {User ID} {optional: Reason}``")]
[BlockUsageInPm, RequireParameterMatch]
public async Task KickUser(CommandRequest request)
{
// get the server channel object out of message. Return if it's somehow not a server channel
if (!(request.OriginalMessage.Channel is IGuildChannel channel))
return;
// get the id of the user, this parses the string to an id
var user = await request.Parameters[0].AsDiscordGuildUser(channel.Guild);
if (user == null)
{
await request.SendSimpleEmbed("Kick", "I can't find that user on the server");
return;
}
// get the permissions of the user we want to kick
var userPermissions =
await PermissionValidator.GetUserPermissionLevel(request.OriginalMessage.Channel, (SocketUser) user);
// if the user has sufficient permissions, or is deukbot, warn the user that he's not allowed to do that, and stop
if (userPermissions >= PermissionLevel.Helper || user.Id == Program.Client.CurrentUser.Id)
{
await request.SendSimpleEmbed("Kick", "You are not allowed to kick that user");
return;
}
// see if a reason was given, use that if so
var reason = string.Empty;
if (request.Parameters.Length >= 2)
{
reason = request.Parameters[1].AsString();
}
// and kick
await user.KickAsync(reason);
await request.SendSimpleEmbed("Kick", $"User was kicked: {user.Username}");
}
[Command("ban", PermissionLevel.Moderator)]
[CommandHelp("Bans a user from the server",
"Bans a user from the server. Will not work on people with a helper role, or higher.\n" +
"Usage: \n" +
"``ban {User Mention} {optional: Reason}``\n" +
"``ban {User ID} {optional: Reason}``")]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Remainder)]
[BlockUsageInPm, RequireParameterMatch]
public async Task BanUser(CommandRequest request)
{
// get the server channel object out of message. Return if it's somehow not a server channel
if (!(request.OriginalMessage.Channel is IGuildChannel channel))
return;
// get the id of the user, this parses the string to an id
var user = await request.Parameters[0].AsDiscordGuildUser(channel.Guild);
if (user != null)
{
// get the permissions of the user we want to kick
var userPermissions =
await PermissionValidator.GetUserPermissionLevel(request.OriginalMessage.Channel, (SocketUser) user);
// if the user has sufficient permissions, or is deukbot, warn the user that he's not allowed to do that, and stop
if (userPermissions >= PermissionLevel.Helper || user.Id == Program.Client.CurrentUser.Id)
{
await request.SendSimpleEmbed("Ban", "You are not allowed to ban that user");
return;
}
}
var userId = request.Parameters[0].AsUlong();
if (!userId.HasValue)
return;
// see if a reason was given, use that if so
var reason = string.Empty;
if (request.Parameters.Length >= 2)
{
reason = request.Parameters[1].AsString();
}
if (user != null)
{
string desc = "No reason was given.";
if (!string.IsNullOrWhiteSpace(reason))
{
desc = "The given reason was: " + reason;
}
var eb = EmbedFactory.GetStandardEmbedBuilder();
eb.Title = "Ban";
eb.Description = desc;
user.SendMessageAsync("", embed: eb.Build());
}
// and ban
await channel.Guild.AddBanAsync(userId.Value, 0, reason, RequestOptions.Default);
await request.SendSimpleEmbed("Ban", $"User was banned: <@!{userId}>");
}
[Command("silence", PermissionLevel.Helper)]
[Command("mute", PermissionLevel.Helper)]
[Command("timeout", PermissionLevel.Helper)]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Timespan)]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Number)]
[CommandParameters(ParameterMatcher.ParameterType.User)]
[CommandHelp("Silences a user for a set amount of time",
"Allows you to mute a user for a set amount of time.\n." +
"Usage:\n" +
"``mute {User Mention} {amount of minutes to silence}``\n" +
"``mute {User ID} {amount of minutes to silence}``\n" +
"``mute {User Mention} {Timespan (amount + time indicator: i.e. 5s, 10m, 3h, 1d)}``\n" +
"``mute {User ID} {Timespan (amount + time indicator: i.e. 5s, 10m, 3h, 1d)}``\n")]
[BlockUsageInPm]
public async Task SilenceUser(CommandRequest request)
{
// get the server channel object out of message. Return if it's somehow not a server channel
if (!(request.OriginalMessage.Channel is IGuildChannel channel))
return;
// get the id of the user, this parses the string to an id
var user = await request.Parameters[0].AsDiscordGuildUser(channel.Guild);
if (user == null)
{
await request.SendSimpleEmbed("Silence", "I can't find that user on the server");
return;
}
TimeSpan span;
if (request.Parameters.Length == 1)
{
span = TimeSpan.FromMinutes(5);
}
else
{
switch (request.Parameters[1].Type)
{
case ParameterMatcher.ParameterType.Number:
var minutes = request.Parameters[1].AsInt();
if (!minutes.HasValue)
return;
span = TimeSpan.FromMinutes(minutes.Value);
break;
case ParameterMatcher.ParameterType.Timespan:
var sp = TimespanHelper.Parse(request.Parameters[1].AsString());
if (sp.HasValue)
{
span = sp.Value;
}
else
{
return;
}
break;
default:
return;
}
}
var msg = await SilenceUser(user, request.OriginalMessage.Author, span);
if (msg != null)
{
request.SendSimpleEmbed("Silence", msg);
}
}
[Command("warn", PermissionLevel.Helper)]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Remainder)]
[BlockUsageInPm, RequireParameterMatch]
public async Task WarnUser(CommandRequest request)
{
// get the server channel object out of message. Return if it's somehow not a server channel
if (!(request.OriginalMessage.Channel is IGuildChannel channel))
return;
// get the id of the user, this parses the string to an id
var user = await request.Parameters[0].AsDiscordGuildUser(channel.Guild);
if (user == null)
{
await request.SendSimpleEmbed("Warn", "I can't find that user on the server");
return;
}
var message = request.Parameters[1].AsString();
if (string.IsNullOrWhiteSpace(message))
{
await request.SendSimpleEmbed("Warn", "A warning can't be empty!");
return;
}
await WarnHandler.AddWarning(channel.GuildId, user.Id, message);
var warnEmbed = EmbedFactory.GetStandardEmbedBuilder();
warnEmbed.Title = $"Warning from the {channel.Guild.Name} server!";
warnEmbed.Description = message;
await user.SendMessageAsync(embed: warnEmbed.Build());
request.SendSimpleEmbed("Warn", "User was warned!");
}
[Command("warns", PermissionLevel.Helper)]
[CommandParameters(ParameterMatcher.ParameterType.User)]
[BlockUsageInPm, RequireParameterMatch]
public async Task GetUserWarns(CommandRequest request)
{
// get the server channel object out of message. Return if it's somehow not a server channel
if (!(request.OriginalMessage.Channel is IGuildChannel channel))
return;
// get the id of the user, this parses the string to an id
var user = await request.Parameters[0].AsDiscordGuildUser(channel.Guild);
if (user == null)
{
await request.SendSimpleEmbed("Warn", "I can't find that user on the server");
return;
}
var warnings = await WarnHandler.GetWarnings(channel.GuildId, user.Id);
var eb = EmbedFactory.GetStandardEmbedBuilder();
eb.Title = $"Warnings for User";
eb.Author = new EmbedAuthorBuilder()
{
Name = user.Username,
IconUrl = user.GetAvatarUrl()
};
var desc = new StringBuilder();
foreach (var warn in warnings)
{
desc.Append($"**{warn.Id} -** {warn.Message}\r\n");
}
eb.Description = desc.ToString();
request.OriginalMessage.Channel.SendMessageAsync("", embed: eb.Build());
}
private static async Task<string> SilenceUser(IGuildUser user, IUser author, TimeSpan span)
{
if (user.Id == Program.BotId)
{
return "Stop trying to mute me.";
}
if (user.Id == author.Id)
return "You can't mute yourself...";
if (span.TotalHours > 24)
return "Can't mute for that long.";
var silencedRoleId = ServerSettingHandler.GetSettings(user.GuildId).MutedRoleId;
if (silencedRoleId == 0)
{
return
"No silenced role has been set. The server owner should do ``!silencedrole {role id}`` to set one first.";
}
var silencedRole = user.Guild.GetRole(silencedRoleId);
if (silencedRole == null)
{
return "Can't find the silenced role. Has it been deleted?";
}
await user.AddRoleAsync(silencedRole);
if (span.TotalSeconds <= 0)
span = TimeSpan.FromMinutes(5);
await Task.Delay(span);
await user.RemoveRoleAsync(silencedRole);
return null;
}
}
}