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 class CommandHandler
{ {
public static Dictionary<string, Command> Commands { get; } = new Dictionary<string, Command>(); public static Dictionary<string, Command> Commands { get; } = new Dictionary<string, Command>();
private const char CommandTrigger = '!'; public const char CommandTrigger = '!';
public static void Build() public static void Build()
{ {
@ -43,7 +43,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler
if (string.IsNullOrWhiteSpace(message.Content)) if (string.IsNullOrWhiteSpace(message.Content))
return; return;
if (message.Content[0] != CommandTrigger) if (message.Content[0] != CommandTrigger && message.MentionedUsers.All(x => x.Id != Program.BotId))
return; return;
var req = await CommandRequest.Create(message); var req = await CommandRequest.Create(message);
@ -53,6 +53,9 @@ namespace DeukBot4.MessageHandlers.CommandHandler
case CommandRequest.RequestCode.Invalid: case CommandRequest.RequestCode.Invalid:
await Logger.LogError("Invalid content: " + message.Content); await Logger.LogError("Invalid content: " + message.Content);
return; return;
case CommandRequest.RequestCode.InvalidParameters:
await Logger.LogError("Invalid parameters: " + message.Content);
break;
case CommandRequest.RequestCode.Forbidden: case CommandRequest.RequestCode.Forbidden:
await Logger.Log( await Logger.Log(
$"Unauthorized user tried to run command: {message.Author.Username} -> {message.Content}"); $"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); await req.Item1.Command.Invoke(req.Item1);
break; break;
case CommandRequest.RequestCode.UnknownCommand: 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( 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; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
} }
private static async Task<string> GetSimilarCommand(string command) private static async Task<string> GetSimilarCommand(string command, PermissionLevel permission)
{ {
var closestString = ""; var closestString = "";
var similarity = int.MaxValue; var similarity = int.MaxValue;
foreach (var cmd in Commands) foreach (var cmd in Commands)
{ {
if (cmd.Value.Permission > permission)
continue;
var distance = Lehvenstein.LevenshteinDistance(command, cmd.Key); var distance = Lehvenstein.LevenshteinDistance(command, cmd.Key);
if (distance >= similarity) if (distance >= similarity)
continue; continue;

View File

@ -47,5 +47,36 @@ namespace DeukBot4.MessageHandlers.CommandHandler
// and kick // and kick
await user.KickAsync(reason); 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 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); private static readonly Regex CommandNameMatcher = new Regex(CommandNamePattern);
public Command Command { get; } public Command Command { get; }
//public string ParameterString { get; }
public SocketMessage OriginalMessage { get; } public SocketMessage OriginalMessage { get; }
public RequestParameter[] Parameters { get; private set; } public RequestParameter[] Parameters { get; private set; }
public PermissionLevel RequestPermissions { get; } public PermissionLevel RequestPermissions { get; }
@ -28,7 +28,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
public enum RequestCode public enum RequestCode
{ {
OK, UnknownCommand, Invalid, Forbidden OK, UnknownCommand, Invalid, Forbidden, InvalidParameters
} }
public static async Task<(CommandRequest, RequestCode, object)> Create(SocketMessage message) 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); var parameters = ParameterMatcher.GetParameterValues(command, parameterString);
if (parameters == null) if (parameters == null)
{ {
return (null, RequestCode.Invalid, parameterString); return (null, RequestCode.InvalidParameters, parameterString);
} }
return (new CommandRequest(originalMessage, command, permission, parameters), RequestCode.OK, null); return (new CommandRequest(originalMessage, command, permission, parameters), RequestCode.OK, null);
} }

View File

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