More work

This commit is contained in:
Deukhoofd 2018-03-29 21:57:16 +02:00
parent 64776e18eb
commit ba1096be6d
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
12 changed files with 126 additions and 12 deletions

View File

@ -1,2 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=messagehandlers_005Cattributes/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=messagehandlers_005Cattributes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=messagehandlers_005Ccommandhandler_005Ccommands/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -0,0 +1,10 @@
using System;
namespace DeukBot4.MessageHandlers
{
[AttributeUsage(AttributeTargets.Method)]
public class BlockUsageInPmAttribute : Attribute
{
}
}

View File

@ -12,5 +12,20 @@ namespace DeukBot4.MessageHandlers
{ {
Types = types; Types = types;
} }
public CommandParametersAttribute(ParameterMatcher.ParameterType type)
{
Types = new []{type};
}
public CommandParametersAttribute(ParameterMatcher.ParameterType type, ParameterMatcher.ParameterType type2)
{
Types = new []{type, type2};
}
public CommandParametersAttribute(ParameterMatcher.ParameterType type, ParameterMatcher.ParameterType type2,
ParameterMatcher.ParameterType type3)
{
Types = new []{type, type2, type3};
}
} }
} }

View File

@ -9,7 +9,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler
{ {
public class Command public class Command
{ {
public Command(string name, PermissionLevel permission, string shortHelp, string longHelp, public Command(string name, PermissionLevel permission, string shortHelp, string longHelp, bool forbidInPm,
ParameterMatcher.ParameterType[][] parameterTypes, MethodInfo function, CommandContainerBase commandContainer) ParameterMatcher.ParameterType[][] parameterTypes, MethodInfo function, CommandContainerBase commandContainer)
{ {
Name = name; Name = name;
@ -20,9 +20,10 @@ namespace DeukBot4.MessageHandlers.CommandHandler
CommandContainer = commandContainer; CommandContainer = commandContainer;
ParameterTypes = parameterTypes; ParameterTypes = parameterTypes;
HasHelp = true; HasHelp = true;
ForbidInPm = forbidInPm;
} }
public Command(string name, PermissionLevel permission, ParameterMatcher.ParameterType[][] parameterTypes, public Command(string name, PermissionLevel permission, ParameterMatcher.ParameterType[][] parameterTypes, bool forbidInPm,
MethodInfo function, CommandContainerBase commandContainer) MethodInfo function, CommandContainerBase commandContainer)
{ {
Name = name; Name = name;
@ -31,6 +32,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler
CommandContainer = commandContainer; CommandContainer = commandContainer;
ParameterTypes = parameterTypes; ParameterTypes = parameterTypes;
HasHelp = false; HasHelp = false;
ForbidInPm = forbidInPm;
} }
public string Name { get; } public string Name { get; }
@ -41,6 +43,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler
public CommandContainerBase CommandContainer { get; } public CommandContainerBase CommandContainer { get; }
public bool HasHelp { get; } public bool HasHelp { get; }
public ParameterMatcher.ParameterType[][] ParameterTypes { get; } public ParameterMatcher.ParameterType[][] ParameterTypes { get; }
public bool ForbidInPm { get; }
private string[] _parameterMatchers; private string[] _parameterMatchers;

View File

@ -33,19 +33,21 @@ namespace DeukBot4.MessageHandlers.CommandHandler
parametersAttributes.ToArray(); parametersAttributes.ToArray();
var parameters = commandParametersAttributes.Select(x => x.Types).ToArray(); var parameters = commandParametersAttributes.Select(x => x.Types).ToArray();
var forbidPm = methodInfo.GetCustomAttributes(typeof(BlockUsageInPmAttribute), true).Any();
foreach (var commandAttribute in commandAttributes) foreach (var commandAttribute in commandAttributes)
{ {
if (commandAttribute == null) if (commandAttribute == null)
continue; continue;
if (helpAttribute == null) if (helpAttribute == null)
{ {
commands.Add(new Command(commandAttribute.Command, commandAttribute.Permission, parameters, commands.Add(new Command(commandAttribute.Command, commandAttribute.Permission, parameters, forbidPm,
methodInfo, this)); methodInfo, this));
} }
else else
{ {
commands.Add(new Command(commandAttribute.Command, commandAttribute.Permission, commands.Add(new Command(commandAttribute.Command, commandAttribute.Permission,
helpAttribute.ShortHelp, helpAttribute.LongHelp, parameters, methodInfo, this)); helpAttribute.ShortHelp, helpAttribute.LongHelp, forbidPm, parameters, methodInfo, this));
} }
} }

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using DeukBot4.MessageHandlers.CommandHandler.RequestStructure; using DeukBot4.MessageHandlers.CommandHandler.RequestStructure;
using DeukBot4.MessageHandlers.Permissions; using DeukBot4.MessageHandlers.Permissions;
using DeukBot4.Utilities; using DeukBot4.Utilities;
using Discord;
using Discord.WebSocket; using Discord.WebSocket;
namespace DeukBot4.MessageHandlers.CommandHandler namespace DeukBot4.MessageHandlers.CommandHandler
@ -53,10 +54,17 @@ namespace DeukBot4.MessageHandlers.CommandHandler
{ {
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}");
} }
else if (resultCode == CommandRequest.RequestCode.OK) else if (resultCode == CommandRequest.RequestCode.OK)
{ {
if (!(message.Channel is IGuildChannel) && req.Item1.Command.ForbidInPm)
{
await Logger.Log(
$"User is trying to use blocked command in PM: {message.Author.Username}");
return;
}
await req.Item1.Command.Invoke(req.Item1); await req.Item1.Command.Invoke(req.Item1);
} }

View File

@ -0,0 +1,55 @@
using System.Threading.Tasks;
using DeukBot4.MessageHandlers.CommandHandler.RequestStructure;
using DeukBot4.MessageHandlers.Permissions;
using Discord;
using Discord.WebSocket;
namespace DeukBot4.MessageHandlers.CommandHandler
{
public class ModeratorCommands : CommandContainerBase
{
public override string Name => "Moderator";
[Command("kick", PermissionLevel.Moderator)]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Remainder)]
[BlockUsageInPm]
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;
// if no parameters are found, stop
if (request.Parameters.Length == 0)
return;
// if the first parameter is empty, stop, this means it's not a valid user id
if (string.IsNullOrWhiteSpace(request.Parameters[0].AsString()))
return;
// get the id, this parses the string to an id
var id = request.Parameters[0].AsUlong();
// get the user using this id and the channel object.
var user = await channel.Guild.GetUserAsync(id);
// 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 this bot, 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 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);
}
}
}

