--- a/net/minecraft/commands/CommandSourceStack.java
+++ b/net/minecraft/commands/CommandSourceStack.java
@@ -8,6 +8,7 @@
 import com.mojang.brigadier.suggestion.Suggestions;
 import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
@@ -21,6 +22,7 @@
 import net.minecraft.network.chat.ChatSender;
 import net.minecraft.network.chat.ChatType;
 import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.MutableComponent;
 import net.minecraft.network.chat.OutgoingPlayerChatMessage;
 import net.minecraft.resources.ResourceKey;
 import net.minecraft.resources.ResourceLocation;
@@ -35,8 +37,10 @@
 import net.minecraft.world.level.dimension.DimensionType;
 import net.minecraft.world.phys.Vec2;
 import net.minecraft.world.phys.Vec3;
+import com.mojang.brigadier.tree.CommandNode; // CraftBukkit
+
+public class CommandSourceStack implements SharedSuggestionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper
 
-public class CommandSourceStack implements SharedSuggestionProvider {
     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;
@@ -55,9 +59,10 @@
     private final Vec2 rotation;
     private final CommandSigningContext signingContext;
     private final TaskChainer chatMessageChainer;
+    public java.util.Map<Thread, CommandNode> currentCommand = new java.util.concurrent.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, (context, success, result) -> {
+        this(output, pos, rot, world, level, name, displayName, server, entity, false, (commandcontext, flag, j) -> {
         }, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.IMMEDIATE);
     }
 
@@ -99,8 +104,9 @@
     }
 
     public CommandSourceStack withCallback(ResultConsumer<CommandSourceStack> consumer, BinaryOperator<ResultConsumer<CommandSourceStack>> merger) {
-        ResultConsumer<CommandSourceStack> resultConsumer = merger.apply(this.consumer, consumer);
-        return this.withCallback(resultConsumer);
+        ResultConsumer<CommandSourceStack> resultconsumer1 = (ResultConsumer) merger.apply(this.consumer, consumer);
+
+        return this.withCallback(resultconsumer1);
     }
 
     public CommandSourceStack withSuppressedOutput() {
@@ -123,9 +129,10 @@
         if (world == this.level) {
             return this;
         } else {
-            double d = DimensionType.getTeleportationScale(this.level.dimensionType(), world.dimensionType());
-            Vec3 vec3 = new Vec3(this.worldPosition.x * d, this.worldPosition.y, this.worldPosition.z * d);
-            return new CommandSourceStack(this.source, vec3, this.rotation, world, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.consumer, this.anchor, this.signingContext, this.chatMessageChainer);
+            double d0 = DimensionType.getTeleportationScale(this.level.dimensionType(), world.dimensionType());
+            Vec3 vec3d = new Vec3(this.worldPosition.x * d0, this.worldPosition.y, this.worldPosition.z * d0);
+
+            return new CommandSourceStack(this.source, vec3d, this.rotation, world, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.consumer, this.anchor, this.signingContext, this.chatMessageChainer);
         }
     }
 
@@ -134,14 +141,15 @@
     }
 
     public CommandSourceStack facing(Vec3 position) {
-        Vec3 vec3 = this.anchor.apply(this);
-        double d = position.x - vec3.x;
-        double e = position.y - vec3.y;
-        double f = position.z - vec3.z;
-        double g = Math.sqrt(d * d + f * f);
-        float h = Mth.wrapDegrees((float)(-(Mth.atan2(e, g) * (double)(180F / (float)Math.PI))));
-        float i = Mth.wrapDegrees((float)(Mth.atan2(f, d) * (double)(180F / (float)Math.PI)) - 90.0F);
-        return this.withRotation(new Vec2(h, i));
+        Vec3 vec3d1 = this.anchor.apply(this);
+        double d0 = position.x - vec3d1.x;
+        double d1 = position.y - vec3d1.y;
+        double d2 = position.z - vec3d1.z;
+        double d3 = Math.sqrt(d0 * d0 + d2 * d2);
+        float f = Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875D)));
+        float f1 = Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875D) - 90.0F);
+
+        return this.withRotation(new Vec2(f, f1));
     }
 
     public CommandSourceStack withSigningContext(CommandSigningContext signedArguments) {
@@ -164,11 +172,47 @@
         return this.entity != null ? this.entity.asChatSender() : ChatSender.SYSTEM;
     }
 
