diff --git a/Spigot-API-Patches/0016-Fix-infinite-recursion-with-plugin-tab-completers.patch b/Spigot-API-Patches/0016-Fix-infinite-recursion-with-plugin-tab-completers.patch new file mode 100644 index 000000000..bd50e03aa --- /dev/null +++ b/Spigot-API-Patches/0016-Fix-infinite-recursion-with-plugin-tab-completers.patch @@ -0,0 +1,93 @@ +From 3217d06837310e286c73e39f4d73ef7b19716274 Mon Sep 17 00:00:00 2001 +From: DemonWav +Date: Sun, 31 Jan 2016 01:20:21 -0600 +Subject: [PATCH] Fix infinite recursion with plugin tab completers + + +diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java +index c126a1e..f0860a9 100644 +--- a/src/main/java/org/bukkit/command/Command.java ++++ b/src/main/java/org/bukkit/command/Command.java +@@ -86,28 +86,16 @@ public abstract class Command { + * @throws IllegalArgumentException if sender, alias, or args is null + */ + 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"); +- +- if (args.length == 0) { +- return ImmutableList.of(); +- } +- +- String lastWord = args[args.length - 1]; +- +- Player senderPlayer = sender instanceof Player ? (Player) sender : null; +- +- ArrayList matchedPlayers = new ArrayList(); +- for (Player player : sender.getServer().getOnlinePlayers()) { +- String name = player.getName(); +- if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) { +- matchedPlayers.add(name); +- } +- } +- +- Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER); +- return matchedPlayers; ++ // PaperSpigot - location tab-completes ++ /* ++ To prevent infinite recursion, this implementation has been moved down to ++ tabCompleteImpl(CommandSender sender, String alias, String[] args). The infinite recursion happens when ++ a subclass calls super.tabComplete(CommandSender sender, String alias, String[] args, Location location), ++ which would end up calling tabComplete(CommandSender sender, String alias, String[] args), but rather than ++ this method, it would call the overridden method, which would call super.tabComplete again, etc. To prevent ++ this we move the actual main logic to a separate private method. ++ */ ++ return tabCompleteImpl(sender, alias, args); + } + + // PaperSpigot start - location tab-completes +@@ -130,7 +118,32 @@ public abstract class Command { + */ + public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException { + // Simply default to the standard tab-complete, subclasses can override this if needed +- return tabComplete(sender, alias, args); ++ return tabCompleteImpl(sender, alias, args); ++ } ++ ++ private List tabCompleteImpl(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"); ++ ++ if (args.length == 0) { ++ return ImmutableList.of(); ++ } ++ ++ String lastWord = args[args.length - 1]; ++ ++ Player senderPlayer = sender instanceof Player ? (Player) sender : null; ++ ++ ArrayList matchedPlayers = new ArrayList(); ++ for (Player player : sender.getServer().getOnlinePlayers()) { ++ String name = player.getName(); ++ if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) { ++ matchedPlayers.add(name); ++ } ++ } ++ ++ Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER); ++ return matchedPlayers; + } + // PaperSpigot end + +@@ -447,4 +460,4 @@ public abstract class Command { + public String toString() { + return getClass().getName() + '(' + name + ')'; + } +-} ++} +\ No newline at end of file +-- +1.9.1 + diff --git a/Spigot-Server-Patches/0087-Make-block-location-tab-completion-be-a-per-world-co.patch b/Spigot-Server-Patches/0087-Make-block-location-tab-completion-be-a-per-world-co.patch new file mode 100644 index 000000000..c67f6e6b2 --- /dev/null +++ b/Spigot-Server-Patches/0087-Make-block-location-tab-completion-be-a-per-world-co.patch @@ -0,0 +1,38 @@ +From bcfd15f836f3331070c285e6f4a8221cf6a69760 Mon Sep 17 00:00:00 2001 +From: DemonWav +Date: Sun, 31 Jan 2016 01:21:03 -0600 +Subject: [PATCH] Make block location tab completion be a per-world + configurable value + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index e130052..642880e 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -1639,7 +1639,7 @@ public final class CraftServer implements Server { + try { + // send location info if present + // completions = getCommandMap().tabComplete(player, message.substring(1)); +- if (blockPosition == null) { ++ if (blockPosition == null || !((CraftWorld) player.getWorld()).getHandle().paperSpigotConfig.allowBlockLocationTabCompletion) { + completions = getCommandMap().tabComplete(player, message.substring(1)); + } else { + completions = getCommandMap().tabComplete(player, message.substring(1), new Location(player.getWorld(), blockPosition.getX(), blockPosition.getY(), blockPosition.getZ())); +diff --git a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java +index ecb9519..008b79c 100644 +--- a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java ++++ b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java +@@ -396,4 +396,10 @@ public class PaperSpigotWorldConfig + { + allChunksAreSlimeChunks = getBoolean( "all-chunks-are-slime-chunks", false ); + } ++ ++ public boolean allowBlockLocationTabCompletion; ++ private void allowBlockLocationTabCompletion() ++ { ++ allowBlockLocationTabCompletion = getBoolean( "allow-block-location-tab-completion", true ); ++ } + } +-- +1.9.1 +