diff options
Diffstat (limited to 'Spigot-Server-Patches/0051-Ensure-commands-are-not-ran-async.patch')
-rw-r--r-- | Spigot-Server-Patches/0051-Ensure-commands-are-not-ran-async.patch | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0051-Ensure-commands-are-not-ran-async.patch b/Spigot-Server-Patches/0051-Ensure-commands-are-not-ran-async.patch new file mode 100644 index 0000000000..457aa012d7 --- /dev/null +++ b/Spigot-Server-Patches/0051-Ensure-commands-are-not-ran-async.patch @@ -0,0 +1,86 @@ +From d94378d518cda98be6fc17c01200ed86b7ac3790 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Thu, 3 Mar 2016 01:17:12 -0600 +Subject: [PATCH] Ensure commands are not ran async + +Plugins calling Player.chat("/foo") or Server.dispatchCommand() could +trigger the server to execute a command while on another thread. + +These commands would then process EXPECTING to be on the main thread, leaving to +very hard to trace concurrency issues. + +This change will synchronize the command execution back to the main thread, causing a +big slowdown in execution but throwing an exception at same time to raise awareness +that it is happening so that plugin authors can fix their code to stop executing commands async. + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index e19513a96..fd2c0c4f2 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -1267,6 +1267,29 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { + } + + if (!async && s.startsWith("/")) { ++ // Paper Start ++ if (org.spigotmc.AsyncCatcher.enabled && !org.bukkit.Bukkit.isPrimaryThread()) { ++ final String fCommandLine = s; ++ MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Command Dispatched Async: " + fCommandLine); ++ MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); ++ Waitable wait = new Waitable() { ++ @Override ++ protected Object evaluate() { ++ chat(fCommandLine, false); ++ return null; ++ } ++ }; ++ minecraftServer.processQueue.add(wait); ++ try { ++ wait.get(); ++ return; ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on! ++ } catch (Exception e) { ++ throw new RuntimeException("Exception processing chat command", e.getCause()); ++ } ++ } ++ // Paper End + this.handleCommand(s); + } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { + // Do nothing, this is coming from a plugin +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 30ed3ad58..a795a165a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -647,6 +647,29 @@ public final class CraftServer implements Server { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(commandLine, "CommandLine cannot be null"); + ++ // Paper Start ++ if (org.spigotmc.AsyncCatcher.enabled && !Bukkit.isPrimaryThread()) { ++ final CommandSender fSender = sender; ++ final String fCommandLine = commandLine; ++ Bukkit.getLogger().log(Level.SEVERE, "Command Dispatched Async: " + commandLine); ++ Bukkit.getLogger().log(Level.SEVERE, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); ++ org.bukkit.craftbukkit.util.Waitable<Boolean> wait = new org.bukkit.craftbukkit.util.Waitable<Boolean>() { ++ @Override ++ protected Boolean evaluate() { ++ return dispatchCommand(fSender, fCommandLine); ++ } ++ }; ++ net.minecraft.server.MinecraftServer.getServer().processQueue.add(wait); ++ try { ++ return wait.get(); ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on! ++ } catch (Exception e) { ++ throw new RuntimeException("Exception processing dispatch command", e.getCause()); ++ } ++ } ++ // Paper End ++ + if (commandMap.dispatch(sender, commandLine)) { + return true; + } +-- +2.12.0.windows.1 + |