--- ../work/decompile-8eb82bde/net/minecraft/server/CommandBlockListenerAbstract.java 2014-12-11 20:04:50.493619968 +0000 +++ src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java 2014-12-11 20:02:45.005621331 +0000 @@ -4,6 +4,13 @@ import java.util.Date; import java.util.concurrent.Callable; +// CraftBukkit start +import java.util.ArrayList; +import org.apache.logging.log4j.Level; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; +import com.google.common.base.Joiner; +// CraftBukkit end + public abstract class CommandBlockListenerAbstract implements ICommandListener { private static final SimpleDateFormat a = new SimpleDateFormat("HH:mm:ss"); @@ -13,6 +20,7 @@ public String e = ""; private String f = "@"; private final CommandObjectiveExecutor g = new CommandObjectiveExecutor(); + protected org.bukkit.command.CommandSender sender; // CraftBukkit - add sender public CommandBlockListenerAbstract() {} @@ -79,7 +87,10 @@ try { this.d = null; - this.b = icommandhandler.a(this, this.e); + // this.b = icommandhandler.a(this, this.e); + // CraftBukkit start - Handle command block commands using Bukkit dispatcher + this.b= executeCommand(this, sender, this.e); + // CraftBukkit end } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Executing command block"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Command to be executed"); @@ -91,8 +102,129 @@ } else { this.b = 0; } + } + + // CraftBukkit start + + public static int executeCommand(ICommandListener sender, org.bukkit.command.CommandSender bSender, String command) { + org.bukkit.command.SimpleCommandMap commandMap = sender.getWorld().getServer().getCommandMap(); + Joiner joiner = Joiner.on(" "); + if (command.startsWith("/")) { + command = command.substring(1); + } + String[] args = command.split(" "); + ArrayList commands = new ArrayList(); + + // Block disallowed commands + if (args[0].equalsIgnoreCase("stop") || args[0].equalsIgnoreCase("kick") || args[0].equalsIgnoreCase("op") + || args[0].equalsIgnoreCase("deop") || args[0].equalsIgnoreCase("ban") || args[0].equalsIgnoreCase("ban-ip") + || args[0].equalsIgnoreCase("pardon") || args[0].equalsIgnoreCase("pardon-ip") || args[0].equalsIgnoreCase("reload")) { + return 0; + } + + // If the world has no players don't run + if (sender.getWorld().players.isEmpty()) { + return 0; + } + + // Handle vanilla commands; + org.bukkit.command.Command commandBlockCommand = commandMap.getCommand(args[0]); + if (sender.getWorld().getServer().getCommandBlockOverride(args[0])) { + commandBlockCommand = commandMap.getCommand("minecraft:" + args[0]); + } + if (commandBlockCommand instanceof VanillaCommandWrapper) { + command = command.trim(); + if (command.startsWith("/")) { + command = command.substring(1); + } + String as[] = command.split(" "); + as = VanillaCommandWrapper.dropFirstArgument(as); + return ((VanillaCommandWrapper) commandBlockCommand).dispatchVanillaCommand(sender, as); + } + + // Make sure this is a valid command + if (commandMap.getCommand(args[0]) == null) { + return 0; + } + + // testfor command requires special handling + if (args[0].equalsIgnoreCase("testfor")) { + if (args.length < 2) { + return 0; + } + + EntityPlayer[] players = ((java.util.List) PlayerSelector.getPlayers(sender, args[1], EntityPlayer.class)).toArray(new EntityPlayer[0]); + + if (players != null && players.length > 0) { + return players.length; + } else { + EntityPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(args[1]); + if (player == null) { + return 0; + } else { + return 1; + } + } + } + + commands.add(args); + + // Find positions of command block syntax, if any + ArrayList newCommands = new ArrayList(); + for (int i = 0; i < args.length; i++) { + if (PlayerSelector.isPattern(args[i])) { + for (int j = 0; j < commands.size(); j++) { + newCommands.addAll(buildCommands(sender, commands.get(j), i)); + } + ArrayList temp = commands; + commands = newCommands; + newCommands = temp; + newCommands.clear(); + } + } + + int completed = 0; + + // Now dispatch all of the commands we ended up with + for (int i = 0; i < commands.size(); i++) { + try { + if (commandMap.dispatch(bSender, joiner.join(java.util.Arrays.asList(commands.get(i))))) { + completed++; + } + } catch (Throwable exception) { + if (sender instanceof TileEntityCommandListener) { + TileEntityCommandListener listener = (TileEntityCommandListener) sender; + MinecraftServer.getLogger().log(Level.WARN, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().getX(), listener.getChunkCoordinates().getY(), listener.getChunkCoordinates().getZ()), exception); + } else if (sender instanceof EntityMinecartCommandBlockListener) { + EntityMinecartCommandBlockListener listener = (EntityMinecartCommandBlockListener) sender; + MinecraftServer.getLogger().log(Level.WARN, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().getX(), listener.getChunkCoordinates().getY(), listener.getChunkCoordinates().getZ()), exception); + } else { + MinecraftServer.getLogger().log(Level.WARN, String.format("Unknown CommandBlock failed to handle command"), exception); + } + } + } + + return completed; + } + + private static ArrayList buildCommands(ICommandListener sender, String[] args, int pos) { + ArrayList commands = new ArrayList(); + java.util.List players = (java.util.List)PlayerSelector.getPlayers(sender, args[pos], EntityPlayer.class); + + if (players != null) { + for (EntityPlayer player : players) { + if (player.world != sender.getWorld()) { + continue; + } + String[] command = args.clone(); + command[pos] = player.getName(); + commands.add(command); + } + } + return commands; } + // CraftBukkit end public String getName() { return this.f;