Introducing Command Scopes.

Command Scopes allows to reject/accept an invoked command before it gets executed based on the originating channel.
keep-around/c2ad1056d9638eb2b3dbb39f2be4e03c2244b492
Pingex aka Raphaël 9 years ago
parent b935767eec
commit c2ad1056d9

@ -42,4 +42,9 @@ public @interface AnnotatedCommand
* Default permission, ie. when the permissions provider doesn't return anything. * Default permission, ie. when the permissions provider doesn't return anything.
*/ */
DefaultPermission defaultPermission() default DefaultPermission.EVERYONE; DefaultPermission defaultPermission() default DefaultPermission.EVERYONE;
/**
* Tells where the command should run, ie. PM or guild chat, or both
*/
CommandScope scope() default CommandScope.NOWHERE;
} }

@ -42,6 +42,11 @@ public abstract class Command implements ICommandExecutor
*/ */
private DefaultPermission defaultPermission; private DefaultPermission defaultPermission;
/**
* Tells where the command should run, ie. PM or guild chat, or both
*/
private CommandScope commandScope;
/** /**
* Basic constructor. * Basic constructor.
* @param name Name of the command * @param name Name of the command
@ -50,8 +55,9 @@ public abstract class Command implements ICommandExecutor
* @param isEnabled Is the command enabled ? * @param isEnabled Is the command enabled ?
* @param usage Command usage help * @param usage Command usage help
* @param defaultPermission Default permission, ie. when the permissions provider doesn't return anything. * @param defaultPermission Default permission, ie. when the permissions provider doesn't return anything.
* @param commandScope Tells where the command should run, ie. PM or guild chat, or both
*/ */
public Command(String name, List<String> aliases, String description, boolean isEnabled, String usage, DefaultPermission defaultPermission) public Command(String name, List<String> aliases, String description, boolean isEnabled, String usage, DefaultPermission defaultPermission, CommandScope commandScope)
{ {
this.name = name; this.name = name;
this.aliases = aliases; this.aliases = aliases;
@ -59,6 +65,7 @@ public abstract class Command implements ICommandExecutor
this.isEnabled = isEnabled; this.isEnabled = isEnabled;
this.usage = usage; this.usage = usage;
this.defaultPermission = defaultPermission; this.defaultPermission = defaultPermission;
this.commandScope = commandScope;
} }
/** /**
@ -71,6 +78,7 @@ public abstract class Command implements ICommandExecutor
public static final boolean IS_ENABLED = true; public static final boolean IS_ENABLED = true;
public static final String USAGE = "No command usage provided."; public static final String USAGE = "No command usage provided.";
public static final DefaultPermission DEFAULT_PERMISSION = DefaultPermission.EVERYONE; public static final DefaultPermission DEFAULT_PERMISSION = DefaultPermission.EVERYONE;
public static final CommandScope COMMAND_SCOPE = CommandScope.NOWHERE; // NOWHERE is enforced as a default value to force devs to specify a real scope.
} }
/** /**
@ -108,6 +116,11 @@ public abstract class Command implements ICommandExecutor
*/ */
private DefaultPermission defaultPermission = Defaults.DEFAULT_PERMISSION; private DefaultPermission defaultPermission = Defaults.DEFAULT_PERMISSION;
/**
* Tells where the command should run, ie. PM or guild chat, or both
*/
private CommandScope commandScope = Defaults.COMMAND_SCOPE;
public Builder(String name) public Builder(String name)
{ {
this.name = name; this.name = name;
@ -153,6 +166,12 @@ public abstract class Command implements ICommandExecutor
return this; return this;
} }
public Builder commandScope(CommandScope commandScope)
{
this.commandScope = commandScope;
return this;
}
/** /**
* Build a new Command using a supplied executor. * Build a new Command using a supplied executor.
* @param toExecute The body of the command. * @param toExecute The body of the command.
@ -160,7 +179,7 @@ public abstract class Command implements ICommandExecutor
*/ */
public Command build(ICommandExecutor toExecute) public Command build(ICommandExecutor toExecute)
{ {
return new Command(name, aliases, description, isEnabled, usage, defaultPermission) return new Command(name, aliases, description, isEnabled, usage, defaultPermission, commandScope)
{ {
@Override @Override
public void execute(MessageReceivedEvent event, List<String> arguments) throws Throwable public void execute(MessageReceivedEvent event, List<String> arguments) throws Throwable
@ -178,7 +197,7 @@ public abstract class Command implements ICommandExecutor
*/ */
public Command build(Method target, Object invokable) public Command build(Method target, Object invokable)
{ {
return new Command(name, aliases, description, isEnabled, usage, defaultPermission) return new Command(name, aliases, description, isEnabled, usage, defaultPermission, commandScope)
{ {
@Override @Override
public void execute(MessageReceivedEvent event, List<String> arguments) throws Throwable public void execute(MessageReceivedEvent event, List<String> arguments) throws Throwable
@ -212,6 +231,7 @@ public abstract class Command implements ICommandExecutor
.enabled(meta.isEnabled()) .enabled(meta.isEnabled())
.usage(meta.usage()) .usage(meta.usage())
.defaultPermission(meta.defaultPermission()) .defaultPermission(meta.defaultPermission())
.commandScope(meta.scope())
.build(target, invokable); .build(target, invokable);
} }
@ -245,6 +265,11 @@ public abstract class Command implements ICommandExecutor
return defaultPermission; return defaultPermission;
} }
public CommandScope getScope()
{
return commandScope;
}
public void setEnabled(boolean enabled) public void setEnabled(boolean enabled)
{ {
isEnabled = enabled; isEnabled = enabled;

@ -75,6 +75,14 @@ public class CommandHandler
return; return;
} }
// Scope check
if(!targetCommand.get().getScope().test(event.getMessage().getChannel()))
{
LOGGER.debug("User {} attempted to run a command outside of its intended scope.", event.getMessage().getAuthor().getID());
DiscordInteractionsUtil.sendMessage(event.getMessage().getChannel(), "Cannot run this command outside of its intended scope. Valid scope is: " + targetCommand.get().getScope() + ".");
return;
}
// Authorize // Authorize
if(!PermissionsHandler.canRunCommand(event.getMessage(), targetCommand.get())) if(!PermissionsHandler.canRunCommand(event.getMessage(), targetCommand.get()))
{ {

@ -0,0 +1,45 @@
package net.pingex.dcf.commands;
import sx.blah.discord.handle.obj.IChannel;
import java.util.function.Predicate;
/**
* CommandScope allows devs to tell where Commands should run.
* ie. PM, guild chat, etc
*/
public enum CommandScope
{
/**
* Allows only in a guild chat
*/
GUILD_CHAT(iChannel -> !iChannel.isPrivate()),
/**
* Only via PM with the bot
*/
PRIVATE_MESSAGE(IChannel::isPrivate),
/**
* Allows unconditionally
*/
ANYWHERE(iChannel -> true),
/**
* Denies unconditionally
* Default value
*/
NOWHERE(iChannel -> false);
private Predicate<IChannel> channel;
CommandScope(Predicate<IChannel> channel)
{
this.channel = channel;
}
public boolean test(IChannel iChannel)
{
return channel.test(iChannel);
}
}

@ -32,6 +32,7 @@ public class InternalCommands implements IWithCommands
private static final boolean IS_ENABLED = true; private static final boolean IS_ENABLED = true;
private static final String USAGE = "Page"; private static final String USAGE = "Page";
private static final DefaultPermission DEFAULT_PERMISSION = DefaultPermission.EVERYONE; private static final DefaultPermission DEFAULT_PERMISSION = DefaultPermission.EVERYONE;
private static final CommandScope COMMAND_SCOPE = CommandScope.ANYWHERE;
/** /**
* How many commands should be displayed on each page * How many commands should be displayed on each page
@ -42,7 +43,7 @@ public class InternalCommands implements IWithCommands
private ListCommand() private ListCommand()
{ {
super(NAME, ALIASES, DESCRIPTION, IS_ENABLED, USAGE, DEFAULT_PERMISSION); super(NAME, ALIASES, DESCRIPTION, IS_ENABLED, USAGE, DEFAULT_PERMISSION, COMMAND_SCOPE);
} }
@Override @Override
@ -113,12 +114,13 @@ public class InternalCommands implements IWithCommands
private static final boolean IS_ENABLED = true; private static final boolean IS_ENABLED = true;
private static final String USAGE = "Command"; private static final String USAGE = "Command";
private static final DefaultPermission DEFAULT_PERMISSION = DefaultPermission.EVERYONE; private static final DefaultPermission DEFAULT_PERMISSION = DefaultPermission.EVERYONE;
private static final CommandScope COMMAND_SCOPE = CommandScope.ANYWHERE;
static final UsageCommand INSTANCE = new UsageCommand(); static final UsageCommand INSTANCE = new UsageCommand();
private UsageCommand() private UsageCommand()
{ {
super(NAME, ALIASES, DESCRIPTION, IS_ENABLED, USAGE, DEFAULT_PERMISSION); super(NAME, ALIASES, DESCRIPTION, IS_ENABLED, USAGE, DEFAULT_PERMISSION, COMMAND_SCOPE);
} }
@Override @Override