From 6fcc9cce6df2834e36f170e813983cd52aab3ceb Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Mon, 25 Feb 2019 19:26:56 +1100 Subject: [PATCH] Add creative mode NBT permissions By: md_5 --- .../level/ServerPlayerGameMode.java.patch | 30 ++++++++++++------ .../ServerGamePacketListenerImpl.java.patch | 31 ++++++++++++------- .../minecraft/world/item/BlockItem.java.patch | 9 ++++++ .../world/item/DebugStickItem.java.patch | 9 ++++++ .../permissions/CraftDefaultPermissions.java | 6 ++++ 5 files changed, 65 insertions(+), 20 deletions(-) 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 4d66920645..5352294fce 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 @@ -66,7 +66,7 @@ BlockState iblockdata; if (this.hasDelayedDestroy) { -@@ -146,11 +172,33 @@ +@@ -146,15 +172,45 @@ if (action == ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK) { if (!this.level.mayInteract(this.player, pos)) { @@ -99,8 +99,20 @@ + if (this.isCreative()) { this.destroyAndAck(pos, sequence, "creative destroy"); ++ return; ++ } ++ ++ // Spigot start - handle debug stick left click for non-creative ++ if (this.player.getMainHandItem().is(net.minecraft.world.item.Items.DEBUG_STICK) ++ && ((net.minecraft.world.item.DebugStickItem) net.minecraft.world.item.Items.DEBUG_STICK).handleInteraction(this.player, this.level.getBlockState(pos), this.level, pos, false, this.player.getMainHandItem())) { ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); return; -@@ -166,7 +214,19 @@ + } ++ // Spigot end + + if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { + this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); +@@ -166,7 +222,19 @@ float f = 1.0F; iblockdata = this.level.getBlockState(pos); @@ -121,7 +133,7 @@ EnchantmentHelper.onHitBlock(this.level, this.player.getMainHandItem(), this.player, this.player, EquipmentSlot.MAINHAND, Vec3.atCenterOf(pos), iblockdata, (item) -> { this.player.onEquippedItemBroken(item, EquipmentSlot.MAINHAND); }); -@@ -174,6 +234,26 @@ +@@ -174,6 +242,26 @@ f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos); } @@ -148,7 +160,7 @@ if (!iblockdata.isAir() && f >= 1.0F) { this.destroyAndAck(pos, sequence, "insta mine"); } else { -@@ -218,13 +298,15 @@ +@@ -218,13 +306,15 @@ } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { this.isDestroyingBlock = false; if (!Objects.equals(this.destroyPos, pos)) { @@ -165,7 +177,7 @@ } } -@@ -242,10 +324,65 @@ +@@ -242,10 +332,65 @@ public boolean destroyBlock(BlockPos pos) { BlockState iblockdata = this.level.getBlockState(pos); @@ -232,7 +244,7 @@ BlockEntity tileentity = this.level.getBlockEntity(pos); Block block = iblockdata.getBlock(); -@@ -255,6 +392,10 @@ +@@ -255,6 +400,10 @@ } else if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { return false; } else { @@ -243,7 +255,7 @@ BlockState iblockdata1 = block.playerWillDestroy(this.level, pos, iblockdata, this.player); boolean flag = this.level.removeBlock(pos, false); -@@ -263,19 +404,32 @@ +@@ -263,19 +412,32 @@ } if (this.isCreative()) { @@ -279,7 +291,7 @@ } } } -@@ -321,15 +475,54 @@ +@@ -321,15 +483,54 @@ } } @@ -334,7 +346,7 @@ if (itileinventory != null) { player.openMenu(itileinventory); return InteractionResult.CONSUME; -@@ -359,7 +552,7 @@ +@@ -359,7 +560,7 @@ } } 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 4c6e35418b..f00c119eb6 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 @@ -40,7 +40,7 @@ import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; -@@ -192,11 +195,69 @@ +@@ -192,12 +195,70 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; @@ -50,7 +50,7 @@ import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import org.slf4j.Logger; -+ + +// CraftBukkit start +import com.mojang.datafixers.util.Pair; +import java.util.Arrays; @@ -107,9 +107,10 @@ +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.SmithingInventory; +// CraftBukkit end - ++ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener { + static final Logger LOGGER = LogUtils.getLogger(); @@ -247,7 +308,7 @@ private boolean waitingForSwitchToConfig; @@ -126,7 +127,7 @@ - this.chatMessageChain = new FutureChain(server); + this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat } - ++ + // CraftBukkit start - add fields and methods + private int lastTick = MinecraftServer.currentTick; + private int allowedPlayerTicks = 1; @@ -142,7 +143,7 @@ + private float lastYaw = Float.MAX_VALUE; + private boolean justTeleported = false; + // CraftBukkit end -+ + @Override public void tick() { + org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.startTiming(); // Spigot @@ -222,7 +223,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,20 +568,73 @@ +@@ -449,19 +568,72 @@ d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; @@ -241,8 +242,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) { @@ -291,12 +292,11 @@ + 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 +671,7 @@ this.lastGoodZ = this.awaitingPositionFromClient.z; this.player.hasChangedDimension(); @@ -334,6 +334,15 @@ Suggestions suggestions1 = suggestions.getList().size() <= 1000 ? suggestions : new Suggestions(suggestions.getRange(), suggestions.getList().subList(0, 1000)); this.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions1)); +@@ -668,7 +849,7 @@ + ItemStack itemstack = iblockdata.getCloneItemStack(worldserver, blockposition, flag); + + if (!itemstack.isEmpty()) { +- if (flag) { ++ if (flag && this.player.getBukkitEntity().hasPermission("minecraft.nbt.copy")) { // Spigot + ServerGamePacketListenerImpl.addBlockDataToItem(iblockdata, worldserver, blockposition, itemstack); + } + @@ -866,6 +1047,13 @@ AbstractContainerMenu container = this.player.containerMenu; diff --git a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch index 99dc10ca00..a688ebb0e3 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch @@ -81,3 +81,12 @@ } protected boolean mustSurvive() { +@@ -178,7 +208,7 @@ + return false; + } + +- if (tileentitytypes1.onlyOpCanSetNbt() && (player == null || !player.canUseGameMasterBlocks())) { ++ if (tileentitytypes1.onlyOpCanSetNbt() && (player == null || !(player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place"))))) { // Spigot - add permission + return false; + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch index 5ecf01e96f..b81a2063de 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch @@ -5,6 +5,15 @@ package net.minecraft.world.item; import java.util.Collection; +@@ -52,7 +53,7 @@ + } + + public boolean handleInteraction(Player player, BlockState state, LevelAccessor world, BlockPos pos, boolean update, ItemStack stack) { +- if (!player.canUseGameMasterBlocks()) { ++ if (!player.canUseGameMasterBlocks() && !(player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.debugstick")) && !player.getBukkitEntity().hasPermission("minecraft.debugstick.always")) { // Spigot + return false; + } else { + Holder holder = state.getBlockHolder(); @@ -92,7 +93,7 @@ } 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 448edd0d72..5ac25dab93 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 @@ -11,6 +11,12 @@ public final class CraftDefaultPermissions { public static void registerCorePermissions() { Permission parent = DefaultPermissions.registerPermission(CraftDefaultPermissions.ROOT, "Gives the user the ability to use all vanilla utilities and commands"); CommandPermissions.registerPermissions(parent); + // Spigot start + DefaultPermissions.registerPermission(CraftDefaultPermissions.ROOT + ".nbt.place", "Gives the user the ability to place restricted blocks with NBT in creative", org.bukkit.permissions.PermissionDefault.OP, parent); + 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); + // Spigot end parent.recalculatePermissibles(); } }