geforkt von Mirrors/FastAsyncWorldEdit
Overhauled command handling and suggestion support.
Dieser Commit ist enthalten in:
Ursprung
2258513104
Commit
33e1e0b1f1
32
src/bukkit/java/com/sk89q/bukkit/util/CommandInspector.java
Normale Datei
32
src/bukkit/java/com/sk89q/bukkit/util/CommandInspector.java
Normale Datei
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.bukkit.util;
|
||||||
|
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
public interface CommandInspector {
|
||||||
|
|
||||||
|
String getShortText(Command command);
|
||||||
|
|
||||||
|
String getFullText(Command command);
|
||||||
|
|
||||||
|
boolean testPermission(CommandSender sender, Command command);
|
||||||
|
}
|
@ -26,9 +26,12 @@ import org.bukkit.OfflinePlayer;
|
|||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginIdentifiableCommand;
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of a dynamically registered {@link org.bukkit.command.Command} attached to a plugin
|
* An implementation of a dynamically registered {@link org.bukkit.command.Command} attached to a plugin
|
||||||
@ -76,6 +79,15 @@ public class DynamicPluginCommand extends org.bukkit.command.Command implements
|
|||||||
return owningPlugin;
|
return owningPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
|
||||||
|
if (owner instanceof TabCompleter) {
|
||||||
|
return ((TabCompleter) owner).onTabComplete(sender, this, alias, args);
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public boolean testPermissionSilent(CommandSender sender) {
|
public boolean testPermissionSilent(CommandSender sender) {
|
||||||
@ -83,7 +95,10 @@ public class DynamicPluginCommand extends org.bukkit.command.Command implements
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registeredWith instanceof CommandsManager<?>) {
|
if (registeredWith instanceof CommandInspector) {
|
||||||
|
CommandInspector resolver = (CommandInspector) registeredWith;
|
||||||
|
return resolver.testPermission(sender, this);
|
||||||
|
} else if (registeredWith instanceof CommandsManager<?>) {
|
||||||
try {
|
try {
|
||||||
for (String permission : permissions) {
|
for (String permission : permissions) {
|
||||||
if (((CommandsManager<CommandSender>) registeredWith).hasPermission(sender, permission)) {
|
if (((CommandsManager<CommandSender>) registeredWith).hasPermission(sender, permission)) {
|
||||||
|
@ -40,6 +40,11 @@ public class DynamicPluginCommandHelpTopic extends HelpTopic {
|
|||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
this.name = "/" + cmd.getName();
|
this.name = "/" + cmd.getName();
|
||||||
|
|
||||||
|
if (cmd.getRegisteredWith() instanceof CommandInspector) {
|
||||||
|
CommandInspector resolver = (CommandInspector) cmd.getRegisteredWith();
|
||||||
|
this.shortText = resolver.getShortText(cmd);
|
||||||
|
this.fullText = resolver.getFullText(cmd);
|
||||||
|
} else {
|
||||||
String fullTextTemp = null;
|
String fullTextTemp = null;
|
||||||
StringBuilder fullText = new StringBuilder();
|
StringBuilder fullText = new StringBuilder();
|
||||||
|
|
||||||
@ -67,7 +72,7 @@ public class DynamicPluginCommandHelpTopic extends HelpTopic {
|
|||||||
fullText.append(ChatColor.BOLD).append(ChatColor.GOLD).append("Usage: ").append(ChatColor.WHITE);
|
fullText.append(ChatColor.BOLD).append(ChatColor.GOLD).append("Usage: ").append(ChatColor.WHITE);
|
||||||
fullText.append(split[0]).append("\n");
|
fullText.append(split[0]).append("\n");
|
||||||
|
|
||||||
if (cmd.getAliases().size() > 0) {
|
if (!cmd.getAliases().isEmpty()) {
|
||||||
fullText.append(ChatColor.BOLD).append(ChatColor.GOLD).append("Aliases: ").append(ChatColor.WHITE);
|
fullText.append(ChatColor.BOLD).append(ChatColor.GOLD).append("Aliases: ").append(ChatColor.WHITE);
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String alias : cmd.getAliases()) {
|
for (String alias : cmd.getAliases()) {
|
||||||
@ -84,11 +89,15 @@ public class DynamicPluginCommandHelpTopic extends HelpTopic {
|
|||||||
}
|
}
|
||||||
this.fullText = fullText.toString();
|
this.fullText = fullText.toString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public boolean canSee(CommandSender player) {
|
public boolean canSee(CommandSender player) {
|
||||||
if (cmd.getPermissions() != null && cmd.getPermissions().length > 0) {
|
if (cmd.getRegisteredWith() instanceof CommandInspector) {
|
||||||
|
CommandInspector resolver = (CommandInspector) cmd.getRegisteredWith();
|
||||||
|
return resolver.testPermission(player, cmd);
|
||||||
|
} else if (cmd.getPermissions() != null && cmd.getPermissions().length > 0) {
|
||||||
if (cmd.getRegisteredWith() instanceof CommandsManager) {
|
if (cmd.getRegisteredWith() instanceof CommandsManager) {
|
||||||
try {
|
try {
|
||||||
for (String perm : cmd.getPermissions()) {
|
for (String perm : cmd.getPermissions()) {
|
||||||
@ -123,7 +132,7 @@ public class DynamicPluginCommandHelpTopic extends HelpTopic {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFullText(CommandSender forWho) {
|
public String getFullText(CommandSender forWho) {
|
||||||
if (this.fullText == null || this.fullText.length() == 0) {
|
if (this.fullText == null || this.fullText.isEmpty()) {
|
||||||
return getShortText();
|
return getShortText();
|
||||||
} else {
|
} else {
|
||||||
return this.fullText;
|
return this.fullText;
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
|
import com.sk89q.bukkit.util.CommandInspector;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
|
import com.sk89q.worldedit.util.command.CommandMapping;
|
||||||
|
import com.sk89q.worldedit.util.command.Description;
|
||||||
|
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
class BukkitCommandInspector implements CommandInspector {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(BukkitCommandInspector.class.getCanonicalName());
|
||||||
|
private final WorldEditPlugin plugin;
|
||||||
|
private final Dispatcher dispatcher;
|
||||||
|
|
||||||
|
BukkitCommandInspector(WorldEditPlugin plugin, Dispatcher dispatcher) {
|
||||||
|
checkNotNull(plugin);
|
||||||
|
checkNotNull(dispatcher);
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.dispatcher = dispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getShortText(Command command) {
|
||||||
|
CommandMapping mapping = dispatcher.get(command.getName());
|
||||||
|
if (mapping != null) {
|
||||||
|
return mapping.getDescription().getShortDescription();
|
||||||
|
} else {
|
||||||
|
logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
|
||||||
|
return "Help text not available";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullText(Command command) {
|
||||||
|
CommandMapping mapping = dispatcher.get(command.getName());
|
||||||
|
if (mapping != null) {
|
||||||
|
Description description = mapping.getDescription();
|
||||||
|
return "Usage: " + description.getUsage() + (description.getHelp() != null ? "\n" + description.getHelp() : "");
|
||||||
|
} else {
|
||||||
|
logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
|
||||||
|
return "Help text not available";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testPermission(CommandSender sender, Command command) {
|
||||||
|
CommandMapping mapping = dispatcher.get(command.getName());
|
||||||
|
if (mapping != null) {
|
||||||
|
CommandLocals locals = new CommandLocals();
|
||||||
|
locals.put(Actor.class, plugin.wrapCommandSender(sender));
|
||||||
|
return mapping.getCallable().testPermission(locals);
|
||||||
|
} else {
|
||||||
|
logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -125,15 +125,14 @@ public class BukkitServerInterface extends ServerInterface {
|
|||||||
@Override
|
@Override
|
||||||
public void registerCommands(Dispatcher dispatcher) {
|
public void registerCommands(Dispatcher dispatcher) {
|
||||||
List<CommandInfo> toRegister = new ArrayList<CommandInfo>();
|
List<CommandInfo> toRegister = new ArrayList<CommandInfo>();
|
||||||
|
BukkitCommandInspector inspector = new BukkitCommandInspector(plugin, dispatcher);
|
||||||
for (CommandMapping command : dispatcher.getCommands()) {
|
for (CommandMapping command : dispatcher.getCommands()) {
|
||||||
Description description = command.getDescription();
|
Description description = command.getDescription();
|
||||||
List<String> permissions = description.getPermissions();
|
List<String> permissions = description.getPermissions();
|
||||||
String[] permissionsArray = new String[permissions.size()];
|
String[] permissionsArray = new String[permissions.size()];
|
||||||
permissions.toArray(permissionsArray);
|
permissions.toArray(permissionsArray);
|
||||||
|
|
||||||
toRegister.add(new CommandInfo(
|
toRegister.add(new CommandInfo(description.getUsage(), description.getShortDescription(), command.getAllAliases(), inspector, permissionsArray));
|
||||||
description.getUsage(), description.getDescription(),
|
|
||||||
command.getAllAliases(), dispatcher, permissionsArray));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamicCommands.register(toRegister);
|
dynamicCommands.register(toRegister);
|
||||||
|
@ -96,20 +96,21 @@ public class WorldEditListener implements Listener {
|
|||||||
String[] split = event.getMessage().split(" ");
|
String[] split = event.getMessage().split(" ");
|
||||||
|
|
||||||
if (split.length > 0) {
|
if (split.length > 0) {
|
||||||
split = plugin.getWorldEdit().commandDetection(split);
|
split[0] = split[0].substring(1);
|
||||||
split[0] = "/" + split[0];
|
split = plugin.getWorldEdit().getPlatformManager().getCommandManager().commandDetection(split);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String newMessage = StringUtil.joinString(split, " ");
|
final String newMessage = "/" + StringUtil.joinString(split, " ");
|
||||||
|
|
||||||
if (!newMessage.equals(event.getMessage())) {
|
if (!newMessage.equals(event.getMessage())) {
|
||||||
event.setMessage(newMessage);
|
event.setMessage(newMessage);
|
||||||
plugin.getServer().getPluginManager().callEvent(event);
|
plugin.getServer().getPluginManager().callEvent(event);
|
||||||
|
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
if (event.getMessage().length() > 0) {
|
if (!event.getMessage().isEmpty()) {
|
||||||
plugin.getServer().dispatchCommand(event.getPlayer(),
|
plugin.getServer().dispatchCommand(event.getPlayer(), event.getMessage().substring(1));
|
||||||
event.getMessage().substring(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit;
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
import com.sk89q.util.yaml.YAMLProcessor;
|
import com.sk89q.util.yaml.YAMLProcessor;
|
||||||
import com.sk89q.wepif.PermissionsResolverManager;
|
import com.sk89q.wepif.PermissionsResolverManager;
|
||||||
import com.sk89q.worldedit.*;
|
import com.sk89q.worldedit.*;
|
||||||
@ -27,17 +28,21 @@ import com.sk89q.worldedit.bukkit.selections.CylinderSelection;
|
|||||||
import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection;
|
import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection;
|
||||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
import com.sk89q.worldedit.event.platform.CommandEvent;
|
||||||
|
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
|
||||||
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
|
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||||
import com.sk89q.worldedit.regions.*;
|
import com.sk89q.worldedit.regions.*;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
@ -47,7 +52,7 @@ import java.util.zip.ZipEntry;
|
|||||||
*
|
*
|
||||||
* @author sk89q
|
* @author sk89q
|
||||||
*/
|
*/
|
||||||
public class WorldEditPlugin extends JavaPlugin {
|
public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the CUI's plugin channel registration
|
* The name of the CUI's plugin channel registration
|
||||||
@ -217,19 +222,32 @@ public class WorldEditPlugin extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, org.bukkit.command.Command cmd, String commandLabel, String[] args) {
|
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
|
||||||
// Add the command to the array because the underlying command handling
|
// Add the command to the array because the underlying command handling
|
||||||
// code of WorldEdit expects it
|
// code of WorldEdit expects it
|
||||||
String[] split = new String[args.length + 1];
|
String[] split = new String[args.length + 1];
|
||||||
System.arraycopy(args, 0, split, 1, args.length);
|
System.arraycopy(args, 0, split, 1, args.length);
|
||||||
split[0] = "/" + cmd.getName();
|
split[0] = cmd.getName();
|
||||||
|
|
||||||
CommandEvent event = new CommandEvent(wrapCommandSender(sender), split);
|
CommandEvent event = new CommandEvent(wrapCommandSender(sender), Joiner.on(" ").join(split));
|
||||||
getWorldEdit().getEventBus().post(event);
|
getWorldEdit().getEventBus().post(event);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(CommandSender sender, Command cmd, String commandLabel, String[] args) {
|
||||||
|
// Add the command to the array because the underlying command handling
|
||||||
|
// code of WorldEdit expects it
|
||||||
|
String[] split = new String[args.length + 1];
|
||||||
|
System.arraycopy(args, 0, split, 1, args.length);
|
||||||
|
split[0] = cmd.getName();
|
||||||
|
|
||||||
|
CommandSuggestionEvent event = new CommandSuggestionEvent(wrapCommandSender(sender), Joiner.on(" ").join(split));
|
||||||
|
getWorldEdit().getEventBus().post(event);
|
||||||
|
return event.getSuggestions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the session for the player.
|
* Gets the session for the player.
|
||||||
*
|
*
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.forge;
|
package com.sk89q.worldedit.forge;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.google.common.io.Closer;
|
import com.google.common.io.Closer;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
@ -123,8 +124,10 @@ public class ForgeWorldEdit {
|
|||||||
if (((EntityPlayerMP) event.sender).worldObj.isRemote) return;
|
if (((EntityPlayerMP) event.sender).worldObj.isRemote) return;
|
||||||
String[] split = new String[event.parameters.length + 1];
|
String[] split = new String[event.parameters.length + 1];
|
||||||
System.arraycopy(event.parameters, 0, split, 1, event.parameters.length);
|
System.arraycopy(event.parameters, 0, split, 1, event.parameters.length);
|
||||||
split[0] = ("/" + event.command.getCommandName());
|
split[0] = event.command.getCommandName();
|
||||||
WorldEdit.getInstance().handleCommand(wrap((EntityPlayerMP) event.sender), split);
|
com.sk89q.worldedit.event.platform.CommandEvent weEvent =
|
||||||
|
new com.sk89q.worldedit.event.platform.CommandEvent(wrap((EntityPlayerMP) event.sender), Joiner.on(" ").join(split));
|
||||||
|
WorldEdit.getInstance().getEventBus().post(weEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ import com.sk89q.worldedit.blocks.BlockType;
|
|||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||||
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
|
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
|
||||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
|
||||||
import com.sk89q.worldedit.event.platform.InputType;
|
import com.sk89q.worldedit.event.platform.InputType;
|
||||||
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
|
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
@ -740,22 +739,6 @@ public class WorldEdit {
|
|||||||
return event.isCancelled();
|
return event.isCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* @param split
|
|
||||||
* @return whether the command was processed
|
|
||||||
*/
|
|
||||||
public boolean handleCommand(Player player, String[] split) {
|
|
||||||
CommandEvent event = new CommandEvent(player, split);
|
|
||||||
getEventBus().post(event);
|
|
||||||
return event.isCancelled();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] commandDetection(String[] split) {
|
|
||||||
return getPlatformManager().getCommandManager().commandDetection(split);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a WorldEdit script.
|
* Executes a WorldEdit script.
|
||||||
*
|
*
|
||||||
|
@ -546,8 +546,8 @@ public class UtilityCommands {
|
|||||||
|
|
||||||
if (description.getHelp() != null) {
|
if (description.getHelp() != null) {
|
||||||
actor.print(description.getHelp());
|
actor.print(description.getHelp());
|
||||||
} else if (description.getDescription() != null) {
|
} else if (description.getShortDescription() != null) {
|
||||||
actor.print(description.getDescription());
|
actor.print(description.getShortDescription());
|
||||||
} else {
|
} else {
|
||||||
actor.print("No further help is available.");
|
actor.print("No further help is available.");
|
||||||
}
|
}
|
||||||
|
@ -30,20 +30,20 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
public class CommandEvent extends AbstractCancellable {
|
public class CommandEvent extends AbstractCancellable {
|
||||||
|
|
||||||
private final Actor actor;
|
private final Actor actor;
|
||||||
private final String[] args;
|
private final String arguments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
*
|
*
|
||||||
* @param actor the player
|
* @param actor the player
|
||||||
* @param args the arguments
|
* @param arguments the arguments
|
||||||
*/
|
*/
|
||||||
public CommandEvent(Actor actor, String[] args) {
|
public CommandEvent(Actor actor, String arguments) {
|
||||||
checkNotNull(actor);
|
checkNotNull(actor);
|
||||||
checkNotNull(args);
|
checkNotNull(arguments);
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.args = args;
|
this.arguments = arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,8 +60,8 @@ public class CommandEvent extends AbstractCancellable {
|
|||||||
*
|
*
|
||||||
* @return the arguments
|
* @return the arguments
|
||||||
*/
|
*/
|
||||||
public String[] getArguments() {
|
public String getArguments() {
|
||||||
return args;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.event.platform;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.event.Event;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Posted when suggestions for auto-completion are requested for command input.
|
||||||
|
*/
|
||||||
|
public class CommandSuggestionEvent extends Event {
|
||||||
|
|
||||||
|
private final Actor actor;
|
||||||
|
private final String arguments;
|
||||||
|
private List<String> suggestions = Collections.emptyList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param actor the player
|
||||||
|
* @param arguments the arguments
|
||||||
|
*/
|
||||||
|
public CommandSuggestionEvent(Actor actor, String arguments) {
|
||||||
|
checkNotNull(actor);
|
||||||
|
checkNotNull(arguments);
|
||||||
|
|
||||||
|
this.actor = actor;
|
||||||
|
this.arguments = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the actor that issued the command.
|
||||||
|
*
|
||||||
|
* @return the actor that issued the command
|
||||||
|
*/
|
||||||
|
public Actor getActor() {
|
||||||
|
return actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the arguments.
|
||||||
|
*
|
||||||
|
* @return the arguments
|
||||||
|
*/
|
||||||
|
public String getArguments() {
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of suggestions that are to be presented.
|
||||||
|
*
|
||||||
|
* @return the list of suggestions
|
||||||
|
*/
|
||||||
|
public List<String> getSuggestions() {
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of suggestions that are to be presented.
|
||||||
|
*
|
||||||
|
* @param suggestions the list of suggestions
|
||||||
|
*/
|
||||||
|
public void setSuggestions(List<String> suggestions) {
|
||||||
|
checkNotNull(suggestions);
|
||||||
|
this.suggestions = suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -30,8 +30,9 @@ import com.sk89q.worldedit.LocalSession;
|
|||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.command.*;
|
import com.sk89q.worldedit.command.*;
|
||||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
import com.sk89q.worldedit.event.platform.CommandEvent;
|
||||||
|
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
|
||||||
|
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
|
||||||
import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
|
import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
|
||||||
import com.sk89q.worldedit.internal.command.CommandPermissionsHandler;
|
|
||||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||||
import com.sk89q.worldedit.internal.command.WorldEditExceptionConverter;
|
import com.sk89q.worldedit.internal.command.WorldEditExceptionConverter;
|
||||||
import com.sk89q.worldedit.session.request.Request;
|
import com.sk89q.worldedit.session.request.Request;
|
||||||
@ -87,11 +88,11 @@ public final class CommandManager {
|
|||||||
|
|
||||||
// Set up the commands manager
|
// Set up the commands manager
|
||||||
ParametricBuilder builder = new ParametricBuilder();
|
ParametricBuilder builder = new ParametricBuilder();
|
||||||
|
builder.setAuthorizer(new ActorAuthorizer());
|
||||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||||
builder.attach(new CommandPermissionsHandler());
|
builder.addExceptionConverter(new WorldEditExceptionConverter(worldEdit));
|
||||||
builder.attach(new WorldEditExceptionConverter(worldEdit));
|
builder.addInvokeListener(new LegacyCommandsHandler());
|
||||||
builder.attach(new LegacyCommandsHandler());
|
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, logger));
|
||||||
builder.attach(new CommandLoggingHandler(worldEdit, logger));
|
|
||||||
|
|
||||||
dispatcher = new CommandGraph()
|
dispatcher = new CommandGraph()
|
||||||
.builder(builder)
|
.builder(builder)
|
||||||
@ -171,8 +172,6 @@ public final class CommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String[] commandDetection(String[] split) {
|
public String[] commandDetection(String[] split) {
|
||||||
split[0] = split[0].substring(1);
|
|
||||||
|
|
||||||
// Quick script shortcut
|
// Quick script shortcut
|
||||||
if (split[0].matches("^[^/].*\\.js$")) {
|
if (split[0].matches("^[^/].*\\.js$")) {
|
||||||
String[] newSplit = new String[split.length + 1];
|
String[] newSplit = new String[split.length + 1];
|
||||||
@ -185,13 +184,14 @@ public final class CommandManager {
|
|||||||
String searchCmd = split[0].toLowerCase();
|
String searchCmd = split[0].toLowerCase();
|
||||||
|
|
||||||
// Try to detect the command
|
// Try to detect the command
|
||||||
if (dispatcher.contains(searchCmd)) {
|
if (!dispatcher.contains(searchCmd)) {
|
||||||
} else if (worldEdit.getConfiguration().noDoubleSlash && dispatcher.contains("/" + searchCmd)) {
|
if (worldEdit.getConfiguration().noDoubleSlash && dispatcher.contains("/" + searchCmd)) {
|
||||||
split[0] = "/" + split[0];
|
split[0] = "/" + split[0];
|
||||||
} else if (split[0].length() >= 2 && split[0].charAt(0) == '/'
|
} else if (searchCmd.length() >= 2 && searchCmd.charAt(0) == '/' && dispatcher.contains(searchCmd.substring(1))) {
|
||||||
&& dispatcher.contains(searchCmd.substring(1))) {
|
|
||||||
split[0] = split[0].substring(1);
|
split[0] = split[0].substring(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return split;
|
return split;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ public final class CommandManager {
|
|||||||
Request.reset();
|
Request.reset();
|
||||||
|
|
||||||
Actor actor = platformManager.createProxyActor(event.getActor());
|
Actor actor = platformManager.createProxyActor(event.getActor());
|
||||||
String split[] = commandDetection(event.getArguments());
|
String split[] = commandDetection(event.getArguments().split(" "));
|
||||||
|
|
||||||
// No command found!
|
// No command found!
|
||||||
if (!dispatcher.contains(split[0])) {
|
if (!dispatcher.contains(split[0])) {
|
||||||
@ -216,7 +216,7 @@ public final class CommandManager {
|
|||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dispatcher.call(Joiner.on(" ").join(split), locals);
|
dispatcher.call(null, Joiner.on(" ").join(split), locals);
|
||||||
} catch (CommandPermissionsException e) {
|
} catch (CommandPermissionsException e) {
|
||||||
actor.printError("You don't have permission to do this.");
|
actor.printError("You don't have permission to do this.");
|
||||||
} catch (InvalidUsageException e) {
|
} catch (InvalidUsageException e) {
|
||||||
@ -255,6 +255,15 @@ public final class CommandManager {
|
|||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void handleCommandSuggestion(CommandSuggestionEvent event) {
|
||||||
|
try {
|
||||||
|
event.setSuggestions(dispatcher.getSuggestions(event.getArguments()));
|
||||||
|
} catch (CommandException e) {
|
||||||
|
event.getActor().printError(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the command dispatcher instance.
|
* Get the command dispatcher instance.
|
||||||
*
|
*
|
||||||
|
@ -19,23 +19,22 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.internal.command;
|
package com.sk89q.worldedit.internal.command;
|
||||||
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.util.command.parametric.PermissionsHandler;
|
import com.sk89q.worldedit.util.auth.Authorizer;
|
||||||
|
|
||||||
public class CommandPermissionsHandler extends PermissionsHandler {
|
/**
|
||||||
|
* Implementation of an authorizer that uses {@link Actor#hasPermission(String)}.
|
||||||
public CommandPermissionsHandler() {
|
*/
|
||||||
}
|
public class ActorAuthorizer implements Authorizer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasPermission(CommandContext context, String permission) {
|
public boolean testPermission(CommandLocals locals, String permission) {
|
||||||
Actor sender = context.getLocals().get(Actor.class);
|
Actor sender = locals.get(Actor.class);
|
||||||
if (sender == null) {
|
if (sender == null) {
|
||||||
throw new RuntimeException("Uh oh! No 'Actor' specified so that we can check permissions");
|
throw new RuntimeException("Uh oh! No 'Actor' specified so that we can check permissions");
|
||||||
} else {
|
} else {
|
||||||
return sender.hasPermission(permission);
|
return sender.hasPermission(permission);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
38
src/main/java/com/sk89q/worldedit/util/auth/Authorizer.java
Normale Datei
38
src/main/java/com/sk89q/worldedit/util/auth/Authorizer.java
Normale Datei
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.util.auth;
|
||||||
|
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether permission is granted.
|
||||||
|
*/
|
||||||
|
public interface Authorizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether permission is granted for the given context.
|
||||||
|
*
|
||||||
|
* @param locals locals
|
||||||
|
* @param permission the permission string
|
||||||
|
* @return true if permitted
|
||||||
|
*/
|
||||||
|
boolean testPermission(CommandLocals locals, String permission);
|
||||||
|
|
||||||
|
}
|
35
src/main/java/com/sk89q/worldedit/util/auth/NullAuthorizer.java
Normale Datei
35
src/main/java/com/sk89q/worldedit/util/auth/NullAuthorizer.java
Normale Datei
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.util.auth;
|
||||||
|
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of {@link Authorizer} that always returns false for
|
||||||
|
* tests of permissions.
|
||||||
|
*/
|
||||||
|
public class NullAuthorizer implements Authorizer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testPermission(CommandLocals locals, String permission) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,7 +22,8 @@ package com.sk89q.worldedit.util.command;
|
|||||||
import com.sk89q.minecraft.util.commands.CommandException;
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
|
||||||
import java.util.Collection;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,13 +40,17 @@ public interface CommandCallable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the correct command based on the input.
|
* Execute the correct command based on the input.
|
||||||
|
* </p>
|
||||||
|
* The implementing class must perform the necessary permission checks.
|
||||||
*
|
*
|
||||||
|
* @param alias the alias that was used to invoke this command,
|
||||||
|
* which may be null if this is a "root" command
|
||||||
* @param arguments the arguments
|
* @param arguments the arguments
|
||||||
* @param locals the locals
|
* @param locals the locals
|
||||||
* @return the called command, or null if there was no command found
|
* @return the called command, or null if there was no command found
|
||||||
* @throws CommandException thrown on a command error
|
* @throws CommandException thrown on a command error
|
||||||
*/
|
*/
|
||||||
boolean call(String arguments, CommandLocals locals) throws CommandException;
|
boolean call(@Nullable String alias, String arguments, CommandLocals locals) throws CommandException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of suggestions based on input.
|
* Get a list of suggestions based on input.
|
||||||
@ -54,7 +59,7 @@ public interface CommandCallable {
|
|||||||
* @return a list of suggestions
|
* @return a list of suggestions
|
||||||
* @throws CommandException thrown if there was a parsing error
|
* @throws CommandException thrown if there was a parsing error
|
||||||
*/
|
*/
|
||||||
Collection<String> getSuggestions(String arguments) throws CommandException;
|
List<String> getSuggestions(String arguments) throws CommandException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an object describing this command.
|
* Get an object describing this command.
|
||||||
@ -63,4 +68,12 @@ public interface CommandCallable {
|
|||||||
*/
|
*/
|
||||||
Description getDescription();
|
Description getDescription();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether this command can be executed with the given context.
|
||||||
|
*
|
||||||
|
* @param locals the locals
|
||||||
|
* @return true if execution is permitted
|
||||||
|
*/
|
||||||
|
boolean testPermission(CommandLocals locals);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public interface Description {
|
|||||||
*
|
*
|
||||||
* @return a description, or null if no description is available
|
* @return a description, or null if no description is available
|
||||||
*/
|
*/
|
||||||
String getDescription();
|
String getShortDescription();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a longer help text about this command.
|
* Get a longer help text about this command.
|
||||||
|
@ -49,7 +49,7 @@ public class SimpleDescription implements Description {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getShortDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ public class SimpleDescription implements Description {
|
|||||||
* Set the description of the command.
|
* Set the description of the command.
|
||||||
*
|
*
|
||||||
* @param description the description
|
* @param description the description
|
||||||
* @see #getDescription()
|
* @see #getShortDescription()
|
||||||
*/
|
*/
|
||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
|
@ -25,6 +25,7 @@ import com.sk89q.minecraft.util.commands.CommandException;
|
|||||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,20 +90,20 @@ public class SimpleDispatcher implements Dispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean call(String arguments, CommandLocals locals) throws CommandException {
|
public boolean call(@Nullable String alias, String arguments, CommandLocals locals) throws CommandException {
|
||||||
String[] split = CommandContext.split(arguments);
|
String[] split = CommandContext.split(arguments);
|
||||||
Set<String> aliases = getPrimaryAliases();
|
Set<String> aliases = getPrimaryAliases();
|
||||||
|
|
||||||
if (aliases.isEmpty()) {
|
if (aliases.isEmpty()) {
|
||||||
throw new InvalidUsageException("This command has no sub-commands.", getDescription());
|
throw new InvalidUsageException("This command has no sub-commands.", getDescription());
|
||||||
} else if (split.length != 0) {
|
} else if (split.length > 0) {
|
||||||
String subCommand = split[0];
|
String subCommand = split[0];
|
||||||
|
String subArguments = Joiner.on(" ").join(Arrays.copyOfRange(split, 1, split.length));
|
||||||
CommandMapping mapping = get(subCommand);
|
CommandMapping mapping = get(subCommand);
|
||||||
String passedArguments = Joiner.on(" ").join(Arrays.copyOfRange(split, 1, split.length));
|
|
||||||
|
|
||||||
if (mapping != null) {
|
if (mapping != null) {
|
||||||
try {
|
try {
|
||||||
mapping.getCallable().call(passedArguments, locals);
|
mapping.getCallable().call(subCommand, subArguments, locals);
|
||||||
} catch (CommandException e) {
|
} catch (CommandException e) {
|
||||||
e.prependStack(subCommand);
|
e.prependStack(subCommand);
|
||||||
throw e;
|
throw e;
|
||||||
@ -119,13 +120,14 @@ public class SimpleDispatcher implements Dispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getSuggestions(String arguments) throws CommandException {
|
public List<String> getSuggestions(String arguments) throws CommandException {
|
||||||
String[] split = CommandContext.split(arguments);
|
String[] split = CommandContext.split(arguments);
|
||||||
|
|
||||||
if (split.length == 0) {
|
if (split.length == 0) {
|
||||||
return getAllAliases();
|
return new ArrayList<String>(getAllAliases());
|
||||||
} else if (split.length == 1) {
|
} else if (split.length == 1) {
|
||||||
String prefix = split[0];
|
String prefix = split[0];
|
||||||
|
if (!prefix.isEmpty()) {
|
||||||
List<String> suggestions = new ArrayList<String>();
|
List<String> suggestions = new ArrayList<String>();
|
||||||
|
|
||||||
for (String alias : getAllAliases()) {
|
for (String alias : getAllAliases()) {
|
||||||
@ -135,6 +137,9 @@ public class SimpleDispatcher implements Dispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return suggestions;
|
return suggestions;
|
||||||
|
} else {
|
||||||
|
return new ArrayList<String>(getAllAliases());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
String subCommand = split[0];
|
String subCommand = split[0];
|
||||||
CommandMapping mapping = get(subCommand);
|
CommandMapping mapping = get(subCommand);
|
||||||
@ -153,6 +158,17 @@ public class SimpleDispatcher implements Dispatcher {
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testPermission(CommandLocals locals) {
|
||||||
|
for (CommandMapping mapping : getCommands()) {
|
||||||
|
if (mapping.getCallable().testPermission(locals)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of subcommands for display.
|
* Get a list of subcommands for display.
|
||||||
*
|
*
|
||||||
|
@ -79,14 +79,14 @@ public class DispatcherNode {
|
|||||||
*
|
*
|
||||||
* @param object the object provided to the {@link ParametricBuilder}
|
* @param object the object provided to the {@link ParametricBuilder}
|
||||||
* @return this object
|
* @return this object
|
||||||
* @see ParametricBuilder#register(com.sk89q.worldedit.util.command.Dispatcher, Object)
|
* @see ParametricBuilder#registerMethodsAsCommands(com.sk89q.worldedit.util.command.Dispatcher, Object)
|
||||||
*/
|
*/
|
||||||
public DispatcherNode build(Object object) {
|
public DispatcherNode build(Object object) {
|
||||||
ParametricBuilder builder = graph.getBuilder();
|
ParametricBuilder builder = graph.getBuilder();
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
throw new RuntimeException("No ParametricBuilder set");
|
throw new RuntimeException("No ParametricBuilder set");
|
||||||
}
|
}
|
||||||
builder.register(getDispatcher(), object);
|
builder.registerMethodsAsCommands(getDispatcher(), object);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ import com.sk89q.minecraft.util.commands.Command;
|
|||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
import com.sk89q.minecraft.util.commands.CommandException;
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
|
import com.sk89q.worldedit.util.auth.Authorizer;
|
||||||
|
import com.sk89q.worldedit.util.auth.NullAuthorizer;
|
||||||
import com.sk89q.worldedit.util.command.CommandCallable;
|
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||||
import com.sk89q.worldedit.util.command.binding.PrimitiveBindings;
|
import com.sk89q.worldedit.util.command.binding.PrimitiveBindings;
|
||||||
@ -39,6 +41,8 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates commands using annotations placed on methods and individual parameters of
|
* Creates commands using annotations placed on methods and individual parameters of
|
||||||
* such methods.
|
* such methods.
|
||||||
@ -52,6 +56,7 @@ public class ParametricBuilder {
|
|||||||
private final Paranamer paranamer = new CachingParanamer();
|
private final Paranamer paranamer = new CachingParanamer();
|
||||||
private final List<InvokeListener> invokeListeners = new ArrayList<InvokeListener>();
|
private final List<InvokeListener> invokeListeners = new ArrayList<InvokeListener>();
|
||||||
private final List<ExceptionConverter> exceptionConverters = new ArrayList<ExceptionConverter>();
|
private final List<ExceptionConverter> exceptionConverters = new ArrayList<ExceptionConverter>();
|
||||||
|
private Authorizer authorizer = new NullAuthorizer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new builder.
|
* Create a new builder.
|
||||||
@ -115,7 +120,7 @@ public class ParametricBuilder {
|
|||||||
* @param listener the listener
|
* @param listener the listener
|
||||||
* @see InvokeHandler the handler
|
* @see InvokeHandler the handler
|
||||||
*/
|
*/
|
||||||
public void attach(InvokeListener listener) {
|
public void addInvokeListener(InvokeListener listener) {
|
||||||
invokeListeners.add(listener);
|
invokeListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +133,7 @@ public class ParametricBuilder {
|
|||||||
* @param converter the converter
|
* @param converter the converter
|
||||||
* @see ExceptionConverter for an explanation
|
* @see ExceptionConverter for an explanation
|
||||||
*/
|
*/
|
||||||
public void attach(ExceptionConverter converter) {
|
public void addExceptionConverter(ExceptionConverter converter) {
|
||||||
exceptionConverters.add(converter);
|
exceptionConverters.add(converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +146,7 @@ public class ParametricBuilder {
|
|||||||
* @param object the object contain the methods
|
* @param object the object contain the methods
|
||||||
* @throws ParametricException thrown if the commands cannot be registered
|
* @throws ParametricException thrown if the commands cannot be registered
|
||||||
*/
|
*/
|
||||||
public void register(Dispatcher dispatcher, Object object) throws ParametricException {
|
public void registerMethodsAsCommands(Dispatcher dispatcher, Object object) throws ParametricException {
|
||||||
for (Method method : object.getClass().getDeclaredMethods()) {
|
for (Method method : object.getClass().getDeclaredMethods()) {
|
||||||
Command definition = method.getAnnotation(Command.class);
|
Command definition = method.getAnnotation(Command.class);
|
||||||
if (definition != null) {
|
if (definition != null) {
|
||||||
@ -202,4 +207,22 @@ public class ParametricBuilder {
|
|||||||
return exceptionConverters;
|
return exceptionConverters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authorizer.
|
||||||
|
*
|
||||||
|
* @return the authorizer
|
||||||
|
*/
|
||||||
|
public Authorizer getAuthorizer() {
|
||||||
|
return authorizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the authorizer.
|
||||||
|
*
|
||||||
|
* @param authorizer the authorizer
|
||||||
|
*/
|
||||||
|
public void setAuthorizer(Authorizer authorizer) {
|
||||||
|
checkNotNull(authorizer);
|
||||||
|
this.authorizer = authorizer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import com.sk89q.minecraft.util.commands.*;
|
|||||||
import com.sk89q.worldedit.util.command.*;
|
import com.sk89q.worldedit.util.command.*;
|
||||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -40,6 +41,7 @@ class ParametricCallable implements CommandCallable {
|
|||||||
private final ParameterData[] parameters;
|
private final ParameterData[] parameters;
|
||||||
private final Set<Character> valueFlags = new HashSet<Character>();
|
private final Set<Character> valueFlags = new HashSet<Character>();
|
||||||
private final SimpleDescription description = new SimpleDescription();
|
private final SimpleDescription description = new SimpleDescription();
|
||||||
|
private final CommandPermissions commandPermissions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
@ -50,11 +52,7 @@ class ParametricCallable implements CommandCallable {
|
|||||||
* @param definition the command definition annotation
|
* @param definition the command definition annotation
|
||||||
* @throws ParametricException thrown on an error
|
* @throws ParametricException thrown on an error
|
||||||
*/
|
*/
|
||||||
ParametricCallable(
|
ParametricCallable(ParametricBuilder builder, Object object, Method method, Command definition) throws ParametricException {
|
||||||
ParametricBuilder builder,
|
|
||||||
Object object, Method method,
|
|
||||||
Command definition) throws ParametricException {
|
|
||||||
|
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
this.object = object;
|
this.object = object;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
@ -101,8 +99,7 @@ class ParametricCallable implements CommandCallable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parameter.setName(names.length > 0 ?
|
parameter.setName(names.length > 0 ? names[i] : generateName(type, parameter.getClassifier(), i));
|
||||||
names[i] : generateName(type, parameter.getClassifier(), i));
|
|
||||||
|
|
||||||
// Track all value flags
|
// Track all value flags
|
||||||
if (parameter.isValueFlag()) {
|
if (parameter.isValueFlag()) {
|
||||||
@ -115,9 +112,7 @@ class ParametricCallable implements CommandCallable {
|
|||||||
|
|
||||||
// Don't know how to parse for this type of value
|
// Don't know how to parse for this type of value
|
||||||
if (parameter.getBinding() == null) {
|
if (parameter.getBinding() == null) {
|
||||||
throw new ParametricException(
|
throw new ParametricException("Don't know how to handle the parameter type '" + type + "' in\n" + method.toGenericString());
|
||||||
"Don't know how to handle the parameter type '" + type + "' in\n" +
|
|
||||||
method.toGenericString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,11 +154,19 @@ class ParametricCallable implements CommandCallable {
|
|||||||
|
|
||||||
// Set parameters
|
// Set parameters
|
||||||
description.setParameters(userParameters);
|
description.setParameters(userParameters);
|
||||||
|
|
||||||
|
// Get permissions annotation
|
||||||
|
commandPermissions = method.getAnnotation(CommandPermissions.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean call(String stringArguments, CommandLocals locals) throws CommandException {
|
public boolean call(@Nullable String alias, String stringArguments, CommandLocals locals) throws CommandException {
|
||||||
String[] split = CommandContext.split(stringArguments);
|
// Test permission
|
||||||
|
if (!testPermission(locals)) {
|
||||||
|
throw new CommandPermissionsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] split = CommandContext.split(alias + " " + stringArguments);
|
||||||
CommandContext context = new CommandContext(split, getValueFlags(), false, locals);
|
CommandContext context = new CommandContext(split, getValueFlags(), false, locals);
|
||||||
|
|
||||||
Object[] args = new Object[parameters.length];
|
Object[] args = new Object[parameters.length];
|
||||||
@ -218,12 +221,9 @@ class ParametricCallable implements CommandCallable {
|
|||||||
handler.postInvoke(handler, method, parameters, args, context);
|
handler.postInvoke(handler, method, parameters, args, context);
|
||||||
}
|
}
|
||||||
} catch (MissingParameterException e) {
|
} catch (MissingParameterException e) {
|
||||||
throw new InvalidUsageException(
|
throw new InvalidUsageException("Too few parameters!", getDescription());
|
||||||
"Too few parameters!", getDescription());
|
|
||||||
} catch (UnconsumedParameterException e) {
|
} catch (UnconsumedParameterException e) {
|
||||||
throw new InvalidUsageException(
|
throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), getDescription());
|
||||||
"Too many parameters! Unused parameters: "
|
|
||||||
+ e.getUnconsumed(), getDescription());
|
|
||||||
} catch (ParameterException e) {
|
} catch (ParameterException e) {
|
||||||
if (e.getCause() != null) {
|
if (e.getCause() != null) {
|
||||||
for (ExceptionConverter converter : builder.getExceptionConverters()) {
|
for (ExceptionConverter converter : builder.getExceptionConverters()) {
|
||||||
@ -231,10 +231,10 @@ class ParametricCallable implements CommandCallable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert parameter != null;
|
||||||
String name = parameter.getName();
|
String name = parameter.getName();
|
||||||
|
|
||||||
throw new InvalidUsageException("For parameter '" + name + "': "
|
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), getDescription());
|
||||||
+ e.getMessage(), getDescription());
|
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
for (ExceptionConverter converter : builder.getExceptionConverters()) {
|
for (ExceptionConverter converter : builder.getExceptionConverters()) {
|
||||||
converter.convert(e.getCause());
|
converter.convert(e.getCause());
|
||||||
@ -252,7 +252,7 @@ class ParametricCallable implements CommandCallable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getSuggestions(String stringArguments) throws CommandException {
|
public List<String> getSuggestions(String stringArguments) throws CommandException {
|
||||||
String[] split = CommandContext.split(stringArguments);
|
String[] split = CommandContext.split(stringArguments);
|
||||||
CommandContext context = new CommandContext(split, getValueFlags());
|
CommandContext context = new CommandContext(split, getValueFlags());
|
||||||
|
|
||||||
@ -281,9 +281,7 @@ class ParametricCallable implements CommandCallable {
|
|||||||
ParameterData lastConsumer = null;
|
ParameterData lastConsumer = null;
|
||||||
String lastConsumed = null;
|
String lastConsumed = null;
|
||||||
|
|
||||||
for (int i = 0; i < parameters.length; i++) {
|
for (ParameterData parameter : parameters) {
|
||||||
ParameterData parameter = parameters[i];
|
|
||||||
|
|
||||||
if (parameter.getFlag() != null) {
|
if (parameter.getFlag() != null) {
|
||||||
continue; // We already handled flags
|
continue; // We already handled flags
|
||||||
}
|
}
|
||||||
@ -353,6 +351,21 @@ class ParametricCallable implements CommandCallable {
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testPermission(CommandLocals locals) {
|
||||||
|
if (commandPermissions != null) {
|
||||||
|
for (String perm : commandPermissions.value()) {
|
||||||
|
if (builder.getAuthorizer().testPermission(locals, perm)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the right {@link ArgumentStack}.
|
* Get the right {@link ArgumentStack}.
|
||||||
*
|
*
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* WorldEdit, a Minecraft world manipulation toolkit
|
|
||||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
|
||||||
* Copyright (C) WorldEdit team and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser 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 Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sk89q.worldedit.util.command.parametric;
|
|
||||||
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandException;
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A handler for the {@link CommandPermissions} annotation.
|
|
||||||
*/
|
|
||||||
public abstract class PermissionsHandler extends AbstractInvokeListener implements InvokeHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InvokeHandler createInvokeHandler() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preProcess(Object object, Method method,
|
|
||||||
ParameterData[] parameters, CommandContext context)
|
|
||||||
throws CommandException, ParameterException {
|
|
||||||
CommandPermissions annotation = method.getAnnotation(CommandPermissions.class);
|
|
||||||
if (annotation != null) {
|
|
||||||
for (String perm : annotation.value()) {
|
|
||||||
if (hasPermission(context, perm)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new CommandPermissionsException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preInvoke(Object object, Method method, ParameterData[] parameters,
|
|
||||||
Object[] args, CommandContext context) throws CommandException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInvoke(Object object, Method method, ParameterData[] parameters,
|
|
||||||
Object[] args, CommandContext context) throws CommandException {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean hasPermission(CommandContext context, String permission);
|
|
||||||
|
|
||||||
}
|
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren