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.
This commit is contained in:
Eric 2021-07-24 23:33:54 +02:00
parent 331c912402
commit acd447c6ec
12 changed files with 393 additions and 179 deletions

32
pom.xml
View File

@ -91,13 +91,17 @@
<id>plotsquared-repo</id>
<url>https://plotsquared.com/mvn/</url>
</repository>
<repository>
<id>inventive-repo</id>
<url>https://repo.inventivetalent.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.4-R0.1-SNAPSHOT</version>
<version>1.17.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -170,26 +174,38 @@
<systemPath>${project.basedir}/lib/PlotSquared-Bukkit-4.4.495.jar</systemPath>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<!-- Shaded dependencies -->
<dependency>
<groupId>org.codemc.worldguardwrapper</groupId>
<artifactId>worldguardwrapper</artifactId>
<version>1.1.6-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>1.7</version>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.3.1</version>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.26</version>
<version>2.0.0-alpha2</version>
</dependency>
<dependency>
<groupId>org.inventivetalent</groupId>
<artifactId>reflectionhelper</artifactId>
<version>1.18.4-SNAPSHOT</version>
</dependency>
</dependencies>
@ -219,7 +235,7 @@
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.bstats.bukkit</pattern>
<pattern>org.bstats</pattern>
<shadedPattern>de.epiceric.shopchest.dependencies.bstats</shadedPattern>
</relocation>
<relocation>
@ -234,6 +250,10 @@
<pattern>org.slf4j</pattern>
<shadedPattern>de.epiceric.shopchest.dependencies.slf4j</shadedPattern>
</relocation>
<relocation>
<pattern>org.inventivetalent.reflection</pattern>
<shadedPattern>de.epiceric.shopchest.dependencies.reflectionhelper</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>

View File

@ -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;

View File

@ -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")));

View File

@ -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();

View File

@ -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,8 +53,33 @@ 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();
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);
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);
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 {
packet = packetPlayOutEntityTeleportClass.getConstructor().newInstance();
Field[] fields = packetPlayOutEntityTeleportClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
@ -61,7 +88,6 @@ public class ArmorStandWrapper {
boolean isPre9 = Utils.getMajorVersion() < 9;
fields[0].set(packet, entityId);
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));
@ -74,6 +100,13 @@ public class ArmorStandWrapper {
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;
}
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;
}
}

View File

@ -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 {
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");

View File

@ -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) {

View File

@ -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());

View File

@ -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;
@ -12,7 +13,8 @@ public class SpawnEggMeta {
private static String getNBTEntityID(ShopChest plugin, ItemStack stack) {
try {
Class<?> craftItemStackClass = Utils.getCraftClass("inventory.CraftItemStack");
OBCClassResolver obcClassResolver = new OBCClassResolver();
Class<?> craftItemStackClass = obcClassResolver.resolveSilent("inventory.CraftItemStack");
if (craftItemStackClass == null) {
plugin.debug("Failed to get NBTEntityID: Could not find CraftItemStack class");

View File

@ -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) {

View File

@ -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);

View File

@ -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