Plugin <=> CommandSystem interaction.

keep-around/d31701866686f66088b78de2e29736ae36e55a68
Pingex aka Raphaël 9 years ago
parent 2b0238dff1
commit 279d8aae13

@ -0,0 +1,39 @@
package net.pingex.dcf.commands;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicated a method which is in fact a command
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AnnotatedCommand
{
/**
* Main name of the command
*/
String name();
/**
* Command can also be called using the following list of aliases
*/
String[] aliases() default {};
/**
* Description of the command.
*/
String description() default Command.Defaults.DESCRIPTION;
/**
* Is the command enabled ? Can it be invoked ?
*/
boolean isEnabled() default Command.Defaults.IS_ENABLED;
/**
* Command usage help
*/
String usage() default Command.Defaults.USAGE;
}

@ -1,5 +1,6 @@
package net.pingex.dcf.commands;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -141,12 +142,23 @@ public abstract class Command implements ICommandExecutor
return new Command(name, aliases, description, isEnabled, usage)
{
@Override
public void execute(List<String> arguments)
public void execute(List<String> arguments) throws Throwable
{
toExecute.execute(arguments);
}
};
}
/**
* Build a new Command using a method and a target object (for use with annotated command)
* @param target The method which needs to be invoked
* @param invokable The matching object
* @return Built command.
*/
public Command build(Method target, Object invokable)
{
return build(arguments -> target.invoke(invokable));
}
}
/**
@ -159,6 +171,21 @@ public abstract class Command implements ICommandExecutor
return new Builder(name);
}
/**
* Create a new command object from an annotated method
* @param target Target method
* @return A new created command built from the method, or `null` if the method is not a valid command.
*/
public static Command buildFromAnnotatedCommand(AnnotatedCommand meta, Method target, Object invokable)
{
return builder(meta.name())
.aliases(Arrays.asList(meta.aliases()))
.description(meta.description())
.enabled(meta.isEnabled())
.usage(meta.usage())
.build(target, invokable);
}
public String getName()
{
return name;

@ -3,9 +3,11 @@ package net.pingex.dcf.commands;
import net.pingex.dcf.commands.parser.BasicParser;
import net.pingex.dcf.commands.parser.ICommandParser;
import net.pingex.dcf.commands.parser.ParserException;
import net.pingex.dcf.modularity.PluginWrapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import sx.blah.discord.handle.impl.events.MessageReceivedEvent;
import java.lang.reflect.Method;
import java.util.List;
/**
@ -41,7 +43,42 @@ public class CommandHandler
return; // Not a command
}
LOGGER.debug("Attempting to run command {} by user #{}.", command, event.getMessage().getAuthor().getID());
}
/**
* Registers a plugin's commands, if any
* @param pluginWrapper Target plugin
*/
public static void registerPlugin(PluginWrapper pluginWrapper)
{
LOGGER.debug("Registering commands for plugin {}.", pluginWrapper.getId());
// Raw commands
if(IWithCommands.class.isAssignableFrom(pluginWrapper.getInstance().getClass()))
{
LOGGER.debug("Plugin has commands (raw commands).");
((IWithCommands) pluginWrapper.getInstance()).getCommands().forEach(CommandRegistry::registerCommand);
}
// Annotated commands
if(IWithAnnotatedCommands.class.isAssignableFrom(pluginWrapper.getInstance().getClass()))
{
LOGGER.debug("Plugin has commands (annotated commands).");
((IWithAnnotatedCommands) pluginWrapper.getInstance()).getAnnotatedObjects().forEach(e ->
{
for(Method i : e.getClass().getMethods())
if(i.isAnnotationPresent(AnnotatedCommand.class))
CommandRegistry.registerCommand(Command.buildFromAnnotatedCommand(i.getAnnotation(AnnotatedCommand.class), i, e));
});
}
}
/**
* Unregisters a plugin's commands, if any
* @param pluginWrapper Target plugin
*/
public static void unregisterPlugin(PluginWrapper pluginWrapper)
{
LOGGER.debug("Removing commands for plugin {}.", pluginWrapper.getId());
}
}

@ -8,5 +8,5 @@ import java.util.List;
@FunctionalInterface
public interface ICommandExecutor
{
void execute(List<String> arguments);
void execute(List<String> arguments) throws Throwable;
}

@ -0,0 +1,16 @@
package net.pingex.dcf.commands;
import java.util.Set;
/**
* Indicates a plugin which can run commands (using annotated commands)
*/
@FunctionalInterface
public interface IWithAnnotatedCommands
{
/**
* Gives all annotated commands for this plugin.
* @return A set of objects which contains annotated commands.
*/
Set<Object> getAnnotatedObjects();
}

@ -0,0 +1,16 @@
package net.pingex.dcf.commands;
import java.util.Set;
/**
* Indicates a plugin which can run commands (using commands object)
*/
@FunctionalInterface
public interface IWithCommands
{
/**
* Give all commands
* @return ALL THE COMMANDS \o/
*/
Set<Command> getCommands();
}