276afaa2ea
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: c2d72c82 SPIGOT-3102: Add EXPLOSION SpawnReason CraftBukkit Changes: fca41573 SPIGOT-5136: EntityPortalEvent getting called on interdimensional entity teleports 604c8bf0 SPIGOT-3102: Add EXPLOSION SpawnReason 375969a6 Re-add chunk GC for plugin chunk loads 58151368 SPIGOT-5123: Snapshot tile entities can end up with a non-null world 491c8482 SPIGOT-5130: PersistentDataContainer not removing values on TileEntities Spigot Changes: d05d3c1f Rebuild patches
122 lines
6.1 KiB
Diff
122 lines
6.1 KiB
Diff
From 5a1511dd4ec61e4cc6a70e8b11cd1d8b7a7af630 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
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 fa37c19c69..4ca45743d0 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
@@ -1582,6 +1582,29 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
|
}
|
|
|
|
if (!async && s.startsWith("/")) {
|
|
+ // Paper Start
|
|
+ if (!org.spigotmc.AsyncCatcher.shuttingDown && !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() == 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 3083538088..58428bfbf7 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -707,6 +707,29 @@ public final class CraftServer implements Server {
|
|
Validate.notNull(commandLine, "CommandLine cannot be null");
|
|
org.spigotmc.AsyncCatcher.catchOp( "command dispatch" ); // Spigot
|
|
|
|
+ // Paper Start
|
|
+ if (!org.spigotmc.AsyncCatcher.shuttingDown && !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;
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
|
index ddef523ea8..70f8d42992 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
|
@@ -13,6 +13,7 @@ public class ServerShutdownThread extends Thread {
|
|
public void run() {
|
|
try {
|
|
org.spigotmc.AsyncCatcher.enabled = false; // Spigot
|
|
+ org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper
|
|
server.close();
|
|
} finally {
|
|
try {
|
|
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
|
|
index aeed769725..9f7d2ef932 100644
|
|
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
|
|
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
|
|
@@ -6,6 +6,7 @@ public class AsyncCatcher
|
|
{
|
|
|
|
public static boolean enabled = true;
|
|
+ public static boolean shuttingDown = false; // Paper
|
|
|
|
public static void catchOp(String reason)
|
|
{
|
|
diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java
|
|
index e7b953ca31..ccea803f58 100644
|
|
--- a/src/main/java/org/spigotmc/RestartCommand.java
|
|
+++ b/src/main/java/org/spigotmc/RestartCommand.java
|
|
@@ -43,6 +43,7 @@ public class RestartCommand extends Command
|
|
private static void restart(final String restartScript)
|
|
{
|
|
AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us
|
|
+ org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper
|
|
try
|
|
{
|
|
String[] split = restartScript.split( " " );
|
|
--
|
|
2.22.0
|
|
|