+    // Paper start
+    @Override
+    public org.bukkit.entity.Entity getBukkitEntity() {
+        return getEntity() != null ? getEntity().getBukkitEntity() : null;
+    }
+
+    @Override
+    public org.bukkit.World getBukkitWorld() {
+        return getLevel() != null ? getLevel().getWorld() : null;
+    }
+
+    @Override
+    public org.bukkit.Location getBukkitLocation() {
+        Vec3 pos = getPosition();
+        org.bukkit.World world = getBukkitWorld();
+        Vec2 rot = getRotation();
+        return world != null && pos != null ? new org.bukkit.Location(world, pos.x, pos.y, pos.z, rot != null ? rot.x : 0, rot != null ? rot.y : 0) : null;
+    }
+    // Paper end
+
     @Override
     public boolean hasPermission(int level) {
+        // CraftBukkit start
+        // Paper start - fix concurrency issue
+        CommandNode currentCommand = this.currentCommand.get(Thread.currentThread());
+        if (currentCommand != null) {
+            return this.hasPermission(level, org.bukkit.craftbukkit.v1_19_R1.command.VanillaCommandWrapper.getPermission(currentCommand));
+            // Paper end
+        }
+        // CraftBukkit end
+
         return this.permissionLevel >= level;
     }
 
+    // CraftBukkit start
+    public boolean hasPermission(int i, String bukkitPermission) {
+        // World is null when loading functions
+        return ((this.getLevel() == null || !this.getLevel().getCraftServer().ignoreVanillaPermissions) && this.permissionLevel >= i) || this.getBukkitSender().hasPermission(bukkitPermission);
+    }
+    // CraftBukkit end
+
     public Vec3 getPosition() {
         return this.worldPosition;
     }
