From acd447c6ec4a20f8be719b297ca52e3bc2a9314d Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 24 Jul 2021 23:33:54 +0200 Subject: [PATCH] First steps towards 1.17 support The plugin works, but the localization part has yet to be done, and support for other plugins has to be updated to the latest versions. --- pom.xml | 32 ++- .../java/de/epiceric/shopchest/ShopChest.java | 8 +- .../shopchest/language/LanguageUtils.java | 7 +- .../listeners/ShopInteractListener.java | 9 +- .../shopchest/nms/ArmorStandWrapper.java | 87 ++++-- .../shopchest/nms/CustomBookMeta.java | 9 +- .../de/epiceric/shopchest/nms/Hologram.java | 2 +- .../epiceric/shopchest/nms/JsonBuilder.java | 19 +- .../epiceric/shopchest/nms/SpawnEggMeta.java | 6 +- .../de/epiceric/shopchest/shop/ShopItem.java | 22 +- .../de/epiceric/shopchest/utils/Utils.java | 112 ++++---- src/main/resources/item_names.txt | 259 ++++++++++++++---- 12 files changed, 393 insertions(+), 179 deletions(-) diff --git a/pom.xml b/pom.xml index 1327ae6..aa61c9d 100644 --- a/pom.xml +++ b/pom.xml @@ -91,13 +91,17 @@ plotsquared-repo https://plotsquared.com/mvn/ + + inventive-repo + https://repo.inventivetalent.org/content/groups/public/ + org.spigotmc spigot-api - 1.16.4-R0.1-SNAPSHOT + 1.17.1-R0.1-SNAPSHOT provided @@ -170,26 +174,38 @@ ${project.basedir}/lib/PlotSquared-Bukkit-4.4.495.jar + + org.projectlombok + lombok + 1.18.20 + provided + + org.codemc.worldguardwrapper worldguardwrapper - 1.1.6-SNAPSHOT + 1.2.0-SNAPSHOT org.bstats bstats-bukkit - 1.7 + 2.2.1 com.zaxxer HikariCP - 3.3.1 + 5.0.0 org.slf4j slf4j-jdk14 - 1.7.26 + 2.0.0-alpha2 + + + org.inventivetalent + reflectionhelper + 1.18.4-SNAPSHOT @@ -219,7 +235,7 @@ false - org.bstats.bukkit + org.bstats de.epiceric.shopchest.dependencies.bstats @@ -234,6 +250,10 @@ org.slf4j de.epiceric.shopchest.dependencies.slf4j + + org.inventivetalent.reflection + de.epiceric.shopchest.dependencies.reflectionhelper + diff --git a/src/main/java/de/epiceric/shopchest/ShopChest.java b/src/main/java/de/epiceric/shopchest/ShopChest.java index cdaf9e8..92646a7 100644 --- a/src/main/java/de/epiceric/shopchest/ShopChest.java +++ b/src/main/java/de/epiceric/shopchest/ShopChest.java @@ -20,6 +20,8 @@ import com.plotsquared.core.PlotSquared; import com.wasteofplastic.askyblock.ASkyBlock; import org.bstats.bukkit.Metrics; +import org.bstats.charts.AdvancedPie; +import org.bstats.charts.SimplePie; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -340,9 +342,9 @@ public class ShopChest extends JavaPlugin { debug("Initializing Metrics..."); Metrics metrics = new Metrics(this, 1726); - metrics.addCustomChart(new Metrics.SimplePie("creative_setting", () -> Config.creativeSelectItem ? "Enabled" : "Disabled")); - metrics.addCustomChart(new Metrics.SimplePie("database_type", () -> Config.databaseType.toString())); - metrics.addCustomChart(new Metrics.AdvancedPie("shop_type", () -> { + metrics.addCustomChart(new SimplePie("creative_setting", () -> Config.creativeSelectItem ? "Enabled" : "Disabled")); + metrics.addCustomChart(new SimplePie("database_type", () -> Config.databaseType.toString())); + metrics.addCustomChart(new AdvancedPie("shop_type", () -> { int normal = 0; int admin = 0; diff --git a/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java b/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java index 6630b8e..27830c8 100644 --- a/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java +++ b/src/main/java/de/epiceric/shopchest/language/LanguageUtils.java @@ -1391,7 +1391,6 @@ public class LanguageUtils { itemNames.add(new ItemName(Material.PURPUR_SLAB, langConfig.getString("block.minecraft.purpur_slab", "Purpur Slab"))); itemNames.add(new ItemName(Material.END_STONE_BRICKS, langConfig.getString("block.minecraft.end_stone_bricks", "End Stone Bricks"))); itemNames.add(new ItemName(Material.BEETROOTS, langConfig.getString("block.minecraft.beetroots", "Beetroots"))); - itemNames.add(new ItemName(Material.GRASS_PATH, langConfig.getString("block.minecraft.grass_path", "Grass Path"))); itemNames.add(new ItemName(Material.MAGMA_BLOCK, langConfig.getString("block.minecraft.magma_block", "Magma Block"))); itemNames.add(new ItemName(Material.NETHER_WART_BLOCK, langConfig.getString("block.minecraft.nether_wart_block", "Nether Wart Block"))); itemNames.add(new ItemName(Material.RED_NETHER_BRICKS, langConfig.getString("block.minecraft.red_nether_bricks", "Red Nether Bricks"))); @@ -2069,6 +2068,12 @@ public class LanguageUtils { itemNames.add(new ItemName(Material.valueOf("ZOMBIE_PIGMAN_SPAWN_EGG"), langConfig.getString("item.minecraft.zombie_pigman_spawn_egg", "Zombie Pigman Spawn Egg"))); } + if (Utils.getMajorVersion() >= 17) { + itemNames.add(new ItemName(Material.DIRT_PATH, langConfig.getString("block.minecraft.grass_path", "Grass Path"))); + } else { + itemNames.add(new ItemName(Material.valueOf("GRASS_PATH"), langConfig.getString("block.minecraft.grass_path", "Grass Path"))); + } + // Add Enchantment Names enchantmentNames.add(new EnchantmentName(Enchantment.DAMAGE_ALL, langConfig.getString("enchantment.minecraft.sharpness", "Sharpness"))); enchantmentNames.add(new EnchantmentName(Enchantment.DAMAGE_UNDEAD, langConfig.getString("enchantment.minecraft.smite", "Smite"))); diff --git a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java index c53edaa..0702daf 100644 --- a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java +++ b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java @@ -36,6 +36,8 @@ import org.bukkit.scheduler.BukkitRunnable; import org.codemc.worldguardwrapper.WorldGuardWrapper; import org.codemc.worldguardwrapper.flag.IWrappedFlag; import org.codemc.worldguardwrapper.flag.WrappedState; +import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver; +import org.inventivetalent.reflection.resolver.minecraft.OBCClassResolver; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.config.Config; @@ -664,9 +666,12 @@ public class ShopInteractListener implements Listener { JsonBuilder.PartArray rootArray = new JsonBuilder.PartArray(); try { - Class craftItemStackClass = Utils.getCraftClass("inventory.CraftItemStack"); + OBCClassResolver obcClassResolver = new OBCClassResolver(); + NMSClassResolver nmsClassResolver = new NMSClassResolver(); + + Class craftItemStackClass = obcClassResolver.resolveSilent("inventory.CraftItemStack"); Object nmsStack = craftItemStackClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, product.getItemStack()); - Class nbtTagCompoundClass = Utils.getNMSClass("NBTTagCompound"); + Class nbtTagCompoundClass = nmsClassResolver.resolveSilent("nbt.NBTTagCompound"); Object nbtTagCompound = nbtTagCompoundClass.getConstructor().newInstance(); nmsStack.getClass().getMethod("save", nbtTagCompoundClass).invoke(nmsStack, nbtTagCompound); jsonItem = new JsonPrimitive(nbtTagCompound.toString()).toString(); diff --git a/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java b/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java index f10287a..56ea9c4 100644 --- a/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java +++ b/src/main/java/de/epiceric/shopchest/nms/ArmorStandWrapper.java @@ -1,31 +1,33 @@ package de.epiceric.shopchest.nms; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.UUID; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.utils.Utils; public class ArmorStandWrapper { - - private final Class packetPlayOutEntityDestroyClass = Utils.getNMSClass("PacketPlayOutEntityDestroy"); - private final Class packetPlayOutEntityMetadataClass = Utils.getNMSClass("PacketPlayOutEntityMetadata"); - private final Class packetPlayOutEntityTeleportClass = Utils.getNMSClass("PacketPlayOutEntityTeleport"); - private final Class dataWatcherClass = Utils.getNMSClass("DataWatcher"); + private final NMSClassResolver nmsClassResolver = new NMSClassResolver(); + private final Class packetDataSerializerClass = nmsClassResolver.resolveSilent("network.PacketDataSerializer"); + private final Class packetPlayOutEntityDestroyClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityDestroy"); + private final Class packetPlayOutEntityMetadataClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityMetadata"); + private final Class packetPlayOutEntityTeleportClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityTeleport"); + private final Class dataWatcherClass = nmsClassResolver.resolveSilent("network.syncher.DataWatcher"); private final UUID uuid = UUID.randomUUID(); private final int entityId; private ShopChest plugin; - private Object entity; private Location location; private String customName; - public ArmorStandWrapper(ShopChest plugin, Location location, String customName, boolean interactable) { + public ArmorStandWrapper(ShopChest plugin, Location location, String customName) { this.plugin = plugin; this.location = location; this.customName = customName; @@ -51,29 +53,60 @@ public class ArmorStandWrapper { public void setLocation(Location location) { this.location = location; + double y = location.getY() + (Utils.getServerVersion().equals("v1_8_R1") ? 0 : 1.975); + Object packet; + try { - Object packet = packetPlayOutEntityTeleportClass.getConstructor().newInstance(); - Field[] fields = packetPlayOutEntityTeleportClass.getDeclaredFields(); - for (Field field : fields) { - field.setAccessible(true); - } + if (Utils.getMajorVersion() >= 17) { + // Empty constructor does not exist anymore in 1.17+ so create packet via serializer + Class byteBufClass = Class.forName("io.netty.buffer.ByteBuf"); + Class unpooledClass = Class.forName("io.netty.buffer.Unpooled"); + Object buffer = unpooledClass.getMethod("buffer").invoke(null); + Object serializer = packetDataSerializerClass.getConstructor(byteBufClass).newInstance(buffer); - boolean isPre9 = Utils.getMajorVersion() < 9; - fields[0].set(packet, entityId); + Method d = packetDataSerializerClass.getMethod("d", int.class); + Method writeDouble = packetDataSerializerClass.getMethod("writeDouble", double.class); + Method writeByte = packetDataSerializerClass.getMethod("writeByte", int.class); + Method writeBoolean = packetDataSerializerClass.getMethod("writeBoolean", boolean.class); - double y = location.getY() + (Utils.getServerVersion().equals("v1_8_R1") ? 0 : 1.975); - if (isPre9) { - fields[1].set(packet, (int)(location.getX() * 32)); - fields[2].set(packet, (int)(y * 32)); - fields[3].set(packet, (int)(location.getZ() * 32)); + d.invoke(serializer, getEntityId()); + writeDouble.invoke(serializer, location.getX()); + writeDouble.invoke(serializer, y); + writeDouble.invoke(serializer, location.getZ()); + writeByte.invoke(serializer, 0); + writeByte.invoke(serializer, 0); + writeBoolean.invoke(serializer, false); + + packet = packetPlayOutEntityTeleportClass.getConstructor(packetDataSerializerClass).newInstance(serializer); } else { - fields[1].set(packet, location.getX()); - fields[2].set(packet, y); - fields[3].set(packet, location.getZ()); + packet = packetPlayOutEntityTeleportClass.getConstructor().newInstance(); + Field[] fields = packetPlayOutEntityTeleportClass.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + } + + boolean isPre9 = Utils.getMajorVersion() < 9; + fields[0].set(packet, entityId); + + if (isPre9) { + fields[1].set(packet, (int)(location.getX() * 32)); + fields[2].set(packet, (int)(y * 32)); + fields[3].set(packet, (int)(location.getZ() * 32)); + } else { + fields[1].set(packet, location.getX()); + fields[2].set(packet, y); + fields[3].set(packet, location.getZ()); + } + fields[4].set(packet, (byte) 0); + fields[5].set(packet, (byte) 0); + fields[6].set(packet, true); + } + + if (packet == null) { + plugin.getLogger().severe("Could not set hologram location"); + plugin.debug("Could not set armor stand location: Packet is null"); + return; } - fields[4].set(packet, (byte) 0); - fields[5].set(packet, (byte) 0); - fields[6].set(packet, true); for (Player player : location.getWorld().getPlayers()) { Utils.sendPacket(plugin, packet, player); @@ -123,8 +156,4 @@ public class ArmorStandWrapper { public String getCustomName() { return customName; } - - public Object getEntity() { - return entity; - } } diff --git a/src/main/java/de/epiceric/shopchest/nms/CustomBookMeta.java b/src/main/java/de/epiceric/shopchest/nms/CustomBookMeta.java index cd51f52..290015f 100644 --- a/src/main/java/de/epiceric/shopchest/nms/CustomBookMeta.java +++ b/src/main/java/de/epiceric/shopchest/nms/CustomBookMeta.java @@ -3,14 +3,15 @@ package de.epiceric.shopchest.nms; import java.lang.reflect.InvocationTargetException; import org.bukkit.inventory.ItemStack; +import org.inventivetalent.reflection.resolver.minecraft.OBCClassResolver; import de.epiceric.shopchest.ShopChest; -import de.epiceric.shopchest.utils.Utils; // For versions below 1.9.4, since Bukkit's BookMeta // didn't have generations in those versions -public class CustomBookMeta { +public class CustomBookMeta { + private static final OBCClassResolver obcClassResolver = new OBCClassResolver(); public enum Generation { ORIGINAL, @@ -21,7 +22,7 @@ public class CustomBookMeta { public static Generation getGeneration(ItemStack book) { try { - Class craftItemStackClass = Utils.getCraftClass("inventory.CraftItemStack"); + Class craftItemStackClass = obcClassResolver.resolveSilent("inventory.CraftItemStack"); if (craftItemStackClass == null) { ShopChest.getInstance().debug("Failed to get NBTGeneration: Could not find CraftItemStack class"); @@ -61,7 +62,7 @@ public class CustomBookMeta { public static void setGeneration(ItemStack book, Generation generation) { try { - Class craftItemStackClass = Utils.getCraftClass("inventory.CraftItemStack"); + Class craftItemStackClass = obcClassResolver.resolveSilent("inventory.CraftItemStack"); if (craftItemStackClass == null) { ShopChest.getInstance().debug("Failed to get NBTGeneration: Could not find CraftItemStack class"); diff --git a/src/main/java/de/epiceric/shopchest/nms/Hologram.java b/src/main/java/de/epiceric/shopchest/nms/Hologram.java index 97caf80..08b0320 100644 --- a/src/main/java/de/epiceric/shopchest/nms/Hologram.java +++ b/src/main/java/de/epiceric/shopchest/nms/Hologram.java @@ -193,7 +193,7 @@ public class Hologram { loc.subtract(0, line * 0.25, 0); } - ArmorStandWrapper wrapper = new ArmorStandWrapper(plugin, loc, text, false); + ArmorStandWrapper wrapper = new ArmorStandWrapper(plugin, loc, text); wrappers.add(line, wrapper); if (forceUpdateLine) { diff --git a/src/main/java/de/epiceric/shopchest/nms/JsonBuilder.java b/src/main/java/de/epiceric/shopchest/nms/JsonBuilder.java index 0079d7c..946d20c 100644 --- a/src/main/java/de/epiceric/shopchest/nms/JsonBuilder.java +++ b/src/main/java/de/epiceric/shopchest/nms/JsonBuilder.java @@ -12,6 +12,8 @@ import java.util.regex.Pattern; import org.bukkit.ChatColor; import org.bukkit.entity.Player; +import org.inventivetalent.reflection.resolver.FieldResolver; +import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.utils.Utils; @@ -115,22 +117,17 @@ public class JsonBuilder { private Part rootPart; private ShopChest plugin; - private Class iChatBaseComponentClass = Utils.getNMSClass("IChatBaseComponent"); - private Class packetPlayOutChatClass = Utils.getNMSClass("PacketPlayOutChat"); - private Class chatSerializerClass; + private final NMSClassResolver nmsClassResolver = new NMSClassResolver(); + private Class iChatBaseComponentClass = nmsClassResolver.resolveSilent("network.chat.IChatBaseComponent"); + private Class packetPlayOutChatClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutChat"); + private Class chatSerializerClass = nmsClassResolver.resolveSilent("ChatSerializer", "network.chat.IChatBaseComponent$ChatSerializer"); private Class chatMessageTypeClass; public JsonBuilder(ShopChest plugin) { this.plugin = plugin; - if (Utils.getServerVersion().equals("v1_8_R1")) { - chatSerializerClass = Utils.getNMSClass("ChatSerializer"); - } else { - chatSerializerClass = Utils.getNMSClass("IChatBaseComponent$ChatSerializer"); - } - if (Utils.getMajorVersion() >= 16) { - chatMessageTypeClass = Utils.getNMSClass("ChatMessageType"); + chatMessageTypeClass = nmsClassResolver.resolveSilent("network.chat.ChatMessageType"); } Class[] requiredClasses = new Class[] { @@ -241,7 +238,7 @@ public class JsonBuilder { Object packetPlayOutChat = Utils.getMajorVersion() < 16 ? packetPlayOutChatClass.getConstructor(iChatBaseComponentClass).newInstance(iChatBaseComponent) : packetPlayOutChatClass.getConstructor(iChatBaseComponentClass, chatMessageTypeClass, UUID.class) - .newInstance(iChatBaseComponent, chatMessageTypeClass.getField("CHAT").get(null), UUID.randomUUID()); + .newInstance(iChatBaseComponent, (new FieldResolver(chatMessageTypeClass)).resolve("CHAT", "a").get(null), UUID.randomUUID()); Utils.sendPacket(plugin, packetPlayOutChat, p); plugin.debug("Sent JSON: " + toString()); diff --git a/src/main/java/de/epiceric/shopchest/nms/SpawnEggMeta.java b/src/main/java/de/epiceric/shopchest/nms/SpawnEggMeta.java index 4aa261b..45de850 100644 --- a/src/main/java/de/epiceric/shopchest/nms/SpawnEggMeta.java +++ b/src/main/java/de/epiceric/shopchest/nms/SpawnEggMeta.java @@ -4,6 +4,7 @@ import java.lang.reflect.InvocationTargetException; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import org.inventivetalent.reflection.resolver.minecraft.OBCClassResolver; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.utils.Utils; @@ -11,8 +12,9 @@ import de.epiceric.shopchest.utils.Utils; public class SpawnEggMeta { private static String getNBTEntityID(ShopChest plugin, ItemStack stack) { - try { - Class craftItemStackClass = Utils.getCraftClass("inventory.CraftItemStack"); + try { + OBCClassResolver obcClassResolver = new OBCClassResolver(); + Class craftItemStackClass = obcClassResolver.resolveSilent("inventory.CraftItemStack"); if (craftItemStackClass == null) { plugin.debug("Failed to get NBTEntityID: Could not find CraftItemStack class"); diff --git a/src/main/java/de/epiceric/shopchest/shop/ShopItem.java b/src/main/java/de/epiceric/shopchest/shop/ShopItem.java index 6077a4c..9acda03 100644 --- a/src/main/java/de/epiceric/shopchest/shop/ShopItem.java +++ b/src/main/java/de/epiceric/shopchest/shop/ShopItem.java @@ -11,6 +11,8 @@ import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver; +import org.inventivetalent.reflection.resolver.minecraft.OBCClassResolver; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.utils.Utils; @@ -25,13 +27,15 @@ public class ShopItem { private final UUID uuid = UUID.randomUUID(); private final int entityId; - private final Class packetPlayOutEntityDestroyClass = Utils.getNMSClass("PacketPlayOutEntityDestroy"); - private final Class packetPlayOutEntityVelocityClass = Utils.getNMSClass("PacketPlayOutEntityVelocity"); - private final Class packetPlayOutEntityMetadataClass = Utils.getNMSClass("PacketPlayOutEntityMetadata"); - private final Class dataWatcherClass = Utils.getNMSClass("DataWatcher"); - private final Class vec3dClass = Utils.getNMSClass("Vec3D"); - private final Class craftItemStackClass = Utils.getCraftClass("inventory.CraftItemStack"); - private final Class nmsItemStackClass = Utils.getNMSClass("ItemStack"); + private final NMSClassResolver nmsClassResolver = new NMSClassResolver(); + private final OBCClassResolver obcClassResolver = new OBCClassResolver(); + private final Class packetPlayOutEntityDestroyClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityDestroy"); + private final Class packetPlayOutEntityVelocityClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityVelocity"); + private final Class packetPlayOutEntityMetadataClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutEntityMetadata"); + private final Class dataWatcherClass = nmsClassResolver.resolveSilent("network.syncher.DataWatcher"); + private final Class vec3dClass = nmsClassResolver.resolveSilent("world.phys.Vec3D"); + private final Class craftItemStackClass = obcClassResolver.resolveSilent("inventory.CraftItemStack"); + private final Class nmsItemStackClass = nmsClassResolver.resolveSilent("world.item.ItemStack"); public ShopItem(ShopChest plugin, ItemStack itemStack, Location location) { this.plugin = plugin; @@ -39,11 +43,9 @@ public class ShopItem { this.location = location; this.entityId = Utils.getFreeEntityId(); - Class entityClass = Utils.getNMSClass("Entity"); - Class[] requiredClasses = new Class[] { nmsItemStackClass, craftItemStackClass, packetPlayOutEntityMetadataClass, dataWatcherClass, - packetPlayOutEntityDestroyClass, entityClass, packetPlayOutEntityVelocityClass, + packetPlayOutEntityDestroyClass, packetPlayOutEntityVelocityClass, }; for (Class c : requiredClasses) { diff --git a/src/main/java/de/epiceric/shopchest/utils/Utils.java b/src/main/java/de/epiceric/shopchest/utils/Utils.java index f8d24d8..0b5a01d 100644 --- a/src/main/java/de/epiceric/shopchest/utils/Utils.java +++ b/src/main/java/de/epiceric/shopchest/utils/Utils.java @@ -1,5 +1,6 @@ package de.epiceric.shopchest.utils; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -32,6 +33,11 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; +import org.inventivetalent.reflection.minecraft.DataWatcher; +import org.inventivetalent.reflection.resolver.ClassResolver; +import org.inventivetalent.reflection.resolver.FieldResolver; +import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver; +import org.inventivetalent.reflection.resolver.minecraft.OBCClassResolver; import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.config.Placeholder; @@ -43,6 +49,15 @@ import de.epiceric.shopchest.nms.JsonBuilder; import de.epiceric.shopchest.shop.Shop; public class Utils { + static NMSClassResolver nmsClassResolver = new NMSClassResolver(); + static Class entityClass = nmsClassResolver.resolveSilent("world.entity.Entity"); + static Class entityArmorStandClass = nmsClassResolver.resolveSilent("world.entity.decoration.EntityArmorStand"); + static Class entityItemClass = nmsClassResolver.resolveSilent("world.entity.item.EntityItem"); + static Class dataWatcherClass = nmsClassResolver.resolveSilent("network.syncher.DataWatcher"); + static Class dataWatcherObjectClass = nmsClassResolver.resolveSilent("network.syncher.DataWatcherObject"); + static Class chatSerializerClass = nmsClassResolver.resolveSilent("ChatSerializer", "network.chat.IChatBaseComponent$ChatSerializer"); + + private Utils() {} /** * Check if two items are similar to each other @@ -335,30 +350,6 @@ public class Utils { jb.sendJson(p); } - /** - * @param className Name of the class - * @return Class in {@code net.minecraft.server.[VERSION]} package with the specified name or {@code null} if the class was not found - */ - public static Class getNMSClass(String className) { - try { - return Class.forName("net.minecraft.server." + getServerVersion() + "." + className); - } catch (ClassNotFoundException e) { - return null; - } - } - - /** - * @param className Name of the class - * @return Class in {@code org.bukkit.craftbukkit.[VERSION]} package with the specified name or {@code null} if the class was not found - */ - public static Class getCraftClass(String className) { - try { - return Class.forName("org.bukkit.craftbukkit." + getServerVersion() + "." + className); - } catch (ClassNotFoundException e) { - return null; - } - } - /** * Create a NMS data watcher object to send via a {@code PacketPlayOutEntityMetadata} packet. * Gravity will be disabled and the custom name will be displayed if available. @@ -370,12 +361,6 @@ public class Utils { int majorVersion = getMajorVersion(); try { - Class entityClass = getNMSClass("Entity"); - Class entityArmorStandClass = getNMSClass("EntityArmorStand"); - Class entityItemClass = getNMSClass("EntityItem"); - Class dataWatcherClass = getNMSClass("DataWatcher"); - Class dataWatcherObjectClass = getNMSClass("DataWatcherObject"); - byte entityFlags = nmsItemStack == null ? (byte) 0b100000 : 0; // invisible if armor stand byte armorStandFlags = nmsItemStack == null ? (byte) 0b10000 : 0; // marker (since 1.8_R2) @@ -414,6 +399,8 @@ public class Utils { dataWatcherObjectFieldNames = new String[] {"T", "AIR_TICKS", "ay", "ax", "az", "aA", "ITEM", "b"}; } else if ("v1_16_R2".equals(version) || "v1_16_R3".equals(version)) { dataWatcherObjectFieldNames = new String[] {"S", "AIR_TICKS", "ar", "aq", "as", "at", "ITEM", "b"}; + } else if ("v1_17_R1".equals(version)) { + dataWatcherObjectFieldNames = new String[] {"Z", "aI", "aK", "aJ", "aL", "aM", "c", "bG"}; } else { return null; } @@ -452,7 +439,6 @@ public class Utils { register.invoke(dataWatcher, fNoGravity.get(null), true); if (majorVersion >= 13) { if (customName != null) { - Class chatSerializerClass = Utils.getNMSClass("IChatBaseComponent$ChatSerializer"); Object iChatBaseComponent = chatSerializerClass.getMethod("a", String.class).invoke(null, JsonBuilder.parse(customName).toString()); register.invoke(dataWatcher, fCustomName.get(null), Optional.of(iChatBaseComponent)); } else { @@ -477,8 +463,7 @@ public class Utils { */ public static int getFreeEntityId() { try { - Class entityClass = getNMSClass("Entity"); - Field entityCountField = entityClass.getDeclaredField("entityCount"); + Field entityCountField = new FieldResolver(entityClass).resolve("entityCount", "b"); entityCountField.setAccessible(true); if (entityCountField.getType() == int.class) { int id = entityCountField.getInt(null); @@ -500,24 +485,45 @@ public class Utils { */ public static Object createPacketSpawnEntity(ShopChest plugin, int id, UUID uuid, Location loc, EntityType type) { try { - Class packetClass = getNMSClass("PacketPlayOutSpawnEntity"); - Object packet = packetClass.getConstructor().newInstance(); + Class packetPlayOutSpawnEntityClass = nmsClassResolver.resolveSilent("network.protocol.game.PacketPlayOutSpawnEntity"); + Class entityTypesClass = nmsClassResolver.resolveSilent("world.entity.EntityTypes"); + Class vec3dClass = nmsClassResolver.resolveSilent("world.phys.Vec3D"); + boolean isPre9 = getMajorVersion() < 9; boolean isPre14 = getMajorVersion() < 14; + double y = loc.getY(); + if (type == EntityType.ARMOR_STAND && !getServerVersion().equals("v1_8_R1")) { + // Marker armor stand => lift by normal armor stand height + y += 1.975; + } + + if (getMajorVersion() >= 17) { + // Empty packet constructor does not exist anymore in 1.17+ + Constructor c = packetPlayOutSpawnEntityClass.getConstructor(int.class, UUID.class, double.class, double.class, double.class, + float.class, float.class, entityTypesClass, int.class, vec3dClass); + + Object vec3d = vec3dClass.getField("a").get(null); + Object entityType = entityTypesClass.getField(type == EntityType.ARMOR_STAND ? "c" : "Q").get(null); + + return c.newInstance(id, uuid, loc.getX(), y, loc.getZ(), 0f, 0f, entityType, 0, vec3d); + } + + Object packet = packetPlayOutSpawnEntityClass.getConstructor().newInstance(); + Field[] fields = new Field[12]; - fields[0] = packetClass.getDeclaredField("a"); // ID - fields[1] = packetClass.getDeclaredField("b"); // UUID (Only 1.9+) - fields[2] = packetClass.getDeclaredField(isPre9 ? "b" : "c"); // Loc X - fields[3] = packetClass.getDeclaredField(isPre9 ? "c" : "d"); // Loc Y - fields[4] = packetClass.getDeclaredField(isPre9 ? "d" : "e"); // Loc Z - fields[5] = packetClass.getDeclaredField(isPre9 ? "e" : "f"); // Mot X - fields[6] = packetClass.getDeclaredField(isPre9 ? "f" : "g"); // Mot Y - fields[7] = packetClass.getDeclaredField(isPre9 ? "g" : "h"); // Mot Z - fields[8] = packetClass.getDeclaredField(isPre9 ? "h" : "i"); // Pitch - fields[9] = packetClass.getDeclaredField(isPre9 ? "i" : "j"); // Yaw - fields[10] = packetClass.getDeclaredField(isPre9 ? "j" : "k"); // Type - fields[11] = packetClass.getDeclaredField(isPre9 ? "k" : "l"); // Data + fields[0] = packetPlayOutSpawnEntityClass.getDeclaredField("a"); // ID + fields[1] = packetPlayOutSpawnEntityClass.getDeclaredField("b"); // UUID (Only 1.9+) + fields[2] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "b" : "c"); // Loc X + fields[3] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "c" : "d"); // Loc Y + fields[4] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "d" : "e"); // Loc Z + fields[5] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "e" : "f"); // Mot X + fields[6] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "f" : "g"); // Mot Y + fields[7] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "g" : "h"); // Mot Z + fields[8] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "h" : "i"); // Pitch + fields[9] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "i" : "j"); // Yaw + fields[10] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "j" : "k"); // Type + fields[11] = packetPlayOutSpawnEntityClass.getDeclaredField(isPre9 ? "k" : "l"); // Data for (Field field : fields) { field.setAccessible(true); @@ -525,16 +531,9 @@ public class Utils { Object entityType = null; if (!isPre14) { - Class entityTypesClass = getNMSClass("EntityTypes"); entityType = entityTypesClass.getField(type == EntityType.ARMOR_STAND ? "ARMOR_STAND" : "ITEM").get(null); } - double y = loc.getY(); - if (type == EntityType.ARMOR_STAND && !getServerVersion().equals("v1_8_R1")) { - // Marker armor stand => lift by normal armor stand height - y += 1.975; - } - fields[0].set(packet, id); if (!isPre9) fields[1].set(packet, uuid); if (isPre9) { @@ -578,14 +577,15 @@ public class Utils { return false; } - Class packetClass = getNMSClass("Packet"); + Class packetClass = nmsClassResolver.resolveSilent("network.protocol.Packet"); if (packetClass == null) { plugin.debug("Failed to send packet: Could not find Packet class"); return false; } Object nmsPlayer = player.getClass().getMethod("getHandle").invoke(player); - Object playerConnection = nmsPlayer.getClass().getField("playerConnection").get(nmsPlayer); + Field fConnection = (new FieldResolver(nmsPlayer.getClass())).resolve("playerConnection", "b"); + Object playerConnection = fConnection.get(nmsPlayer); playerConnection.getClass().getMethod("sendPacket", packetClass).invoke(playerConnection, packet); diff --git a/src/main/resources/item_names.txt b/src/main/resources/item_names.txt index 268a926..3b64c9f 100644 --- a/src/main/resources/item_names.txt +++ b/src/main/resources/item_names.txt @@ -20,6 +20,9 @@ ACACIA_WOOD ACTIVATOR_RAIL AIR ALLIUM +AMETHYST_BLOCK +AMETHYST_CLUSTER +AMETHYST_SHARD ANCIENT_DEBRIS ANDESITE ANDESITE_SLAB @@ -31,6 +34,10 @@ ARMOR_STAND ARROW ATTACHED_MELON_STEM ATTACHED_PUMPKIN_STEM +AXOLOTL_BUCKET +AXOLOTL_SPAWN_EGG +AZALEA +AZALEA_LEAVES AZURE_BLUET BAKED_POTATO BAMBOO @@ -41,15 +48,17 @@ BASALT BAT_SPAWN_EGG BEACON BEDROCK -BEE_NEST -BEE_SPAWN_EGG BEEF BEEHIVE BEETROOT +BEETROOTS BEETROOT_SEEDS BEETROOT_SOUP -BEETROOTS +BEE_NEST +BEE_SPAWN_EGG BELL +BIG_DRIPLEAF +BIG_DRIPLEAF_STEM BIRCH_BOAT BIRCH_BUTTON BIRCH_DOOR @@ -66,8 +75,14 @@ BIRCH_STAIRS BIRCH_TRAPDOOR BIRCH_WALL_SIGN BIRCH_WOOD +BLACKSTONE +BLACKSTONE_SLAB +BLACKSTONE_STAIRS +BLACKSTONE_WALL BLACK_BANNER BLACK_BED +BLACK_CANDLE +BLACK_CANDLE_CAKE BLACK_CARPET BLACK_CONCRETE BLACK_CONCRETE_POWDER @@ -79,16 +94,14 @@ BLACK_STAINED_GLASS_PANE BLACK_TERRACOTTA BLACK_WALL_BANNER BLACK_WOOL -BLACKSTONE -BLACKSTONE_SLAB -BLACKSTONE_STAIRS -BLACKSTONE_WALL BLAST_FURNACE BLAZE_POWDER BLAZE_ROD BLAZE_SPAWN_EGG BLUE_BANNER BLUE_BED +BLUE_CANDLE +BLUE_CANDLE_CAKE BLUE_CARPET BLUE_CONCRETE BLUE_CONCRETE_POWDER @@ -116,12 +129,14 @@ BRAIN_CORAL_WALL_FAN BREAD BREWING_STAND BRICK +BRICKS BRICK_SLAB BRICK_STAIRS BRICK_WALL -BRICKS BROWN_BANNER BROWN_BED +BROWN_CANDLE +BROWN_CANDLE_CAKE BROWN_CARPET BROWN_CONCRETE BROWN_CONCRETE_POWDER @@ -141,30 +156,38 @@ BUBBLE_CORAL_BLOCK BUBBLE_CORAL_FAN BUBBLE_CORAL_WALL_FAN BUCKET +BUDDING_AMETHYST +BUNDLE CACTUS CAKE +CALCITE CAMPFIRE +CANDLE +CANDLE_CAKE CARROT -CARROT_ON_A_STICK CARROTS +CARROT_ON_A_STICK CARTOGRAPHY_TABLE CARVED_PUMPKIN CAT_SPAWN_EGG CAULDRON CAVE_AIR CAVE_SPIDER_SPAWN_EGG +CAVE_VINES +CAVE_VINES_PLANT CHAIN -CHAIN_COMMAND_BLOCK CHAINMAIL_BOOTS CHAINMAIL_CHESTPLATE CHAINMAIL_HELMET CHAINMAIL_LEGGINGS +CHAIN_COMMAND_BLOCK CHARCOAL CHEST CHEST_MINECART CHICKEN CHICKEN_SPAWN_EGG CHIPPED_ANVIL +CHISELED_DEEPSLATE CHISELED_NETHER_BRICKS CHISELED_POLISHED_BLACKSTONE CHISELED_QUARTZ_BLOCK @@ -181,6 +204,10 @@ COAL COAL_BLOCK COAL_ORE COARSE_DIRT +COBBLED_DEEPSLATE +COBBLED_DEEPSLATE_SLAB +COBBLED_DEEPSLATE_STAIRS +COBBLED_DEEPSLATE_WALL COBBLESTONE COBBLESTONE_SLAB COBBLESTONE_STAIRS @@ -205,8 +232,13 @@ COOKED_PORKCHOP COOKED_RABBIT COOKED_SALMON COOKIE +COPPER_BLOCK +COPPER_INGOT +COPPER_ORE CORNFLOWER COW_SPAWN_EGG +CRACKED_DEEPSLATE_BRICKS +CRACKED_DEEPSLATE_TILES CRACKED_NETHER_BRICKS CRACKED_POLISHED_BLACKSTONE_BRICKS CRACKED_STONE_BRICKS @@ -233,12 +265,17 @@ CRIMSON_TRAPDOOR CRIMSON_WALL_SIGN CROSSBOW CRYING_OBSIDIAN +CUT_COPPER +CUT_COPPER_SLAB +CUT_COPPER_STAIRS CUT_RED_SANDSTONE CUT_RED_SANDSTONE_SLAB CUT_SANDSTONE CUT_SANDSTONE_SLAB CYAN_BANNER CYAN_BED +CYAN_CANDLE +CYAN_CANDLE_CAKE CYAN_CARPET CYAN_CONCRETE CYAN_CONCRETE_POWDER @@ -294,6 +331,23 @@ DEAD_TUBE_CORAL_BLOCK DEAD_TUBE_CORAL_FAN DEAD_TUBE_CORAL_WALL_FAN DEBUG_STICK +DEEPSLATE +DEEPSLATE_BRICKS +DEEPSLATE_BRICK_SLAB +DEEPSLATE_BRICK_STAIRS +DEEPSLATE_BRICK_WALL +DEEPSLATE_COAL_ORE +DEEPSLATE_COPPER_ORE +DEEPSLATE_DIAMOND_ORE +DEEPSLATE_EMERALD_ORE +DEEPSLATE_GOLD_ORE +DEEPSLATE_IRON_ORE +DEEPSLATE_LAPIS_ORE +DEEPSLATE_REDSTONE_ORE +DEEPSLATE_TILES +DEEPSLATE_TILE_SLAB +DEEPSLATE_TILE_STAIRS +DEEPSLATE_TILE_WALL DETECTOR_RAIL DIAMOND DIAMOND_AXE @@ -313,6 +367,7 @@ DIORITE_SLAB DIORITE_STAIRS DIORITE_WALL DIRT +DIRT_PATH DISPENSER DOLPHIN_SPAWN_EGG DONKEY_SPAWN_EGG @@ -322,6 +377,7 @@ DRAGON_HEAD DRAGON_WALL_HEAD DRIED_KELP DRIED_KELP_BLOCK +DRIPSTONE_BLOCK DROPPER DROWNED_SPAWN_EGG EGG @@ -333,40 +389,46 @@ EMERALD_ORE ENCHANTED_BOOK ENCHANTED_GOLDEN_APPLE ENCHANTING_TABLE +ENDERMAN_SPAWN_EGG +ENDERMITE_SPAWN_EGG +ENDER_CHEST +ENDER_EYE +ENDER_PEARL END_CRYSTAL END_GATEWAY END_PORTAL END_PORTAL_FRAME END_ROD END_STONE +END_STONE_BRICKS END_STONE_BRICK_SLAB END_STONE_BRICK_STAIRS END_STONE_BRICK_WALL -END_STONE_BRICKS -ENDER_CHEST -ENDER_EYE -ENDER_PEARL -ENDERMAN_SPAWN_EGG -ENDERMITE_SPAWN_EGG EVOKER_SPAWN_EGG EXPERIENCE_BOTTLE +EXPOSED_COPPER +EXPOSED_CUT_COPPER +EXPOSED_CUT_COPPER_SLAB +EXPOSED_CUT_COPPER_STAIRS FARMLAND FEATHER FERMENTED_SPIDER_EYE FERN FILLED_MAP FIRE +FIREWORK_ROCKET +FIREWORK_STAR FIRE_CHARGE FIRE_CORAL FIRE_CORAL_BLOCK FIRE_CORAL_FAN FIRE_CORAL_WALL_FAN -FIREWORK_ROCKET -FIREWORK_STAR FISHING_ROD FLETCHING_TABLE FLINT FLINT_AND_STEEL +FLOWERING_AZALEA +FLOWERING_AZALEA_LEAVES FLOWER_BANNER_PATTERN FLOWER_POT FOX_SPAWN_EGG @@ -383,10 +445,12 @@ GLISTERING_MELON_SLICE GLOBE_BANNER_PATTERN GLOWSTONE GLOWSTONE_DUST -GOLD_BLOCK -GOLD_INGOT -GOLD_NUGGET -GOLD_ORE +GLOW_BERRIES +GLOW_INK_SAC +GLOW_ITEM_FRAME +GLOW_LICHEN +GLOW_SQUID_SPAWN_EGG +GOAT_SPAWN_EGG GOLDEN_APPLE GOLDEN_AXE GOLDEN_BOOTS @@ -399,16 +463,21 @@ GOLDEN_LEGGINGS GOLDEN_PICKAXE GOLDEN_SHOVEL GOLDEN_SWORD +GOLD_BLOCK +GOLD_INGOT +GOLD_NUGGET +GOLD_ORE GRANITE GRANITE_SLAB GRANITE_STAIRS GRANITE_WALL GRASS GRASS_BLOCK -GRASS_PATH GRAVEL GRAY_BANNER GRAY_BED +GRAY_CANDLE +GRAY_CANDLE_CAKE GRAY_CARPET GRAY_CONCRETE GRAY_CONCRETE_POWDER @@ -422,6 +491,8 @@ GRAY_WALL_BANNER GRAY_WOOL GREEN_BANNER GREEN_BED +GREEN_CANDLE +GREEN_CANDLE_CAKE GREEN_CARPET GREEN_CONCRETE GREEN_CONCRETE_POWDER @@ -436,14 +507,15 @@ GREEN_WOOL GRINDSTONE GUARDIAN_SPAWN_EGG GUNPOWDER +HANGING_ROOTS HAY_BLOCK HEART_OF_THE_SEA HEAVY_WEIGHTED_PRESSURE_PLATE HOGLIN_SPAWN_EGG -HONEY_BLOCK -HONEY_BOTTLE HONEYCOMB HONEYCOMB_BLOCK +HONEY_BLOCK +HONEY_BOTTLE HOPPER HOPPER_MINECART HORN_CORAL @@ -456,6 +528,7 @@ ICE INFESTED_CHISELED_STONE_BRICKS INFESTED_COBBLESTONE INFESTED_CRACKED_STONE_BRICKS +INFESTED_DEEPSLATE INFESTED_MOSSY_STONE_BRICKS INFESTED_STONE INFESTED_STONE_BRICKS @@ -505,9 +578,11 @@ LANTERN LAPIS_BLOCK LAPIS_LAZULI LAPIS_ORE +LARGE_AMETHYST_BUD LARGE_FERN LAVA LAVA_BUCKET +LAVA_CAULDRON LEAD LEATHER LEATHER_BOOTS @@ -517,8 +592,12 @@ LEATHER_HORSE_ARMOR LEATHER_LEGGINGS LECTERN LEVER +LIGHT +LIGHTNING_ROD LIGHT_BLUE_BANNER LIGHT_BLUE_BED +LIGHT_BLUE_CANDLE +LIGHT_BLUE_CANDLE_CAKE LIGHT_BLUE_CARPET LIGHT_BLUE_CONCRETE LIGHT_BLUE_CONCRETE_POWDER @@ -532,6 +611,8 @@ LIGHT_BLUE_WALL_BANNER LIGHT_BLUE_WOOL LIGHT_GRAY_BANNER LIGHT_GRAY_BED +LIGHT_GRAY_CANDLE +LIGHT_GRAY_CANDLE_CAKE LIGHT_GRAY_CARPET LIGHT_GRAY_CONCRETE LIGHT_GRAY_CONCRETE_POWDER @@ -549,6 +630,8 @@ LILY_OF_THE_VALLEY LILY_PAD LIME_BANNER LIME_BED +LIME_CANDLE +LIME_CANDLE_CAKE LIME_CARPET LIME_CONCRETE LIME_CONCRETE_POWDER @@ -566,6 +649,8 @@ LODESTONE LOOM MAGENTA_BANNER MAGENTA_BED +MAGENTA_CANDLE +MAGENTA_CANDLE_CAKE MAGENTA_CARPET MAGENTA_CONCRETE MAGENTA_CONCRETE_POWDER @@ -581,6 +666,7 @@ MAGMA_BLOCK MAGMA_CREAM MAGMA_CUBE_SPAWN_EGG MAP +MEDIUM_AMETHYST_BUD MELON MELON_SEEDS MELON_SLICE @@ -593,10 +679,12 @@ MOSSY_COBBLESTONE MOSSY_COBBLESTONE_SLAB MOSSY_COBBLESTONE_STAIRS MOSSY_COBBLESTONE_WALL +MOSSY_STONE_BRICKS MOSSY_STONE_BRICK_SLAB MOSSY_STONE_BRICK_STAIRS MOSSY_STONE_BRICK_WALL -MOSSY_STONE_BRICKS +MOSS_BLOCK +MOSS_CARPET MOVING_PISTON MULE_SPAWN_EGG MUSHROOM_STEM @@ -618,19 +706,6 @@ MUTTON MYCELIUM NAME_TAG NAUTILUS_SHELL -NETHER_BRICK -NETHER_BRICK_FENCE -NETHER_BRICK_SLAB -NETHER_BRICK_STAIRS -NETHER_BRICK_WALL -NETHER_BRICKS -NETHER_GOLD_ORE -NETHER_PORTAL -NETHER_QUARTZ_ORE -NETHER_SPROUTS -NETHER_STAR -NETHER_WART -NETHER_WART_BLOCK NETHERITE_AXE NETHERITE_BLOCK NETHERITE_BOOTS @@ -644,6 +719,19 @@ NETHERITE_SCRAP NETHERITE_SHOVEL NETHERITE_SWORD NETHERRACK +NETHER_BRICK +NETHER_BRICKS +NETHER_BRICK_FENCE +NETHER_BRICK_SLAB +NETHER_BRICK_STAIRS +NETHER_BRICK_WALL +NETHER_GOLD_ORE +NETHER_PORTAL +NETHER_QUARTZ_ORE +NETHER_SPROUTS +NETHER_STAR +NETHER_WART +NETHER_WART_BLOCK NOTE_BLOCK OAK_BOAT OAK_BUTTON @@ -666,6 +754,8 @@ OBSIDIAN OCELOT_SPAWN_EGG ORANGE_BANNER ORANGE_BED +ORANGE_CANDLE +ORANGE_CANDLE_CAKE ORANGE_CARPET ORANGE_CONCRETE ORANGE_CONCRETE_POWDER @@ -679,6 +769,10 @@ ORANGE_TULIP ORANGE_WALL_BANNER ORANGE_WOOL OXEYE_DAISY +OXIDIZED_COPPER +OXIDIZED_CUT_COPPER +OXIDIZED_CUT_COPPER_SLAB +OXIDIZED_CUT_COPPER_STAIRS PACKED_ICE PAINTING PANDA_SPAWN_EGG @@ -688,12 +782,15 @@ PEONY PETRIFIED_OAK_SLAB PHANTOM_MEMBRANE PHANTOM_SPAWN_EGG -PIG_SPAWN_EGG PIGLIN_BANNER_PATTERN +PIGLIN_BRUTE_SPAWN_EGG PIGLIN_SPAWN_EGG +PIG_SPAWN_EGG PILLAGER_SPAWN_EGG PINK_BANNER PINK_BED +PINK_CANDLE +PINK_CANDLE_CAKE PINK_CARPET PINK_CONCRETE PINK_CONCRETE_POWDER @@ -711,6 +808,7 @@ PISTON_HEAD PLAYER_HEAD PLAYER_WALL_HEAD PODZOL +POINTED_DRIPSTONE POISONOUS_POTATO POLAR_BEAR_SPAWN_EGG POLISHED_ANDESITE @@ -718,15 +816,19 @@ POLISHED_ANDESITE_SLAB POLISHED_ANDESITE_STAIRS POLISHED_BASALT POLISHED_BLACKSTONE +POLISHED_BLACKSTONE_BRICKS POLISHED_BLACKSTONE_BRICK_SLAB POLISHED_BLACKSTONE_BRICK_STAIRS POLISHED_BLACKSTONE_BRICK_WALL -POLISHED_BLACKSTONE_BRICKS POLISHED_BLACKSTONE_BUTTON POLISHED_BLACKSTONE_PRESSURE_PLATE POLISHED_BLACKSTONE_SLAB POLISHED_BLACKSTONE_STAIRS POLISHED_BLACKSTONE_WALL +POLISHED_DEEPSLATE +POLISHED_DEEPSLATE_SLAB +POLISHED_DEEPSLATE_STAIRS +POLISHED_DEEPSLATE_WALL POLISHED_DIORITE POLISHED_DIORITE_SLAB POLISHED_DIORITE_STAIRS @@ -741,6 +843,7 @@ POTATOES POTION POTTED_ACACIA_SAPLING POTTED_ALLIUM +POTTED_AZALEA_BUSH POTTED_AZURE_BLUET POTTED_BAMBOO POTTED_BIRCH_SAPLING @@ -754,6 +857,7 @@ POTTED_DANDELION POTTED_DARK_OAK_SAPLING POTTED_DEAD_BUSH POTTED_FERN +POTTED_FLOWERING_AZALEA_BUSH POTTED_JUNGLE_SAPLING POTTED_LILY_OF_THE_VALLEY POTTED_OAK_SAPLING @@ -768,11 +872,14 @@ POTTED_WARPED_FUNGUS POTTED_WARPED_ROOTS POTTED_WHITE_TULIP POTTED_WITHER_ROSE +POWDER_SNOW +POWDER_SNOW_BUCKET +POWDER_SNOW_CAULDRON POWERED_RAIL PRISMARINE +PRISMARINE_BRICKS PRISMARINE_BRICK_SLAB PRISMARINE_BRICK_STAIRS -PRISMARINE_BRICKS PRISMARINE_CRYSTALS PRISMARINE_SHARD PRISMARINE_SLAB @@ -787,6 +894,8 @@ PUMPKIN_SEEDS PUMPKIN_STEM PURPLE_BANNER PURPLE_BED +PURPLE_CANDLE +PURPLE_CANDLE_CAKE PURPLE_CARPET PURPLE_CONCRETE PURPLE_CONCRETE_POWDER @@ -815,8 +924,23 @@ RABBIT_SPAWN_EGG RABBIT_STEW RAIL RAVAGER_SPAWN_EGG +RAW_COPPER +RAW_COPPER_BLOCK +RAW_GOLD +RAW_GOLD_BLOCK +RAW_IRON +RAW_IRON_BLOCK +REDSTONE +REDSTONE_BLOCK +REDSTONE_LAMP +REDSTONE_ORE +REDSTONE_TORCH +REDSTONE_WALL_TORCH +REDSTONE_WIRE RED_BANNER RED_BED +RED_CANDLE +RED_CANDLE_CAKE RED_CARPET RED_CONCRETE RED_CONCRETE_POWDER @@ -824,10 +948,10 @@ RED_DYE RED_GLAZED_TERRACOTTA RED_MUSHROOM RED_MUSHROOM_BLOCK +RED_NETHER_BRICKS RED_NETHER_BRICK_SLAB RED_NETHER_BRICK_STAIRS RED_NETHER_BRICK_WALL -RED_NETHER_BRICKS RED_SAND RED_SANDSTONE RED_SANDSTONE_SLAB @@ -840,16 +964,10 @@ RED_TERRACOTTA RED_TULIP RED_WALL_BANNER RED_WOOL -REDSTONE -REDSTONE_BLOCK -REDSTONE_LAMP -REDSTONE_ORE -REDSTONE_TORCH -REDSTONE_WALL_TORCH -REDSTONE_WIRE REPEATER REPEATING_COMMAND_BLOCK RESPAWN_ANCHOR +ROOTED_DIRT ROSE_BUSH ROTTEN_FLESH SADDLE @@ -862,10 +980,11 @@ SANDSTONE_SLAB SANDSTONE_STAIRS SANDSTONE_WALL SCAFFOLDING +SCULK_SENSOR SCUTE +SEAGRASS SEA_LANTERN SEA_PICKLE -SEAGRASS SHEARS SHEEP_SPAWN_EGG SHIELD @@ -882,8 +1001,11 @@ SKULL_BANNER_PATTERN SLIME_BALL SLIME_BLOCK SLIME_SPAWN_EGG +SMALL_AMETHYST_BUD +SMALL_DRIPLEAF SMITHING_TABLE SMOKER +SMOOTH_BASALT SMOOTH_QUARTZ SMOOTH_QUARTZ_SLAB SMOOTH_QUARTZ_STAIRS @@ -896,8 +1018,8 @@ SMOOTH_SANDSTONE_STAIRS SMOOTH_STONE SMOOTH_STONE_SLAB SNOW -SNOW_BLOCK SNOWBALL +SNOW_BLOCK SOUL_CAMPFIRE SOUL_FIRE SOUL_LANTERN @@ -911,6 +1033,7 @@ SPIDER_EYE SPIDER_SPAWN_EGG SPLASH_POTION SPONGE +SPORE_BLOSSOM SPRUCE_BOAT SPRUCE_BUTTON SPRUCE_DOOR @@ -927,15 +1050,17 @@ SPRUCE_STAIRS SPRUCE_TRAPDOOR SPRUCE_WALL_SIGN SPRUCE_WOOD +SPYGLASS SQUID_SPAWN_EGG STICK STICKY_PISTON STONE +STONECUTTER STONE_AXE +STONE_BRICKS STONE_BRICK_SLAB STONE_BRICK_STAIRS STONE_BRICK_WALL -STONE_BRICKS STONE_BUTTON STONE_HOE STONE_PICKAXE @@ -944,7 +1069,6 @@ STONE_SHOVEL STONE_SLAB STONE_STAIRS STONE_SWORD -STONECUTTER STRAY_SPAWN_EGG STRIDER_SPAWN_EGG STRING @@ -976,6 +1100,7 @@ TALL_GRASS TALL_SEAGRASS TARGET TERRACOTTA +TINTED_GLASS TIPPED_ARROW TNT TNT_MINECART @@ -993,6 +1118,7 @@ TUBE_CORAL TUBE_CORAL_BLOCK TUBE_CORAL_FAN TUBE_CORAL_WALL_FAN +TUFF TURTLE_EGG TURTLE_HELMET TURTLE_SPAWN_EGG @@ -1025,6 +1151,27 @@ WARPED_WALL_SIGN WARPED_WART_BLOCK WATER WATER_BUCKET +WATER_CAULDRON +WAXED_COPPER_BLOCK +WAXED_CUT_COPPER +WAXED_CUT_COPPER_SLAB +WAXED_CUT_COPPER_STAIRS +WAXED_EXPOSED_COPPER +WAXED_EXPOSED_CUT_COPPER +WAXED_EXPOSED_CUT_COPPER_SLAB +WAXED_EXPOSED_CUT_COPPER_STAIRS +WAXED_OXIDIZED_COPPER +WAXED_OXIDIZED_CUT_COPPER +WAXED_OXIDIZED_CUT_COPPER_SLAB +WAXED_OXIDIZED_CUT_COPPER_STAIRS +WAXED_WEATHERED_COPPER +WAXED_WEATHERED_CUT_COPPER +WAXED_WEATHERED_CUT_COPPER_SLAB +WAXED_WEATHERED_CUT_COPPER_STAIRS +WEATHERED_COPPER +WEATHERED_CUT_COPPER +WEATHERED_CUT_COPPER_SLAB +WEATHERED_CUT_COPPER_STAIRS WEEPING_VINES WEEPING_VINES_PLANT WET_SPONGE @@ -1032,6 +1179,8 @@ WHEAT WHEAT_SEEDS WHITE_BANNER WHITE_BED +WHITE_CANDLE +WHITE_CANDLE_CAKE WHITE_CARPET WHITE_CONCRETE WHITE_CONCRETE_POWDER @@ -1059,6 +1208,8 @@ WRITABLE_BOOK WRITTEN_BOOK YELLOW_BANNER YELLOW_BED +YELLOW_CANDLE +YELLOW_CANDLE_CAKE YELLOW_CARPET YELLOW_CONCRETE YELLOW_CONCRETE_POWDER