From f7a676930a5a075ea7cc8ab13262de0ca82152e0 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Wed, 18 Jul 2018 01:37:30 +0100 Subject: [PATCH] NOT FINISHED! restore dropped patches, fix one more! --- ...item-frames-performance-and-bug-fixe.patch | 8 +- .../0252-AsyncTabCompleteEvent.patch | 143 ++++++++++++++++++ ...253-Avoid-NPE-in-PathfinderGoalTempt.patch | 22 +++ 3 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 Spigot-Server-Patches/0252-AsyncTabCompleteEvent.patch create mode 100644 Spigot-Server-Patches/0253-Avoid-NPE-in-PathfinderGoalTempt.patch diff --git a/Spigot-Server-Patches/0113-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/Spigot-Server-Patches/0113-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index 1639a506b..468f7274d 100644 --- a/Spigot-Server-Patches/0113-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/Spigot-Server-Patches/0113-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -1,4 +1,4 @@ -From 2cfae6d7882500d8af89756f8353d22d148098f1 Mon Sep 17 00:00:00 2001 +From 3ae97c4b74a8a3e42b84e5fffe41d84ec489cf18 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 29 Apr 2016 20:02:00 -0400 Subject: [PATCH] Improve Maps (in item frames) performance and bug fixes @@ -13,7 +13,7 @@ custom renderers are in use, defaulting to the much simpler Vanilla system. Additionally, numerous issues to player position tracking on maps has been fixed. diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index 1aa32bf11..36a961cb7 100644 +index 1aa32bf11..83bfb6611 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -610,6 +610,12 @@ public abstract class EntityHuman extends EntityLiving { @@ -22,7 +22,7 @@ index 1aa32bf11..36a961cb7 100644 // CraftBukkit end + // Paper start - remove player from map on drop + if (itemstack.getItem() == Items.FILLED_MAP) { -+ WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, this.world); ++ WorldMap worldmap = ItemWorldMap.getSavedMap(itemstack, this.world); + worldmap.updateSeenPlayers(this, itemstack); + } + // Paper stop @@ -140,5 +140,5 @@ index 256a13178..5768cd512 100644 public RenderData() { -- -2.17.1 +2.18.0 diff --git a/Spigot-Server-Patches/0252-AsyncTabCompleteEvent.patch b/Spigot-Server-Patches/0252-AsyncTabCompleteEvent.patch new file mode 100644 index 000000000..23c28acff --- /dev/null +++ b/Spigot-Server-Patches/0252-AsyncTabCompleteEvent.patch @@ -0,0 +1,143 @@ +From d6b423ce8aea858a4e606fd70e440b302706c6f5 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 26 Nov 2017 13:19:58 -0500 +Subject: [PATCH] AsyncTabCompleteEvent + +Let plugins be able to control tab completion of commands and chat async. + +This will be useful for frameworks like ACF so we can define async safe completion handlers, +and avoid going to main for tab completions. + +Especially useful if you need to query a database in order to obtain the results for tab +completion, such as offline players. + +Also adds isCommand and getLocation to the sync TabCompleteEvent + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index e01013efd..74a665142 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -2277,24 +2277,51 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { + // CraftBukkit end + } + +- public void a(PacketPlayInTabComplete packetplayintabcomplete) { +- PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.x()); ++ // Paper start - async tab completion ++ public void a(PacketPlayInTabComplete packet) { + // CraftBukkit start + if (chatSpamField.addAndGet(this, 10) > 500 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { +- this.disconnect(new ChatMessage("disconnect.spam", new Object[0])); ++ minecraftServer.postToMainThread(() -> this.disconnect(new ChatMessage("disconnect.spam", new Object[0]))); + return; + } + // CraftBukkit end +- ArrayList arraylist = Lists.newArrayList(); +- Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b(), packetplayintabcomplete.c()).iterator(); + +- while (iterator.hasNext()) { +- String s = (String) iterator.next(); ++ com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event; ++ java.util.List completions = new ArrayList<>(); ++ BlockPosition blockpos = packet.b(); ++ String buffer = packet.a(); ++ boolean isCommand = buffer.startsWith("/") || packet.c(); ++ event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getPlayer(), completions, ++ buffer, isCommand, blockpos != null ? MCUtil.toLocation(player.world, blockpos) : null); ++ event.callEvent(); ++ completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.getCompletions(); ++ if (event.isCancelled() || event.isHandled()) { ++ // Still fire sync event with the provided completions, if someone is listening ++ if (!event.isCancelled() && org.bukkit.event.server.TabCompleteEvent.getHandlerList().getRegisteredListeners().length > 0) { ++ java.util.List finalCompletions = completions; ++ Waitable> syncCompletions = new Waitable>() { ++ @Override ++ protected java.util.List evaluate() { ++ org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(PlayerConnection.this.getPlayer(), buffer, finalCompletions, isCommand, blockpos != null ? MCUtil.toLocation(player.world, blockpos) : null); ++ return syncEvent.callEvent() ? syncEvent.getCompletions() : com.google.common.collect.ImmutableList.of(); ++ } ++ }; ++ server.getServer().processQueue.add(syncCompletions); ++ try { ++ completions = syncCompletions.get(); ++ } catch (InterruptedException | ExecutionException e1) { ++ e1.printStackTrace(); ++ } ++ } + +- arraylist.add(s); ++ this.player.playerConnection.sendPacket(new PacketPlayOutTabComplete(completions.toArray(new String[completions.size()]))); ++ return; + } +- +- this.player.playerConnection.sendPacket(new PacketPlayOutTabComplete((String[]) arraylist.toArray(new String[arraylist.size()]))); ++ minecraftServer.postToMainThread(() -> { ++ java.util.List syncCompletions = this.minecraftServer.tabCompleteCommand(this.player, buffer, blockpos, isCommand); ++ this.player.playerConnection.sendPacket(new PacketPlayOutTabComplete(syncCompletions.toArray(new String[syncCompletions.size()]))); ++ }); ++ // Paper end + } + + public void a(PacketPlayInSettings packetplayinsettings) { +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 2dd7ed96a..e86c16755 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -1643,8 +1643,8 @@ public final class CraftServer implements Server { + } else { + offers = tabCompleteChat(player, message); + } +- +- TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers); ++ ++ TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), pos) : null); // Paper + getPluginManager().callEvent(tabEvent); + + return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions(); +diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java +index 1e3aae3b8..95d13c146 100644 +--- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java ++++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java +@@ -28,6 +28,39 @@ public class ConsoleCommandCompleter implements Completer { + public void complete(LineReader reader, ParsedLine line, List candidates) { + final CraftServer server = this.server.server; + final String buffer = line.line(); ++ // Async Tab Complete ++ com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event; ++ java.util.List completions = new java.util.ArrayList<>(); ++ event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(server.getConsoleSender(), completions, ++ buffer, true, null); ++ event.callEvent(); ++ completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.getCompletions(); ++ ++ if (event.isCancelled() || event.isHandled()) { ++ // Still fire sync event with the provided completions, if someone is listening ++ if (!event.isCancelled() && TabCompleteEvent.getHandlerList().getRegisteredListeners().length > 0) { ++ List finalCompletions = completions; ++ Waitable> syncCompletions = new Waitable>() { ++ @Override ++ protected List evaluate() { ++ org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(server.getConsoleSender(), buffer, finalCompletions); ++ return syncEvent.callEvent() ? syncEvent.getCompletions() : com.google.common.collect.ImmutableList.of(); ++ } ++ }; ++ server.getServer().processQueue.add(syncCompletions); ++ try { ++ completions = syncCompletions.get(); ++ } catch (InterruptedException | ExecutionException e1) { ++ e1.printStackTrace(); ++ } ++ } ++ ++ if (!completions.isEmpty()) { ++ candidates.addAll(completions.stream().map(Candidate::new).collect(java.util.stream.Collectors.toList())); ++ } ++ return; ++ } ++ + // Paper end + Waitable> waitable = new Waitable>() { + @Override +-- +2.17.1 + diff --git a/Spigot-Server-Patches/0253-Avoid-NPE-in-PathfinderGoalTempt.patch b/Spigot-Server-Patches/0253-Avoid-NPE-in-PathfinderGoalTempt.patch new file mode 100644 index 000000000..bbc853dbd --- /dev/null +++ b/Spigot-Server-Patches/0253-Avoid-NPE-in-PathfinderGoalTempt.patch @@ -0,0 +1,22 @@ +From 9879e7c10bb47f2cfaa41d001896592517a6b429 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 29 Nov 2017 22:18:54 -0500 +Subject: [PATCH] Avoid NPE in PathfinderGoalTempt + + +diff --git a/src/main/java/net/minecraft/server/PathfinderGoalTempt.java b/src/main/java/net/minecraft/server/PathfinderGoalTempt.java +index 188825d19..8004f3a3f 100644 +--- a/src/main/java/net/minecraft/server/PathfinderGoalTempt.java ++++ b/src/main/java/net/minecraft/server/PathfinderGoalTempt.java +@@ -54,7 +54,7 @@ public class PathfinderGoalTempt extends PathfinderGoal { + } + this.target = (event.getTarget() == null) ? null : ((CraftLivingEntity) event.getTarget()).getHandle(); + } +- return tempt; ++ return tempt && this.target != null; // Paper - must have target - plugin might of cancelled + // CraftBukkit end + } + } +-- +2.18.0 +