2024-12-11 22:26:55 +01:00
--- a/net/minecraft/commands/CommandSourceStack.java
+++ b/net/minecraft/commands/CommandSourceStack.java
2025-05-28 13:23:32 +02:00
@@ -47,7 +_,7 @@
2024-12-11 22:26:55 +01:00
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
2025-05-28 13:23:32 +02:00
-public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, PermissionSource, SharedSuggestionProvider {
+public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, PermissionSource, SharedSuggestionProvider, io.papermc.paper.command.brigadier.PaperCommandSourceStack { // Paper - Brigadier API
2020-04-19 18:15:29 -04:00
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"));
2022-08-01 22:50:34 -04:00
public final CommandSource source;
2025-05-28 13:23:32 +02:00
@@ -65,6 +_,7 @@
2024-12-11 22:26:55 +01:00
private final Vec2 rotation;
private final CommandSigningContext signingContext;
private final TaskChainer chatMessageChainer;
2021-01-29 17:54:03 +01:00
+ public boolean bypassSelectorPermissions = false; // Paper - add bypass for selector permissions
2024-12-11 22:26:55 +01:00
2024-12-13 21:21:48 +01:00
public CommandSourceStack(
CommandSource source,
2025-05-28 13:23:32 +02:00
@@ -190,6 +_,30 @@
2025-01-11 22:29:16 +01:00
);
}
2025-04-12 17:26:44 +02:00
2025-01-11 22:29:16 +01:00
+ // Paper start - Expose 'with' functions from the CommandSourceStack
+ @Override
+ public CommandSourceStack withLocation(org.bukkit.Location location) {
+ return this.getLocation().equals(location)
+ ? this
+ : new CommandSourceStack(
+ this.source,
+ new Vec3(location.x(), location.y(), location.z()),
+ new Vec2(location.getPitch(), location.getYaw()),
+ ((org.bukkit.craftbukkit.CraftWorld) location.getWorld()).getHandle(),
+ this.permissionLevel,
+ this.textName,
+ this.displayName,
+ this.server,
+ this.entity,
+ this.silent,
+ this.resultCallback,
+ this.anchor,
+ this.signingContext,
+ this.chatMessageChainer
+ );
+ }
+ // Paper end - Expose 'with' functions from the CommandSourceStack
2025-04-12 17:26:44 +02:00
+
2025-01-11 22:29:16 +01:00
public CommandSourceStack withRotation(Vec2 rotation) {
return this.rotation.equals(rotation)
2025-04-12 17:26:44 +02:00
? this
2025-05-28 13:23:32 +02:00
@@ -396,6 +_,32 @@
2024-12-11 22:26:55 +01:00
return this.permissionLevel >= level;
2024-12-13 21:21:48 +01:00
}
2022-01-24 15:32:02 -08:00
+ // Paper start - Fix permission levels for command blocks
+ private boolean forceRespectPermissionLevel() {
+ return this.source == CommandSource.NULL || (this.source instanceof final net.minecraft.world.level.BaseCommandBlock commandBlock && commandBlock.getLevel().paperConfig().commandBlocks.forceFollowPermLevel);
+ }
+ // Paper end - Fix permission levels for command blocks
+
2024-12-11 22:26:55 +01:00
+ // CraftBukkit start
+ public boolean hasPermission(int i, String bukkitPermission) {
2022-01-24 15:32:02 -08:00
+ // Paper start - Fix permission levels for command blocks
+ final java.util.function.BooleanSupplier hasBukkitPerm = () -> this.source == CommandSource.NULL /*treat NULL as having all bukkit perms*/ || this.getBukkitSender().hasPermission(bukkitPermission); // lazily check bukkit perms to the benefit of custom permission setups
+ // if the server is null, we must check the vanilla perm level system
+ // if ignoreVanillaPermissions is true, we can skip vanilla perms and just run the bukkit perm check
+ //noinspection ConstantValue
+ if (this.getServer() == null || !this.getServer().server.ignoreVanillaPermissions) { // server & level are null for command function loading
+ final boolean hasPermLevel = this.permissionLevel >= i;
+ if (this.forceRespectPermissionLevel()) { // NULL CommandSource and command blocks (if setting is enabled) should always pass the vanilla perm check
+ return hasPermLevel && hasBukkitPerm.getAsBoolean();
+ } else { // otherwise check vanilla perm first then bukkit perm, matching upstream behavior
+ return hasPermLevel || hasBukkitPerm.getAsBoolean();
+ }
+ }
+ return hasBukkitPerm.getAsBoolean();
+ // Paper end - Fix permission levels for command blocks
2024-12-13 21:21:48 +01:00
+ }
2024-12-11 22:26:55 +01:00
+ // CraftBukkit end
2024-12-13 21:21:48 +01:00
+
2024-12-11 22:26:55 +01:00
public Vec3 getPosition() {
return this.worldPosition;
2024-12-13 21:21:48 +01:00
}
2025-05-28 13:23:32 +02:00
@@ -500,20 +_,25 @@
2024-12-13 21:21:48 +01:00
Component component = Component.translatable("chat.type.admin", this.getDisplayName(), message).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC);
if (this.server.getGameRules().getBoolean(GameRules.RULE_SENDCOMMANDFEEDBACK)) {
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
- if (serverPlayer.commandSource() != this.source && this.server.getPlayerList().isOp(serverPlayer.getGameProfile())) {
+ if (serverPlayer.commandSource() != this.source && serverPlayer.getBukkitEntity().hasPermission("minecraft.admin.command_feedback")) { // CraftBukkit
serverPlayer.sendSystemMessage(component);
2024-12-11 22:26:55 +01:00
}
}
2014-02-09 14:39:01 +11:00
}
- if (this.source != this.server && this.server.getGameRules().getBoolean(GameRules.RULE_LOGADMINCOMMANDS)) {
+ if (this.source != this.server && this.server.getGameRules().getBoolean(GameRules.RULE_LOGADMINCOMMANDS) && !org.spigotmc.SpigotConfig.silentCommandBlocks) { // Spigot
2024-12-13 21:21:48 +01:00
this.server.sendSystemMessage(component);
2014-02-09 14:39:01 +11:00
}
2017-06-17 18:48:21 -04:00
}
public void sendFailure(Component message) {
+ // Paper start - Add UnknownCommandEvent
+ this.sendFailure(message, true);
+ }
+ public void sendFailure(Component message, boolean withStyle) {
+ // Paper end - Add UnknownCommandEvent
if (this.source.acceptsFailure() && !this.silent) {
- this.source.sendSystemMessage(Component.empty().append(message).withStyle(ChatFormatting.RED));
+ this.source.sendSystemMessage(withStyle ? Component.empty().append(message).withStyle(ChatFormatting.RED) : message); // Paper - Add UnknownCommandEvent
}
}
2024-12-13 21:21:48 +01:00
2025-05-28 13:23:32 +02:00
@@ -524,7 +_,7 @@
2025-01-12 17:50:08 +01:00
@Override
public Collection<String> getOnlinePlayerNames() {
- return Lists.newArrayList(this.server.getPlayerNames());
+ return this.entity instanceof ServerPlayer sourcePlayer && !sourcePlayer.getBukkitEntity().hasPermission("paper.bypass-visibility.tab-completion") ? this.getServer().getPlayerList().getPlayers().stream().filter(serverPlayer -> sourcePlayer.getBukkitEntity().canSee(serverPlayer.getBukkitEntity())).map(serverPlayer -> serverPlayer.getGameProfile().getName()).toList() : Lists.newArrayList(this.server.getPlayerNames()); // Paper - Make CommandSourceStack respect hidden players
}
@Override
2025-05-28 13:23:32 +02:00
@@ -604,4 +_,16 @@
2024-12-11 22:26:55 +01:00
public boolean isSilent() {
return this.silent;
}
+
2022-08-01 22:50:34 -04:00
+ // Paper start
+ @Override
+ public CommandSourceStack getHandle() {
+ return this;
+ }
+ // Paper end
2024-12-11 22:26:55 +01:00
+ // CraftBukkit start
+ public org.bukkit.command.CommandSender getBukkitSender() {
+ return this.source.getBukkitSender(this);
+ }
+ // CraftBukkit end
}