diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 7a7a9fe2a4..4fdcc40539 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -110,9 +110,9 @@ + this.player.connection.send(tileentity.getUpdatePacket()); + } + // CraftBukkit end - return; - } - ++ return; ++ } ++ + // CraftBukkit start + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND); + if (event.isCancelled()) { @@ -123,10 +123,10 @@ + if (tileentity != null) { + this.player.connection.send(tileentity.getUpdatePacket()); + } -+ return; -+ } + return; + } + // CraftBukkit end -+ + if (this.isCreative()) { this.destroyAndAck(pos, sequence, "creative destroy"); return; @@ -214,7 +214,7 @@ } } -@@ -242,10 +341,65 @@ +@@ -242,19 +341,78 @@ public boolean destroyBlock(BlockPos pos) { BlockState iblockdata = this.level.getBlockState(pos); @@ -281,7 +281,10 @@ BlockEntity tileentity = this.level.getBlockEntity(pos); Block block = iblockdata.getBlock(); -@@ -255,6 +409,10 @@ +- if (block instanceof GameMasterBlock && !this.player.canUseGameMasterBlocks()) { ++ if (block instanceof GameMasterBlock && !this.player.canUseGameMasterBlocks() && !(block instanceof net.minecraft.world.level.block.CommandBlock && (this.player.isCreative() && this.player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission + this.level.sendBlockUpdated(pos, iblockdata, iblockdata, 3); + return false; } else if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { return false; } else { diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index f64b334c12..c9ce7c1a0a 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -278,7 +278,7 @@ ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); this.send(ClientboundMoveVehiclePacket.fromEntity(entity)); return; -@@ -449,19 +583,72 @@ +@@ -449,20 +583,73 @@ d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; @@ -297,8 +297,8 @@ + this.player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit this.send(ClientboundMoveVehiclePacket.fromEntity(entity)); return; -+ } -+ + } + + // CraftBukkit start - fire PlayerMoveEvent + Player player = this.getCraftPlayer(); + if (!this.hasMoved) { @@ -347,11 +347,12 @@ + this.justTeleported = false; + return; + } - } ++ } + // CraftBukkit end - ++ this.player.serverLevel().getChunkSource().move(this.player); entity.recordMovementThroughBlocks(new Vec3(d0, d1, d2), entity.position()); + Vec3 vec3d = new Vec3(entity.getX() - d0, entity.getY() - d1, entity.getZ() - d2); @@ -499,6 +686,7 @@ this.lastGoodZ = this.awaitingPositionFromClient.z; this.player.hasChangedDimension(); @@ -453,6 +454,24 @@ }); } +@@ -568,7 +816,7 @@ + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + if (!this.server.isCommandBlockEnabled()) { + this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); +- } else if (!this.player.canUseGameMasterBlocks()) { ++ } else if (!this.player.canUseGameMasterBlocks() && (!this.player.isCreative() || !this.player.getBukkitEntity().hasPermission("minecraft.commandblock"))) { // Paper - command block permission + this.player.sendSystemMessage(Component.translatable("advMode.notAllowed")); + } else { + BaseCommandBlock commandblocklistenerabstract = null; +@@ -635,7 +883,7 @@ + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + if (!this.server.isCommandBlockEnabled()) { + this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); +- } else if (!this.player.canUseGameMasterBlocks()) { ++ } else if (!this.player.canUseGameMasterBlocks() && (!this.player.isCreative() || !this.player.getBukkitEntity().hasPermission("minecraft.commandblock"))) { // Paper - command block permission + this.player.sendSystemMessage(Component.translatable("advMode.notAllowed")); + } else { + BaseCommandBlock commandblocklistenerabstract = packet.getCommandBlock(this.player.level()); @@ -668,7 +916,7 @@ ItemStack itemstack = iblockdata.getCloneItemStack(worldserver, blockposition, flag); @@ -983,10 +1002,12 @@ if (this.player.hasClientLoaded()) { this.ackBlockChangesUpTo(packet.getSequence()); ServerLevel worldserver = this.player.serverLevel(); -@@ -1296,6 +1863,47 @@ - this.player.absRotateTo(f, f1); - } +@@ -1294,8 +1861,49 @@ + if (f1 != this.player.getXRot() || f != this.player.getYRot()) { + this.player.absRotateTo(f, f1); ++ } ++ + // CraftBukkit start + // Raytrace to look for 'rogue armswings' + double d0 = this.player.getX(); @@ -1017,8 +1038,8 @@ + cancelled = event.useItemInHand() == Event.Result.DENY; + } + this.player.gameMode.firedInteract = false; -+ } -+ + } + + if (cancelled) { + this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 + return; @@ -1558,7 +1579,7 @@ + ItemStack itemInHand = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand); + boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof Mob; + Item origItem = ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null ? null : ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem(); - ++ + ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); + + // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a @@ -1566,7 +1587,7 @@ + entity.getBukkitEntity().update(ServerGamePacketListenerImpl.this.player); + ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); + } -+ + + if (triggerLeashUpdate && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { + // Refresh the current leash state + ServerGamePacketListenerImpl.this.send(new ClientboundSetEntityLinkPacket(entity, ((Mob) entity).getLeashHolder())); diff --git a/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch index c68ecd1ff9..9abec14ca4 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch @@ -20,3 +20,12 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Executing command block"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Command to be executed"); +@@ -200,7 +204,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.getCommandSenderWorld().isClientSide) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CommandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CommandBlock.java.patch index c91c7c27b9..6c6c7fbbd8 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CommandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CommandBlock.java.patch @@ -26,3 +26,12 @@ if (powered != flag1) { blockEntity.setPowered(powered); if (powered) { +@@ -141,7 +152,7 @@ + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + BlockEntity tileentity = world.getBlockEntity(pos); + +- if (tileentity instanceof CommandBlockEntity && player.canUseGameMasterBlocks()) { ++ if (tileentity instanceof CommandBlockEntity && (player.canUseGameMasterBlocks() || (player.isCreative() && player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission + player.openCommandBlock((CommandBlockEntity) tileentity); + return InteractionResult.SUCCESS; + } else { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java index 245ad120a3..e0e61115ad 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java @@ -16,6 +16,7 @@ public final class CraftDefaultPermissions { DefaultPermissions.registerPermission(CraftDefaultPermissions.ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent); DefaultPermissions.registerPermission(CraftDefaultPermissions.ROOT + ".debugstick", "Gives the user the ability to use the debug stick in creative", org.bukkit.permissions.PermissionDefault.OP, parent); DefaultPermissions.registerPermission(CraftDefaultPermissions.ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE/* , parent */); // Paper - should not have this parent, as it's not a "vanilla" utility + DefaultPermissions.registerPermission(CraftDefaultPermissions.ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper // Spigot end parent.recalculatePermissibles(); }