From bcd66b64977790e401e872e4b1f926964b1e4327 Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Thu, 11 Aug 2022 20:37:13 +0200 Subject: [PATCH] Add version 1.19.2 --- .github/workflows/maven.yml | 1 + IF/pom.xml | 6 + .../util/version/Version.java | 17 +- .../util/version/VersionMatcher.java | 32 ++- README.md | 1 + nms/1_19_2/pom.xml | 58 ++++ .../nms/v1_19_2/AnvilInventoryImpl.java | 266 ++++++++++++++++++ .../nms/v1_19_2/BeaconInventoryImpl.java | 199 +++++++++++++ .../CartographyTableInventoryImpl.java | 213 ++++++++++++++ .../v1_19_2/EnchantingTableInventoryImpl.java | 213 ++++++++++++++ .../nms/v1_19_2/GrindstoneInventoryImpl.java | 247 ++++++++++++++++ .../nms/v1_19_2/MerchantInventoryImpl.java | 97 +++++++ .../v1_19_2/SmithingTableInventoryImpl.java | 251 +++++++++++++++++ .../nms/v1_19_2/StonecutterInventoryImpl.java | 219 ++++++++++++++ .../nms/v1_19_2/util/CustomInventoryUtil.java | 41 +++ .../nms/v1_19_2/util/TextHolderUtil.java | 65 +++++ pom.xml | 1 + 17 files changed, 1915 insertions(+), 12 deletions(-) create mode 100644 nms/1_19_2/pom.xml create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/AnvilInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/BeaconInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/CartographyTableInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/EnchantingTableInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/GrindstoneInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/MerchantInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/SmithingTableInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/StonecutterInventoryImpl.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/CustomInventoryUtil.java create mode 100644 nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/TextHolderUtil.java diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 4462ef65..35cce1a8 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -73,5 +73,6 @@ jobs: mvn paper-nms:init -pl nms/1_18_2 mvn paper-nms:init -pl nms/1_19_0 mvn paper-nms:init -pl nms/1_19_1 + mvn paper-nms:init -pl nms/1_19_2 - name: Build with Maven run: mvn -B package --file pom.xml diff --git a/IF/pom.xml b/IF/pom.xml index 70ff7b3b..540dedf3 100644 --- a/IF/pom.xml +++ b/IF/pom.xml @@ -112,6 +112,12 @@ ${project.version} compile + + com.github.stefvanschie.inventoryframework + 1_19_2 + ${project.version} + compile + org.spigotmc spigot-api diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java index 16289452..7a3c9918 100644 --- a/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java @@ -83,18 +83,25 @@ public enum Version { V1_18_2, /** - * Version 1.19 + * Version 1.19.0 * * @since 0.10.6 */ - V1_19, + V1_19_0, /** * Version 1.19.1 * * @since 0.10.7 */ - V1_19_1; + V1_19_1, + + /** + * Version 1.19.2 + * + * @since 0.10.7 + */ + V1_19_2; /** * Gets the version currently being used. If the used version is not supported, an @@ -138,9 +145,11 @@ public static Version getVersion() { case "1.18.2": return V1_18_2; case "1.19": - return V1_19; + return V1_19_0; case "1.19.1": return V1_19_1; + case "1.19.2": + return V1_19_2; default: throw new UnsupportedVersionException("The server version provided is not supported"); } diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java index d22a0a79..7d78c348 100644 --- a/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java @@ -252,10 +252,12 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.AnvilInventoryImpl.class); ANVIL_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.AnvilInventoryImpl.class); - ANVIL_INVENTORIES.put(Version.V1_19, + ANVIL_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.AnvilInventoryImpl.class); ANVIL_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.AnvilInventoryImpl.class); + ANVIL_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.AnvilInventoryImpl.class); BEACON_INVENTORIES = new EnumMap<>(Version.class); BEACON_INVENTORIES.put(Version.V1_14, @@ -278,10 +280,12 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.BeaconInventoryImpl.class); BEACON_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.BeaconInventoryImpl.class); - BEACON_INVENTORIES.put(Version.V1_19, + BEACON_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.BeaconInventoryImpl.class); BEACON_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.BeaconInventoryImpl.class); + BEACON_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.BeaconInventoryImpl.class); CARTOGRAPHY_TABLE_INVENTORIES = new EnumMap<>(Version.class); CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_14, @@ -304,10 +308,12 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.CartographyTableInventoryImpl.class); CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.CartographyTableInventoryImpl.class); - CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_19, + CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.CartographyTableInventoryImpl.class); CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.CartographyTableInventoryImpl.class); + CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.CartographyTableInventoryImpl.class); ENCHANTING_TABLE_INVENTORIES = new EnumMap<>(Version.class); ENCHANTING_TABLE_INVENTORIES.put(Version.V1_14, @@ -330,10 +336,12 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.EnchantingTableInventoryImpl.class); ENCHANTING_TABLE_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.EnchantingTableInventoryImpl.class); - ENCHANTING_TABLE_INVENTORIES.put(Version.V1_19, + ENCHANTING_TABLE_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.EnchantingTableInventoryImpl.class); ENCHANTING_TABLE_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.EnchantingTableInventoryImpl.class); + ENCHANTING_TABLE_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.EnchantingTableInventoryImpl.class); GRINDSTONE_INVENTORIES = new EnumMap<>(Version.class); GRINDSTONE_INVENTORIES.put(Version.V1_14, @@ -356,10 +364,12 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.GrindstoneInventoryImpl.class); GRINDSTONE_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.GrindstoneInventoryImpl.class); - GRINDSTONE_INVENTORIES.put(Version.V1_19, + GRINDSTONE_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.GrindstoneInventoryImpl.class); GRINDSTONE_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.GrindstoneInventoryImpl.class); + GRINDSTONE_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.GrindstoneInventoryImpl.class); MERCHANT_INVENTORIES = new EnumMap<>(Version.class); MERCHANT_INVENTORIES.put(Version.V1_14, @@ -382,10 +392,12 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.MerchantInventoryImpl.class); MERCHANT_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.MerchantInventoryImpl.class); - MERCHANT_INVENTORIES.put(Version.V1_19, + MERCHANT_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.MerchantInventoryImpl.class); MERCHANT_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.MerchantInventoryImpl.class); + MERCHANT_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.MerchantInventoryImpl.class); SMITHING_TABLE_INVENTORIES = new EnumMap<>(Version.class); SMITHING_TABLE_INVENTORIES.put(Version.V1_16_1, @@ -404,10 +416,12 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.SmithingTableInventoryImpl.class); SMITHING_TABLE_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.SmithingTableInventoryImpl.class); - SMITHING_TABLE_INVENTORIES.put(Version.V1_19, + SMITHING_TABLE_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.SmithingTableInventoryImpl.class); SMITHING_TABLE_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.SmithingTableInventoryImpl.class); + SMITHING_TABLE_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.SmithingTableInventoryImpl.class); STONECUTTER_INVENTORIES = new EnumMap<>(Version.class); STONECUTTER_INVENTORIES.put(Version.V1_14, @@ -430,9 +444,11 @@ public static StonecutterInventory newStonecutterInventory(@NotNull Version vers com.github.stefvanschie.inventoryframework.nms.v1_18_1.StonecutterInventoryImpl.class); STONECUTTER_INVENTORIES.put(Version.V1_18_2, com.github.stefvanschie.inventoryframework.nms.v1_18_2.StonecutterInventoryImpl.class); - STONECUTTER_INVENTORIES.put(Version.V1_19, + STONECUTTER_INVENTORIES.put(Version.V1_19_0, com.github.stefvanschie.inventoryframework.nms.v1_19_0.StonecutterInventoryImpl.class); STONECUTTER_INVENTORIES.put(Version.V1_19_1, com.github.stefvanschie.inventoryframework.nms.v1_19_1.StonecutterInventoryImpl.class); + STONECUTTER_INVENTORIES.put(Version.V1_19_2, + com.github.stefvanschie.inventoryframework.nms.v1_19_2.StonecutterInventoryImpl.class); } } diff --git a/README.md b/README.md index bd5e79a4..117bbee1 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ mvn paper-nms:init -pl nms/1_18_1 mvn paper-nms:init -pl nms/1_18_2 mvn paper-nms:init -pl nms/1_19_0 mvn paper-nms:init -pl nms/1_19_1 +mvn paper-nms:init -pl nms/1_19_2 ``` Your environment is now set up correctly. To create a build, run the following inside the root folder of the project. diff --git a/nms/1_19_2/pom.xml b/nms/1_19_2/pom.xml new file mode 100644 index 00000000..f2241ad6 --- /dev/null +++ b/nms/1_19_2/pom.xml @@ -0,0 +1,58 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.10.6 + ../../pom.xml + + 4.0.0 + + 1_19_2 + + + true + + + + + com.github.stefvanschie.inventoryframework + abstraction + ${project.version} + compile + + + ca.bkaw + paper-nms + 1.19.2-SNAPSHOT + provided + + + + + + + ca.bkaw + paper-nms-maven-plugin + 1.2.1 + + + process-classes + + remap + + + + + + + + + + bytecode.space + https://repo.bytecode.space/repository/maven-public/ + + + \ No newline at end of file diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/AnvilInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/AnvilInventoryImpl.java new file mode 100644 index 00000000..80fb8969 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/AnvilInventoryImpl.java @@ -0,0 +1,266 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.AnvilInventory; +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.CustomInventoryUtil; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.TextHolderUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.NonNullList; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.AnvilMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryAnvil; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal anvil inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class AnvilInventoryImpl extends AnvilInventory { + + public AnvilInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull TextHolder title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for an anvil should be 3, but is '" + itemAmount + "'" + ); + } + + ServerPlayer serverPlayer = getServerPlayer(player); + ContainerAnvilImpl containerAnvil = new ContainerAnvilImpl(serverPlayer, items); + + serverPlayer.containerMenu = containerAnvil; + + int id = containerAnvil.containerId; + Component message = TextHolderUtil.toComponent(title); + + serverPlayer.connection.send(new ClientboundOpenScreenPacket(id, MenuType.ANVIL, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = CustomInventoryUtil.convertToNMSItems(items); + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + ItemStack cursor = CraftItemStack.asNMSCopy(player.getItemOnCursor()); + ServerPlayerConnection playerConnection = getPlayerConnection(serverPlayer); + + playerConnection.send(new ClientboundContainerSetContentPacket(containerId, state, nmsItems, cursor)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(containerId, state, 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(containerId, state, 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.EMPTY); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, ItemStack.EMPTY)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.10.7 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.10.7 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(containerId, state, 2, item)); + } + + /** + * Gets the container id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the container id for + * @return the container id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } + + /** + * Gets the player connection for the specified player + * + * @param serverPlayer the player to get the player connection from + * @return the player connection + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayerConnection getPlayerConnection(@NotNull ServerPlayer serverPlayer) { + return serverPlayer.connection; + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container anvil for responding to item renaming + * + * @since 0.10.7 + */ + private class ContainerAnvilImpl extends AnvilMenu { + + /** + * The player for whom this anvil container is + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container anvil + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Creates a new custom anvil container for the specified player + * + * @param serverPlayer the player for who this anvil container is + * @since 0.10.7 + */ + public ContainerAnvilImpl(@NotNull ServerPlayer serverPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), + ContainerLevelAccess.create(serverPlayer.getCommandSenderWorld(), new BlockPos(0, 0, 0))); + + this.player = serverPlayer.getBukkitEntity(); + + inputSlots.setItem(0, CraftItemStack.asNMSCopy(items[0])); + inputSlots.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultSlots.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + Location location = access.getLocation(); + CraftInventory inventory = new CraftInventoryAnvil(location, inputSlots, resultSlots, + this) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Override + public void setItemName(@Nullable String name) { + text = name == null ? "" : name; + + sendResultItem(player, resultSlots.getItem(0)); + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean stillValid(@Nullable net.minecraft.world.entity.player.Player nmsPlayer) { + return true; + } + + @Override + public void slotsChanged(Container container) {} + + @Override + public void removed(net.minecraft.world.entity.player.Player nmsPlayer) {} + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/BeaconInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/BeaconInventoryImpl.java new file mode 100644 index 00000000..5ae4ba93 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/BeaconInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.BeaconInventory; +import net.minecraft.core.NonNullList; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.BeaconMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryBeacon; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal beacon inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class BeaconInventoryImpl extends BeaconInventory { + + public BeaconInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + ContainerBeaconImpl containerBeacon = new ContainerBeaconImpl(serverPlayer, item); + + serverPlayer.containerMenu = containerBeacon; + + int id = containerBeacon.containerId; + Component beacon = Component.literal("Beacon"); + + serverPlayer.connection.send(new ClientboundOpenScreenPacket(id, MenuType.BEACON, beacon)); + + sendItem(player, item); + } + + @Override + public void sendItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + NonNullList items = NonNullList.of( + ItemStack.EMPTY, //the first item doesn't count for some reason, so send a dummy item + CraftItemStack.asNMSCopy(item) + ); + + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + ItemStack cursor = CraftItemStack.asNMSCopy(player.getItemOnCursor()); + ServerPlayerConnection playerConnection = getPlayerConnection(serverPlayer); + + playerConnection.send(new ClientboundContainerSetContentPacket(containerId, state, items, cursor)); + } + + @Override + public void clearCursor(@NotNull Player player) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, ItemStack.EMPTY)); + } + + /** + * Gets the container id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the container id for + * @return the container id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } + + /** + * Gets the player connection for the specified player + * + * @param serverPlayer the player to get the player connection from + * @return the player connection + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayerConnection getPlayerConnection(@NotNull ServerPlayer serverPlayer) { + return serverPlayer.connection; + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container beacon + * + * @since 0.10.7 + */ + private class ContainerBeaconImpl extends BeaconMenu { + + /** + * The player for this beacon container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container beacon + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the beacon field + */ + @NotNull + private final Field beaconField; + + public ContainerBeaconImpl(@NotNull ServerPlayer serverPlayer, @Nullable org.bukkit.inventory.ItemStack item) { + super(serverPlayer.nextContainerCounter(), serverPlayer.getInventory()); + + this.player = serverPlayer.getBukkitEntity(); + + try { + //noinspection JavaReflectionMemberAccess + this.beaconField = BeaconMenu.class.getDeclaredField("r"); //beacon + this.beaconField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + ItemStack itemStack = CraftItemStack.asNMSCopy(item); + + ((Container) beaconField.get(this)).setItem(0, itemStack); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryBeacon((Container) beaconField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean stillValid(@Nullable net.minecraft.world.entity.player.Player nmsPlayer) { + return true; + } + + @Override + public void slotsChanged(Container container) {} + + @Override + public void removed(net.minecraft.world.entity.player.Player nmsPlayer) {} + + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/CartographyTableInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/CartographyTableInventoryImpl.java new file mode 100644 index 00000000..bf6b8303 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/CartographyTableInventoryImpl.java @@ -0,0 +1,213 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.CartographyTableInventory; +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.CustomInventoryUtil; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.TextHolderUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.CartographyTableMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryCartography; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal cartography table inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class CartographyTableInventoryImpl extends CartographyTableInventory { + + public CartographyTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull TextHolder title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a cartography table should be 3, but is '" + itemAmount + "'" + ); + } + + ServerPlayer serverPlayer = getServerPlayer(player); + ContainerCartographyTableImpl containerCartographyTable = new ContainerCartographyTableImpl( + serverPlayer, items + ); + + serverPlayer.containerMenu = containerCartographyTable; + + int id = containerCartographyTable.containerId; + Component message = TextHolderUtil.toComponent(title); + + serverPlayer.connection.send(new ClientboundOpenScreenPacket(id, MenuType.CARTOGRAPHY_TABLE, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = CustomInventoryUtil.convertToNMSItems(items); + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + ItemStack cursor = CraftItemStack.asNMSCopy(player.getItemOnCursor()); + ServerPlayerConnection playerConnection = getPlayerConnection(serverPlayer); + + playerConnection.send(new ClientboundContainerSetContentPacket(containerId, state, nmsItems, cursor)); + } + + @Override + public void clearCursor(@NotNull Player player) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, ItemStack.EMPTY)); + } + + /** + * Gets the container id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the container id for + * @return the container id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } + + /** + * Gets the player connection for the specified player + * + * @param serverPlayer the player to get the player connection from + * @return the player connection + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayerConnection getPlayerConnection(@NotNull ServerPlayer serverPlayer) { + return serverPlayer.connection; + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container cartography table + * + * @since 0.10.7 + */ + private class ContainerCartographyTableImpl extends CartographyTableMenu { + + /** + * The player for this cartography table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container cartography table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultContainerField; + + public ContainerCartographyTableImpl(@NotNull ServerPlayer serverPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(serverPlayer.nextContainerCounter(), serverPlayer.getInventory()); + + this.player = serverPlayer.getBukkitEntity(); + + try { + //noinspection JavaReflectionMemberAccess + this.resultContainerField = CartographyTableMenu.class.getDeclaredField("u"); //resultContainer + this.resultContainerField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + container.setItem(0, CraftItemStack.asNMSCopy(items[0])); + container.setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryCartography(super.container, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean stillValid(@Nullable net.minecraft.world.entity.player.Player nmsPlayer) { + return true; + } + + @Override + public void slotsChanged(Container container) {} + + @Override + public void removed(net.minecraft.world.entity.player.Player nmsPlayer) {} + + @NotNull + @Contract(pure = true) + private Container getResultInventory() { + try { + return (Container) resultContainerField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/EnchantingTableInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/EnchantingTableInventoryImpl.java new file mode 100644 index 00000000..f519e751 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/EnchantingTableInventoryImpl.java @@ -0,0 +1,213 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.EnchantingTableInventory; +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.TextHolderUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.EnchantmentMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryEnchanting; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal enchanting table inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class EnchantingTableInventoryImpl extends EnchantingTableInventory { + + public EnchantingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull TextHolder title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for an enchanting table should be 2, but is '" + itemAmount + "'" + ); + } + + ServerPlayer serverPlayer = getServerPlayer(player); + ContainerEnchantingTableImpl containerEnchantmentTable = new ContainerEnchantingTableImpl(serverPlayer, items); + + serverPlayer.containerMenu = containerEnchantmentTable; + + int id = containerEnchantmentTable.containerId; + Component message = TextHolderUtil.toComponent(title); + + serverPlayer.connection.send(new ClientboundOpenScreenPacket(id, MenuType.ENCHANTMENT, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.of( + ItemStack.EMPTY, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + ItemStack cursor = CraftItemStack.asNMSCopy(player.getItemOnCursor()); + ServerPlayerConnection playerConnection = getPlayerConnection(serverPlayer); + + playerConnection.send(new ClientboundContainerSetContentPacket(containerId, state, nmsItems, cursor)); + } + + @Override + public void clearCursor(@NotNull Player player) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, ItemStack.EMPTY)); + } + + /** + * Gets the containerId id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the containerId id for + * @return the containerId id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } + + /** + * Gets the player connection for the specified player + * + * @param serverPlayer the player to get the player connection from + * @return the player connection + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayerConnection getPlayerConnection(@NotNull ServerPlayer serverPlayer) { + return serverPlayer.connection; + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.10.7 + */ + private class ContainerEnchantingTableImpl extends EnchantmentMenu { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the enchant slots field + */ + @NotNull + private final Field enchantSlotsField; + + public ContainerEnchantingTableImpl(@NotNull ServerPlayer serverPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(serverPlayer.nextContainerCounter(), serverPlayer.getInventory()); + + this.player = serverPlayer.getBukkitEntity(); + + try { + //noinspection JavaReflectionMemberAccess + this.enchantSlotsField = EnchantmentMenu.class.getDeclaredField("n"); //enchantSlots + this.enchantSlotsField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + Container input = (Container) enchantSlotsField.get(this); + + input.setItem(0, CraftItemStack.asNMSCopy(items[0])); + input.setItem(1, CraftItemStack.asNMSCopy(items[1])); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryEnchanting((Container) enchantSlotsField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + exception.printStackTrace(); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean stillValid(@Nullable net.minecraft.world.entity.player.Player nmsPlayer) { + return true; + } + + @Override + public void slotsChanged(Container container) {} + + @Override + public void removed(net.minecraft.world.entity.player.Player nmsPlayer) {} + + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/GrindstoneInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/GrindstoneInventoryImpl.java new file mode 100644 index 00000000..2852d292 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/GrindstoneInventoryImpl.java @@ -0,0 +1,247 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.GrindstoneInventory; +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.CustomInventoryUtil; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.TextHolderUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.GrindstoneMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryGrindstone; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal grindstone inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class GrindstoneInventoryImpl extends GrindstoneInventory { + + public GrindstoneInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull TextHolder title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a grindstone should be 3, but is '" + itemAmount + "'" + ); + } + + ServerPlayer serverPlayer = getServerPlayer(player); + ContainerGrindstoneImpl containerGrindstone = new ContainerGrindstoneImpl(serverPlayer, items); + + serverPlayer.containerMenu = containerGrindstone; + + int id = containerGrindstone.containerId; + Component message = TextHolderUtil.toComponent(title); + + serverPlayer.connection.send(new ClientboundOpenScreenPacket(id, MenuType.GRINDSTONE, message)); + + sendItems(player, items, player.getItemOnCursor()); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items, + @Nullable org.bukkit.inventory.ItemStack cursor) { + if (cursor == null) { + throw new IllegalArgumentException("Cursor may not be null on version 1.19.2"); + } + + NonNullList nmsItems = CustomInventoryUtil.convertToNMSItems(items); + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + ItemStack nmsCursor = CraftItemStack.asNMSCopy(cursor); + ServerPlayerConnection playerConnection = getPlayerConnection(serverPlayer); + + playerConnection.send(new ClientboundContainerSetContentPacket(containerId, state, nmsItems, nmsCursor)); + } + + @Override + public void clearCursor(@NotNull Player player) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, ItemStack.EMPTY)); + } + + /** + * Gets the containerId id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the containerId id for + * @return the containerId id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } + + /** + * Gets the player connection for the specified player + * + * @param serverPlayer the player to get the player connection from + * @return the player connection + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayerConnection getPlayerConnection(@NotNull ServerPlayer serverPlayer) { + return serverPlayer.connection; + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container grindstone + * + * @since 0.10.7 + */ + private class ContainerGrindstoneImpl extends GrindstoneMenu { + + /** + * The player for this grindstone container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container grindstone + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the craft inventory field + */ + @NotNull + private final Field repairSlotsField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultSlotsField; + + public ContainerGrindstoneImpl(@NotNull ServerPlayer serverPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(serverPlayer.nextContainerCounter(), serverPlayer.getInventory()); + + this.player = serverPlayer.getBukkitEntity(); + + try { + //noinspection JavaReflectionMemberAccess + this.repairSlotsField = GrindstoneMenu.class.getDeclaredField("t"); //repairSlots + this.repairSlotsField.setAccessible(true); + + //noinspection JavaReflectionMemberAccess + this.resultSlotsField = GrindstoneMenu.class.getDeclaredField("s"); //resultSlots + this.resultSlotsField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getCraftInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getCraftInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(2, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryGrindstone(getCraftInventory(), getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean stillValid(@Nullable net.minecraft.world.entity.player.Player nmsPlayer) { + return true; + } + + @Override + public void slotsChanged(Container container) {} + + @Override + public void removed(net.minecraft.world.entity.player.Player nmsPlayer) {} + + /** + * Gets the craft inventory + * + * @return the craft inventory + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private Container getCraftInventory() { + try { + return (Container) repairSlotsField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private Container getResultInventory() { + try { + return (Container) resultSlotsField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/MerchantInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/MerchantInventoryImpl.java new file mode 100644 index 00000000..1909a514 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/MerchantInventoryImpl.java @@ -0,0 +1,97 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.MerchantInventory; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.trading.MerchantOffer; +import net.minecraft.world.item.trading.MerchantOffers; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MerchantRecipe; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Map; + +/** + * Internal merchant inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class MerchantInventoryImpl extends MerchantInventory { + + @Override + public void sendMerchantOffers(@NotNull Player player, + @NotNull List> trades, + int level, int experience) { + MerchantOffers offers = new MerchantOffers(); + + for (Map.Entry entry : trades) { + MerchantRecipe recipe = entry.getKey(); + List ingredients = recipe.getIngredients(); + + if (ingredients.size() < 1) { + throw new IllegalStateException("Merchant recipe has no ingredients"); + } + + ItemStack itemA = ingredients.get(0); + ItemStack itemB = null; + + if (ingredients.size() >= 2) { + itemB = ingredients.get(1); + } + + net.minecraft.world.item.ItemStack nmsItemA = CraftItemStack.asNMSCopy(itemA); + net.minecraft.world.item.ItemStack nmsItemB = net.minecraft.world.item.ItemStack.EMPTY; + net.minecraft.world.item.ItemStack nmsItemResult = CraftItemStack.asNMSCopy(recipe.getResult()); + + if (itemB != null) { + nmsItemB = CraftItemStack.asNMSCopy(itemB); + } + + int uses = recipe.getUses(); + int maxUses = recipe.getMaxUses(); + int exp = recipe.getVillagerExperience(); + float multiplier = recipe.getPriceMultiplier(); + + MerchantOffer merchantOffer = new MerchantOffer( + nmsItemA, nmsItemB, nmsItemResult, uses, maxUses, exp, multiplier + ); + merchantOffer.setSpecialPriceDiff(entry.getValue()); + + offers.add(merchantOffer); + } + + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + + serverPlayer.sendMerchantOffers(containerId, offers, level, experience, true, false); + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * Gets the containerId id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the containerId id for + * @return the containerId id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/SmithingTableInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/SmithingTableInventoryImpl.java new file mode 100644 index 00000000..0af9f007 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/SmithingTableInventoryImpl.java @@ -0,0 +1,251 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.SmithingTableInventory; +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.CustomInventoryUtil; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.TextHolderUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.NonNullList; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.SmithingMenu; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventorySmithing; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal smithing table inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class SmithingTableInventoryImpl extends SmithingTableInventory { + + public SmithingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull TextHolder title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a smithing table should be 3, but is '" + itemAmount + "'" + ); + } + + ServerPlayer serverPlayer = getServerPlayer(player); + ContainerSmithingTableImpl containerSmithingTable = new ContainerSmithingTableImpl(serverPlayer, items); + + serverPlayer.containerMenu = containerSmithingTable; + + int id = containerSmithingTable.containerId; + Component message = TextHolderUtil.toComponent(title); + + serverPlayer.connection.send(new ClientboundOpenScreenPacket(id, MenuType.SMITHING, message)); + + sendItems(player, items, player.getItemOnCursor()); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items, + @Nullable org.bukkit.inventory.ItemStack cursor) { + NonNullList nmsItems = CustomInventoryUtil.convertToNMSItems(items); + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + ItemStack nmsCursor = CraftItemStack.asNMSCopy(cursor); + ServerPlayerConnection playerConnection = getPlayerConnection(serverPlayer); + + playerConnection.send(new ClientboundContainerSetContentPacket(containerId, state, nmsItems, nmsCursor)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(containerId, state, 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(containerId, state, 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.EMPTY); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, ItemStack.EMPTY)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.10.7 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.10.7 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(containerId, state, 2, item)); + } + + /** + * Gets the container id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the container id for + * @return the container id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } + + /** + * Gets the player connection for the specified player + * + * @param serverPlayer the player to get the player connection from + * @return the player connection + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayerConnection getPlayerConnection(@NotNull ServerPlayer serverPlayer) { + return serverPlayer.connection; + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container smithing table + * + * @since 0.10.7 + */ + private class ContainerSmithingTableImpl extends SmithingMenu { + + /** + * The player for this smithing table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container smithing table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + public ContainerSmithingTableImpl(@NotNull ServerPlayer serverPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), + ContainerLevelAccess.create(serverPlayer.getCommandSenderWorld(), new BlockPos(0, 0, 0))); + + this.player = serverPlayer.getBukkitEntity(); + + inputSlots.setItem(0, CraftItemStack.asNMSCopy(items[0])); + inputSlots.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultSlots.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventorySmithing(access.getLocation(), inputSlots, resultSlots) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean stillValid(@Nullable net.minecraft.world.entity.player.Player nmsPlayer) { + return true; + } + + @Override + public void slotsChanged(Container container) {} + + @Override + public void removed(net.minecraft.world.entity.player.Player nmsPlayer) {} + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/StonecutterInventoryImpl.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/StonecutterInventoryImpl.java new file mode 100644 index 00000000..a6c3f38f --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/StonecutterInventoryImpl.java @@ -0,0 +1,219 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2; + +import com.github.stefvanschie.inventoryframework.abstraction.StonecutterInventory; +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; +import com.github.stefvanschie.inventoryframework.nms.v1_19_2.util.TextHolderUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.StonecutterMenu; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryStonecutter; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal stonecutter inventory for 1.19.2 + * + * @since 0.10.7 + */ +public class StonecutterInventoryImpl extends StonecutterInventory { + + public StonecutterInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull TextHolder title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 2, but is '" + itemAmount + "'" + ); + } + + ServerPlayer serverPlayer = getServerPlayer(player); + ContainerStonecutterImpl containerEnchantmentTable = new ContainerStonecutterImpl(serverPlayer, items); + + serverPlayer.containerMenu = containerEnchantmentTable; + + int id = containerEnchantmentTable.containerId; + Component message = TextHolderUtil.toComponent(title); + ClientboundOpenScreenPacket packet = new ClientboundOpenScreenPacket(id, MenuType.STONECUTTER, message); + + serverPlayer.connection.send(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.of( + ItemStack.EMPTY, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + ServerPlayer serverPlayer = getServerPlayer(player); + int containerId = getContainerId(serverPlayer); + int state = serverPlayer.containerMenu.incrementStateId(); + ItemStack cursor = CraftItemStack.asNMSCopy(player.getItemOnCursor()); + ServerPlayerConnection playerConnection = getPlayerConnection(serverPlayer); + + playerConnection.send(new ClientboundContainerSetContentPacket(containerId, state, nmsItems, cursor)); + } + + @Override + public void clearCursor(@NotNull Player player) { + ServerPlayer serverPlayer = getServerPlayer(player); + int state = serverPlayer.containerMenu.incrementStateId(); + + getPlayerConnection(serverPlayer).send(new ClientboundContainerSetSlotPacket(-1, state, -1, ItemStack.EMPTY)); + } + + /** + * Gets the container id for the inventory view the player currently has open + * + * @param nmsPlayer the player to get the container id for + * @return the container id + * @since 0.10.7 + */ + @Contract(pure = true) + private int getContainerId(@NotNull net.minecraft.world.entity.player.Player nmsPlayer) { + return nmsPlayer.containerMenu.containerId; + } + + /** + * Gets the player connection for the specified player + * + * @param serverPlayer the player to get the player connection from + * @return the player connection + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayerConnection getPlayerConnection(@NotNull ServerPlayer serverPlayer) { + return serverPlayer.connection; + } + + /** + * Gets the server player associated to this player + * + * @param player the player to get the server player from + * @return the server player + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private ServerPlayer getServerPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.10.7 + */ + private class ContainerStonecutterImpl extends StonecutterMenu { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultContainerField; + + public ContainerStonecutterImpl(@NotNull ServerPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.getInventory()); + + this.player = entityPlayer.getBukkitEntity(); + + try { + //noinspection JavaReflectionMemberAccess + this.resultContainerField = StonecutterMenu.class.getDeclaredField("A"); //resultContainer + this.resultContainerField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + container.setItem(0, CraftItemStack.asNMSCopy(items[0])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[1])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryStonecutter(this.container, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean stillValid(@Nullable net.minecraft.world.entity.player.Player nmsPlayer) { + return true; + } + + @Override + public void slotsChanged(Container container) {} + + @Override + public void removed(net.minecraft.world.entity.player.Player nmsPlayer) {} + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + public Container getResultInventory() { + try { + return (Container) resultContainerField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/CustomInventoryUtil.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/CustomInventoryUtil.java new file mode 100644 index 00000000..fcda8d03 --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/CustomInventoryUtil.java @@ -0,0 +1,41 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2.util; + +import net.minecraft.core.NonNullList; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A utility class for custom inventories + * + * @since 0.10.7 + */ +public final class CustomInventoryUtil { + + /** + * A private constructor to prevent construction. + */ + private CustomInventoryUtil() {} + + /** + * Converts an array of Bukkit items into a non-null list of NMS items. The returned list is modifiable. If no items + * were specified, this returns an empty list. + * + * @param items the items to convert + * @return a list of converted items + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + public static NonNullList convertToNMSItems(@Nullable org.bukkit.inventory.ItemStack @NotNull [] items) { + NonNullList nmsItems = NonNullList.create(); + + for (org.bukkit.inventory.ItemStack item : items) { + nmsItems.add(CraftItemStack.asNMSCopy(item)); + } + + return nmsItems; + } +} diff --git a/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/TextHolderUtil.java b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/TextHolderUtil.java new file mode 100644 index 00000000..5760f79b --- /dev/null +++ b/nms/1_19_2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_19_2/util/TextHolderUtil.java @@ -0,0 +1,65 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_19_2.util; + +import com.github.stefvanschie.inventoryframework.adventuresupport.ComponentHolder; +import com.github.stefvanschie.inventoryframework.adventuresupport.StringHolder; +import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +/** + * A utility class for adding {@link TextHolder} support. + * + * @since 0.10.7 + */ +public final class TextHolderUtil { + + private TextHolderUtil() { + //private constructor to prevent construction + } + + /** + * Converts the specified value to a vanilla component. + * + * @param holder the value to convert + * @return the value as a vanilla component + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + public static Component toComponent(@NotNull TextHolder holder) { + if (holder instanceof StringHolder) { + return toComponent((StringHolder) holder); + } else { + return toComponent((ComponentHolder) holder); + } + } + + /** + * Converts the specified legacy string holder to a vanilla component. + * + * @param holder the value to convert + * @return the value as a vanilla component + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private static Component toComponent(@NotNull StringHolder holder) { + return Component.literal(holder.asLegacyString()); + } + + /** + * Converts the specified Adventure component holder to a vanilla component. + * + * @param holder the value to convert + * @return the value as a vanilla component + * @since 0.10.7 + */ + @NotNull + @Contract(pure = true) + private static Component toComponent(@NotNull ComponentHolder holder) { + return Objects.requireNonNull(Component.Serializer.fromJson(holder.asJson())); + } +} diff --git a/pom.xml b/pom.xml index 2ca1369b..86024fd1 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,7 @@ IF nms/abstraction + nms/1_19_2 nms/1_19_1 nms/1_19_0 nms/1_18_2