diff --git a/src/main/java/net/pingex/dcf/permissions/PermissionsCommands.java b/src/main/java/net/pingex/dcf/permissions/PermissionsCommands.java index de35167..e0cd221 100644 --- a/src/main/java/net/pingex/dcf/permissions/PermissionsCommands.java +++ b/src/main/java/net/pingex/dcf/permissions/PermissionsCommands.java @@ -11,7 +11,6 @@ import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IRole; import sx.blah.discord.handle.obj.IUser; import java.util.*; -import java.util.regex.Pattern; /** * Commands for the permissions package. @@ -30,13 +29,10 @@ public class PermissionsCommands implements IWithCommands new Command.Builder("perm:canRun") .description("Tells whether target user is allowed to run the command.") .enabled(true) - .usage("Command [verbose]") + .usage("Command [verbose]") .defaultPermission(DefaultPermission.BOT_OWNER) .build(PermissionsCommands::isAllowedImpl); - private static Pattern usernamePattern = Pattern.compile("^.*#\\d{4}$"); - private static Pattern idPattern = Pattern.compile("^\\d{18}$"); - private static void isAllowedImpl(MessageReceivedEvent event, List arguments) { // Parameters @@ -46,15 +42,8 @@ public class PermissionsCommands implements IWithCommands IGuild targetGuild = null; ICommandPermissionsProvider provider = PermissionsHandler.getProvider(); - try - { - targetGuild = event.getMessage().getGuild(); - } - catch(UnsupportedOperationException ignored) // DM NOP - {} - // Argchk size - if(arguments.size() != 2 && arguments.size() != 3) + if(arguments.size() != 3 && arguments.size() != 4) { DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "Invalid arguments."); return; @@ -70,28 +59,50 @@ public class PermissionsCommands implements IWithCommands else target = uncheckedTarget.get(); // Argchk#2 - uid OR username#1234 OR "me" - Optional uncheckedUser = Optional.empty(); - if(arguments.get(1).equalsIgnoreCase("me")) - userToLookup = event.getMessage().getAuthor(); + if(arguments.get(1).equalsIgnoreCase("me")) userToLookup = event.getMessage().getAuthor(); // me else // Anything else try { - uncheckedUser = ArgumentParser.checkParseUsernameOrID(arguments.get(1), event.getClient()); + Optional uncheckedUser = ArgumentParser.checkParseUsernameOrID(arguments.get(1), event.getClient()); + + if(uncheckedUser.isPresent()) userToLookup = uncheckedUser.get(); + else + { + DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "User not found."); + return; + } } catch(ArgumentParser.ParserException e) { DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "Invalid arguments."); return; } - if(!uncheckedUser.isPresent()) + + // Argchk#3 - Guild + if(arguments.get(2).equalsIgnoreCase("this")) + try + { + targetGuild = event.getMessage().getGuild(); // this + } + catch(UnsupportedOperationException ignored) // DM + { + DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "`this` is not supported outside a guild."); + return; + } + else if(arguments.get(2).equals("*")) targetGuild = null; // Global - ~NOP + else // Parse Name/ID { - DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "User not found."); - return; + Optional uncheckedGuild = ArgumentParser.checkParseGuildOrID(arguments.get(2), event.getClient()); + if(uncheckedGuild.isPresent()) targetGuild = uncheckedGuild.get(); + else + { + DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "Guild not found."); + return; + } } - userToLookup = uncheckedUser.get(); - // Argchk#3 - verbosity - if(arguments.size() == 3) verbose = true; + // Argchk#4 - verbosity + if(arguments.size() == 4) verbose = true; // ======================================== @@ -196,37 +207,44 @@ public class PermissionsCommands implements IWithCommands else targetCommand = uncheckedCommand.get(); // Argchk#2 User#Disc/UID - Optional uncheckedUser = Optional.empty(); try { - uncheckedUser = ArgumentParser.checkParseUsernameOrID(arguments.get(1), event.getClient()); + Optional uncheckedUser = ArgumentParser.checkParseUsernameOrID(arguments.get(1), event.getClient()); + + if(uncheckedUser.isPresent()) targetUser = uncheckedUser.get(); + else + { + DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "User not found."); + return; + } } catch(ArgumentParser.ParserException e) { DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "Invalid arguments."); return; } - if(!uncheckedUser.isPresent()) - { - DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "User not found."); - return; - } - else targetUser = uncheckedUser.get(); // Argchk#3 Guild - if(arguments.get(2).equalsIgnoreCase("this")) targetGuild = event.getMessage().getGuild(); // this - else if(arguments.get(2).matches("^\\d{18}$")) targetGuild = event.getClient().getGuildByID(arguments.get(2)); // GID - else - for(IGuild i : event.getClient().getGuilds()) // Name - if(arguments.get(2).equalsIgnoreCase(i.getName())) - { - targetGuild = i; - break; - } - if(targetGuild == null && !arguments.get(2).equals("*")) // Global + if(arguments.get(2).equalsIgnoreCase("this")) + try + { + targetGuild = event.getMessage().getGuild(); // this + } + catch(UnsupportedOperationException ignored) // DM + { + DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "`this` is not supported outside a guild."); + return; + } + else if(arguments.get(2).equals("*")) targetGuild = null; // Global - ~NOP + else // Parse Name/ID { - DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "Guild not found."); - return; + Optional uncheckedGuild = ArgumentParser.checkParseGuildOrID(arguments.get(2), event.getClient()); + if(uncheckedGuild.isPresent()) targetGuild = uncheckedGuild.get(); + else + { + DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "Guild not found."); + return; + } } // Argchk#4 true/false/null diff --git a/src/main/java/net/pingex/dcf/util/ArgumentParser.java b/src/main/java/net/pingex/dcf/util/ArgumentParser.java index 489e9d9..6755e77 100644 --- a/src/main/java/net/pingex/dcf/util/ArgumentParser.java +++ b/src/main/java/net/pingex/dcf/util/ArgumentParser.java @@ -2,6 +2,7 @@ package net.pingex.dcf.util; import org.apache.commons.lang3.ClassUtils; import sx.blah.discord.api.IDiscordClient; +import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IUser; import java.util.ArrayList; import java.util.List; @@ -117,6 +118,34 @@ public class ArgumentParser return Optional.ofNullable(foundUser); } + /** + * Binds a guild or an ID to an actual {@link IGuild}. + * The following guild input formats are allowed: + *
    + *
  • 18-digit UID: "123456789012345678"
  • + *
  • Guild name: "Discord Developers"
  • + *
+ * + * @param input String to parse + * @param client Discord instance to look for guilds + * @return A filled Optional when a guild was found, an empty one otherwise. + */ + public static Optional checkParseGuildOrID(String input, IDiscordClient client) + { + IGuild foundGuild = null; + + if(idPattern.matcher(input).matches()) foundGuild = client.getGuildByID(input); // ID + else + for(IGuild i : client.getGuilds()) // Name + if(input.equalsIgnoreCase(i.getName())) + { + foundGuild = i; + break; + } + + return Optional.ofNullable(foundGuild); + } + /** * Thrown whenever any parse operation failed. */