Force commands to be dispatched synchronously
[22:29:12] <Aikar> just add that [22:29:17] <Aikar> that forces it fixed [22:29:31] <Aikar> and then when his users spam him hell fix it :P
This commit is contained in:
parent
314212b236
commit
56c14f8f07
@ -0,0 +1,86 @@
|
||||
From 3d5bf73817dbd5e89595cc27a80a9cfe0b5860eb Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 8 Oct 2014 19:51:28 -0400
|
||||
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 1138042..4391ad7 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
@@ -1079,6 +1079,29 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
|
||||
}
|
||||
|
||||
if (!async && s.startsWith("/")) {
|
||||
+ // PaperSpigot Start
|
||||
+ if (!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());
|
||||
+ }
|
||||
+ }
|
||||
+ // PaperSpigot 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 97f9f96..a54b3e8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -639,6 +639,29 @@ public final class CraftServer implements Server {
|
||||
Validate.notNull(sender, "Sender cannot be null");
|
||||
Validate.notNull(commandLine, "CommandLine cannot be null");
|
||||
|
||||
+ // PaperSpigot Start
|
||||
+ if (!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());
|
||||
+ }
|
||||
+ }
|
||||
+ // PaperSpigot End
|
||||
+
|
||||
if (commandMap.dispatch(sender, commandLine)) {
|
||||
return true;
|
||||
}
|
||||
--
|
||||
2.7.0
|
||||
|
Loading…
Reference in New Issue
Block a user