diff options
Diffstat (limited to 'patch-remap/mache-vineflower-stripped/net/minecraft/server/level/ServerPlayerGameMode.java.patch')
-rw-r--r-- | patch-remap/mache-vineflower-stripped/net/minecraft/server/level/ServerPlayerGameMode.java.patch | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/server/level/ServerPlayerGameMode.java.patch new file mode 100644 index 0000000000..1a1bd0900e --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -0,0 +1,327 @@ +--- a/net/minecraft/server/level/ServerPlayerGameMode.java ++++ b/net/minecraft/server/level/ServerPlayerGameMode.java +@@ -21,10 +23,28 @@ + import net.minecraft.world.level.block.Block; + import net.minecraft.world.level.block.GameMasterBlock; + import net.minecraft.world.level.block.entity.BlockEntity; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; ++import org.slf4j.Logger; ++ ++// CraftBukkit start ++import java.util.ArrayList; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.network.ServerGamePacketListenerImpl; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.CakeBlock; ++import net.minecraft.world.level.block.DoorBlock; ++import net.minecraft.world.level.block.state.properties.BlockPropertyDoubleBlockHalf; + import net.minecraft.world.phys.BlockHitResult; + import net.minecraft.world.phys.Vec3; +-import org.slf4j.Logger; ++import org.bukkit.GameMode; ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.event.block.BlockBreakEvent; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.Event; ++import org.bukkit.event.block.Action; ++import org.bukkit.event.player.PlayerGameModeChangeEvent; ++import org.bukkit.event.player.PlayerInteractEvent; ++// CraftBukkit end + + public class ServerPlayerGameMode { + private static final Logger LOGGER = LogUtils.getLogger(); +@@ -51,12 +76,16 @@ + if (gameModeForPlayer == this.gameModeForPlayer) { + return false; + } else { ++ // CraftBukkit start ++ PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(player.getBukkitEntity(), GameMode.getByValue(gameModeForPlayer.getId())); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return false; ++ } ++ // CraftBukkit end + this.setGameModeForPlayer(gameModeForPlayer, this.previousGameModeForPlayer); + this.player.onUpdateAbilities(); +- this.player +- .server +- .getPlayerList() +- .broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player)); ++ this.player.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit + this.level.updateSleepingPlayerList(); + return true; + } +@@ -86,7 +115,9 @@ + } + + public void tick() { +- this.gameTicks++; ++ this.gameTicks = MinecraftServer.currentTick; // CraftBukkit; ++ IBlockData iblockdata; ++ + if (this.hasDelayedDestroy) { + BlockState blockState = this.level.getBlockState(this.delayedDestroyPos); + if (blockState.isAir()) { +@@ -134,11 +169,33 @@ + } else { + if (action == ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK) { + if (!this.level.mayInteract(this.player, pos)) { ++ // CraftBukkit start - fire PlayerInteractEvent ++ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, face, this.player.getInventory().getSelected(), EnumHand.MAIN_HAND); + this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); + this.debugLogging(pos, false, sequence, "may not interact"); ++ // Update any tile entity data for this block ++ BlockEntity tileentity = level.getBlockEntity(pos); ++ if (tileentity != null) { ++ this.player.connection.send(tileentity.getUpdatePacket()); ++ } ++ // CraftBukkit end + return; + } + ++ // CraftBukkit start ++ PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, face, this.player.getInventory().getSelected(), EnumHand.MAIN_HAND); ++ if (event.isCancelled()) { ++ // Let the client know the block still exists ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); ++ // Update any tile entity data for this block ++ BlockEntity tileentity = this.level.getBlockEntity(pos); ++ if (tileentity != null) { ++ this.player.connection.send(tileentity.getUpdatePacket()); ++ } ++ return; ++ } ++ // CraftBukkit end ++ + if (this.isCreative()) { + this.destroyAndAck(pos, sequence, "creative destroy"); + return; +@@ -152,13 +209,46 @@ + + this.destroyProgressStart = this.gameTicks; + float f = 1.0F; +- BlockState blockState = this.level.getBlockState(pos); +- if (!blockState.isAir()) { +- blockState.attack(this.level, pos, this.player); +- f = blockState.getDestroyProgress(this.player, this.player.level(), pos); ++ ++ iblockdata = this.level.getBlockState(pos); ++ // CraftBukkit start - Swings at air do *NOT* exist. ++ if (event.useInteractedBlock() == Event.Result.DENY) { ++ // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. ++ IBlockData data = this.level.getBlockState(pos); ++ if (data.getBlock() instanceof DoorBlock) { ++ // For some reason *BOTH* the bottom/top part have to be marked updated. ++ boolean bottom = data.getValue(DoorBlock.HALF) == BlockPropertyDoubleBlockHalf.LOWER; ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, bottom ? pos.above() : pos.below())); ++ } else if (data.getBlock() instanceof TrapDoorBlock) { ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); ++ } ++ } else if (!iblockdata.isAir()) { ++ iblockdata.attack(this.level, pos, this.player); ++ f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos); + } + +- if (!blockState.isAir() && f >= 1.0F) { ++ if (event.useItemInHand() == Event.Result.DENY) { ++ // If we 'insta destroyed' then the client needs to be informed. ++ if (f > 1.0f) { ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); ++ } ++ return; ++ } ++ org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, pos, this.player.getInventory().getSelected(), f >= 1.0f); ++ ++ if (blockEvent.isCancelled()) { ++ // Let the client know the block still exists ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); ++ return; ++ } ++ ++ if (blockEvent.getInstaBreak()) { ++ f = 2.0f; ++ } ++ // CraftBukkit end ++ ++ if (!iblockdata.isAir() && f >= 1.0F) { + this.destroyAndAck(pos, sequence, "insta mine"); + } else { + if (this.isDestroyingBlock) { +@@ -199,13 +292,15 @@ + } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { + this.isDestroyingBlock = false; + if (!Objects.equals(this.destroyPos, pos)) { +- LOGGER.warn("Mismatch in destroy block pos: {} {}", this.destroyPos, pos); ++ ServerPlayerGameMode.LOGGER.debug("Mismatch in destroy block pos: {} {}", this.destroyPos, pos); // CraftBukkit - SPIGOT-5457 sent by client when interact event cancelled + this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); + this.debugLogging(pos, true, sequence, "aborted mismatched destroying"); + } + + this.level.destroyBlockProgress(this.player.getId(), pos, -1); + this.debugLogging(pos, true, sequence, "aborted destroying"); ++ ++ CraftEventFactory.callBlockDamageAbortEvent(this.player, pos, this.player.getInventory().getSelected()); // CraftBukkit + } + } + } +@@ -220,37 +317,112 @@ + } + + public boolean destroyBlock(BlockPos pos) { +- BlockState blockState = this.level.getBlockState(pos); +- if (!this.player.getMainHandItem().getItem().canAttackBlock(blockState, this.level, pos, this.player)) { ++ IBlockData iblockdata = this.level.getBlockState(pos); ++ // CraftBukkit start - fire BlockBreakEvent ++ org.bukkit.block.Block bblock = CraftBlock.at(level, pos); ++ BlockBreakEvent event = null; ++ ++ if (this.player instanceof ServerPlayer) { ++ // Sword + Creative mode pre-cancel ++ boolean isSwordNoBreak = !this.player.getMainHandItem().getItem().canAttackBlock(iblockdata, this.level, pos, this.player); ++ ++ // Tell client the block is gone immediately then process events ++ // Don't tell the client if its a creative sword break because its not broken! ++ if (level.getBlockEntity(pos) == null && !isSwordNoBreak) { ++ ClientboundBlockUpdatePacket packet = new ClientboundBlockUpdatePacket(pos, Blocks.AIR.defaultBlockState()); ++ this.player.connection.send(packet); ++ } ++ ++ event = new BlockBreakEvent(bblock, this.player.getBukkitEntity()); ++ ++ // Sword + Creative mode pre-cancel ++ event.setCancelled(isSwordNoBreak); ++ ++ // Calculate default block experience ++ IBlockData nmsData = this.level.getBlockState(pos); ++ Block nmsBlock = nmsData.getBlock(); ++ ++ ItemStack itemstack = this.player.getItemBySlot(EquipmentSlot.MAINHAND); ++ ++ if (nmsBlock != null && !event.isCancelled() && !this.isCreative() && this.player.hasCorrectToolForDrops(nmsBlock.defaultBlockState())) { ++ event.setExpToDrop(nmsBlock.getExpDrop(nmsData, this.level, pos, itemstack, true)); ++ } ++ ++ this.level.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ if (isSwordNoBreak) { ++ return false; ++ } ++ // Let the client know the block still exists ++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); ++ ++ // Brute force all possible updates ++ for (Direction dir : Direction.values()) { ++ this.player.connection.send(new ClientboundBlockUpdatePacket(level, pos.relative(dir))); ++ } ++ ++ // Update any tile entity data for this block ++ BlockEntity tileentity = this.level.getBlockEntity(pos); ++ if (tileentity != null) { ++ this.player.connection.send(tileentity.getUpdatePacket()); ++ } ++ return false; ++ } ++ } ++ // CraftBukkit end ++ ++ if (false && !this.player.getMainHandItem().getItem().canAttackBlock(iblockdata, this.level, pos, this.player)) { // CraftBukkit - false + return false; + } else { +- BlockEntity blockEntity = this.level.getBlockEntity(pos); +- Block block = blockState.getBlock(); ++ iblockdata = this.level.getBlockState(pos); // CraftBukkit - update state from plugins ++ if (iblockdata.isAir()) return false; // CraftBukkit - A plugin set block to air without cancelling ++ BlockEntity tileentity = this.level.getBlockEntity(pos); ++ Block block = iblockdata.getBlock(); ++ + if (block instanceof GameMasterBlock && !this.player.canUseGameMasterBlocks()) { + this.level.sendBlockUpdated(pos, blockState, blockState, 3); + return false; + } else if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { + return false; + } else { +- BlockState blockState1 = block.playerWillDestroy(this.level, pos, blockState, this.player); ++ // CraftBukkit start ++ org.bukkit.block.BlockState state = bblock.getState(); ++ level.captureDrops = new ArrayList<>(); ++ // CraftBukkit end ++ IBlockData iblockdata1 = block.playerWillDestroy(this.level, pos, iblockdata, this.player); + boolean flag = this.level.removeBlock(pos, false); + if (flag) { + block.destroy(this.level, pos, blockState1); + } + + if (this.isCreative()) { +- return true; ++ // return true; // CraftBukkit + } else { +- ItemStack mainHandItem = this.player.getMainHandItem(); +- ItemStack itemStack = mainHandItem.copy(); +- boolean hasCorrectToolForDrops = this.player.hasCorrectToolForDrops(blockState1); +- mainHandItem.mineBlock(this.level, blockState1, pos, this.player); +- if (flag && hasCorrectToolForDrops) { +- block.playerDestroy(this.level, this.player, pos, blockState1, blockEntity, itemStack); ++ ItemStack itemstack = this.player.getMainHandItem(); ++ ItemStack itemstack1 = itemstack.copy(); ++ boolean flag1 = this.player.hasCorrectToolForDrops(iblockdata1); ++ ++ itemstack.mineBlock(this.level, iblockdata1, pos, this.player); ++ if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items ++ block.playerDestroy(this.level, this.player, pos, iblockdata1, tileentity, itemstack1); + } + +- return true; ++ // return true; // CraftBukkit + } ++ // CraftBukkit start ++ if (event.isDropItems()) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, level.captureDrops); ++ } ++ level.captureDrops = null; ++ ++ // Drop event experience ++ if (flag && event != null) { ++ iblockdata.getBlock().popExperience(this.level, pos, event.getExpToDrop()); ++ } ++ ++ return true; ++ // CraftBukkit end + } + } + } +@@ -294,10 +468,19 @@ + } + } + +- public InteractionResult useItemOn(ServerPlayer player, Level level, ItemStack stack, InteractionHand hand, BlockHitResult hitResult) { +- BlockPos blockPos = hitResult.getBlockPos(); +- BlockState blockState = level.getBlockState(blockPos); +- if (!blockState.getBlock().isEnabled(level.enabledFeatures())) { ++ // CraftBukkit start - whole method ++ public boolean interactResult = false; ++ public boolean firedInteract = false; ++ public BlockPos interactPosition; ++ public EnumHand interactHand; ++ public ItemStack interactItemStack; ++ public InteractionResult useItemOn(ServerPlayer player, Level level, ItemStack stack, EnumHand hand, BlockHitResult hitResult) { ++ BlockPos blockposition = hitResult.getBlockPos(); ++ IBlockData iblockdata = level.getBlockState(blockposition); ++ InteractionResult enuminteractionresult = InteractionResult.PASS; ++ boolean cancelledBlock = false; ++ ++ if (!iblockdata.getBlock().isEnabled(level.enabledFeatures())) { + return InteractionResult.FAIL; + } else if (this.gameModeForPlayer == GameType.SPECTATOR) { + MenuProvider menuProvider = blockState.getMenuProvider(level, blockPos); +@@ -339,6 +557,8 @@ + return InteractionResult.PASS; + } + } ++ return enuminteractionresult; ++ // CraftBukkit end + } + + public void setLevel(ServerLevel serverLevel) { |