diff options
author | t00thpick1 <t00thpick1dirko@gmail.com> | 2014-02-07 18:40:59 -0500 |
---|---|---|
committer | Travis Watkins <amaranth@ubuntu.com> | 2014-02-08 03:17:14 -0600 |
commit | 553acdf0cdde1abe59399a83af5cc3deb78c188f (patch) | |
tree | 4d20a9a3fbb5fde08fbc359bd3bec62d7a15f47e /src/main/java/org | |
parent | b18bedd848be2a1396087e768601c85c791e00aa (diff) | |
download | craftbukkit-553acdf0cdde1abe59399a83af5cc3deb78c188f.tar craftbukkit-553acdf0cdde1abe59399a83af5cc3deb78c188f.tar.gz craftbukkit-553acdf0cdde1abe59399a83af5cc3deb78c188f.tar.lz craftbukkit-553acdf0cdde1abe59399a83af5cc3deb78c188f.tar.xz craftbukkit-553acdf0cdde1abe59399a83af5cc3deb78c188f.zip |
[Bleeding] Implement Mojang command fallback system. Adds BUKKIT-5385
Diffstat (limited to 'src/main/java/org')
5 files changed, 340 insertions, 10 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 17c8039b..22f394d5 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<String, World> worlds = new LinkedHashMap<String, World>(); private YamlConfiguration configuration; + private YamlConfiguration commandsConfiguration; private final Yaml yaml = new Yaml(new SafeConstructor()); private final Map<String, OfflinePlayer> 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<String, Object> 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 <stat_name> [player]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBan(), "/ban <playername> [reason]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBanIp(), "/ban-ip <ip-address|playername>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBanList(), "/banlist [ips]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandClear(), "/clear <playername> [item] [metadata]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamemodeDefault(), "/defaultgamemode <mode>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandDeop(), "/deop <playername>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandDifficulty(), "/difficulty <new difficulty>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandEffect(), "/effect <player> <effect|clear> [seconds] [amplifier]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandEnchant(), "/enchant <playername> <enchantment ID> [enchantment level]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamemode(), "/gamemode <mode> [player]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamerule(), "/gamerule <rulename> [true|false]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGive(), "/give <playername> <item> [amount] [metadata] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandHelp(), "/help [page|commandname]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandIdleTimeout(), "/setidletimeout <Minutes until kick>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandKick(), "/kick <playername> [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 <actiontext>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandOp(), "/op <playername>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPardon(), "/pardon <playername>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPardonIP(), "/pardon-ip <ip-address>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPlaySound(), "/playsound <sound> <playername> [x] [y] [z] [volume] [pitch] [minimumVolume]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSay(), "/say <message>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandScoreboard(), "/scoreboard")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSeed(), "/seed")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSetBlock(), "/setblock <x> <y> <z> <tilename> [datavalue] [oldblockHandling] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSetWorldSpawn(), "/setworldspawn [x] [y] [z]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSpawnpoint(), "/spawnpoint <playername> [x] [y] [z]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSpreadPlayers(), "/spreadplayers <x> <z> [spreadDistance] [maxRange] [respectTeams] <playernames>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSummon(), "/summon <EntityName> [x] [y] [z] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTp(), "/tp [player] <target>\n/tp [player] <x> <y> <z>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTell(), "/tell <playername> <message>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTellRaw(), "/tellraw <playername> <raw message>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTestFor(), "/testfor <playername | selector> [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTestForBlock(), "/testforblock <x> <y> <z> <tilename> [datavalue] [dataTag]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTime(), "/time set <value>\n/time add <value>")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandToggleDownfall(), "/toggledownfall")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandWeather(), "/weather <clear/rain/thunder> [duration in seconds]")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandWhitelist(), "/whitelist (add|remove) <player>\n/whitelist (on|off|list|reload)")); + commandMap.register("minecraft", new VanillaCommandWrapper(new CommandXp(), "/xp <amount> [player]\n/xp <amount>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<String, String[]> getCommandAliases() { - ConfigurationSection section = configuration.getConfigurationSection("aliases"); + ConfigurationSection section = commandsConfiguration.getConfigurationSection("aliases"); Map<String, String[]> result = new LinkedHashMap<String, String[]>(); if (section != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 07c26f1f..8d127fbe 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 f901d6c6..bdee7d73 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 00000000..63bb9731 --- /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<String> 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<String>) 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 27f9ce9d..7dd5afef 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<HelpTopic> 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<String, Set<HelpTopic>> pluginIndexes = new HashMap<String, Set<HelpTopic>>(); fillPluginIndexes(pluginIndexes, server.getCommandMap().getCommands()); - fillPluginIndexes(pluginIndexes, server.getCommandMap().getFallbackCommands()); for (Map.Entry<String, Set<HelpTopic>> 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"; } |