View File

@ -14,6 +14,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler
[Command("roles", PermissionLevel.Admin)] [Command("roles", PermissionLevel.Admin)]
[CommandHelp("Lists all roles on the server along with their IDs", "Lists all roles on the server along with their IDs")] [CommandHelp("Lists all roles on the server along with their IDs", "Lists all roles on the server along with their IDs")]
[BlockUsageInPm]
public async Task ListServerRoles(CommandRequest request) public async Task ListServerRoles(CommandRequest request)
{ {
var channel = request.OriginalMessage.Channel; var channel = request.OriginalMessage.Channel;

View File

@ -12,6 +12,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
Word, Word,
Number, Number,
Remainder, Remainder,
User,
} }
public static string[] GenerateRegex(Command command) public static string[] GenerateRegex(Command command)
@ -38,6 +39,8 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
return " *(\\d+)"; return " *(\\d+)";
case ParameterType.Remainder: case ParameterType.Remainder:
return " *(.*)"; return " *(.*)";
case ParameterType.User:
return " *(?:<@(?<id>\\d*)>)|(?<id>\\d*)";
default: default:
throw new ArgumentOutOfRangeException(nameof(type), type, null); throw new ArgumentOutOfRangeException(nameof(type), type, null);
} }

View File

@ -24,5 +24,14 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
{ {
return _value; return _value;
} }
public ulong AsUlong()
{
if (ulong.TryParse(_value, out var i))
{
return i;
}
throw new ArgumentException();
}
} }
} }

View File

@ -80,25 +80,32 @@ namespace DeukBot4.MessageHandlers.Permissions
public static async Task<PermissionLevel> GetUserPermissionLevel(SocketMessage message) public static async Task<PermissionLevel> GetUserPermissionLevel(SocketMessage message)
{ {
if (message.Author.Id == Program.Settings.OwnerId) return await GetUserPermissionLevel(message.Channel, message.Author);
}
public static async Task<PermissionLevel> GetUserPermissionLevel(ISocketMessageChannel channel, SocketUser user)
{
if (user.Id == Program.Settings.OwnerId)
{ {
return PermissionLevel.BotCreator; return PermissionLevel.BotCreator;
} }
if (message.Author.IsBot) if (user.IsBot)
{ {
return PermissionLevel.Bot; return PermissionLevel.Bot;
} }
if (!(message.Channel is IGuildChannel serverChannel)) if (!(channel is IGuildChannel serverChannel))
return PermissionLevel.Everyone; return PermissionLevel.Everyone;
if (serverChannel.Guild.OwnerId == message.Author.Id)
if (serverChannel.Guild.OwnerId == user.Id)
return PermissionLevel.ServerOwner; return PermissionLevel.ServerOwner;
if (!(message.Author is IGuildUser user)) if (!(user is IGuildUser guildUser))
return PermissionLevel.Everyone; return PermissionLevel.Everyone;
var perms = await GetDatabasePermissionLevel(serverChannel.GuildId, user.RoleIds.ToArray()); var perms = await GetDatabasePermissionLevel(serverChannel.GuildId, guildUser.RoleIds.ToArray());
return perms; return perms;
} }
} }
} }