mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-23 17:57:38 +00:00
Refactored command handling code to be more reusable.
This commit is contained in:
parent
50b9f300d5
commit
ad62dbe565
@ -21,12 +21,48 @@ package com.sk89q.minecraft.util.commands;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation indicates a command. Methods should be marked with this
|
||||||
|
* annotation to tell {@link CommandsManager} that the method is a command.
|
||||||
|
* Note that the method name can actually be anything.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Command {
|
public @interface Command {
|
||||||
|
/**
|
||||||
|
* A list of aliases for the command. The first alias is the most
|
||||||
|
* important -- it is the main name of the command. (The method name
|
||||||
|
* is never used for anything).
|
||||||
|
*/
|
||||||
String[] aliases();
|
String[] aliases();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage instruction. Example text for usage could be
|
||||||
|
* <code>[-h] [name] [message]</code>.
|
||||||
|
*/
|
||||||
String usage() default "";
|
String usage() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A short description for the command.
|
||||||
|
*/
|
||||||
String desc();
|
String desc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum number of arguments. This should be 0 or above.
|
||||||
|
*/
|
||||||
int min() default 0;
|
int min() default 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of arguments. Use -1 for an unlimited number
|
||||||
|
* of arguments.
|
||||||
|
*/
|
||||||
int max() default -1;
|
int max() default -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags allow special processing for flags such as -h in the command,
|
||||||
|
* allowing users to easily turn on a flag. This is a string with
|
||||||
|
* each character being a flag. Use A-Z and a-z as possible flags.
|
||||||
|
*/
|
||||||
String flags() default "";
|
String flags() default "";
|
||||||
}
|
}
|
||||||
|
37
src/com/sk89q/minecraft/util/commands/CommandException.java
Normal file
37
src/com/sk89q/minecraft/util/commands/CommandException.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.minecraft.util.commands;
|
||||||
|
|
||||||
|
public class CommandException extends Exception {
|
||||||
|
private static final long serialVersionUID = 870638193072101739L;
|
||||||
|
|
||||||
|
public CommandException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandException(Throwable t) {
|
||||||
|
super(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,7 +22,16 @@ package com.sk89q.minecraft.util.commands;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates a list of permissions that should be checked.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface CommandPermissions {
|
public @interface CommandPermissions {
|
||||||
|
/**
|
||||||
|
* A list of permissions. Only one permission has to be met
|
||||||
|
* for the command to be permitted.
|
||||||
|
*/
|
||||||
String[] value();
|
String[] value();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.minecraft.util.commands;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when not enough permissions are satisfied.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
|
public class CommandPermissionsException extends CommandException {
|
||||||
|
private static final long serialVersionUID = -602374621030168291L;
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.minecraft.util.commands;
|
||||||
|
|
||||||
|
public class CommandUsageException extends CommandException {
|
||||||
|
private static final long serialVersionUID = -6761418114414516542L;
|
||||||
|
|
||||||
|
protected String usage;
|
||||||
|
|
||||||
|
public CommandUsageException(String message, String usage) {
|
||||||
|
super(message);
|
||||||
|
this.usage = usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsage() {
|
||||||
|
return usage;
|
||||||
|
}
|
||||||
|
}
|
@ -28,24 +28,51 @@ import java.util.Set;
|
|||||||
import com.sk89q.util.StringUtil;
|
import com.sk89q.util.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for handling commands.
|
* Manager for handling commands. This allows you to easily process commands,
|
||||||
|
* including nested commands, by correctly annotating methods of a class.
|
||||||
|
* The commands are thus declaratively defined, and it's easy to spot
|
||||||
|
* how permissions and commands work out, and it decreases the opportunity
|
||||||
|
* for errors because the consistency would cause any odd balls to show.
|
||||||
|
* The manager also handles some boilerplate code such as number of arguments
|
||||||
|
* checking and printing usage.
|
||||||
|
*
|
||||||
|
* <p>To use this, it is merely a matter of registering classes containing
|
||||||
|
* the commands (as methods with the proper annotations) with the
|
||||||
|
* manager. When you want to process a command, use one of the
|
||||||
|
* <code>execute</code> methods. If something is wrong, such as incorrect
|
||||||
|
* usage, insufficient permissions, or a missing command altogether, an
|
||||||
|
* exception will be raised for upstream handling.
|
||||||
|
*
|
||||||
|
* <p>To mark a method as a command, use {@link Command}. For nested commands,
|
||||||
|
* see {@link NestedCommand}. To handle permissions, use
|
||||||
|
* {@link CommandPermissions}.
|
||||||
|
*
|
||||||
|
* <p>This uses Java reflection extensively, but to reduce the overhead of
|
||||||
|
* reflection, command lookups are completely cached on registration. This
|
||||||
|
* allows for fast command handling. Method invocation still has to be done
|
||||||
|
* with reflection, but this is quite fast in that of itself.
|
||||||
*
|
*
|
||||||
* @author sk89q
|
* @author sk89q
|
||||||
|
* @param <T> command sender class
|
||||||
*/
|
*/
|
||||||
public class CommandsManager {
|
public abstract class CommandsManager<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping of nested commands (including aliases) with a description.
|
* Mapping of commands (including aliases) with a description. Root
|
||||||
|
* commands are stored under a key of null, whereas child commands are
|
||||||
|
* cached under their respective {@link Method}.
|
||||||
*/
|
*/
|
||||||
public Map<Method, Map<String, Method>> commands
|
protected Map<Method, Map<String, Method>> commands
|
||||||
= new HashMap<Method, Map<String, Method>>();
|
= new HashMap<Method, Map<String, Method>>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping of commands (not including aliases) with a description.
|
* Mapping of commands (not including aliases) with a description.
|
||||||
*/
|
*/
|
||||||
public Map<String, String> descs = new HashMap<String, String>();
|
protected Map<String, String> descs = new HashMap<String, String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an object that contains commands (denoted by the
|
* Register an object that contains commands (denoted by
|
||||||
* <code>com.sk89q.util.commands.Command</code> annotation. The methods are
|
* {@link Command}. The methods are
|
||||||
* cached into a map for later usage and it reduces the overhead of
|
* cached into a map for later usage and it reduces the overhead of
|
||||||
* reflection (method lookup via reflection is relatively slow).
|
* reflection (method lookup via reflection is relatively slow).
|
||||||
*
|
*
|
||||||
@ -109,7 +136,8 @@ public class CommandsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see whether there is a command.
|
* Checks to see whether there is a command named such at the root level.
|
||||||
|
* This will check aliases as well.
|
||||||
*
|
*
|
||||||
* @param command
|
* @param command
|
||||||
* @return
|
* @return
|
||||||
@ -119,7 +147,7 @@ public class CommandsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of command descriptions.
|
* Get a list of command descriptions. This is only for root commands.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ -135,7 +163,7 @@ public class CommandsManager {
|
|||||||
* @param cmd
|
* @param cmd
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getUsage(String[] args, int level, Command cmd) {
|
protected String getUsage(String[] args, int level, Command cmd) {
|
||||||
StringBuilder command = new StringBuilder();
|
StringBuilder command = new StringBuilder();
|
||||||
|
|
||||||
command.append("/");
|
command.append("/");
|
||||||
@ -156,11 +184,13 @@ public class CommandsManager {
|
|||||||
* @param args
|
* @param args
|
||||||
* @param level
|
* @param level
|
||||||
* @param method
|
* @param method
|
||||||
* @param palyer
|
* @param player
|
||||||
* @return
|
* @return
|
||||||
|
* @throws CommandException
|
||||||
*/
|
*/
|
||||||
private String getNestedUsage(String[] args, int level, Method method,
|
protected String getNestedUsage(String[] args, int level,
|
||||||
CommandsPlayer player) {
|
Method method, T player) throws CommandException {
|
||||||
|
|
||||||
StringBuilder command = new StringBuilder();
|
StringBuilder command = new StringBuilder();
|
||||||
|
|
||||||
command.append("/");
|
command.append("/");
|
||||||
@ -171,6 +201,7 @@ public class CommandsManager {
|
|||||||
|
|
||||||
|
|
||||||
Map<String, Method> map = commands.get(method);
|
Map<String, Method> map = commands.get(method);
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
command.append("<");
|
command.append("<");
|
||||||
|
|
||||||
@ -178,6 +209,7 @@ public class CommandsManager {
|
|||||||
|
|
||||||
for (Map.Entry<String, Method> entry : map.entrySet()) {
|
for (Map.Entry<String, Method> entry : map.entrySet()) {
|
||||||
Method childMethod = entry.getValue();
|
Method childMethod = entry.getValue();
|
||||||
|
found = true;
|
||||||
|
|
||||||
if (hasPermission(childMethod, player)) {
|
if (hasPermission(childMethod, player)) {
|
||||||
Command childCmd = childMethod.getAnnotation(Command.class);
|
Command childCmd = childMethod.getAnnotation(Command.class);
|
||||||
@ -189,7 +221,12 @@ public class CommandsManager {
|
|||||||
if (allowedCommands.size() > 0) {
|
if (allowedCommands.size() > 0) {
|
||||||
command.append(StringUtil.joinString(allowedCommands, "|", 0));
|
command.append(StringUtil.joinString(allowedCommands, "|", 0));
|
||||||
} else {
|
} else {
|
||||||
command.append("action");
|
if (!found) {
|
||||||
|
command.append("?");
|
||||||
|
} else {
|
||||||
|
//command.append("action");
|
||||||
|
throw new CommandPermissionsException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
command.append(">");
|
command.append(">");
|
||||||
@ -197,18 +234,42 @@ public class CommandsManager {
|
|||||||
return command.toString();
|
return command.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to execute a command. This version takes a separate command
|
||||||
|
* name (for the root command) and then a list of following arguments.
|
||||||
|
*
|
||||||
|
* @param cmd command to run
|
||||||
|
* @param args arguments
|
||||||
|
* @param player command source
|
||||||
|
* @param methodArgs method arguments
|
||||||
|
* @throws CommandException
|
||||||
|
*/
|
||||||
|
public void execute(String cmd, String[] args, T player,
|
||||||
|
Object ... methodArgs) throws CommandException {
|
||||||
|
|
||||||
|
String[] newArgs = new String[args.length + 1];
|
||||||
|
System.arraycopy(args, 0, newArgs, 1, args.length);
|
||||||
|
newArgs[0] = cmd;
|
||||||
|
Object[] newMethodArgs = new Object[methodArgs.length + 1];
|
||||||
|
System.arraycopy(methodArgs, 0, newMethodArgs, 1, methodArgs.length);
|
||||||
|
|
||||||
|
executeMethod(null, newArgs, player, newMethodArgs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to execute a command.
|
* Attempt to execute a command.
|
||||||
*
|
*
|
||||||
* @param args
|
* @param args
|
||||||
* @param player
|
* @param player
|
||||||
* @param methodArgs
|
* @param methodArgs
|
||||||
* @return
|
* @throws CommandException
|
||||||
* @throws Throwable
|
|
||||||
*/
|
*/
|
||||||
public boolean execute(String[] args, CommandsPlayer player,
|
public void execute(String[] args, T player,
|
||||||
Object[] methodArgs) throws Throwable {
|
Object ... methodArgs) throws CommandException {
|
||||||
return executeMethod(null, args, player, methodArgs, 0);
|
|
||||||
|
Object[] newMethodArgs = new Object[methodArgs.length + 1];
|
||||||
|
System.arraycopy(methodArgs, 0, newMethodArgs, 1, methodArgs.length);
|
||||||
|
executeMethod(null, args, player, newMethodArgs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,12 +280,11 @@ public class CommandsManager {
|
|||||||
* @param player
|
* @param player
|
||||||
* @param methodArgs
|
* @param methodArgs
|
||||||
* @param level
|
* @param level
|
||||||
* @return
|
* @throws CommandException
|
||||||
* @throws Throwable
|
|
||||||
*/
|
*/
|
||||||
public boolean executeMethod(Method parent, String[] args,
|
public void executeMethod(Method parent, String[] args,
|
||||||
CommandsPlayer player, Object[] methodArgs, int level)
|
T player, Object[] methodArgs, int level) throws CommandException {
|
||||||
throws Throwable {
|
|
||||||
String cmdName = args[level];
|
String cmdName = args[level];
|
||||||
|
|
||||||
Map<String, Method> map = commands.get(parent);
|
Map<String, Method> map = commands.get(parent);
|
||||||
@ -232,25 +292,25 @@ public class CommandsManager {
|
|||||||
|
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
if (parent == null) { // Root
|
if (parent == null) { // Root
|
||||||
return false;
|
throw new UnhandledCommandException();
|
||||||
} else {
|
} else {
|
||||||
player.printError(getNestedUsage(args, level - 1, parent, player));
|
throw new MissingNestedCommandException("Unknown command: " + cmdName,
|
||||||
return true;
|
getNestedUsage(args, level - 1, parent, player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkPermissions(method, player)) {
|
if (!hasPermission(method, player)) {
|
||||||
return true;
|
throw new CommandPermissionsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
int argsCount = args.length - 1 - level;
|
int argsCount = args.length - 1 - level;
|
||||||
|
|
||||||
if (method.isAnnotationPresent(NestedCommand.class)) {
|
if (method.isAnnotationPresent(NestedCommand.class)) {
|
||||||
if (argsCount == 0) {
|
if (argsCount == 0) {
|
||||||
player.printError(getNestedUsage(args, level, method, player));
|
throw new MissingNestedCommandException("Sub-command required.",
|
||||||
return true;
|
getNestedUsage(args, level, method, player));
|
||||||
} else {
|
} else {
|
||||||
return executeMethod(method, args, player, methodArgs, level + 1);
|
executeMethod(method, args, player, methodArgs, level + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Command cmd = method.getAnnotation(Command.class);
|
Command cmd = method.getAnnotation(Command.class);
|
||||||
@ -261,22 +321,19 @@ public class CommandsManager {
|
|||||||
CommandContext context = new CommandContext(newArgs);
|
CommandContext context = new CommandContext(newArgs);
|
||||||
|
|
||||||
if (context.argsLength() < cmd.min()) {
|
if (context.argsLength() < cmd.min()) {
|
||||||
player.printError("Too few arguments.");
|
throw new CommandUsageException("Too few arguments.",
|
||||||
player.printError(getUsage(args, level, cmd));
|
getUsage(args, level, cmd));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.max() != -1 && context.argsLength() > cmd.max()) {
|
if (cmd.max() != -1 && context.argsLength() > cmd.max()) {
|
||||||
player.printError("Too many arguments.");
|
throw new CommandUsageException("Too many arguments.",
|
||||||
player.printError(getUsage(args, level, cmd));
|
getUsage(args, level, cmd));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (char flag : context.getFlags()) {
|
for (char flag : context.getFlags()) {
|
||||||
if (cmd.flags().indexOf(String.valueOf(flag)) == -1) {
|
if (cmd.flags().indexOf(String.valueOf(flag)) == -1) {
|
||||||
player.printError("Unknown flag: " + flag);
|
throw new CommandUsageException("Unknown flag: " + flag,
|
||||||
player.printError(getUsage(args, level, cmd));
|
getUsage(args, level, cmd));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,35 +346,9 @@ public class CommandsManager {
|
|||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
throw e.getCause();
|
throw new WrappedCommandException(e.getCause());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks permissions, prints an error if needed.
|
|
||||||
*
|
|
||||||
* @param method
|
|
||||||
* @param player
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean checkPermissions(Method method, CommandsPlayer player) {
|
|
||||||
if (!method.isAnnotationPresent(CommandPermissions.class)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandPermissions perms = method.getAnnotation(CommandPermissions.class);
|
|
||||||
|
|
||||||
for (String perm : perms.value()) {
|
|
||||||
if (player.hasPermission(perm)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
player.printError("You don't have permission for this command.");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,18 +358,27 @@ public class CommandsManager {
|
|||||||
* @param player
|
* @param player
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean hasPermission(Method method, CommandsPlayer player) {
|
protected boolean hasPermission(Method method, T player) {
|
||||||
CommandPermissions perms = method.getAnnotation(CommandPermissions.class);
|
CommandPermissions perms = method.getAnnotation(CommandPermissions.class);
|
||||||
if (perms == null) {
|
if (perms == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String perm : perms.value()) {
|
for (String perm : perms.value()) {
|
||||||
if (player.hasPermission(perm)) {
|
if (hasPermission(player, perm)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a player permission..
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* @param perm
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract boolean hasPermission(T player, String perm);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.minecraft.util.commands;
|
||||||
|
|
||||||
|
public class MissingNestedCommandException extends CommandUsageException {
|
||||||
|
private static final long serialVersionUID = -4382896182979285355L;
|
||||||
|
|
||||||
|
public MissingNestedCommandException(String message, String usage) {
|
||||||
|
super(message, usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,7 +22,20 @@ package com.sk89q.minecraft.util.commands;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates a nested command. Mark methods with this annotation to tell
|
||||||
|
* {@link CommandsManager} that a method is merely a shell for child
|
||||||
|
* commands. Note that the body of a method marked with this annotation
|
||||||
|
* will never called. Additionally, not all fields of {@link Command} apply
|
||||||
|
* when it is used in conjunction with this annotation, although both
|
||||||
|
* are still required.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface NestedCommand {
|
public @interface NestedCommand {
|
||||||
|
/**
|
||||||
|
* A list of classes with the child commands.
|
||||||
|
*/
|
||||||
Class<?>[] value();
|
Class<?>[] value();
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.minecraft.util.commands;
|
package com.sk89q.minecraft.util.commands;
|
||||||
|
|
||||||
public interface CommandsPlayer {
|
public class UnhandledCommandException extends CommandException {
|
||||||
public void printError(String msg);
|
private static final long serialVersionUID = 3370887306593968091L;
|
||||||
public boolean hasPermission(String perm);
|
|
||||||
}
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.minecraft.util.commands;
|
||||||
|
|
||||||
|
public class WrappedCommandException extends CommandException {
|
||||||
|
private static final long serialVersionUID = -4075721444847778918L;
|
||||||
|
|
||||||
|
public WrappedCommandException(Throwable t) {
|
||||||
|
super(t);
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,6 @@
|
|||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import com.sk89q.minecraft.util.commands.CommandsPlayer;
|
|
||||||
import com.sk89q.worldedit.bags.BlockBag;
|
import com.sk89q.worldedit.bags.BlockBag;
|
||||||
import com.sk89q.worldedit.blocks.BlockType;
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
import com.sk89q.worldedit.util.TargetBlock;
|
import com.sk89q.worldedit.util.TargetBlock;
|
||||||
@ -29,7 +28,7 @@ import com.sk89q.worldedit.util.TargetBlock;
|
|||||||
*
|
*
|
||||||
* @author sk89q
|
* @author sk89q
|
||||||
*/
|
*/
|
||||||
public abstract class LocalPlayer implements CommandsPlayer {
|
public abstract class LocalPlayer {
|
||||||
/**
|
/**
|
||||||
* Server.
|
* Server.
|
||||||
*/
|
*/
|
||||||
|
@ -23,7 +23,12 @@ import java.util.*;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import javax.script.ScriptException;
|
import javax.script.ScriptException;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandUsageException;
|
||||||
import com.sk89q.minecraft.util.commands.CommandsManager;
|
import com.sk89q.minecraft.util.commands.CommandsManager;
|
||||||
|
import com.sk89q.minecraft.util.commands.MissingNestedCommandException;
|
||||||
|
import com.sk89q.minecraft.util.commands.UnhandledCommandException;
|
||||||
|
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||||
import com.sk89q.util.StringUtil;
|
import com.sk89q.util.StringUtil;
|
||||||
import com.sk89q.worldedit.LocalSession.CompassMode;
|
import com.sk89q.worldedit.LocalSession.CompassMode;
|
||||||
import com.sk89q.worldedit.bags.BlockBag;
|
import com.sk89q.worldedit.bags.BlockBag;
|
||||||
@ -67,7 +72,7 @@ public class WorldEdit {
|
|||||||
/**
|
/**
|
||||||
* List of commands.
|
* List of commands.
|
||||||
*/
|
*/
|
||||||
private CommandsManager commands;
|
private CommandsManager<LocalPlayer> commands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a list of WorldEdit sessions, keyed by players' names. Sessions
|
* Stores a list of WorldEdit sessions, keyed by players' names. Sessions
|
||||||
@ -96,7 +101,12 @@ public class WorldEdit {
|
|||||||
this.server = server;
|
this.server = server;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
commands = new CommandsManager();
|
commands = new CommandsManager<LocalPlayer>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(LocalPlayer player, String perm) {
|
||||||
|
return player.hasPermission(perm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
commands.register(ChunkCommands.class);
|
commands.register(ChunkCommands.class);
|
||||||
commands.register(ClipboardCommands.class);
|
commands.register(ClipboardCommands.class);
|
||||||
@ -886,12 +896,19 @@ public class WorldEdit {
|
|||||||
logger.info("WorldEdit: " + player.getName() + ": "
|
logger.info("WorldEdit: " + player.getName() + ": "
|
||||||
+ StringUtil.joinString(split, " "));
|
+ StringUtil.joinString(split, " "));
|
||||||
}
|
}
|
||||||
|
|
||||||
Object[] methodArgs = new Object[] {
|
|
||||||
null, this, session, player, editSession
|
|
||||||
};
|
|
||||||
|
|
||||||
return commands.execute(split, player, methodArgs);
|
commands.execute(split, player, this, session, player, editSession);
|
||||||
|
} catch (CommandPermissionsException e) {
|
||||||
|
player.printError("You don't have permission to do this.");
|
||||||
|
} catch (MissingNestedCommandException e) {
|
||||||
|
player.printError(e.getUsage());
|
||||||
|
} catch (CommandUsageException e) {
|
||||||
|
player.printError(e.getMessage());
|
||||||
|
player.printError(e.getUsage());
|
||||||
|
} catch (WrappedCommandException e) {
|
||||||
|
throw e.getCause();
|
||||||
|
} catch (UnhandledCommandException e) {
|
||||||
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
session.remember(editSession);
|
session.remember(editSession);
|
||||||
editSession.flushQueue();
|
editSession.flushQueue();
|
||||||
|
Loading…
Reference in New Issue
Block a user