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

---
 .../Add-permission-for-command-blocks.patch   | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Spigot-Server-Patches/Add-permission-for-command-blocks.patch

diff --git a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch
new file mode 100644
index 0000000000..5dd95643b7
--- /dev/null
+++ b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch
@@ -0,0 +1,79 @@
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/BlockCommand.java
++++ b/src/main/java/net/minecraft/server/BlockCommand.java
+@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
++++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
+@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/PlayerConnection.java
++++ b/src/main/java/net/minecraft/server/PlayerConnection.java
+@@ -0,0 +0,0 @@ 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;
+@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
++++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
+@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
++++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
+@@ -0,0 +0,0 @@ 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();
+     }