diff --git a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch index e574812b9f..a38dc4015a 100644 --- a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch +++ b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch @@ -40,10 +40,10 @@ + public synchronized boolean canUse(final S source) { + if (source instanceof CommandSourceStack) { + try { -+ ((CommandSourceStack) source).currentCommand = this; ++ ((CommandSourceStack) source).currentCommand.put(Thread.currentThread(), this); // Paper - Thread Safe Vanilla Command permission checking + return this.requirement.test(source); + } finally { -+ ((CommandSourceStack) source).currentCommand = null; ++ ((CommandSourceStack) source).currentCommand.remove(Thread.currentThread()); // Paper - Thread Safe Vanilla Command permission checking + } + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch b/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch index 0d80d5087c..766f7556b1 100644 --- a/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch @@ -15,12 +15,12 @@ private final Vec2 rotation; private final CommandSigningContext signingContext; private final TaskChainer chatMessageChainer; -+ public volatile CommandNode currentCommand; // CraftBukkit ++ public java.util.Map currentCommand = new java.util.concurrent.ConcurrentHashMap<>(); // CraftBukkit // Paper - Thread Safe Vanilla Command permission checking + public boolean bypassSelectorPermissions = false; // Paper - add bypass for selector permissions 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, CommandResultCallback.EMPTY, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(server)); -@@ -169,11 +172,45 @@ +@@ -169,11 +172,47 @@ return this.textName; } @@ -47,9 +47,11 @@ + @Override public boolean hasPermission(int level) { + // CraftBukkit start -+ CommandNode currentCommand = this.currentCommand; ++ // Paper start - Thread Safe Vanilla Command permission checking ++ CommandNode currentCommand = this.currentCommand.get(Thread.currentThread()); + if (currentCommand != null) { + return this.hasPermission(level, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand)); ++ // Paper end - Thread Safe Vanilla Command permission checking + } + // CraftBukkit end + @@ -66,7 +68,7 @@ public Vec3 getPosition() { return this.worldPosition; } -@@ -302,21 +339,26 @@ +@@ -302,21 +341,26 @@ while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); @@ -96,7 +98,7 @@ } } -@@ -400,4 +442,10 @@ +@@ -400,4 +444,10 @@ public boolean isSilent() { return this.silent; }