From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 3 Jul 2018 21:56:23 -0400 Subject: [PATCH] InventoryCloseEvent Reason API Allows you to determine why an inventory was closed, enabling plugin developers to "confirm" things based on if it was player triggered close or not. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index e85390265dca2a55d0bb6f8dd4682d5a8a6cf478..518a900888b0ab51646f12e6b43a3cc12de55564 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1474,7 +1474,7 @@ public class ServerLevel extends Level implements WorldGenLevel { for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) { if (tileentity instanceof net.minecraft.world.Container) { for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) { - h.closeInventory(); + h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason } } } @@ -2458,7 +2458,7 @@ public class ServerLevel extends Level implements WorldGenLevel { // Spigot Start if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) { - h.closeInventory(); + h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason } } // Spigot End diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java index eadc58dd6ccec5e2f1604b94709181a0754d9802..6c31597821e087f690941c997096153ed06e9707 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -692,7 +692,7 @@ public class ServerPlayer extends Player { } // Paper end - Configurable container update tick rate if (!this.level().isClientSide && !this.containerMenu.stillValid(this)) { - this.closeContainer(); + this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason this.containerMenu = this.inventoryMenu; } @@ -885,7 +885,7 @@ public class ServerPlayer extends Player { // SPIGOT-943 - only call if they have an inventory open if (this.containerMenu != this.inventoryMenu) { - this.closeContainer(); + this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper - Inventory close reason } net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure @@ -1509,7 +1509,7 @@ public class ServerPlayer extends Player { } // CraftBukkit end if (this.containerMenu != this.inventoryMenu) { - this.closeContainer(); + this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason } // this.nextContainerCounter(); // CraftBukkit - moved up @@ -1537,7 +1537,13 @@ public class ServerPlayer extends Player { @Override public void closeContainer() { - CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit + // Paper start - Inventory close reason + this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN); + } + @Override + public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { + CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit + // Paper end - Inventory close reason this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); this.doCloseContainer(); } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 51d5bed032f89333917accca242772a09ee98d93..678c46517757e3f37d5051fc88c481cbe8bf861b 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -219,6 +219,7 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.CraftItemEvent; import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; // Paper import org.bukkit.event.inventory.InventoryCreativeEvent; import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.event.inventory.SmithItemEvent; @@ -2538,10 +2539,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleContainerClose(ServerboundContainerClosePacket packet) { + // Paper start - Inventory close reason + this.handleContainerClose(packet, InventoryCloseEvent.Reason.PLAYER); + } + public void handleContainerClose(ServerboundContainerClosePacket packet, InventoryCloseEvent.Reason reason) { + // Paper end - Inventory close reason PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.isImmobile()) return; // CraftBukkit - CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit + CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper this.player.doCloseContainer(); } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java index 99ba7c82f8a8db9d5841cce18ed5f39439b512b0..5517f873e709b6f3b9206f0ad0212a9524f2c691 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -518,7 +518,7 @@ public abstract class PlayerList { // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it // See SPIGOT-5799, SPIGOT-6145 if (entityplayer.containerMenu != entityplayer.inventoryMenu) { - entityplayer.closeContainer(); + entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper - Inventory close reason } PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); // Paper - Adventure diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java index 5f59c7436756645a74ea730b026deb25d1571c9c..fb4cc32f2840098a13981ec4328e7eb6fe4f714b 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -263,7 +263,7 @@ public abstract class Player extends LivingEntity { this.updateIsUnderwater(); super.tick(); if (!this.level().isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) { - this.closeContainer(); + this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason this.containerMenu = this.inventoryMenu; } @@ -495,6 +495,13 @@ public abstract class Player extends LivingEntity { } + // Paper start - Inventory close reason; unused code, but to keep signatures aligned + public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { + closeContainer(); + this.containerMenu = this.inventoryMenu; + } + // Paper end - Inventory close reason + public void closeContainer() { this.containerMenu = this.inventoryMenu; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index 092d2bfab7e8fd9840e853f09adc85311ab29046..af6f8d11f0384c353332f5c5bb0967e518deccbe 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -376,7 +376,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { if (((ServerPlayer) this.getHandle()).connection == null) return; if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) { // fire INVENTORY_CLOSE if one already open - ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId)); + ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId), org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason } ServerPlayer player = (ServerPlayer) this.getHandle(); AbstractContainerMenu container; @@ -446,8 +446,14 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public void closeInventory() { - this.getHandle().closeContainer(); + // Paper start - Inventory close reason + this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLUGIN); } + @Override + public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { + getHandle().closeContainer(reason); + } + // Paper end - Inventory close reason @Override public boolean isBlocking() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index bcbe11807186d2d79a155f6be7bda029ca5f555d..91ca962588fffc486ca44289f2eb0bac6fcd808d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1194,7 +1194,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Close any foreign inventory if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) { - this.getHandle().closeContainer(); + this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper - Inventory close reason } // Check if the fromWorld and toWorld are the same. diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 848bcabb5922c99ee78cb541c87b464cea032749..3ec8302c569ef923ddca3f9bfb3c506832fe7659 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1331,7 +1331,7 @@ public class CraftEventFactory { public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) { if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open - player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId)); + player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason } CraftServer server = player.level().getCraftServer(); @@ -1518,8 +1518,18 @@ public class CraftEventFactory { return event; } + // Paper start + /** + * Incase plugins hooked into this or Spigot adds a new inventory close event. Prefer to pass a reason + * @param human + */ + @Deprecated public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human) { - InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView()); + handleInventoryCloseEvent(human, org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN); + } + public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { + // Paper end + InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView(), reason); // Paper human.level().getCraftServer().getPluginManager().callEvent(event); human.containerMenu.transferTo(human.inventoryMenu, human.getBukkitEntity()); }