From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 16 May 2020 10:05:30 +0200
Subject: [PATCH] Add permission for command blocks


diff --git a/src/main/java/net/minecraft/server/BlockCommand.java b/src/main/java/net/minecraft/server/BlockCommand.java
index d0f75c8f93d3ceb1ee358baeb51f64e7e575bbc0..48cc48bd999c02268fa3270401c0df77a327ab13 100644
--- a/src/main/java/net/minecraft/server/BlockCommand.java
+++ b/src/main/java/net/minecraft/server/BlockCommand.java
@@ -110,7 +110,7 @@ public class BlockCommand extends BlockTileEntity {
     public EnumInteractionResult interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) {
         TileEntity tileentity = world.getTileEntity(blockposition);
 
-        if (tileentity instanceof TileEntityCommand && entityhuman.isCreativeAndOp()) {
+        if (tileentity instanceof TileEntityCommand && (entityhuman.isCreativeAndOp() || (entityhuman.isCreative() && entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
             entityhuman.a((TileEntityCommand) tileentity);
             return EnumInteractionResult.SUCCESS;
         } else {
diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
index ef2a496eda45ae5ee8fe52ef09e77c2906069d2e..6a0d70033b4eec384795b5cccd76bce2265ffbfc 100644
--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
+++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
@@ -178,7 +178,7 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener {
     }
 
     public boolean a(EntityHuman entityhuman) {
-        if (!entityhuman.isCreativeAndOp()) {
+        if (!entityhuman.isCreativeAndOp() && !entityhuman.isCreative() && !entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
             return false;
         } else {
             if (entityhuman.getWorld().isClientSide) {
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index f692276617d9c24ded5e887090e00642b0d63eba..b25b3b48165e5fef4db99c2838de21d4eca502f4 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -612,7 +612,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
         PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandblock, this, this.player.getWorldServer());
         if (!this.minecraftServer.getEnableCommandBlock()) {
             this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
-        } else if (!this.player.isCreativeAndOp()) {
+        } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
             this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
         } else {
             CommandBlockListenerAbstract commandblocklistenerabstract = null;
@@ -675,7 +675,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
         PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandminecart, this, this.player.getWorldServer());
         if (!this.minecraftServer.getEnableCommandBlock()) {
             this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
-        } else if (!this.player.isCreativeAndOp()) {
+        } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
             this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
         } else {
             CommandBlockListenerAbstract commandblocklistenerabstract = packetplayinsetcommandminecart.a(this.player.world);
diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
index ce66090b8dcd846db4507b99e3ef1a2d6104d19b..b1c05304cc4c97ea0df0ea11d8d59c095288ba96 100644
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
@@ -344,7 +344,7 @@ public class PlayerInteractManager {
             TileEntity tileentity = this.world.getTileEntity(blockposition);
             Block block = iblockdata.getBlock();
 
-            if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp()) {
+            if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp() && !(block instanceof BlockCommand && (this.player.isCreative() && this.player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
                 this.world.notify(blockposition, iblockdata, iblockdata, 3);
                 return false;
             } else if (this.player.a((World) this.world, blockposition, this.gamemode)) {
diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
index 525ebf961e5da0687183a5e2ead23ed92cbd9d79..a4a809f302c5ff9c76cde5fc0add2ceec1bdf9b5 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
@@ -16,6 +16,7 @@ public final class CraftDefaultPermissions {
         DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent);
         DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick in creative", org.bukkit.permissions.PermissionDefault.OP, parent);
         DefaultPermissions.registerPermission(ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE, parent);
+        DefaultPermissions.registerPermission(ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper
         // Spigot end
         parent.recalculatePermissibles();
     }
