2020-07-11 09:55:59 +02:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Aikar <aikar@aikar.co>
|
|
|
|
Date: Sat, 11 Jul 2020 03:54:28 -0400
|
|
|
|
Subject: [PATCH] Thread Safe Vanilla Command permission checking
|
|
|
|
|
|
|
|
Datapacks check this on load and are built concurrently. This was breaking them badly due
|
|
|
|
to race conditions.
|
|
|
|
|
|
|
|
Plus, .canUse we want to be safe for async anyways.
|
|
|
|
|
|
|
|
diff --git a/src/main/java/com/mojang/brigadier/tree/CommandNode.java b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
2020-08-25 04:22:08 +02:00
|
|
|
index 6976da79b20280fcd72dcfb8b48e2eb73257faf2..d9c47f3fc18266df3be1f564c01dfc3e26941380 100644
|
2020-07-11 09:55:59 +02:00
|
|
|
--- a/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
|
|
|
+++ b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
|
|
|
@@ -75,10 +75,10 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
2020-08-25 04:22:08 +02:00
|
|
|
public synchronized boolean canUse(final S source) {
|
2020-07-11 09:55:59 +02:00
|
|
|
if (source instanceof CommandListenerWrapper) {
|
|
|
|
try {
|
|
|
|
- ((CommandListenerWrapper) source).currentCommand = this;
|
|
|
|
+ ((CommandListenerWrapper) source).currentCommand.set(this); // Paper
|
|
|
|
return requirement.test(source);
|
|
|
|
} finally {
|
|
|
|
- ((CommandListenerWrapper) source).currentCommand = null;
|
|
|
|
+ ((CommandListenerWrapper) source).currentCommand.set(null); // Paper
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/CommandListenerWrapper.java b/src/main/java/net/minecraft/server/CommandListenerWrapper.java
|
2020-08-25 04:22:08 +02:00
|
|
|
index 7608b5021d66c39b8121f33829cd09d77c847277..90b0cf6470711101400d723747d1f302cf6e23bd 100644
|
2020-07-11 09:55:59 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/CommandListenerWrapper.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/CommandListenerWrapper.java
|
|
|
|
@@ -33,7 +33,7 @@ public class CommandListenerWrapper implements ICompletionProvider, com.destroys
|
|
|
|
private final ResultConsumer<CommandListenerWrapper> l;
|
|
|
|
private final ArgumentAnchor.Anchor m;
|
|
|
|
private final Vec2F n;
|
2020-08-25 04:22:08 +02:00
|
|
|
- public volatile CommandNode currentCommand; // CraftBukkit
|
2020-07-11 09:55:59 +02:00
|
|
|
+ public ThreadLocal<CommandNode> currentCommand = new ThreadLocal<>(); // CraftBukkit // Paper
|
|
|
|
|
|
|
|
public CommandListenerWrapper(ICommandListener icommandlistener, Vec3D vec3d, Vec2F vec2f, WorldServer worldserver, int i, String s, IChatBaseComponent ichatbasecomponent, MinecraftServer minecraftserver, @Nullable Entity entity) {
|
|
|
|
this(icommandlistener, vec3d, vec2f, worldserver, i, s, ichatbasecomponent, minecraftserver, entity, false, (commandcontext, flag, j) -> {
|
2020-08-25 04:22:08 +02:00
|
|
|
@@ -150,9 +150,11 @@ public class CommandListenerWrapper implements ICompletionProvider, com.destroys
|
2020-07-11 09:55:59 +02:00
|
|
|
@Override
|
|
|
|
public boolean hasPermission(int i) {
|
|
|
|
// CraftBukkit start
|
2020-08-25 04:22:08 +02:00
|
|
|
- CommandNode currentCommand = this.currentCommand;
|
2020-07-11 09:55:59 +02:00
|
|
|
+ // Paper start - fix concurrency issue
|
|
|
|
+ CommandNode currentCommand = this.currentCommand.get();
|
|
|
|
if (currentCommand != null) {
|
|
|
|
return hasPermission(i, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand));
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
|