mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-08-02 20:45:27 +02:00
Starting to convert commands to a smarter system :3
This commit is contained in:
84
src/main/java/com/intellectualsites/commands/Argument.java
Normal file
84
src/main/java/com/intellectualsites/commands/Argument.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.intellectualsites.commands;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class Argument<T> {
|
||||
|
||||
private final String name;
|
||||
private final T example;
|
||||
|
||||
public Argument(String name, T example) {
|
||||
this.name = name;
|
||||
this.example = example;
|
||||
}
|
||||
|
||||
public abstract T parse(String in);
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public final T getExample() {
|
||||
return this.example;
|
||||
}
|
||||
|
||||
public static final Argument<Integer> Integer = new Argument<java.lang.Integer>("int", 16) {
|
||||
@Override
|
||||
public Integer parse(String in) {
|
||||
Integer value = null;
|
||||
try {
|
||||
value = java.lang.Integer.parseInt(in);
|
||||
} catch(final Exception ignored) {}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
public static final Argument<Boolean> Boolean = new Argument<java.lang.Boolean>("boolean", true) {
|
||||
@Override
|
||||
public Boolean parse(String in) {
|
||||
Boolean value = null;
|
||||
if (in.equalsIgnoreCase("true") || in.equalsIgnoreCase("Yes") || in.equalsIgnoreCase("1")) {
|
||||
value = true;
|
||||
} else if (in.equalsIgnoreCase("false") || in.equalsIgnoreCase("No") || in.equalsIgnoreCase("0")) {
|
||||
value = false;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
public static final Argument<String> String = new Argument<java.lang.String>("String", "Example") {
|
||||
@Override
|
||||
public String parse(String in) {
|
||||
return in;
|
||||
}
|
||||
};
|
||||
|
||||
public static Argument<String> PlayerName = new Argument<java.lang.String>("PlayerName", "Dinnerbone") {
|
||||
@Override
|
||||
public String parse(String in) {
|
||||
return in.length() < 16 ? in : null;
|
||||
}
|
||||
};
|
||||
|
||||
public static Argument<PlotId> PlotID = new Argument<com.intellectualcrafters.plot.object.PlotId>("PlotID", new PlotId(3, -32)) {
|
||||
@Override
|
||||
public PlotId parse(String in) {
|
||||
PlotId plotID;
|
||||
try {
|
||||
String[] parts = in.split(";");
|
||||
int i1 = java.lang.Integer.parseInt(parts[0]);
|
||||
int i2 = java.lang.Integer.parseInt(parts[1]);
|
||||
plotID = new PlotId(i1, i2);
|
||||
} catch(final Exception e) {
|
||||
return null;
|
||||
}
|
||||
return plotID;
|
||||
}
|
||||
};
|
||||
}
|
140
src/main/java/com/intellectualsites/commands/Command.java
Normal file
140
src/main/java/com/intellectualsites/commands/Command.java
Normal file
@@ -0,0 +1,140 @@
|
||||
package com.intellectualsites.commands;
|
||||
|
||||
import com.intellectualcrafters.plot.commands.CommandCategory;
|
||||
import com.intellectualsites.commands.callers.CommandCaller;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class Command extends CommandManager {
|
||||
|
||||
private Class requiredType = Object.class;
|
||||
private String command, usage = "", description = "", permission = "";
|
||||
private String[] aliases = new String[0];
|
||||
private CommandCategory category;
|
||||
protected Argument[] requiredArguments;
|
||||
|
||||
public Command() {
|
||||
super(null, new ArrayList<Command>());
|
||||
}
|
||||
|
||||
public Command(String command) {
|
||||
super(null, new ArrayList<Command>());
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public Command(String command, String usage) {
|
||||
super(null, new ArrayList<Command>());
|
||||
this.command = command;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public Command(String command, String usage, String description) {
|
||||
super(null, new ArrayList<Command>());
|
||||
this.command = command;
|
||||
this.usage = usage;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Command(String command, String usage, String description, String permission) {
|
||||
super(null, new ArrayList<Command>());
|
||||
this.command = command;
|
||||
this.usage = usage;
|
||||
this.description = description;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
public Command(String command, String[] aliases, String usage) {
|
||||
super(null, new ArrayList<Command>());
|
||||
this.command = command;
|
||||
this.aliases = aliases;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public Command(String command, String[] aliases) {
|
||||
super(null, new ArrayList<Command>());
|
||||
this.command = command;
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
public Command(String command, String usage, String description, String permission, String[] aliases, Class requiredType) {
|
||||
super(null, new ArrayList<Command>());
|
||||
this.command = command;
|
||||
this.usage = usage;
|
||||
this.description = description;
|
||||
this.permission = permission;
|
||||
this.aliases = aliases;
|
||||
this.requiredType = requiredType;
|
||||
}
|
||||
|
||||
final public Class getRequiredType() {
|
||||
return this.requiredType;
|
||||
}
|
||||
|
||||
final protected void create() {
|
||||
Annotation annotation = getClass().getAnnotation(CommandDeclaration.class);
|
||||
if (annotation == null) {
|
||||
throw new RuntimeException("Command does not have a CommandDeclaration");
|
||||
}
|
||||
CommandDeclaration declaration = (CommandDeclaration) annotation;
|
||||
this.command = declaration.command();
|
||||
this.usage = declaration.usage();
|
||||
this.description = declaration.description();
|
||||
this.usage = declaration.usage();
|
||||
this.permission = declaration.permission();
|
||||
this.aliases = declaration.aliases();
|
||||
this.requiredType = declaration.requiredType();
|
||||
this.category = declaration.category();
|
||||
}
|
||||
|
||||
@Override
|
||||
final public String toString() {
|
||||
return this.command;
|
||||
}
|
||||
@Override
|
||||
final public int hashCode() {
|
||||
return this.command.hashCode();
|
||||
}
|
||||
|
||||
public abstract boolean onCommand(CommandCaller caller, String[] arguments);
|
||||
|
||||
final public int handle(CommandCaller caller, String[] args) {
|
||||
if (args.length == 0) {
|
||||
return super.handle(caller, "");
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String s : args) {
|
||||
builder.append(s).append(" ");
|
||||
}
|
||||
String s = builder.substring(0, builder.length() - 1);
|
||||
return super.handle(caller, s);
|
||||
}
|
||||
|
||||
final public String getCommand() {
|
||||
return this.command;
|
||||
}
|
||||
|
||||
final public String getUsage() {
|
||||
return this.usage;
|
||||
}
|
||||
|
||||
final public String getPermission() {
|
||||
return this.permission;
|
||||
}
|
||||
|
||||
final public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
final public String[] getAliases() {
|
||||
return this.aliases;
|
||||
}
|
||||
|
||||
final public Argument[] getRequiredArguments() {
|
||||
return this.requiredArguments;
|
||||
}
|
||||
|
||||
final public CommandCategory getCategory() {
|
||||
return this.category;
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package com.intellectualsites.commands;
|
||||
|
||||
import com.intellectualcrafters.plot.commands.CommandCategory;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CommandDeclaration {
|
||||
|
||||
String command();
|
||||
|
||||
String[] aliases() default "";
|
||||
|
||||
String permission() default "";
|
||||
|
||||
String usage() default "";
|
||||
|
||||
String description() default "";
|
||||
|
||||
Class requiredType() default Object.class;
|
||||
|
||||
CommandCategory category();
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.intellectualsites.commands;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class CommandHandlingOutput {
|
||||
|
||||
public static int CALLER_OF_WRONG_TYPE = -6;
|
||||
public static int NOT_COMMAND = -5;
|
||||
public static int NOT_FOUND = -4;
|
||||
public static int NOT_PERMITTED = -3;
|
||||
public static int ERROR = -2;
|
||||
public static int WRONG_USAGE = -1;
|
||||
|
||||
public static int SUCCESS = 1;
|
||||
|
||||
public static String nameField(int code) {
|
||||
Field[] fields = CommandHandlingOutput.class.getDeclaredFields();
|
||||
for (final Field field : fields) {
|
||||
if (field.getGenericType() == Integer.TYPE) {
|
||||
try {
|
||||
if ((Integer) field.get(CommandHandlingOutput.class) == code) {
|
||||
return field.getName();
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return "null??";
|
||||
}
|
||||
}
|
115
src/main/java/com/intellectualsites/commands/CommandManager.java
Normal file
115
src/main/java/com/intellectualsites/commands/CommandManager.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package com.intellectualsites.commands;
|
||||
|
||||
import com.intellectualsites.commands.callers.CommandCaller;
|
||||
import com.intellectualsites.commands.util.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class CommandManager {
|
||||
|
||||
protected final List<Command> commands;
|
||||
private final Character initialCharacter;
|
||||
|
||||
public CommandManager() {
|
||||
this('/', new ArrayList<Command>());
|
||||
}
|
||||
|
||||
public CommandManager(Character initialCharacter, List<Command> commands) {
|
||||
this.commands = Collections.synchronizedList(commands);
|
||||
this.initialCharacter = initialCharacter;
|
||||
}
|
||||
|
||||
final public void addCommand(final Command command) {
|
||||
this.commands.add(command);
|
||||
}
|
||||
|
||||
final public boolean createCommand(final Command command) {
|
||||
try {
|
||||
command.create();
|
||||
} catch(final Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
if (command.getCommand() != null) {
|
||||
commands.add(command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final public List<Command> getCommands() {
|
||||
return this.commands;
|
||||
}
|
||||
|
||||
final public int handle(CommandCaller caller, String input) {
|
||||
if (initialCharacter != null && !StringUtil.startsWith(initialCharacter, input)) {
|
||||
return CommandHandlingOutput.NOT_COMMAND;
|
||||
}
|
||||
input = initialCharacter == null ? input : StringUtil.replaceFirst(initialCharacter, input);
|
||||
String[] parts = input.split(" ");
|
||||
String[] args;
|
||||
String command = parts[0];
|
||||
if (parts.length == 1) {
|
||||
args = new String[0];
|
||||
} else {
|
||||
args = new String[parts.length - 1];
|
||||
System.arraycopy(parts, 1, args, 0, args.length);
|
||||
}
|
||||
Command cmd = null;
|
||||
for (Command c1 : this.commands) {
|
||||
if (c1.getCommand().equalsIgnoreCase(command) || StringUtil.inArray(command, c1.getAliases(), false)) {
|
||||
cmd = c1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cmd == null) {
|
||||
return CommandHandlingOutput.NOT_FOUND;
|
||||
}
|
||||
if (!cmd.getRequiredType().isInstance(caller.getSuperCaller())) {
|
||||
return CommandHandlingOutput.CALLER_OF_WRONG_TYPE;
|
||||
}
|
||||
if (!caller.hasPermission(cmd.getPermission())) {
|
||||
return CommandHandlingOutput.NOT_PERMITTED;
|
||||
}
|
||||
Argument[] requiredArguments = cmd.getRequiredArguments();
|
||||
if (requiredArguments != null && requiredArguments.length > 0) {
|
||||
boolean success = true;
|
||||
if (args.length < requiredArguments.length) {
|
||||
success = false;
|
||||
} else {
|
||||
for (int i = 0; i < requiredArguments.length; i++) {
|
||||
if (requiredArguments[i].parse(args[i]) == null) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
String usage = cmd.getUsage();
|
||||
caller.sendRequiredArgumentsList(this, cmd, requiredArguments);
|
||||
return CommandHandlingOutput.WRONG_USAGE;
|
||||
}
|
||||
}
|
||||
try {
|
||||
boolean a = cmd.onCommand(caller, args);
|
||||
if (!a) {
|
||||
String usage = cmd.getUsage();
|
||||
if (usage != null && !usage.isEmpty()) {
|
||||
caller.message(usage);
|
||||
}
|
||||
return CommandHandlingOutput.WRONG_USAGE;
|
||||
}
|
||||
} catch(final Throwable t) {
|
||||
t.printStackTrace();
|
||||
return CommandHandlingOutput.ERROR;
|
||||
}
|
||||
return CommandHandlingOutput.SUCCESS;
|
||||
}
|
||||
|
||||
final public char getInitialCharacter() {
|
||||
return this.initialCharacter;
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.intellectualsites.commands.callers;
|
||||
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualsites.commands.Argument;
|
||||
import com.intellectualsites.commands.Command;
|
||||
import com.intellectualsites.commands.CommandManager;
|
||||
|
||||
public interface CommandCaller<T> {
|
||||
|
||||
boolean hasPermission(String permission);
|
||||
|
||||
void message(String message);
|
||||
|
||||
T getSuperCaller();
|
||||
|
||||
void message(C c, String ... args);
|
||||
|
||||
void sendRequiredArgumentsList(CommandManager manager, Command cmd, Argument[] required);
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package com.intellectualsites.commands.callers;
|
||||
|
||||
import com.intellectualsites.commands.Argument;
|
||||
import com.intellectualsites.commands.Command;
|
||||
import com.intellectualsites.commands.CommandManager;
|
||||
|
||||
public class SystemCaller implements CommandCaller {
|
||||
|
||||
public boolean hasPermission(String permission) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void message(String message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
public Object getSuperCaller() {
|
||||
return new Object();
|
||||
}
|
||||
|
||||
public void sendRequiredArgumentsList(CommandManager manager, Command cmd, Argument[] required) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(manager.getInitialCharacter()).append(cmd.getCommand()).append(" requires ");
|
||||
for (Argument argument : required) {
|
||||
builder.append(argument.getName()).append(" (").append(argument.getExample()).append("), ");
|
||||
}
|
||||
message(builder.substring(0, builder.length() - 2));
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package com.intellectualsites.commands.test;
|
||||
|
||||
import com.intellectualsites.commands.*;
|
||||
import com.intellectualsites.commands.callers.CommandCaller;
|
||||
import com.intellectualsites.commands.callers.SystemCaller;
|
||||
|
||||
public class CommandTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
CommandCaller caller = new SystemCaller();
|
||||
CommandManager manager = new CommandManager();
|
||||
if(!manager.createCommand(new TestCommand())) {
|
||||
System.out.println("Failed to create command :(");
|
||||
}
|
||||
manager.handle(caller, "/test banana cow grass");
|
||||
}
|
||||
|
||||
@CommandDeclaration(command = "test", usage = "/test [word]")
|
||||
public static class TestCommand extends Command {
|
||||
TestCommand() {
|
||||
requiredArguments = new Argument[] {
|
||||
Argument.String, Argument.String, Argument.String
|
||||
};
|
||||
addCommand(new Command("banana", new String[0]) {
|
||||
@Override
|
||||
public boolean onCommand(CommandCaller caller, String[] arguments) {
|
||||
if (getCommands().isEmpty()) {
|
||||
addCommand(new Command("cow") {
|
||||
@Override
|
||||
public boolean onCommand(CommandCaller caller, String[] arguments) {
|
||||
caller.message("I eat " + arguments[0]);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
handle(caller, arguments);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandCaller caller, String[] arguments) {
|
||||
handle(caller, arguments);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
package com.intellectualsites.commands.util;
|
||||
|
||||
public class StringUtil {
|
||||
|
||||
public static final String[] emptyArray = new String[0];
|
||||
|
||||
public static boolean startsWith(char c, String s) {
|
||||
return !(s == null || s.isEmpty()) && s.toCharArray()[0] == c;
|
||||
}
|
||||
|
||||
public static String replaceFirst(char c, String s) {
|
||||
if (s == null) {
|
||||
return "";
|
||||
}
|
||||
if (s.isEmpty()) {
|
||||
return s;
|
||||
}
|
||||
char[] chars = s.toCharArray();
|
||||
char[] newChars = new char[chars.length];
|
||||
int used = 0;
|
||||
boolean found = false;
|
||||
for (char cc : chars) {
|
||||
if (!found && c == cc) {
|
||||
found = true;
|
||||
} else {
|
||||
newChars[used++] = cc;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
chars = new char[newChars.length - 1];
|
||||
System.arraycopy(newChars, 0, chars, 0, chars.length);
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public static boolean inArray(String s, String[] a, boolean matchCase) {
|
||||
for (String aS : a) {
|
||||
if (matchCase) {
|
||||
if (s.equals(aS)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (s.equalsIgnoreCase(aS)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user