From eafbb2a4c1b2c02688c3496d157ba870bdc6162b Mon Sep 17 00:00:00 2001 From: Thinkofdeath Date: Tue, 17 Dec 2013 13:56:38 +0000 Subject: [PATCH] Add VanillaCommandWrapper which allows use of vanilla commands instead of Bukkit's versions --- ...-for-fallback-commands-to-be-removed.patch | 32 +++ CraftBukkit-Patches/0002-mc-dev-imports.patch | 103 ++++++- ...low-Disabling-of-Command-TabComplete.patch | 23 +- ...mand-Wrapper-to-Support-New-Commands.patch | 266 ++++++++++++++++++ 4 files changed, 413 insertions(+), 11 deletions(-) create mode 100644 Bukkit-Patches/0020-Allow-for-fallback-commands-to-be-removed.patch create mode 100644 CraftBukkit-Patches/0078-Add-VanillaCommand-Wrapper-to-Support-New-Commands.patch diff --git a/Bukkit-Patches/0020-Allow-for-fallback-commands-to-be-removed.patch b/Bukkit-Patches/0020-Allow-for-fallback-commands-to-be-removed.patch new file mode 100644 index 000000000..af28f6951 --- /dev/null +++ b/Bukkit-Patches/0020-Allow-for-fallback-commands-to-be-removed.patch @@ -0,0 +1,32 @@ +From 47c6643184e01fc22dc9eecbca2aec48e2900616 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Wed, 18 Dec 2013 10:19:50 +1100 +Subject: [PATCH] Allow for fallback commands to be removed. + + +diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java +index f716782..cb0707f 100644 +--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java ++++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java +@@ -326,4 +326,18 @@ public class SimpleCommandMap implements CommandMap { + } + } + } ++ ++ // Spigot Start ++ public static void removeFallback(String name) ++ { ++ Iterator it = fallbackCommands.iterator(); ++ while ( it.hasNext() ) ++ { ++ if ( it.next().getName().equals( name ) ) ++ { ++ it.remove(); ++ } ++ } ++ } ++ // Spigot End + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0002-mc-dev-imports.patch b/CraftBukkit-Patches/0002-mc-dev-imports.patch index 39d68985b..a197cbc48 100644 --- a/CraftBukkit-Patches/0002-mc-dev-imports.patch +++ b/CraftBukkit-Patches/0002-mc-dev-imports.patch @@ -1,4 +1,4 @@ -From 2993d045a90bcfeae07f067426b3c7017cea19de Mon Sep 17 00:00:00 2001 +From de08f8f69e8b657102b9a99a0a1cbdcff2174da8 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 1 Dec 2013 15:10:48 +1100 Subject: [PATCH] mc-dev imports @@ -406,6 +406,105 @@ index 0000000..6d5090b + return false; + } +} +diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java +new file mode 100644 +index 0000000..e63f17c +--- /dev/null ++++ b/src/main/java/net/minecraft/server/CommandDispatcher.java +@@ -0,0 +1,93 @@ ++package net.minecraft.server; ++ ++import java.util.Iterator; ++ ++public class CommandDispatcher extends CommandHandler implements ICommandDispatcher { ++ ++ public CommandDispatcher() { ++ this.a(new CommandTime()); ++ this.a(new CommandGamemode()); ++ this.a(new CommandDifficulty()); ++ this.a(new CommandGamemodeDefault()); ++ this.a(new CommandKill()); ++ this.a(new CommandToggleDownfall()); ++ this.a(new CommandWeather()); ++ this.a(new CommandXp()); ++ this.a(new CommandTp()); ++ this.a(new CommandGive()); ++ this.a(new CommandEffect()); ++ this.a(new CommandEnchant()); ++ this.a(new CommandMe()); ++ this.a(new CommandSeed()); ++ this.a(new CommandHelp()); ++ this.a(new CommandDebug()); ++ this.a(new CommandTell()); ++ this.a(new CommandSay()); ++ this.a(new CommandSpawnpoint()); ++ this.a(new CommandSetWorldSpawn()); ++ this.a(new CommandGamerule()); ++ this.a(new CommandClear()); ++ this.a(new CommandTestFor()); ++ this.a(new CommandSpreadPlayers()); ++ this.a(new CommandPlaySound()); ++ this.a(new CommandScoreboard()); ++ this.a(new CommandAchievement()); ++ this.a(new CommandSummon()); ++ this.a(new CommandSetBlock()); ++ this.a(new CommandTestForBlock()); ++ this.a(new CommandTellRaw()); ++ if (MinecraftServer.getServer().V()) { ++ this.a(new CommandOp()); ++ this.a(new CommandDeop()); ++ this.a(new CommandStop()); ++ this.a(new CommandSaveAll()); ++ this.a(new CommandSaveOff()); ++ this.a(new CommandSaveOn()); ++ this.a(new CommandBanIp()); ++ this.a(new CommandPardonIP()); ++ this.a(new CommandBan()); ++ this.a(new CommandBanList()); ++ this.a(new CommandPardon()); ++ this.a(new CommandKick()); ++ this.a(new CommandList()); ++ this.a(new CommandWhitelist()); ++ this.a(new CommandIdleTimeout()); ++ } else { ++ this.a(new CommandPublish()); ++ } ++ ++ CommandAbstract.a((ICommandDispatcher) this); ++ } ++ ++ public void a(ICommandListener icommandlistener, int i, String s, Object... aobject) { ++ boolean flag = true; ++ ++ if (icommandlistener instanceof CommandBlockListenerAbstract && !MinecraftServer.getServer().worldServer[0].getGameRules().getBoolean("commandBlockOutput")) { ++ flag = false; ++ } ++ ++ ChatMessage chatmessage = new ChatMessage("chat.type.admin", new Object[] { icommandlistener.getName(), new ChatMessage(s, aobject)}); ++ ++ chatmessage.b().setColor(EnumChatFormat.GRAY); ++ chatmessage.b().setItalic(Boolean.valueOf(true)); ++ if (flag) { ++ Iterator iterator = MinecraftServer.getServer().getPlayerList().players.iterator(); ++ ++ while (iterator.hasNext()) { ++ EntityPlayer entityplayer = (EntityPlayer) iterator.next(); ++ ++ if (entityplayer != icommandlistener && MinecraftServer.getServer().getPlayerList().isOp(entityplayer.getName())) { ++ entityplayer.sendMessage(chatmessage); ++ } ++ } ++ } ++ ++ if (icommandlistener != MinecraftServer.getServer()) { ++ MinecraftServer.getServer().sendMessage(chatmessage); ++ } ++ ++ if ((i & 1) != 1) { ++ icommandlistener.sendMessage(new ChatMessage(s, aobject)); ++ } ++ } ++} diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java new file mode 100644 index 0000000..90a2a80 @@ -1606,5 +1705,5 @@ index 0000000..c0db754 + } +} -- -1.8.3.2 +1.8.4.msysgit.0 diff --git a/CraftBukkit-Patches/0038-Allow-Disabling-of-Command-TabComplete.patch b/CraftBukkit-Patches/0038-Allow-Disabling-of-Command-TabComplete.patch index 5591a2b82..277e333af 100644 --- a/CraftBukkit-Patches/0038-Allow-Disabling-of-Command-TabComplete.patch +++ b/CraftBukkit-Patches/0038-Allow-Disabling-of-Command-TabComplete.patch @@ -1,24 +1,29 @@ -From 30b566390c93fe321c36d403a6deb36a6f3c4b83 Mon Sep 17 00:00:00 2001 +From 9257663bcbcb86a961a7560ae825893adef4f025 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 21 Jun 2013 18:05:54 +1000 Subject: [PATCH] Allow Disabling of Command TabComplete diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 11f018b..abe05dc 100644 +index 11f018b..c71ce7c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1398,7 +1398,7 @@ public final class CraftServer implements Server { +@@ -1396,6 +1396,13 @@ public final class CraftServer implements Server { + } + public List tabCompleteCommand(Player player, String message) { ++ // Spigot Start ++ if ( org.spigotmc.SpigotConfig.tabComplete ) ++ { ++ return ImmutableList.of(); ++ } ++ // Spigot End ++ List completions = null; try { -- completions = getCommandMap().tabComplete(player, message.substring(1)); -+ completions = (org.spigotmc.SpigotConfig.tabComplete) ? getCommandMap().tabComplete(player, message.substring(1)) : null; - } catch (CommandException ex) { - player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to tab-complete this command"); - getLogger().log(Level.SEVERE, "Exception when " + player.getName() + " attempted to tab complete " + message, ex); + completions = getCommandMap().tabComplete(player, message.substring(1)); diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java -index 895af4b..21dc8c7 100644 +index 26d5845..dd842c6 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -142,4 +142,10 @@ public class SpigotConfig diff --git a/CraftBukkit-Patches/0078-Add-VanillaCommand-Wrapper-to-Support-New-Commands.patch b/CraftBukkit-Patches/0078-Add-VanillaCommand-Wrapper-to-Support-New-Commands.patch new file mode 100644 index 000000000..364cb4e02 --- /dev/null +++ b/CraftBukkit-Patches/0078-Add-VanillaCommand-Wrapper-to-Support-New-Commands.patch @@ -0,0 +1,266 @@ +From b3011dc8a9d95e3b0f102769229209233c51454d Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Wed, 18 Dec 2013 10:32:15 +1100 +Subject: [PATCH] Add VanillaCommand Wrapper to Support New Commands + +This implements testfor, setblock and summon, as well as the capacity to replace any command with its vanilla version. + +diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +index 5271272..f8d2ecb 100644 +--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java ++++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +@@ -96,7 +96,7 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { + + // Make sure this is a valid command + if (commandMap.getCommand(args[0]) == null) { +- this.b = 0; ++ this.b = org.spigotmc.VanillaCommandWrapper.dispatch( sender, command ); // Spigot - Try vanilla commands + return; + } + +diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java +index e63f17c..e58be15 100644 +--- a/src/main/java/net/minecraft/server/CommandDispatcher.java ++++ b/src/main/java/net/minecraft/server/CommandDispatcher.java +@@ -62,7 +62,7 @@ public class CommandDispatcher extends CommandHandler implements ICommandDispatc + public void a(ICommandListener icommandlistener, int i, String s, Object... aobject) { + boolean flag = true; + +- if (icommandlistener instanceof CommandBlockListenerAbstract && !MinecraftServer.getServer().worldServer[0].getGameRules().getBoolean("commandBlockOutput")) { ++ if (icommandlistener instanceof CommandBlockListenerAbstract && !MinecraftServer.getServer().worlds.get(0).getGameRules().getBoolean("commandBlockOutput")) { // Spigot - worldServer -> worlds + flag = false; + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 68c0f4e..2d79deb 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -546,6 +546,12 @@ public final class CraftServer implements Server { + if (commandMap.dispatch(sender, commandLine)) { + return true; + } ++ // Spigot Start - Try vanilla commands ++ if ( org.spigotmc.VanillaCommandWrapper.dispatch( sender, commandLine ) != -1 ) ++ { ++ return true; ++ } ++ // Spigot End + + sender.sendMessage(org.spigotmc.SpigotConfig.unknownCommandMessage); + +@@ -1399,15 +1405,23 @@ public final class CraftServer implements Server { + } + // Spigot End + +- List completions = null; ++ // Spigot Start ++ List completions = new ArrayList(); + try { +- completions = getCommandMap().tabComplete(player, message.substring(1)); ++ message = message.substring( 1 ); ++ List bukkitCompletions = getCommandMap().tabComplete( player, message ); ++ if ( bukkitCompletions != null ) ++ { ++ completions.addAll( bukkitCompletions ); ++ } ++ completions.addAll( org.spigotmc.VanillaCommandWrapper.complete( player, message ) ); ++ // Spigot End + } catch (CommandException ex) { + player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to tab-complete this command"); + getLogger().log(Level.SEVERE, "Exception when " + player.getName() + " attempted to tab complete " + message, ex); + } + +- return completions == null ? ImmutableList.of() : completions; ++ return completions; // Spigot + } + + public List tabCompleteChat(Player player, String message) { +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index c4a5488..628533e 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -6,6 +6,7 @@ import java.io.IOException; + import java.lang.reflect.InvocationTargetException; + import java.lang.reflect.Method; + import java.lang.reflect.Modifier; ++import java.util.Arrays; + import java.util.HashMap; + import java.util.List; + import java.util.Map; +@@ -14,6 +15,7 @@ import net.minecraft.server.MinecraftServer; + import org.bukkit.Bukkit; + import org.bukkit.ChatColor; + import org.bukkit.command.Command; ++import org.bukkit.command.SimpleCommandMap; + import org.bukkit.configuration.file.YamlConfiguration; + import org.bukkit.craftbukkit.command.TicksPerSecondCommand; + +@@ -204,4 +206,13 @@ public class SpigotConfig + System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) ); + Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count ); + } ++ ++ private static void replaceCommands() ++ { ++ for ( String command : (List) getList( "replace-commands", Arrays.asList( "setblock", "summon", "testforblock" ) ) ) ++ { ++ SimpleCommandMap.removeFallback( command ); ++ VanillaCommandWrapper.allowedCommands.add( command ); ++ } ++ } + } +diff --git a/src/main/java/org/spigotmc/VanillaCommandWrapper.java b/src/main/java/org/spigotmc/VanillaCommandWrapper.java +new file mode 100644 +index 0000000..e778d47 +--- /dev/null ++++ b/src/main/java/org/spigotmc/VanillaCommandWrapper.java +@@ -0,0 +1,146 @@ ++package org.spigotmc; ++ ++import com.google.common.collect.ImmutableList; ++import net.minecraft.server.ChunkCoordinates; ++import net.minecraft.server.EntityMinecartCommandBlock; ++import net.minecraft.server.IChatBaseComponent; ++import net.minecraft.server.ICommandListener; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.TileEntityCommand; ++import net.minecraft.server.World; ++import org.bukkit.ChatColor; ++import org.bukkit.block.Block; ++import org.bukkit.command.CommandSender; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.command.CraftBlockCommandSender; ++import org.bukkit.craftbukkit.entity.CraftMinecartCommand; ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import java.util.ArrayList; ++import java.util.HashSet; ++import java.util.List; ++ ++public class VanillaCommandWrapper ++{ ++ ++ public static final HashSet allowedCommands = new HashSet(); ++ ++ public static int dispatch(CommandSender sender, String commandLine) ++ { ++ int pos = commandLine.indexOf( ' ' ); ++ if ( pos == -1 ) ++ { ++ pos = commandLine.length(); ++ } ++ String name = commandLine.substring( 0, pos ); ++ if ( !allowedCommands.contains( name ) ) ++ { ++ return -1; ++ } ++ if ( !sender.hasPermission( "bukkit.command." + name ) ) ++ { ++ sender.sendMessage( ChatColor.RED + "You do not have permission for this command" ); ++ return 0; ++ } ++ ICommandListener listener = getListener( sender ); ++ if ( listener == null ) ++ { ++ return -1; ++ } ++ return MinecraftServer.getServer().getCommandHandler().a( listener, commandLine ); ++ } ++ ++ public static List complete(CommandSender sender, String commandLine) ++ { ++ int pos = commandLine.indexOf( ' ' ); ++ if ( pos == -1 ) ++ { ++ List completions = new ArrayList(); ++ commandLine = commandLine.toLowerCase(); ++ for ( String command : allowedCommands ) ++ { ++ if ( command.startsWith( commandLine ) && sender.hasPermission( "bukkit.command." + command ) ) ++ { ++ completions.add( "/" + command ); ++ } ++ } ++ return completions; ++ } ++ String name = commandLine.substring( 0, pos ); ++ if ( !allowedCommands.contains( name ) || !sender.hasPermission( "bukkit.command." + name ) ) ++ { ++ return ImmutableList.of(); ++ } ++ ICommandListener listener = getListener( sender ); ++ if ( listener == null ) ++ { ++ return ImmutableList.of(); ++ } ++ return MinecraftServer.getServer().getCommandHandler().b( listener, commandLine ); ++ } ++ ++ private static ICommandListener getListener(CommandSender sender) ++ { ++ if ( sender instanceof CraftPlayer ) ++ { ++ return new PlayerListener( ( (CraftPlayer) sender ).getHandle() ); ++ } ++ if ( sender instanceof CraftBlockCommandSender ) ++ { ++ CraftBlockCommandSender commandBlock = (CraftBlockCommandSender) sender; ++ Block block = commandBlock.getBlock(); ++ return ( (TileEntityCommand) ( (CraftWorld) block.getWorld() ).getTileEntityAt( block.getX(), block.getY(), block.getZ() ) ).a(); ++ } ++ if ( sender instanceof CraftMinecartCommand ) ++ { ++ return ( (EntityMinecartCommandBlock) ( (CraftMinecartCommand) sender ).getHandle() ).e(); ++ } ++ return null; ++ } ++ ++ private static class PlayerListener implements ICommandListener ++ { ++ ++ private final ICommandListener handle; ++ ++ public PlayerListener(ICommandListener handle) ++ { ++ this.handle = handle; ++ } ++ ++ @Override ++ public String getName() ++ { ++ return handle.getName(); ++ } ++ ++ @Override ++ public IChatBaseComponent getScoreboardDisplayName() ++ { ++ return handle.getScoreboardDisplayName(); ++ } ++ ++ @Override ++ public void sendMessage(IChatBaseComponent iChatBaseComponent) ++ { ++ handle.sendMessage( iChatBaseComponent ); ++ } ++ ++ @Override ++ public boolean a(int i, String s) ++ { ++ return true; ++ } ++ ++ @Override ++ public ChunkCoordinates getChunkCoordinates() ++ { ++ return handle.getChunkCoordinates(); ++ } ++ ++ @Override ++ public World getWorld() ++ { ++ return handle.getWorld(); ++ } ++ } ++} +-- +1.8.3.2 +