diff --git a/patches/server/Thread-Safe-Vanilla-Command-permission-checking.patch b/patches/server/Thread-Safe-Vanilla-Command-permission-checking.patch index 807d3f1593..0ba62f8040 100644 --- a/patches/server/Thread-Safe-Vanilla-Command-permission-checking.patch +++ b/patches/server/Thread-Safe-Vanilla-Command-permission-checking.patch @@ -17,11 +17,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (source instanceof CommandSourceStack) { try { - ((CommandSourceStack) source).currentCommand = this; -+ ((CommandSourceStack) source).currentCommand.set(this); // Paper ++ ((CommandSourceStack) source).currentCommand.put(Thread.currentThread(), this); // Paper return this.requirement.test(source); } finally { - ((CommandSourceStack) source).currentCommand = null; -+ ((CommandSourceStack) source).currentCommand.set(null); // Paper ++ ((CommandSourceStack) source).currentCommand.remove(Thread.currentThread()); // Paper } } // CraftBukkit end @@ -29,12 +29,23 @@ diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java +@@ -0,0 +0,0 @@ import com.mojang.brigadier.suggestion.Suggestions; + import com.mojang.brigadier.suggestion.SuggestionsBuilder; + import java.util.Collection; + import java.util.Iterator; ++import java.util.Map; + import java.util.Set; + import java.util.concurrent.CompletableFuture; ++import java.util.concurrent.ConcurrentHashMap; + import java.util.function.BinaryOperator; + import java.util.stream.Stream; + import javax.annotation.Nullable; @@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy private final ResultConsumer consumer; private final EntityAnchorArgument.Anchor anchor; private final Vec2 rotation; - public volatile CommandNode currentCommand; // CraftBukkit -+ public ThreadLocal currentCommand = new ThreadLocal<>(); // CraftBukkit // Paper ++ public Map currentCommand = new ConcurrentHashMap<>(); // CraftBukkit // Paper public CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity) { this(output, pos, rot, world, level, name, displayName, server, entity, false, (commandcontext, flag, j) -> { @@ -44,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start - CommandNode currentCommand = this.currentCommand; + // Paper start - fix concurrency issue -+ CommandNode currentCommand = this.currentCommand.get(); ++ CommandNode currentCommand = this.currentCommand.get(Thread.currentThread()); if (currentCommand != null) { return this.hasPermission(level, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand)); + // Paper end