@@ -184,32 +228,38 @@
 
     public Entity getEntityOrException() throws CommandSyntaxException {
         if (this.entity == null) {
-            throw ERROR_NOT_ENTITY.create();
+            throw CommandSourceStack.ERROR_NOT_ENTITY.create();
         } else {
             return this.entity;
         }
     }
 
     public ServerPlayer getPlayerOrException() throws CommandSyntaxException {
-        Entity var2 = this.entity;
-        if (var2 instanceof ServerPlayer) {
-            return (ServerPlayer)var2;
+        Entity entity = this.entity;
+
+        if (entity instanceof ServerPlayer) {
+            ServerPlayer entityplayer = (ServerPlayer) entity;
+
+            return entityplayer;
         } else {
-            throw ERROR_NOT_PLAYER.create();
+            throw CommandSourceStack.ERROR_NOT_PLAYER.create();
         }
     }
 
     @Nullable
     public ServerPlayer getPlayer() {
-        Entity var2 = this.entity;
-        ServerPlayer var10000;
-        if (var2 instanceof ServerPlayer serverPlayer) {
-            var10000 = serverPlayer;
+        Entity entity = this.entity;
+        ServerPlayer entityplayer;
+
+        if (entity instanceof ServerPlayer) {
+            ServerPlayer entityplayer1 = (ServerPlayer) entity;
+
+            entityplayer = entityplayer1;
         } else {
-            var10000 = null;
+            entityplayer = null;
         }
 
-        return var10000;
+        return entityplayer;
     }
 
     public boolean isPlayer() {
@@ -237,19 +287,17 @@
     }
 
     public boolean shouldFilterMessageTo(ServerPlayer recipient) {
-        ServerPlayer serverPlayer = this.getPlayer();
-        if (recipient == serverPlayer) {
-            return false;
-        } else {
-            return serverPlayer != null && serverPlayer.isTextFilteringEnabled() || recipient.isTextFilteringEnabled();
-        }
+        ServerPlayer entityplayer1 = this.getPlayer();
+
+        return recipient == entityplayer1 ? false : entityplayer1 != null && entityplayer1.isTextFilteringEnabled() || recipient.isTextFilteringEnabled();
     }
 
     public void sendChatMessage(OutgoingPlayerChatMessage message, boolean filterMaskEnabled, ChatType.Bound params) {
         if (!this.silent) {
-            ServerPlayer serverPlayer = this.getPlayer();
-            if (serverPlayer != null) {
-                serverPlayer.sendChatMessage(message, filterMaskEnabled, params);
+            ServerPlayer entityplayer = this.getPlayer();
+
+            if (entityplayer != null) {
+                entityplayer.sendChatMessage(message, filterMaskEnabled, params);
             } else {
                 this.source.sendSystemMessage(params.decorate(message.serverContent()));
             }
@@ -259,9 +307,10 @@
 
     public void sendSystemMessage(Component message) {
         if (!this.silent) {
-            ServerPlayer serverPlayer = this.getPlayer();
-            if (serverPlayer != null) {
-                serverPlayer.sendSystemMessage(message);
+            ServerPlayer entityplayer = this.getPlayer();
+
+            if (entityplayer != null) {
+                entityplayer.sendSystemMessage(message);
             } else {
                 this.source.sendSystemMessage(message);
             }
@@ -281,17 +330,22 @@
     }
 
     private void broadcastToAdmins(Component message) {
-        Component component = Component.translatable("chat.type.admin", this.getDisplayName(), message).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC);
+        MutableComponent ichatmutablecomponent = 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 != this.source && this.server.getPlayerList().isOp(serverPlayer.getGameProfile())) {
-                    serverPlayer.sendSystemMessage(component);
+            Iterator iterator = this.server.getPlayerList().getPlayers().iterator();
+
+            while (iterator.hasNext()) {
+                ServerPlayer entityplayer = (ServerPlayer) iterator.next();
+
+                if (entityplayer != this.source && entityplayer.getBukkitEntity().hasPermission("minecraft.admin.command_feedback")) { // CraftBukkit
+                    entityplayer.sendSystemMessage(ichatmutablecomponent);
                 }
             }
         }
 
-        if (this.source != this.server && this.server.getGameRules().getBoolean(GameRules.RULE_LOGADMINCOMMANDS)) {
-            this.server.sendSystemMessage(component);
+        if (this.source != this.server && this.server.getGameRules().getBoolean(GameRules.RULE_LOGADMINCOMMANDS) && !org.spigotmc.SpigotConfig.silentCommandBlocks) { // Spigot
+            this.server.sendSystemMessage(ichatmutablecomponent);
         }
 
     }
@@ -337,8 +391,8 @@
 
     @Override
     public CompletableFuture<Suggestions> suggestRegistryElements(ResourceKey<? extends Registry<?>> registryRef, SharedSuggestionProvider.ElementSuggestionType suggestedIdType, SuggestionsBuilder builder, CommandContext<?> context) {
-        return this.registryAccess().registry(registryRef).map((registry) -> {
-            this.suggestRegistryElements(registry, suggestedIdType, builder);
+        return (CompletableFuture) this.registryAccess().registry(registryRef).map((iregistry) -> {
+            this.suggestRegistryElements(iregistry, suggestedIdType, builder);
             return builder.buildFuture();
         }).orElseGet(Suggestions::empty);
     }
@@ -352,4 +406,26 @@
     public RegistryAccess registryAccess() {
         return this.server.registryAccess();
     }
+
+    // CraftBukkit start
+    public org.bukkit.command.CommandSender getBukkitSender() {
+        return this.source.getBukkitSender(this);
+    }
+    // CraftBukkit end
+    // Paper start - override getSelectedEntities
+    @Override
+    public Collection<String> getSelectedEntities() {
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && this.source instanceof ServerPlayer player) {
+            double pickDistance = player.gameMode.getGameModeForPlayer().isCreative() ? 5.0F : 4.5F;
+            Vec3 min = player.getEyePosition(1.0F);
+            Vec3 viewVector = player.getViewVector(1.0F);
+            Vec3 max = min.add(viewVector.x * pickDistance, viewVector.y * pickDistance, viewVector.z * pickDistance);
+            net.minecraft.world.phys.AABB aabb = player.getBoundingBox().expandTowards(viewVector.scale(pickDistance)).inflate(1.0D, 1.0D, 1.0D);
+            pickDistance = player.gameMode.getGameModeForPlayer().isCreative() ? 6.0F : pickDistance;
+            net.minecraft.world.phys.EntityHitResult hitResult = net.minecraft.world.entity.projectile.ProjectileUtil.getEntityHitResult(player, min, max, aabb, (e) -> !e.isSpectator() && e.isPickable(), pickDistance);
+            return hitResult != null ? java.util.Collections.singletonList(hitResult.getEntity().getStringUUID()) : SharedSuggestionProvider.super.getSelectedEntities();
+        }
+        return SharedSuggestionProvider.super.getSelectedEntities();
+    }
+    // Paper end
 }
