mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-26 09:42:06 -07:00
Improve command permission lookups
This allows us to append to the vanilla permission check object to avoid having to look into a map. This also fixes non vanilla commands from technically being able to be skipped through permissions.
This commit is contained in:
@@ -24,25 +24,6 @@
|
||||
|
||||
protected CommandNode(final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks) {
|
||||
this.command = command;
|
||||
@@ -61,7 +_,17 @@
|
||||
return modifier;
|
||||
}
|
||||
|
||||
- public boolean canUse(final S source) {
|
||||
+ // CraftBukkit start
|
||||
+ public synchronized boolean canUse(final S source) {
|
||||
+ if (source instanceof final net.minecraft.commands.CommandSourceStack css) {
|
||||
+ try {
|
||||
+ css.currentCommand.put(Thread.currentThread(), this); // Paper - Thread Safe Vanilla Command permission checking
|
||||
+ return this.requirement.test(source);
|
||||
+ } finally {
|
||||
+ css.currentCommand.remove(Thread.currentThread()); // Paper - Thread Safe Vanilla Command permission checking
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
return requirement.test(source);
|
||||
}
|
||||
|
||||
@@ -151,6 +_,12 @@
|
||||
protected abstract String getSortedKey();
|
||||
|
||||
|
@@ -9,11 +9,10 @@
|
||||
public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player"));
|
||||
public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity"));
|
||||
public final CommandSource source;
|
||||
@@ -65,6 +_,8 @@
|
||||
@@ -65,6 +_,7 @@
|
||||
private final Vec2 rotation;
|
||||
private final CommandSigningContext signingContext;
|
||||
private final TaskChainer chatMessageChainer;
|
||||
+ public java.util.Map<Thread, com.mojang.brigadier.tree.CommandNode> 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(
|
||||
@@ -49,19 +48,7 @@
|
||||
public CommandSourceStack withRotation(Vec2 rotation) {
|
||||
return this.rotation.equals(rotation)
|
||||
? this
|
||||
@@ -393,9 +_,44 @@
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(int level) {
|
||||
+ // CraftBukkit start
|
||||
+ // Paper start - Thread Safe Vanilla Command permission checking
|
||||
+ com.mojang.brigadier.tree.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
|
||||
+
|
||||
@@ -396,6 +_,32 @@
|
||||
return this.permissionLevel >= level;
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
AdvancementCommands.register(this.dispatcher);
|
||||
AttributeCommand.register(this.dispatcher, context);
|
||||
ExecuteCommand.register(this.dispatcher, context);
|
||||
@@ -280,6 +_,40 @@
|
||||
@@ -280,6 +_,42 @@
|
||||
PublishCommand.register(this.dispatcher);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
+ for (final CommandNode<CommandSourceStack> node : this.dispatcher.getRoot().getChildren()) {
|
||||
+ if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.<CommandSourceStack>defaultRequirement()) {
|
||||
+ node.requirement = stack -> stack.source == CommandSource.NULL || stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node));
|
||||
+ } else if (node.getRequirement() instanceof net.minecraft.commands.PermissionSource.Check<CommandSourceStack> check) {
|
||||
+ check.vanillaNode().set(node);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Vanilla command permission fixes
|
||||
|
@@ -0,0 +1,24 @@
|
||||
--- a/net/minecraft/commands/PermissionSource.java
|
||||
+++ b/net/minecraft/commands/PermissionSource.java
|
||||
@@ -9,9 +_,20 @@
|
||||
return this.hasPermission(2);
|
||||
}
|
||||
|
||||
- public record Check<T extends PermissionSource>(@Override int requiredLevel) implements PermissionCheck<T> {
|
||||
+ public record Check<T extends PermissionSource>(@Override int requiredLevel, java.util.concurrent.atomic.AtomicReference<com.mojang.brigadier.tree.CommandNode<CommandSourceStack>> vanillaNode) implements PermissionCheck<T> { // Paper
|
||||
+ // Paper start - Vanilla Command permission checking
|
||||
+ public Check(int requiredLevel) {
|
||||
+ this(requiredLevel, new java.util.concurrent.atomic.AtomicReference<>());
|
||||
+ }
|
||||
+ // Paper end - Vanilla Command permission checking
|
||||
@Override
|
||||
public boolean test(T source) {
|
||||
+ // Paper start - Vanilla Command permission checking
|
||||
+ com.mojang.brigadier.tree.CommandNode<CommandSourceStack> currentCommand = vanillaNode.get();
|
||||
+ if (currentCommand != null && source instanceof CommandSourceStack commandSourceStack) {
|
||||
+ return commandSourceStack.hasPermission(this.requiredLevel, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand));
|
||||
+ }
|
||||
+ // Paper end - Vanilla Command permission checking
|
||||
return source.hasPermission(this.requiredLevel);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user