mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-27 04:55:47 +01:00
c0d07c1b67
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: f009c3dd SPIGOT-5810, SPIGOT-5835: 'Better' handling of Player.isOnGround e677c370 Update ECJ version 5058a35d SPIGOT-5860: Item.setItemStack should be NotNull CraftBukkit Changes:d77f4d9b
SPIGOT-5810, SPIGOT-5835: 'Better' handling of Player.isOnGround53c95627
SPIGOT-5865: Piglin does not trigger EntityPickupItemEvent2ab04d24
Update ECJ version7884e079
SPIGOT-5868: Blocks do not tick in custom nether / end2a848286
SPIGOT-5863: Don't check colour in scoreboard length validationf2cbce30
SPIGOT-5866: Beehive unknown TargetReason Spigot Changes: ad703da0 SPIGOT-5870: /plugins "website" field shows "version" 1a27cfd8 #98: Improve output of /plugins command using text components 732d5bab Disable checkstyle in Spigot blocks 0199a9a6 #97: Add Memory Usage to Ticks Per Second Command. 33ea98fc SPIGOT-5858: NPE: Joining the server with an invalid dimension
120 lines
6.3 KiB
Diff
120 lines
6.3 KiB
Diff
From 0000000000000000000000000000000000000000 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 ef622ae8946c7caafa222c42749ddbd90425f61c..b7c621547fe071f136413d91bc4aa43142a2ef42 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
@@ -1615,6 +1615,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 0d28a442e0ffb524140208710b253ca88ae21f90..b16785d48f407101360fb27036e4cfc8cf51dd23 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -752,6 +752,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 ddef523ea8762c927f37f7d16d581e43367e8c6b..70f8d42992aa348ef7b2d03d22cdd59d7c73f0fe 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 aeed7697254af17ffefe8e578353ad216e15f9f3..9f7d2ef932ab41cef5d3d0736d20a7c7e4a2c888 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 e7b953ca312533f7ede12cdab42b2289aefc3b95..ccea803f58e09067cc998c62ffa134d6604878ff 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( " " );
|