From 553acdf0cdde1abe59399a83af5cc3deb78c188f Mon Sep 17 00:00:00 2001 From: t00thpick1 Date: Fri, 7 Feb 2014 18:40:59 -0500 Subject: [PATCH] [Bleeding] Implement Mojang command fallback system. Adds BUKKIT-5385 --- .../server/CommandBlockListenerAbstract.java | 18 +- .../org/bukkit/craftbukkit/CraftServer.java | 131 +++++++++++- .../java/org/bukkit/craftbukkit/Main.java | 6 + .../command/CraftBlockCommandSender.java | 5 + .../command/VanillaCommandWrapper.java | 192 ++++++++++++++++++ .../craftbukkit/help/SimpleHelpMap.java | 16 +- src/main/resources/configurations/bukkit.yml | 8 +- .../resources/configurations/commands.yml | 4 + 8 files changed, 361 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java create mode 100644 src/main/resources/configurations/commands.yml diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java index 527127289b..2f5ee94425 100644 --- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java @@ -6,6 +6,7 @@ import java.util.Date; // 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 @@ -94,14 +95,23 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { return; } - // Make sure this is a valid command - if (commandMap.getCommand(args[0]) == null) { + // If the world has no players don't run + if (this.getWorld().players.isEmpty()) { this.b = 0; return; } - // If the world has no players don't run - if (this.getWorld().players.isEmpty()) { + // Handle vanilla commands; + if (minecraftserver.server.getCommandBlockOverride(args[0])) { + org.bukkit.command.Command commandBlockCommand = commandMap.getCommand("minecraft:" + args[0]); + if (commandBlockCommand instanceof VanillaCommandWrapper) { + this.b = ((VanillaCommandWrapper) commandBlockCommand).dispatchVanillaCommandBlock(this, this.e); + return; + } + } + + // Make sure this is a valid command + if (commandMap.getCommand(args[0]) == null) { this.b = 0; return; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 17c8039b78..22f394d597 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -14,6 +14,7 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.UUID; import java.util.logging.Level; @@ -23,6 +24,47 @@ import javax.imageio.ImageIO; import net.minecraft.server.BanEntry; import net.minecraft.server.ChunkCoordinates; +import net.minecraft.server.CommandAchievement; +import net.minecraft.server.CommandBan; +import net.minecraft.server.CommandBanIp; +import net.minecraft.server.CommandBanList; +import net.minecraft.server.CommandClear; +import net.minecraft.server.CommandDeop; +import net.minecraft.server.CommandDifficulty; +import net.minecraft.server.CommandEffect; +import net.minecraft.server.CommandEnchant; +import net.minecraft.server.CommandGamemode; +import net.minecraft.server.CommandGamemodeDefault; +import net.minecraft.server.CommandGamerule; +import net.minecraft.server.CommandGive; +import net.minecraft.server.CommandHelp; +import net.minecraft.server.CommandIdleTimeout; +import net.minecraft.server.CommandKick; +import net.minecraft.server.CommandKill; +import net.minecraft.server.CommandList; +import net.minecraft.server.CommandMe; +import net.minecraft.server.CommandOp; +import net.minecraft.server.CommandPardon; +import net.minecraft.server.CommandPardonIP; +import net.minecraft.server.CommandPlaySound; +import net.minecraft.server.CommandSay; +import net.minecraft.server.CommandScoreboard; +import net.minecraft.server.CommandSeed; +import net.minecraft.server.CommandSetBlock; +import net.minecraft.server.CommandSetWorldSpawn; +import net.minecraft.server.CommandSpawnpoint; +import net.minecraft.server.CommandSpreadPlayers; +import net.minecraft.server.CommandSummon; +import net.minecraft.server.CommandTell; +import net.minecraft.server.CommandTellRaw; +import net.minecraft.server.CommandTestFor; +import net.minecraft.server.CommandTestForBlock; +import net.minecraft.server.CommandTime; +import net.minecraft.server.CommandToggleDownfall; +import net.minecraft.server.CommandTp; +import net.minecraft.server.CommandWeather; +import net.minecraft.server.CommandWhitelist; +import net.minecraft.server.CommandXp; import net.minecraft.server.Convertable; import net.minecraft.server.ConvertProgressUpdater; import net.minecraft.server.CraftingManager; @@ -77,6 +119,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.conversations.Conversable; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; import org.bukkit.craftbukkit.help.SimpleHelpMap; import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe; import org.bukkit.craftbukkit.inventory.CraftInventoryCustom; @@ -159,6 +202,7 @@ public final class CraftServer implements Server { protected final DedicatedPlayerList playerList; private final Map worlds = new LinkedHashMap(); private YamlConfiguration configuration; + private YamlConfiguration commandsConfiguration; private final Yaml yaml = new Yaml(new SafeConstructor()); private final Map offlinePlayers = new MapMaker().softValues().makeMap(); private final AutoUpdater updater; @@ -178,6 +222,7 @@ public final class CraftServer implements Server { public boolean playerCommandState; private boolean printSaveWarning; private CraftIconCache icon; + private boolean overrideAllCommandBlockCommands = false; private final class BooleanWrapper { private boolean value = true; @@ -212,7 +257,27 @@ public final class CraftServer implements Server { configuration = YamlConfiguration.loadConfiguration(getConfigFile()); configuration.options().copyDefaults(true); configuration.setDefaults(YamlConfiguration.loadConfiguration(getClass().getClassLoader().getResourceAsStream("configurations/bukkit.yml"))); + ConfigurationSection legacyAlias = null; + if (!configuration.isString("aliases")) { + legacyAlias = configuration.getConfigurationSection("aliases"); + configuration.set("aliases", "now-in-commands.yml"); + } saveConfig(); + if (getCommandsConfigFile().isFile()) { + legacyAlias = null; + } + commandsConfiguration = YamlConfiguration.loadConfiguration(getCommandsConfigFile()); + commandsConfiguration.options().copyDefaults(true); + commandsConfiguration.setDefaults(YamlConfiguration.loadConfiguration(getClass().getClassLoader().getResourceAsStream("configurations/commands.yml"))); + saveCommandsConfig(); + if (legacyAlias != null) { + ConfigurationSection aliases = commandsConfiguration.createSection("aliases"); + for (Entry entry : legacyAlias.getValues(true).entrySet()) { + aliases.set(entry.getKey(), entry.getValue()); + } + } + saveCommandsConfig(); + overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*"); ((SimplePluginManager) pluginManager).useTimings(configuration.getBoolean("settings.plugin-profiling")); monsterSpawn = configuration.getInt("spawn-limits.monsters"); animalSpawn = configuration.getInt("spawn-limits.animals"); @@ -235,10 +300,18 @@ public final class CraftServer implements Server { enablePlugins(PluginLoadOrder.STARTUP); } + public boolean getCommandBlockOverride(String command) { + return overrideAllCommandBlockCommands || commandsConfiguration.getStringList("command-block-overrides").contains(command); + } + private File getConfigFile() { return (File) console.options.valueOf("bukkit-settings"); } + private File getCommandsConfigFile() { + return (File) console.options.valueOf("commands-settings"); + } + private void saveConfig() { try { configuration.save(getConfigFile()); @@ -247,6 +320,14 @@ public final class CraftServer implements Server { } } + private void saveCommandsConfig() { + try { + commandsConfiguration.save(getCommandsConfigFile()); + } catch (IOException ex) { + Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, "Could not save " + getCommandsConfigFile(), ex); + } + } + public void loadPlugins() { pluginManager.registerInterface(JavaPluginLoader.class); @@ -283,6 +364,8 @@ public final class CraftServer implements Server { } if (type == PluginLoadOrder.POSTWORLD) { + commandMap.setFallbackCommands(); + setVanillaCommands(); commandMap.registerServerAliases(); loadCustomPermissions(); DefaultPermissions.registerCorePermissions(); @@ -294,6 +377,50 @@ public final class CraftServer implements Server { pluginManager.disablePlugins(); } + private void setVanillaCommands() { + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandAchievement(), "/achievement give [player]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBan(), "/ban [reason]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBanIp(), "/ban-ip ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBanList(), "/banlist [ips]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandClear(), "/clear [item] [metadata]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamemodeDefault(), "/defaultgamemode ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandDeop(), "/deop ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandDifficulty(), "/difficulty ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandEffect(), "/effect [seconds] [amplifier]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandEnchant(), "/enchant [enchantment level]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamemode(), "/gamemode [player]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamerule(), "/gamerule [true|false]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGive(), "/give [amount] [metadata] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandHelp(), "/help [page|commandname]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandIdleTimeout(), "/setidletimeout ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandKick(), "/kick [reason]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandKill(), "/kill [playername]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandList(), "/list")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandMe(), "/me ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandOp(), "/op ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPardon(), "/pardon ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPardonIP(), "/pardon-ip ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPlaySound(), "/playsound [x] [y] [z] [volume] [pitch] [minimumVolume]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSay(), "/say ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandScoreboard(), "/scoreboard")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSeed(), "/seed")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSetBlock(), "/setblock [datavalue] [oldblockHandling] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSetWorldSpawn(), "/setworldspawn [x] [y] [z]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSpawnpoint(), "/spawnpoint [x] [y] [z]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSpreadPlayers(), "/spreadplayers [spreadDistance] [maxRange] [respectTeams] ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSummon(), "/summon [x] [y] [z] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTp(), "/tp [player] \n/tp [player] ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTell(), "/tell ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTellRaw(), "/tellraw ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTestFor(), "/testfor [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTestForBlock(), "/testforblock [datavalue] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTime(), "/time set \n/time add ")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandToggleDownfall(), "/toggledownfall")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandWeather(), "/weather [duration in seconds]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandWhitelist(), "/whitelist (add|remove) \n/whitelist (on|off|list|reload)")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandXp(), "/xp [player]\n/xp L [player]")); + } + private void loadPlugin(Plugin plugin) { try { pluginManager.enablePlugin(plugin); @@ -555,6 +682,7 @@ public final class CraftServer implements Server { public void reload() { configuration = YamlConfiguration.loadConfiguration(getConfigFile()); + commandsConfiguration = YamlConfiguration.loadConfiguration(getCommandsConfigFile()); PropertyManager config = new PropertyManager(console.options); ((DedicatedServer) console).propertyManager = config; @@ -601,6 +729,7 @@ public final class CraftServer implements Server { pluginManager.clearPlugins(); commandMap.clearCommands(); resetRecipes(); + overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*"); int pollCount = 0; @@ -972,7 +1101,7 @@ public final class CraftServer implements Server { } public Map getCommandAliases() { - ConfigurationSection section = configuration.getConfigurationSection("aliases"); + ConfigurationSection section = commandsConfiguration.getConfigurationSection("aliases"); Map result = new LinkedHashMap(); if (section != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 07c26f1f3e..8d127fbe2a 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -100,6 +100,12 @@ public class Main { .defaultsTo(new File("bukkit.yml")) .describedAs("Yml file"); + acceptsAll(asList("C", "commands-settings"), "File for command settings") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("commands.yml")) + .describedAs("Yml file"); + acceptsAll(asList("nojline"), "Disables jline and emulates the vanilla console"); acceptsAll(asList("noconsole"), "Disables the console"); diff --git a/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java index f901d6c614..bdee7d7322 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java +++ b/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.command; +import net.minecraft.server.ICommandListener; import net.minecraft.server.TileEntityCommandListener; import org.bukkit.block.Block; @@ -37,4 +38,8 @@ public class CraftBlockCommandSender extends ServerCommandSender implements Bloc public void setOp(boolean value) { throw new UnsupportedOperationException("Cannot change operator status of a block"); } + + public ICommandListener getTileEntity() { + return commandBlock; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java new file mode 100644 index 0000000000..63bb9731a0 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -0,0 +1,192 @@ +package org.bukkit.craftbukkit.command; + +import java.util.List; + +import net.minecraft.server.ChatMessage; +import net.minecraft.server.CommandAbstract; +import net.minecraft.server.CommandBlockListenerAbstract; +import net.minecraft.server.CommandException; +import net.minecraft.server.EntityMinecartCommandBlock; +import net.minecraft.server.EntityMinecartCommandBlockListener; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.EnumChatFormat; +import net.minecraft.server.ExceptionUsage; +import net.minecraft.server.ICommandListener; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PlayerSelector; +import net.minecraft.server.RemoteControlCommandListener; +import net.minecraft.server.TileEntityCommandListener; +import net.minecraft.server.WorldServer; + +import org.apache.commons.lang.Validate; +import org.apache.logging.log4j.Level; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.RemoteConsoleCommandSender; +import org.bukkit.command.defaults.*; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.entity.CraftMinecartCommand; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.entity.minecart.CommandMinecart; + +public final class VanillaCommandWrapper extends VanillaCommand { + protected final CommandAbstract vanillaCommand; + + public VanillaCommandWrapper(CommandAbstract vanillaCommand) { + super(vanillaCommand.c()); + this.vanillaCommand = vanillaCommand; + } + + public VanillaCommandWrapper(CommandAbstract vanillaCommand, String usage) { + super(vanillaCommand.c()); + this.vanillaCommand = vanillaCommand; + this.description = "A Mojang provided command."; + this.usageMessage = usage; + this.setPermission("vanilla.command." + vanillaCommand.c()); + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if (!testPermission(sender)) return true; + + ICommandListener icommandlistener = getListener(sender); + // Some commands use the worldserver variable but we leave it full of null values, + // so we must temporarily populate it with the world of the commandsender + WorldServer[] prev = MinecraftServer.getServer().worldServer; + MinecraftServer.getServer().worldServer = new WorldServer[]{(WorldServer) icommandlistener.getWorld()}; + try { + vanillaCommand.b(icommandlistener, args); + } catch (ExceptionUsage exceptionusage) { + ChatMessage chatmessage = new ChatMessage("commands.generic.usage", new Object[] {new ChatMessage(exceptionusage.getMessage(), exceptionusage.a())}); + chatmessage.b().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage); + } catch (CommandException commandexception) { + ChatMessage chatmessage = new ChatMessage(commandexception.getMessage(), commandexception.a()); + chatmessage.b().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage); + } finally { + MinecraftServer.getServer().worldServer = prev; + } + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + return (List) vanillaCommand.a(getListener(sender), args); + } + + public final int dispatchVanillaCommandBlock(CommandBlockListenerAbstract icommandlistener, String s) { + // Copied from net.minecraft.server.CommandHandler + s = s.trim(); + if (s.startsWith("/")) { + s = s.substring(1); + } + String as[] = s.split(" "); + as = dropFirstArgument(as); + int i = getPlayerListSize(as); + int j = 0; + // Some commands use the worldserver variable but we leave it full of null values, + // so we must temporarily populate it with the world of the commandsender + WorldServer[] prev = MinecraftServer.getServer().worldServer; + MinecraftServer.getServer().worldServer = new WorldServer[]{(WorldServer) icommandlistener.getWorld()}; + try { + if (vanillaCommand.a(icommandlistener)) { + if (i > -1) { + EntityPlayer aentityplayer[] = PlayerSelector.getPlayers(icommandlistener, as[i]); + String s2 = as[i]; + EntityPlayer aentityplayer1[] = aentityplayer; + int k = aentityplayer1.length; + for (int l = 0; l < k;) { + EntityPlayer entityplayer = aentityplayer1[l]; + as[i] = entityplayer.getName(); + try { + vanillaCommand.b(icommandlistener, as); + j++; + continue; + } catch (CommandException commandexception1) { + ChatMessage chatmessage4 = new ChatMessage(commandexception1.getMessage(), commandexception1.a()); + chatmessage4.b().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage4); + l++; + } + } + + as[i] = s2; + } else { + vanillaCommand.b(icommandlistener, as); + j++; + } + } else { + ChatMessage chatmessage = new ChatMessage("commands.generic.permission", new Object[0]); + chatmessage.b().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage); + } + } catch (ExceptionUsage exceptionusage) { + ChatMessage chatmessage1 = new ChatMessage("commands.generic.usage", new Object[] { new ChatMessage(exceptionusage.getMessage(), exceptionusage.a()) }); + chatmessage1.b().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage1); + } catch (CommandException commandexception) { + ChatMessage chatmessage2 = new ChatMessage(commandexception.getMessage(), commandexception.a()); + chatmessage2.b().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage2); + } catch (Throwable throwable) { + ChatMessage chatmessage3 = new ChatMessage("commands.generic.exception", new Object[0]); + chatmessage3.b().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage3); + if(icommandlistener instanceof TileEntityCommandListener) { + TileEntityCommandListener listener = (TileEntityCommandListener) icommandlistener; + MinecraftServer.av().log(Level.WARN, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().x, listener.getChunkCoordinates().y, listener.getChunkCoordinates().z), throwable); + } else if (icommandlistener instanceof EntityMinecartCommandBlockListener) { + EntityMinecartCommandBlockListener listener = (EntityMinecartCommandBlockListener) icommandlistener; + MinecraftServer.av().log(Level.WARN, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().x, listener.getChunkCoordinates().y, listener.getChunkCoordinates().z), throwable); + } else { + MinecraftServer.av().log(Level.WARN, String.format("Unknown CommandBlock failed to handle command"), throwable); + } + } finally { + MinecraftServer.getServer().worldServer = prev; + } + return j; + } + + private ICommandListener getListener(CommandSender sender) { + if (sender instanceof Player) { + return ((CraftPlayer) sender).getHandle(); + } + if (sender instanceof BlockCommandSender) { + return ((CraftBlockCommandSender) sender).getTileEntity(); + } + if (sender instanceof CommandMinecart) { + return ((EntityMinecartCommandBlock) ((CraftMinecartCommand) sender).getHandle()).e(); + } + if (sender instanceof RemoteConsoleCommandSender) { + return RemoteControlCommandListener.instance; + } + if (sender instanceof ConsoleCommandSender) { + return ((CraftServer) sender.getServer()).getServer(); + } + return null; + } + + private int getPlayerListSize(String as[]) { + for (int i = 0; i < as.length; i++) { + if (vanillaCommand.a(as, i) && PlayerSelector.isList(as[i])) { + return i; + } + } + return -1; + } + + private String[] dropFirstArgument(String as[]) { + String as1[] = new String[as.length - 1]; + for (int i = 1; i < as.length; i++) { + as1[i - 1] = as[i]; + } + + return as1; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java b/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java index 27f9ce9d54..7dd5afef0a 100644 --- a/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java +++ b/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java @@ -3,10 +3,12 @@ package org.bukkit.craftbukkit.help; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; + import org.bukkit.command.*; import org.bukkit.command.defaults.BukkitCommand; import org.bukkit.command.defaults.VanillaCommand; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; import org.bukkit.help.*; import java.util.*; @@ -131,19 +133,13 @@ public class SimpleHelpMap implements HelpMap { continue; } for (String alias : command.getAliases()) { - if (!helpTopics.containsKey("/" + alias)) { + // Only register if this command owns the alias + if (server.getCommandMap().getCommand(alias) == command) { addTopic(new CommandAliasHelpTopic("/" + alias, "/" + command.getLabel(), this)); } } } - // Initialize help topics from the server's fallback commands - for (VanillaCommand command : server.getCommandMap().getFallbackCommands()) { - if (!commandInIgnoredPlugin(command, ignoredPlugins)) { - addTopic(new GenericCommandHelpTopic(command)); - } - } - // Add alias sub-index Collection filteredTopics = Collections2.filter(helpTopics.values(), Predicates.instanceOf(CommandAliasHelpTopic.class)); if (!filteredTopics.isEmpty()) { @@ -153,7 +149,6 @@ public class SimpleHelpMap implements HelpMap { // Initialize plugin-level sub-topics Map> pluginIndexes = new HashMap>(); fillPluginIndexes(pluginIndexes, server.getCommandMap().getCommands()); - fillPluginIndexes(pluginIndexes, server.getCommandMap().getFallbackCommands()); for (Map.Entry> entry : pluginIndexes.entrySet()) { addTopic(new IndexHelpTopic(entry.getKey(), "All commands for " + entry.getKey(), null, entry.getValue(), "Below is a list of all " + entry.getKey() + " commands:")); @@ -186,6 +181,9 @@ public class SimpleHelpMap implements HelpMap { } private String getCommandPluginName(Command command) { + if (command instanceof VanillaCommandWrapper) { + return "Minecraft"; + } if (command instanceof BukkitCommand || command instanceof VanillaCommand) { return "Bukkit"; } diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml index 60a894f664..b806905554 100644 --- a/src/main/resources/configurations/bukkit.yml +++ b/src/main/resources/configurations/bukkit.yml @@ -2,10 +2,10 @@ # As you can see, there's actually not that much to configure without any plugins. # For a reference for any variable inside this file, check out the bukkit wiki at # http://wiki.bukkit.org/Bukkit.yml -# +# # If you need help on this file, feel free to join us on irc or leave a message # on the forums asking for advice. -# +# # IRC: #bukkit @ esper.net # (If this means nothing to you, just go to http://webchat.esper.net/?channels=bukkit ) # Forums: http://forums.bukkit.org/forums/bukkit-help.6/ @@ -44,9 +44,7 @@ auto-updater: preferred-channel: rb host: dl.bukkit.org suggest-channels: true -aliases: -# icanhasbukkit: -# - version +aliases: now-in-commands.yml database: username: bukkit isolation: SERIALIZABLE diff --git a/src/main/resources/configurations/commands.yml b/src/main/resources/configurations/commands.yml new file mode 100644 index 0000000000..0fc05f0957 --- /dev/null +++ b/src/main/resources/configurations/commands.yml @@ -0,0 +1,4 @@ +command-block-overrides: [] +aliases: + icanhasbukkit: + - version