mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 23:10:16 +01:00
fb2c24b36d
Upstream has released updates that appear 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: 05ae036c PR-746: Add option to use cached map color palette 57849c1b PR-759: Add preview chat option in ServerListPingEvent 0169e65d PR-758: Add missing server properties methods from 1.19 CraftBukkit Changes: 622dbe6c2 SPIGOT-7068: SKULK and SKULK_VEIN BlockSpreadEvents Still do not reference the correct source (SKULK_CATALYST) 6c61b73f3 PR-1052: Add option to use cached map color palette c882f38ea SPIGOT-7066: Fix custom END worlds not generating DragonBattle 6866aab59 SPIGOT-2420: Can't set exp drops for EnderDragon death 9dcd46530 PR-1067: Add preview chat option in ServerListPingEvent 36c2681af PR-1066: Add missing server properties methods from 1.19 031eaadd0 Increase outdated build delay 8fda4b12f SPIGOT-7060: SCULK and SCULK_VEIN BlockSpreadEvents do not reference the correct source
118 lines
6.3 KiB
Diff
118 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/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
index 357ff7f3ade2d59a7a2b3d93d7d35534565b6add..e27be8fb00360d546557bdbfec2907736145fa0f 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -1948,6 +1948,29 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
|
}
|
|
|
|
if (!async && s.startsWith("/")) {
|
|
+ // Paper Start
|
|
+ if (!org.spigotmc.AsyncCatcher.shuttingDown && !org.bukkit.Bukkit.isPrimaryThread()) {
|
|
+ final String fCommandLine = s;
|
|
+ LOGGER.error("Command Dispatched Async: " + fCommandLine);
|
|
+ LOGGER.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;
|
|
+ }
|
|
+ };
|
|
+ server.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.getChatVisibility() == ChatVisiblity.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 079cc8db76f08db578828d0114aee52231fef250..101bc3c3742d6d2d477ff4350a037d130149069c 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -859,6 +859,28 @@ 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 (this.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 19c44daaa407b7c1c7a7ffe56fef8c8814c6d5b2..6a073a9dc44d93eba296a0e18a9c7be8a7881725 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
|
|
this.server.close();
|
|
} finally {
|
|
try {
|
|
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
|
|
index 78669fa035b7537ff7e533cf32aaf2995625424f..7585a30e8f063ac2656b5de519b1e9edaceffbc7 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 882e93ad4471e3688f2fcfb1e6f16926786ee5e7..94d8ba376cd1f024b244654cac9bb62bb19e3060 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( " " );
|