--- a/net/minecraft/world/level/BaseCommandBlock.java
+++ b/net/minecraft/world/level/BaseCommandBlock.java
@@ -34,6 +_,11 @@
     private String command = "";
     @Nullable
     private Component customName;
+    // CraftBukkit start
+    @Override
+    public abstract org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper);
+    // CraftBukkit end
+
 
     public int getSuccessCount() {
         return this.successCount;
@@ -108,7 +_,13 @@
                             this.successCount++;
                         }
                     });
-                    server.getCommands().performPrefixedCommand(commandSourceStack, this.command);
+                    // Paper start - ServerCommandEvent
+                    org.bukkit.event.server.ServerCommandEvent event = new org.bukkit.event.server.ServerCommandEvent(commandSourceStack.getBukkitSender(), net.minecraft.commands.Commands.trimOptionalPrefix(this.command));
+                    if (!event.callEvent()) {
+                        return true;
+                    }
+                    server.getCommands().performPrefixedCommand(commandSourceStack, event.getCommand());
+                    // Paper end - ServerCommandEvent
                 } catch (Throwable var6) {
                     CrashReport crashReport = CrashReport.forThrowable(var6, "Executing command block");
                     CrashReportCategory crashReportCategory = crashReport.addCategory("Command to be executed");
@@ -144,6 +_,7 @@
     @Override
     public void sendSystemMessage(Component component) {
         if (this.trackOutput) {
+            org.spigotmc.AsyncCatcher.catchOp("sendSystemMessage to a command block"); // Paper - Don't broadcast messages to command blocks
             this.lastOutput = Component.literal("[" + TIME_FORMAT.format(new Date()) + "] ").append(component);
             this.onUpdated();
         }
@@ -166,7 +_,7 @@
     }
 
     public InteractionResult usedBy(Player player) {
-        if (!player.canUseGameMasterBlocks()) {
+        if (!player.canUseGameMasterBlocks() && (!player.isCreative() || !player.getBukkitEntity().hasPermission("minecraft.commandblock"))) { // Paper - command block permission
             return InteractionResult.PASS;
         } else {
             if (player.level().isClientSide) {
