From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sun, 11 Feb 2018 10:43:46 +0000 Subject: [PATCH] Extend Player Interact cancellation GUIs are opened on the client, meaning that the server cannot block them from opening, However, it is possible to close these GUIs from the server. Flower pots are also not updated on the client when interaction is cancelled, this patch also resolves this. Update adjacent blocks of doors, double plants, pistons and beds when cancelling interaction. diff --git a/src/main/java/net/minecraft/server/level/PlayerInteractManager.java b/src/main/java/net/minecraft/server/level/PlayerInteractManager.java index 51157a9223f3da22d1110cfa211a502de59fb8a1..0ead8f1fabcc8debea8e2211d58a83b34acfcf0b 100644 --- a/src/main/java/net/minecraft/server/level/PlayerInteractManager.java +++ b/src/main/java/net/minecraft/server/level/PlayerInteractManager.java @@ -6,6 +6,7 @@ import net.minecraft.core.BlockPosition; import net.minecraft.core.EnumDirection; import net.minecraft.network.protocol.game.PacketPlayInBlockDig; import net.minecraft.network.protocol.game.PacketPlayOutBlockBreak; +import net.minecraft.network.protocol.game.PacketPlayOutCloseWindow; import net.minecraft.network.protocol.game.PacketPlayOutPlayerInfo; import net.minecraft.world.EnumHand; import net.minecraft.world.EnumInteractionResult; @@ -18,6 +19,7 @@ import net.minecraft.world.level.EnumGamemode; import net.minecraft.world.level.World; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.BlockCommand; +import net.minecraft.world.level.block.BlockFlowerPot; import net.minecraft.world.level.block.BlockJigsaw; import net.minecraft.world.level.block.BlockStructure; import net.minecraft.world.level.block.entity.TileEntity; @@ -179,6 +181,11 @@ public class PlayerInteractManager { PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.inventory.getItemInHand(), EnumHand.MAIN_HAND); if (event.isCancelled()) { // Let the client know the block still exists + // Paper start - brute force neighbor blocks for any attached blocks + for (EnumDirection dir : EnumDirection.values()) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition.shift(dir))); + } + // Paper end this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); // Update any tile entity data for this block TileEntity tileentity = this.world.getTileEntity(blockposition); @@ -483,13 +490,20 @@ public class PlayerInteractManager { interactItemStack = itemstack.cloneItemStack(); 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. if (iblockdata.getBlock() instanceof BlockDoor) { boolean bottom = iblockdata.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER; entityplayer.playerConnection.sendPacket(new PacketPlayOutBlockChange(world, bottom ? blockposition.up() : blockposition.down())); } else if (iblockdata.getBlock() instanceof BlockCake) { entityplayer.getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake + // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method + } else if (iblockdata.getBlock() instanceof BlockStructure) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutCloseWindow()); + } else if (iblockdata.getBlock() instanceof BlockCommand) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutCloseWindow()); } + // Paper end - extend Player Interact cancellation entityplayer.getBukkitEntity().updateInventory(); // SPIGOT-2867 enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? EnumInteractionResult.SUCCESS : EnumInteractionResult.PASS; } else if (this.gamemode == EnumGamemode.SPECTATOR) {