From 7e896541bd3d75a178d3b5553a7fa5ecefda9b03 Mon Sep 17 00:00:00 2001 From: Jake Potrebic <jake.m.potrebic@gmail.com> Date: Sat, 26 Aug 2023 12:28:42 -0700 Subject: [PATCH] Add titleOverride to InventoryOpenEvent (#7540) --- ...-titleOverride-to-InventoryOpenEvent.patch | 52 ++++++++ ...-titleOverride-to-InventoryOpenEvent.patch | 120 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 patches/api/Add-titleOverride-to-InventoryOpenEvent.patch create mode 100644 patches/server/Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/api/Add-titleOverride-to-InventoryOpenEvent.patch b/patches/api/Add-titleOverride-to-InventoryOpenEvent.patch new file mode 100644 index 0000000000..b62c3e7df4 --- /dev/null +++ b/patches/api/Add-titleOverride-to-InventoryOpenEvent.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic <jake.m.potrebic@gmail.com> +Date: Fri, 4 Mar 2022 12:45:21 -0800 +Subject: [PATCH] Add titleOverride to InventoryOpenEvent + + +diff --git a/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java ++++ b/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java +@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; + public class InventoryOpenEvent extends InventoryEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; ++ private net.kyori.adventure.text.Component titleOverride; // Paper + + public InventoryOpenEvent(@NotNull InventoryView transaction) { + super(transaction); +@@ -0,0 +0,0 @@ public class InventoryOpenEvent extends InventoryEvent implements Cancellable { + cancelled = cancel; + } + ++ // Paper start ++ /** ++ * Gets the title override set by another event or null ++ * if not set. ++ * ++ * @return the title override or null ++ */ ++ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component titleOverride() { ++ return this.titleOverride; ++ } ++ ++ /** ++ * Sets the title override or clears the override. ++ * <p> ++ * This is only the title sent to the client in the open packet, this doesn't change ++ * the title returned by {@link InventoryView#title()}, hence "override". ++ * <p> ++ * <b>NOTE:</b> Horse inventories are a special case where setting this will ++ * have no effect. Horse inventory titles are set by the horse display name. ++ * ++ * @param titleOverride the title override or null ++ */ ++ public void titleOverride(net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component titleOverride) { ++ this.titleOverride = titleOverride; ++ } ++ // Paper end ++ + @NotNull + @Override + public HandlerList getHandlers() { diff --git a/patches/server/Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/Add-titleOverride-to-InventoryOpenEvent.patch new file mode 100644 index 0000000000..ab47d06d23 --- /dev/null +++ b/patches/server/Add-titleOverride-to-InventoryOpenEvent.patch @@ -0,0 +1,120 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic <jake.m.potrebic@gmail.com> +Date: Fri, 4 Mar 2022 12:45:03 -0800 +Subject: [PATCH] Add titleOverride to InventoryOpenEvent + + +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { + this.nextContainerCounter(); + AbstractContainerMenu container = factory.createMenu(this.containerCounter, this.getInventory(), this); + ++ Component title = null; // Paper + // CraftBukkit start - Inventory open hook + if (container != null) { + container.setTitle(factory.getDisplayName()); + + boolean cancelled = false; +- container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled); ++ // Paper start ++ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(this, container, cancelled); ++ container = result.getSecond(); ++ title = PaperAdventure.asVanilla(result.getFirst()); ++ // Paper end + if (container == null && !cancelled) { // Let pre-cancelled events fall through + // SPIGOT-5263 - close chest if cancelled + if (factory instanceof Container) { +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { + } else { + // CraftBukkit start + this.containerMenu = container; +- if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper ++ if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), Objects.requireNonNullElseGet(title, container::getTitle))); // Paper + // CraftBukkit end + this.initMenu(container); + return OptionalInt.of(this.containerCounter); +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + Preconditions.checkArgument(windowType != null, "Unknown windowType"); + AbstractContainerMenu container = new CraftContainer(inventory, player, player.nextContainerCounter()); + +- container = CraftEventFactory.callInventoryOpenEvent(player, container); ++ // Paper start ++ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(player, container); ++ container = result.getSecond(); ++ // Paper end + if (container == null) return; + + //String title = container.getBukkitView().getTitle(); // Paper - comment + net.kyori.adventure.text.Component adventure$title = container.getBukkitView().title(); // Paper + if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(container.getBukkitView().getTitle()); // Paper ++ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper + + //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper +@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + } + + // Trigger an INVENTORY_OPEN event +- container = CraftEventFactory.callInventoryOpenEvent(player, container); ++ // Paper start ++ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(player, container); ++ container = result.getSecond(); ++ // Paper end + if (container == null) { + return; + } +@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + //String title = inventory.getTitle(); // Paper - comment + net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper + if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper ++ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper + //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper + player.containerMenu = container; +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -0,0 +0,0 @@ public class CraftEventFactory { + } + + public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container) { +- return CraftEventFactory.callInventoryOpenEvent(player, container, false); ++ // Paper start ++ return callInventoryOpenEventWithTitle(player, container).getSecond(); ++ } ++ public static com.mojang.datafixers.util.Pair<net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component, @org.jetbrains.annotations.Nullable AbstractContainerMenu> callInventoryOpenEventWithTitle(ServerPlayer player, AbstractContainerMenu container) { ++ return CraftEventFactory.callInventoryOpenEventWithTitle(player, container, false); ++ // Paper end + } + ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - use method that acknowledges title overrides + public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) { ++ // Paper start ++ return callInventoryOpenEventWithTitle(player, container, cancelled).getSecond(); ++ } ++ public static com.mojang.datafixers.util.Pair<net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component, @org.jetbrains.annotations.Nullable AbstractContainerMenu> callInventoryOpenEventWithTitle(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) { ++ // Paper end + if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open + player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper + } +@@ -0,0 +0,0 @@ public class CraftEventFactory { + + if (event.isCancelled()) { + container.transferTo(player.containerMenu, craftPlayer); +- return null; ++ return com.mojang.datafixers.util.Pair.of(null, null); // Paper - title override + } + +- return container; ++ return com.mojang.datafixers.util.Pair.of(event.titleOverride(), container); // Paper - title override + } + + public static ItemStack callPreCraftEvent(Container matrix, Container resultInventory, ItemStack result, InventoryView lastCraftView, boolean isRepair) {