Added ban command, improved regex matching for command name

This commit is contained in:
Deukhoofd 2018-03-30 15:41:42 +02:00
parent adf1766690
commit 3ac40ba00e
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
4 changed files with 50 additions and 10 deletions

View File

@ -14,7 +14,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler
public static class CommandHandler
{
public static Dictionary<string, Command> Commands { get; } = new Dictionary<string, Command>();
private const char CommandTrigger = '!';
public const char CommandTrigger = '!';
public static void Build()
{
@ -43,7 +43,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler
if (string.IsNullOrWhiteSpace(message.Content))
return;
if (message.Content[0] != CommandTrigger)
if (message.Content[0] != CommandTrigger && message.MentionedUsers.All(x => x.Id != Program.BotId))
return;
var req = await CommandRequest.Create(message);
@ -53,6 +53,9 @@ namespace DeukBot4.MessageHandlers.CommandHandler
case CommandRequest.RequestCode.Invalid:
await Logger.LogError("Invalid content: " + message.Content);
return;
case CommandRequest.RequestCode.InvalidParameters:
await Logger.LogError("Invalid parameters: " + message.Content);
break;
case CommandRequest.RequestCode.Forbidden:
await Logger.Log(
$"Unauthorized user tried to run command: {message.Author.Username} -> {message.Content}");
@ -67,21 +70,25 @@ namespace DeukBot4.MessageHandlers.CommandHandler
await req.Item1.Command.Invoke(req.Item1);
break;
case CommandRequest.RequestCode.UnknownCommand:
var similar = await GetSimilarCommand(req.Item3.ToString());
var permission = await PermissionValidator.GetUserPermissionLevel(message);
var similar = await GetSimilarCommand(req.Item3.ToString(), permission);
await message.Channel.SendMessageAsync(
$"Unknown command: ``{req.Item3.ToString()}``. Did you mean: ``{similar}``?");
$"Unknown command: ``{req.Item3.ToString()}``. Did you mean: ``{similar}``? " +
$"Alternatively, use ``{CommandTrigger}help`` for a list of all commands");
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private static async Task<string> GetSimilarCommand(string command)
private static async Task<string> GetSimilarCommand(string command, PermissionLevel permission)
{
var closestString = "";
var similarity = int.MaxValue;
foreach (var cmd in Commands)
{
if (cmd.Value.Permission > permission)
continue;
var distance = Lehvenstein.LevenshteinDistance(command, cmd.Key);
if (distance >= similarity)
continue;

View File

@ -47,5 +47,36 @@ namespace DeukBot4.MessageHandlers.CommandHandler
// and kick
await user.KickAsync(reason);
}
[Command("ban", PermissionLevel.Moderator)]
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].AsDiscordUser(channel.Guild);
// 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.OriginalMessage.Channel.SendMessageAsync("You are not allowed to ban 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 ban
await channel.Guild.AddBanAsync(user, 0, reason);
}
}
}

View File

@ -9,11 +9,11 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
{
public class CommandRequest
{
private const string CommandNamePattern = "!([a-zA-Z0-9_]*) *(.*)";
private static readonly string CommandNamePattern =
"(?:" + CommandHandler.CommandTrigger + "+|<@\\d*> !*)([^ ]+) *(.*)";
private static readonly Regex CommandNameMatcher = new Regex(CommandNamePattern);
public Command Command { get; }
//public string ParameterString { get; }
public SocketMessage OriginalMessage { get; }
public RequestParameter[] Parameters { get; private set; }
public PermissionLevel RequestPermissions { get; }
@ -28,7 +28,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
public enum RequestCode
{
OK, UnknownCommand, Invalid, Forbidden
OK, UnknownCommand, Invalid, Forbidden, InvalidParameters
}
public static async Task<(CommandRequest, RequestCode, object)> Create(SocketMessage message)
@ -64,7 +64,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
var parameters = ParameterMatcher.GetParameterValues(command, parameterString);
if (parameters == null)
{
return (null, RequestCode.Invalid, parameterString);
return (null, RequestCode.InvalidParameters, parameterString);
}
return (new CommandRequest(originalMessage, command, permission, parameters), RequestCode.OK, null);
}

View File

@ -9,10 +9,11 @@ using Discord.WebSocket;
namespace DeukBot4
{
class Program
internal static class Program
{
public static DiscordSocketClient Client { get; private set; }
public static Settings Settings { get; private set; }
public static ulong BotId { get; private set; }
private static void Main(string[] args)
{
@ -46,6 +47,7 @@ namespace DeukBot4
{
properties.Username = Settings.Username;
});
BotId = Client.CurrentUser.Id;
}
}
}