Files
TabooLib/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java
坏黑 efeb088a70 版本更新至 4.07
修复:玩家列表排序导致其他小游戏插件报废(自己写个容器保存玩家能累死?非要用傻逼计分板?)
修复:1.8 首次发送 Json 报错问题
2018-05-31 22:16:50 +08:00

1963 lines
88 KiB
Java

package me.skymc.taboolib.nms;
import org.apache.commons.lang.StringUtils;
import org.bukkit.*;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemorySection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Vector;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.Level;
/**
* @author Unknown
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class NMSUtil19 {
protected static boolean failed = false;
protected static boolean legacy = false;
protected static String versionPrefix = "";
protected final static int NBT_TYPE_COMPOUND = 10;
protected final static int NBT_TYPE_INT_ARRAY = 11;
protected final static int NBT_TYPE_DOUBLE = 6;
protected final static int NBT_TYPE_FLOAT = 5;
protected final static int NBT_TYPE_STRING = 8;
protected static int WITHER_SKULL_TYPE = 66;
protected static int FIREWORK_TYPE = 76;
public static Class<?> class_Block;
public static Class<?> class_ItemStack;
public static Class<?> class_NBTBase;
public static Class<?> class_NBTTagCompound;
public static Class<?> class_NBTTagList;
public static Class<?> class_NBTTagByte;
public static Class<?> class_NBTTagDouble;
public static Class<?> class_NBTTagFloat;
public static Class<?> class_NBTTagInt;
public static Class<?> class_NBTTagLong;
public static Class<?> class_NBTTagShort;
public static Class<?> class_NBTTagString;
public static Class<?> class_CraftTask;
public static Class<?> class_CraftInventoryCustom;
public static Class<?> class_CraftItemStack;
public static Class<?> class_CraftBlockState;
public static Class<?> class_CraftLivingEntity;
public static Class<?> class_CraftWorld;
public static Class<?> class_Consumer;
public static Class<?> class_Entity;
public static Class<?> class_EntityCreature;
public static Class<?> class_EntityLiving;
public static Class<?> class_EntityHuman;
public static Class<?> class_DataWatcher;
public static Class<?> class_DamageSource;
public static Class<?> class_EntityDamageSource;
public static Class<?> class_World;
public static Class<?> class_WorldServer;
public static Class<?> class_Packet;
protected static Class<Enum> class_EnumSkyBlock;
public static Class<?> class_EntityPainting;
public static Class<?> class_EntityItemFrame;
public static Class<?> class_EntityMinecartRideable;
public static Class<?> class_EntityTNTPrimed;
public static Class<?> class_AxisAlignedBB;
public static Class<?> class_PathPoint;
public static Class<?> class_PathEntity;
public static Class<?> class_EntityFirework;
public static Class<?> class_CraftSkull;
public static Class<?> class_CraftBanner;
public static Class<?> class_CraftMetaSkull;
public static Class<?> class_CraftMetaBanner;
public static Class<?> class_GameProfile;
public static Class<?> class_GameProfileProperty;
public static Class<?> class_BlockPosition;
public static Class<?> class_NBTCompressedStreamTools;
public static Class<?> class_TileEntity;
public static Class<?> class_TileEntitySign;
public static Class<?> class_TileEntityContainer;
public static Class<?> class_ChestLock;
protected static Class<Enum> class_EnumDirection;
public static Class<?> class_EntityHorse;
public static Class<?> class_EntityWitherSkull;
public static Class<?> class_PacketPlayOutAttachEntity;
public static Class<?> class_PacketPlayOutEntityDestroy;
public static Class<?> class_PacketPlayOutSpawnEntity;
public static Class<?> class_PacketPlayOutSpawnEntityLiving;
public static Class<?> class_PacketPlayOutEntityMetadata;
public static Class<?> class_PacketPlayOutEntityStatus;
public static Class<?> class_PacketPlayOutCustomSoundEffect;
public static Class<?> class_PacketPlayOutExperience;
public static Class<?> class_PacketPlayOutAnimation;
public static Class<?> class_PacketPlayOutBlockBreakAnimation;
protected static Enum<?> enum_SoundCategory_PLAYERS;
protected static Class<Enum> class_EnumSoundCategory;
public static Class<?> class_EntityFallingBlock;
public static Class<?> class_EntityArmorStand;
public static Class<?> class_EntityPlayer;
public static Class<?> class_PlayerConnection;
public static Class<?> class_Chunk;
public static Class<?> class_CraftPlayer;
public static Class<?> class_CraftChunk;
public static Class<?> class_CraftEntity;
public static Class<?> class_EntityProjectile;
public static Class<?> class_EntityFireball;
public static Class<?> class_EntityArrow;
public static Class<?> class_CraftArrow;
public static Class<?> class_MinecraftServer;
public static Class<?> class_CraftServer;
public static Class<?> class_DataWatcherObject;
public static Class<?> class_PacketPlayOutChat;
protected static Class<Enum> class_ChatMessageType;
protected static Enum<?> enum_ChatMessageType_GAME_INFO;
public static Class<?> class_ChatComponentText;
public static Class<?> class_IChatBaseComponent;
protected static Method class_NBTTagList_addMethod;
protected static Method class_NBTTagList_getMethod;
protected static Method class_NBTTagList_getDoubleMethod;
protected static Method class_NBTTagList_sizeMethod;
protected static Method class_NBTTagList_removeMethod;
protected static Method class_NBTTagCompound_getKeysMethod;
protected static Method class_NBTTagCompound_setMethod;
protected static Method class_World_getEntitiesMethod;
protected static Method class_Entity_setSilentMethod;
protected static Method class_Entity_isSilentMethod;
protected static Method class_Entity_setYawPitchMethod;
protected static Method class_Entity_getBukkitEntityMethod;
protected static Method class_EntityLiving_damageEntityMethod;
protected static Method class_DamageSource_getMagicSourceMethod;
protected static Method class_EntityDamageSource_setThornsMethod;
protected static Method class_World_explodeMethod;
protected static Method class_NBTTagCompound_setBooleanMethod;
protected static Method class_NBTTagCompound_setStringMethod;
protected static Method class_NBTTagCompound_setDoubleMethod;
protected static Method class_NBTTagCompound_setLongMethod;
protected static Method class_NBTTagCompound_setIntMethod;
protected static Method class_NBTTagCompound_removeMethod;
protected static Method class_NBTTagCompound_getStringMethod;
protected static Method class_NBTTagCompound_getBooleanMethod;
protected static Method class_NBTTagCompound_getIntMethod;
protected static Method class_NBTTagCompound_getByteMethod;
protected static Method class_NBTTagCompound_getMethod;
protected static Method class_NBTTagCompound_getCompoundMethod;
protected static Method class_NBTTagCompound_getShortMethod;
protected static Method class_NBTTagCompound_getByteArrayMethod;
protected static Method class_NBTTagCompound_getListMethod;
protected static Method class_Entity_saveMethod;
protected static Method class_Entity_getTypeMethod;
protected static Method class_TileEntity_loadMethod;
protected static Method class_TileEntity_saveMethod;
protected static Method class_TileEntity_updateMethod;
protected static Method class_World_addEntityMethod;
protected static Method class_CraftMetaBanner_getPatternsMethod;
protected static Method class_CraftMetaBanner_setPatternsMethod;
protected static Method class_CraftMetaBanner_getBaseColorMethod;
protected static Method class_CraftMetaBanner_setBaseColorMethod;
protected static Method class_CraftBanner_getPatternsMethod;
protected static Method class_CraftBanner_setPatternsMethod;
protected static Method class_CraftBanner_getBaseColorMethod;
protected static Method class_CraftBanner_setBaseColorMethod;
protected static Method class_NBTCompressedStreamTools_loadFileMethod;
protected static Method class_CraftItemStack_asBukkitCopyMethod;
protected static Method class_CraftItemStack_copyMethod;
protected static Method class_CraftItemStack_mirrorMethod;
protected static Method class_NBTTagCompound_hasKeyMethod;
protected static Method class_CraftWorld_getTileEntityAtMethod;
protected static Method class_CraftWorld_createEntityMethod;
protected static Method class_CraftWorld_spawnMethod;
protected static boolean class_CraftWorld_spawnMethod_isLegacy;
protected static Method class_Entity_setLocationMethod;
protected static Method class_Entity_getIdMethod;
protected static Method class_Entity_getDataWatcherMethod;
protected static Method class_Entity_getBoundingBox;
protected static Method class_TileEntityContainer_setLock;
protected static Method class_TileEntityContainer_getLock;
protected static Method class_ChestLock_isEmpty;
protected static Method class_ChestLock_getString;
protected static Method class_ArmorStand_setInvisible;
protected static Method class_ArmorStand_setGravity;
protected static Method class_Entity_setNoGravity;
protected static Method class_CraftPlayer_getHandleMethod;
protected static Method class_CraftChunk_getHandleMethod;
protected static Method class_CraftEntity_getHandleMethod;
protected static Method class_CraftLivingEntity_getHandleMethod;
protected static Method class_CraftWorld_getHandleMethod;
protected static Method class_EntityPlayer_openSignMethod;
protected static Method class_EntityPlayer_setResourcePackMethod;
protected static Method class_CraftServer_getServerMethod;
protected static Method class_MinecraftServer_getResourcePackMethod;
protected static Method class_ItemStack_isEmptyMethod;
protected static Method class_ItemStack_createStackMethod;
protected static Method class_CraftMagicNumbers_getBlockMethod;
protected static Constructor class_CraftInventoryCustom_constructor;
protected static Constructor class_EntityFireworkConstructor;
protected static Constructor class_EntityPaintingConstructor;
protected static Constructor class_EntityItemFrameConstructor;
protected static Constructor class_BlockPosition_Constructor;
protected static Constructor class_PacketSpawnEntityConstructor;
protected static Constructor class_PacketSpawnLivingEntityConstructor;
protected static Constructor class_PacketPlayOutEntityMetadata_Constructor;
protected static Constructor class_PacketPlayOutEntityStatus_Constructor;
protected static Constructor class_PacketPlayOutEntityDestroy_Constructor;
protected static Constructor class_PacketPlayOutCustomSoundEffect_Constructor;
protected static Constructor class_PacketPlayOutExperience_Constructor;
protected static Constructor class_PacketPlayOutAnimation_Constructor;
protected static Constructor class_PacketPlayOutBlockBreakAnimation_Constructor;
protected static Constructor class_ChestLock_Constructor;
protected static Constructor class_AxisAlignedBB_Constructor;
protected static Constructor class_ItemStack_consructor;
protected static Constructor class_NBTTagString_consructor;
protected static Constructor class_NBTTagByte_constructor;
protected static Constructor class_NBTTagDouble_constructor;
protected static Constructor class_NBTTagInt_constructor;
protected static Constructor class_NBTTagFloat_constructor;
protected static Constructor class_NBTTagLong_constructor;
protected static Constructor class_PacketPlayOutChat_constructor;
protected static Constructor class_ChatComponentText_constructor;
protected static Field class_Entity_invulnerableField;
protected static Field class_Entity_motXField;
protected static Field class_Entity_motYField;
protected static Field class_Entity_motZField;
protected static Field class_WorldServer_entitiesByUUIDField;
protected static Field class_ItemStack_tagField;
protected static Field class_DamageSource_MagicField;
protected static Field class_Firework_ticksFlownField;
protected static Field class_Firework_expectedLifespanField;
protected static Field class_CraftSkull_profile;
protected static Field class_CraftMetaSkull_profile;
protected static Field class_GameProfile_properties;
protected static Field class_GameProfileProperty_value;
protected static Field class_EntityTNTPrimed_source;
protected static Field class_NBTTagList_list;
protected static Field class_AxisAlignedBB_minXField;
protected static Field class_AxisAlignedBB_minYField;
protected static Field class_AxisAlignedBB_minZField;
protected static Field class_AxisAlignedBB_maxXField;
protected static Field class_AxisAlignedBB_maxYField;
protected static Field class_AxisAlignedBB_maxZField;
protected static Field class_EntityFallingBlock_hurtEntitiesField;
protected static Field class_EntityFallingBlock_fallHurtMaxField;
protected static Field class_EntityFallingBlock_fallHurtAmountField;
protected static Field class_EntityArmorStand_disabledSlotsField;
protected static Field class_EntityPlayer_playerConnectionField;
protected static Field class_PlayerConnection_floatCountField;
protected static Field class_Chunk_doneField;
protected static Field class_CraftItemStack_getHandleField;
protected static Field class_EntityArrow_lifeField = null;
protected static Field class_EntityArrow_damageField;
protected static Field class_CraftWorld_environmentField;
protected static Field class_MemorySection_mapField;
protected static Field class_NBTTagByte_dataField;
protected static Field class_NBTTagDouble_dataField;
protected static Field class_NBTTagFloat_dataField;
protected static Field class_NBTTagInt_dataField;
protected static Field class_NBTTagLong_dataField;
protected static Field class_NBTTagShort_dataField;
protected static Field class_NBTTagString_dataField;
protected static Field class_Block_durabilityField;
protected static Field class_Entity_jumpingField;
protected static Field class_Entity_moveStrafingField;
protected static Field class_Entity_moveForwardField;
static {
// Find classes Bukkit hides from us. :-D
// Much thanks to @DPOHVAR for sharing the PowerNBT code that powers the reflection approach.
String className = Bukkit.getServer().getClass().getName();
String[] packages = StringUtils.split(className, '.');
if (packages.length == 5) {
versionPrefix = packages[3] + ".";
}
try {
class_Block = fixBukkitClass("net.minecraft.server.Block");
class_Entity = fixBukkitClass("net.minecraft.server.Entity");
class_EntityLiving = fixBukkitClass("net.minecraft.server.EntityLiving");
class_EntityHuman = fixBukkitClass("net.minecraft.server.EntityHuman");
class_ItemStack = fixBukkitClass("net.minecraft.server.ItemStack");
class_DataWatcher = fixBukkitClass("net.minecraft.server.DataWatcher");
class_DataWatcherObject = fixBukkitClass("net.minecraft.server.DataWatcherObject");
class_NBTBase = fixBukkitClass("net.minecraft.server.NBTBase");
class_NBTTagCompound = fixBukkitClass("net.minecraft.server.NBTTagCompound");
class_NBTTagList = fixBukkitClass("net.minecraft.server.NBTTagList");
class_NBTTagString = fixBukkitClass("net.minecraft.server.NBTTagString");
class_NBTTagByte = fixBukkitClass("net.minecraft.server.NBTTagByte");
class_NBTTagDouble = fixBukkitClass("net.minecraft.server.NBTTagDouble");
class_NBTTagFloat = fixBukkitClass("net.minecraft.server.NBTTagFloat");
class_NBTTagInt = fixBukkitClass("net.minecraft.server.NBTTagInt");
class_NBTTagLong = fixBukkitClass("net.minecraft.server.NBTTagLong");
class_NBTTagShort = fixBukkitClass("net.minecraft.server.NBTTagShort");
class_CraftWorld = fixBukkitClass("org.bukkit.craftbukkit.CraftWorld");
class_CraftInventoryCustom = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftInventoryCustom");
class_CraftItemStack = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftItemStack");
class_CraftBlockState = fixBukkitClass("org.bukkit.craftbukkit.block.CraftBlockState");
class_CraftTask = fixBukkitClass("org.bukkit.craftbukkit.scheduler.CraftTask");
class_CraftLivingEntity = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftLivingEntity");
class_Packet = fixBukkitClass("net.minecraft.server.Packet");
class_World = fixBukkitClass("net.minecraft.server.World");
class_WorldServer = fixBukkitClass("net.minecraft.server.WorldServer");
class_EnumSkyBlock = (Class<Enum>) fixBukkitClass("net.minecraft.server.EnumSkyBlock");
class_EnumSoundCategory = (Class<Enum>) fixBukkitClass("net.minecraft.server.SoundCategory");
enum_SoundCategory_PLAYERS = Enum.valueOf(class_EnumSoundCategory, "PLAYERS");
class_EntityPainting = fixBukkitClass("net.minecraft.server.EntityPainting");
class_EntityCreature = fixBukkitClass("net.minecraft.server.EntityCreature");
class_EntityItemFrame = fixBukkitClass("net.minecraft.server.EntityItemFrame");
class_EntityMinecartRideable = fixBukkitClass("net.minecraft.server.EntityMinecartRideable");
class_EntityTNTPrimed = fixBukkitClass("net.minecraft.server.EntityTNTPrimed");
class_AxisAlignedBB = fixBukkitClass("net.minecraft.server.AxisAlignedBB");
class_DamageSource = fixBukkitClass("net.minecraft.server.DamageSource");
class_EntityDamageSource = fixBukkitClass("net.minecraft.server.EntityDamageSource");
class_PathEntity = fixBukkitClass("net.minecraft.server.PathEntity");
class_PathPoint = fixBukkitClass("net.minecraft.server.PathPoint");
class_EntityFirework = fixBukkitClass("net.minecraft.server.EntityFireworks");
class_CraftSkull = fixBukkitClass("org.bukkit.craftbukkit.block.CraftSkull");
class_CraftMetaSkull = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftMetaSkull");
class_NBTCompressedStreamTools = fixBukkitClass("net.minecraft.server.NBTCompressedStreamTools");
class_TileEntity = fixBukkitClass("net.minecraft.server.TileEntity");
class_EntityHorse = fixBukkitClass("net.minecraft.server.EntityHorse");
class_EntityWitherSkull = fixBukkitClass("net.minecraft.server.EntityWitherSkull");
class_PacketPlayOutAttachEntity = fixBukkitClass("net.minecraft.server.PacketPlayOutAttachEntity");
class_PacketPlayOutEntityDestroy = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityDestroy");
class_PacketPlayOutSpawnEntity = fixBukkitClass("net.minecraft.server.PacketPlayOutSpawnEntity");
class_PacketPlayOutSpawnEntityLiving = fixBukkitClass("net.minecraft.server.PacketPlayOutSpawnEntityLiving");
class_PacketPlayOutEntityMetadata = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityMetadata");
class_PacketPlayOutEntityStatus = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityStatus");
class_PacketPlayOutCustomSoundEffect = fixBukkitClass("net.minecraft.server.PacketPlayOutCustomSoundEffect");
class_PacketPlayOutExperience = fixBukkitClass("net.minecraft.server.PacketPlayOutExperience");
class_PacketPlayOutAnimation = fixBukkitClass("net.minecraft.server.PacketPlayOutAnimation");
class_PacketPlayOutBlockBreakAnimation = fixBukkitClass("net.minecraft.server.PacketPlayOutBlockBreakAnimation");
class_EntityFallingBlock = fixBukkitClass("net.minecraft.server.EntityFallingBlock");
class_EntityArmorStand = fixBukkitClass("net.minecraft.server.EntityArmorStand");
class_EntityPlayer = fixBukkitClass("net.minecraft.server.EntityPlayer");
class_PlayerConnection = fixBukkitClass("net.minecraft.server.PlayerConnection");
class_Chunk = fixBukkitClass("net.minecraft.server.Chunk");
class_CraftPlayer = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftPlayer");
class_CraftChunk = fixBukkitClass("org.bukkit.craftbukkit.CraftChunk");
class_CraftEntity = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftEntity");
class_TileEntitySign = fixBukkitClass("net.minecraft.server.TileEntitySign");
class_CraftServer = fixBukkitClass("org.bukkit.craftbukkit.CraftServer");
class_MinecraftServer = fixBukkitClass("net.minecraft.server.MinecraftServer");
class_BlockPosition = fixBukkitClass("net.minecraft.server.BlockPosition");
class_EntityProjectile = NMSUtil19.getBukkitClass("net.minecraft.server.EntityProjectile");
class_EntityFireball = NMSUtil19.getBukkitClass("net.minecraft.server.EntityFireball");
class_EntityArrow = NMSUtil19.getBukkitClass("net.minecraft.server.EntityArrow");
class_CraftArrow = NMSUtil19.getBukkitClass("org.bukkit.craftbukkit.entity.CraftArrow");
class_Entity_getBukkitEntityMethod = class_Entity.getMethod("getBukkitEntity");
class_Entity_setYawPitchMethod = class_Entity.getDeclaredMethod("setYawPitch", Float.TYPE, Float.TYPE);
class_Entity_setYawPitchMethod.setAccessible(true);
class_World_explodeMethod = class_World.getMethod("createExplosion", class_Entity, Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Boolean.TYPE, Boolean.TYPE);
class_NBTTagCompound_setBooleanMethod = class_NBTTagCompound.getMethod("setBoolean", String.class, Boolean.TYPE);
class_NBTTagCompound_setStringMethod = class_NBTTagCompound.getMethod("setString", String.class, String.class);
class_NBTTagCompound_setDoubleMethod = class_NBTTagCompound.getMethod("setDouble", String.class, Double.TYPE);
class_NBTTagCompound_setLongMethod = class_NBTTagCompound.getMethod("setLong", String.class, Long.TYPE);
class_NBTTagCompound_setIntMethod = class_NBTTagCompound.getMethod("setInt", String.class, Integer.TYPE);
class_NBTTagCompound_removeMethod = class_NBTTagCompound.getMethod("remove", String.class);
class_NBTTagCompound_getStringMethod = class_NBTTagCompound.getMethod("getString", String.class);
class_NBTTagCompound_getShortMethod = class_NBTTagCompound.getMethod("getShort", String.class);
class_NBTTagCompound_getIntMethod = class_NBTTagCompound.getMethod("getInt", String.class);
class_NBTTagCompound_getBooleanMethod = class_NBTTagCompound.getMethod("getBoolean", String.class);
class_NBTTagCompound_getByteMethod = class_NBTTagCompound.getMethod("getByte", String.class);
class_NBTTagCompound_getByteArrayMethod = class_NBTTagCompound.getMethod("getByteArray", String.class);
class_NBTTagCompound_getListMethod = class_NBTTagCompound.getMethod("getList", String.class, Integer.TYPE);
class_CraftItemStack_copyMethod = class_CraftItemStack.getMethod("asNMSCopy", ItemStack.class);
class_CraftItemStack_asBukkitCopyMethod = class_CraftItemStack.getMethod("asBukkitCopy", class_ItemStack);
class_CraftItemStack_mirrorMethod = class_CraftItemStack.getMethod("asCraftMirror", class_ItemStack);
class_World_addEntityMethod = class_World.getMethod("addEntity", class_Entity, CreatureSpawnEvent.SpawnReason.class);
class_Entity_setLocationMethod = class_Entity.getMethod("setLocation", Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE);
class_Entity_getIdMethod = class_Entity.getMethod("getId");
class_Entity_getDataWatcherMethod = class_Entity.getMethod("getDataWatcher");
class_ArmorStand_setInvisible = class_EntityArmorStand.getDeclaredMethod("setInvisible", Boolean.TYPE);
class_CraftPlayer_getHandleMethod = class_CraftPlayer.getMethod("getHandle");
class_CraftChunk_getHandleMethod = class_CraftChunk.getMethod("getHandle");
class_CraftEntity_getHandleMethod = class_CraftEntity.getMethod("getHandle");
class_CraftLivingEntity_getHandleMethod = class_CraftLivingEntity.getMethod("getHandle");
class_CraftWorld_getHandleMethod = class_CraftWorld.getMethod("getHandle");
class_EntityPlayer_openSignMethod = class_EntityPlayer.getMethod("openSign", class_TileEntitySign);
class_EntityPlayer_setResourcePackMethod = class_EntityPlayer.getMethod("setResourcePack", String.class, String.class);
class_CraftServer_getServerMethod = class_CraftServer.getMethod("getServer");
class_MinecraftServer_getResourcePackMethod = class_MinecraftServer.getMethod("getResourcePack");
class_CraftInventoryCustom_constructor = class_CraftInventoryCustom.getConstructor(InventoryHolder.class, Integer.TYPE, String.class);
class_EntityFireworkConstructor = class_EntityFirework.getConstructor(class_World, Double.TYPE, Double.TYPE, Double.TYPE, class_ItemStack);
class_PacketSpawnEntityConstructor = class_PacketPlayOutSpawnEntity.getConstructor(class_Entity, Integer.TYPE);
class_PacketSpawnLivingEntityConstructor = class_PacketPlayOutSpawnEntityLiving.getConstructor(class_EntityLiving);
class_PacketPlayOutEntityMetadata_Constructor = class_PacketPlayOutEntityMetadata.getConstructor(Integer.TYPE, class_DataWatcher, Boolean.TYPE);
class_PacketPlayOutEntityStatus_Constructor = class_PacketPlayOutEntityStatus.getConstructor(class_Entity, Byte.TYPE);
class_PacketPlayOutEntityDestroy_Constructor = class_PacketPlayOutEntityDestroy.getConstructor(int[].class);
class_PacketPlayOutCustomSoundEffect_Constructor = class_PacketPlayOutCustomSoundEffect.getConstructor(String.class, class_EnumSoundCategory, Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE);
class_PacketPlayOutExperience_Constructor = class_PacketPlayOutExperience.getConstructor(Float.TYPE, Integer.TYPE, Integer.TYPE);
class_PacketPlayOutAnimation_Constructor = class_PacketPlayOutAnimation.getConstructor(class_Entity, Integer.TYPE);
class_PacketPlayOutBlockBreakAnimation_Constructor = class_PacketPlayOutBlockBreakAnimation.getConstructor(Integer.TYPE, class_BlockPosition, Integer.TYPE);
class_CraftWorld_environmentField = class_CraftWorld.getDeclaredField("environment");
class_CraftWorld_environmentField.setAccessible(true);
class_Entity_invulnerableField = class_Entity.getDeclaredField("invulnerable");
class_Entity_invulnerableField.setAccessible(true);
class_Entity_motXField = class_Entity.getDeclaredField("motX");
class_Entity_motXField.setAccessible(true);
class_Entity_motYField = class_Entity.getDeclaredField("motY");
class_Entity_motYField.setAccessible(true);
class_Entity_motZField = class_Entity.getDeclaredField("motZ");
class_Entity_motZField.setAccessible(true);
class_ItemStack_tagField = class_ItemStack.getDeclaredField("tag");
class_ItemStack_tagField.setAccessible(true);
class_EntityTNTPrimed_source = class_EntityTNTPrimed.getDeclaredField("source");
class_EntityTNTPrimed_source.setAccessible(true);
class_AxisAlignedBB_minXField = class_AxisAlignedBB.getField("a");
class_AxisAlignedBB_minYField = class_AxisAlignedBB.getField("b");
class_AxisAlignedBB_minZField = class_AxisAlignedBB.getField("c");
class_AxisAlignedBB_maxXField = class_AxisAlignedBB.getField("d");
class_AxisAlignedBB_maxYField = class_AxisAlignedBB.getField("e");
class_AxisAlignedBB_maxZField = class_AxisAlignedBB.getField("f");
class_EntityPlayer_playerConnectionField = class_EntityPlayer.getDeclaredField("playerConnection");
class_Firework_ticksFlownField = class_EntityFirework.getDeclaredField("ticksFlown");
class_Firework_ticksFlownField.setAccessible(true);
class_Firework_expectedLifespanField = class_EntityFirework.getDeclaredField("expectedLifespan");
class_Firework_expectedLifespanField.setAccessible(true);
class_NBTTagString_consructor = class_NBTTagString.getConstructor(String.class);
class_NBTTagByte_constructor = class_NBTTagByte.getConstructor(Byte.TYPE);
class_NBTTagDouble_constructor = class_NBTTagDouble.getConstructor(Double.TYPE);
class_NBTTagInt_constructor = class_NBTTagInt.getConstructor(Integer.TYPE);
class_NBTTagFloat_constructor = class_NBTTagFloat.getConstructor(Float.TYPE);
class_NBTTagLong_constructor = class_NBTTagLong.getConstructor(Long.TYPE);
class_NBTTagList_list = class_NBTTagList.getDeclaredField("list");
class_NBTTagList_list.setAccessible(true);
class_NBTTagByte_dataField = class_NBTTagByte.getDeclaredField("data");
class_NBTTagByte_dataField.setAccessible(true);
class_NBTTagDouble_dataField = class_NBTTagDouble.getDeclaredField("data");
class_NBTTagDouble_dataField.setAccessible(true);
class_NBTTagFloat_dataField = class_NBTTagFloat.getDeclaredField("data");
class_NBTTagFloat_dataField.setAccessible(true);
class_NBTTagInt_dataField = class_NBTTagInt.getDeclaredField("data");
class_NBTTagInt_dataField.setAccessible(true);
class_NBTTagLong_dataField = class_NBTTagLong.getDeclaredField("data");
class_NBTTagLong_dataField.setAccessible(true);
class_NBTTagShort_dataField = class_NBTTagShort.getDeclaredField("data");
class_NBTTagShort_dataField.setAccessible(true);
class_NBTTagString_dataField = class_NBTTagString.getDeclaredField("data");
class_NBTTagString_dataField.setAccessible(true);
class_NBTTagCompound_getKeysMethod = class_NBTTagCompound.getMethod("c");
class_NBTTagList_addMethod = class_NBTTagList.getMethod("add", class_NBTBase);
class_NBTTagList_getMethod = class_NBTTagList.getMethod("get", Integer.TYPE);
class_NBTTagList_sizeMethod = class_NBTTagList.getMethod("size");
class_NBTTagList_removeMethod = class_NBTTagList.getMethod("remove", Integer.TYPE);
class_NBTTagCompound_setMethod = class_NBTTagCompound.getMethod("set", String.class, class_NBTBase);
class_NBTTagCompound_hasKeyMethod = class_NBTTagCompound.getMethod("hasKey", String.class);
class_NBTTagCompound_getMethod = class_NBTTagCompound.getMethod("get", String.class);
class_NBTTagCompound_getCompoundMethod = class_NBTTagCompound.getMethod("getCompound", String.class);
class_EntityFallingBlock_hurtEntitiesField = class_EntityFallingBlock.getDeclaredField("hurtEntities");
class_EntityFallingBlock_hurtEntitiesField.setAccessible(true);
class_EntityFallingBlock_fallHurtAmountField = class_EntityFallingBlock.getDeclaredField("fallHurtAmount");
class_EntityFallingBlock_fallHurtAmountField.setAccessible(true);
class_EntityFallingBlock_fallHurtMaxField = class_EntityFallingBlock.getDeclaredField("fallHurtMax");
class_EntityFallingBlock_fallHurtMaxField.setAccessible(true);
class_Chunk_doneField = class_Chunk.getDeclaredField("done");
class_Chunk_doneField.setAccessible(true);
class_CraftItemStack_getHandleField = class_CraftItemStack.getDeclaredField("handle");
class_CraftItemStack_getHandleField.setAccessible(true);
class_MemorySection_mapField = MemorySection.class.getDeclaredField("map");
class_MemorySection_mapField.setAccessible(true);
class_TileEntityContainer = fixBukkitClass("net.minecraft.server.TileEntityContainer");
class_ChestLock = fixBukkitClass("net.minecraft.server.ChestLock");
class_Entity_getBoundingBox = class_Entity.getMethod("getBoundingBox");
class_GameProfile = getClass("com.mojang.authlib.GameProfile");
class_GameProfileProperty = getClass("com.mojang.authlib.properties.Property");
class_CraftSkull_profile = class_CraftSkull.getDeclaredField("profile");
class_CraftSkull_profile.setAccessible(true);
class_CraftMetaSkull_profile = class_CraftMetaSkull.getDeclaredField("profile");
class_CraftMetaSkull_profile.setAccessible(true);
class_GameProfile_properties = class_GameProfile.getDeclaredField("properties");
class_GameProfile_properties.setAccessible(true);
class_GameProfileProperty_value = class_GameProfileProperty.getDeclaredField("value");
class_GameProfileProperty_value.setAccessible(true);
class_CraftMetaBanner = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftMetaBanner");
class_CraftMetaBanner_getBaseColorMethod = class_CraftMetaBanner.getMethod("getBaseColor");
class_CraftMetaBanner_getPatternsMethod = class_CraftMetaBanner.getMethod("getPatterns");
class_CraftMetaBanner_setPatternsMethod = class_CraftMetaBanner.getMethod("setPatterns", List.class);
class_CraftMetaBanner_setBaseColorMethod = class_CraftMetaBanner.getMethod("setBaseColor", DyeColor.class);
class_CraftBanner = fixBukkitClass("org.bukkit.craftbukkit.block.CraftBanner");
class_CraftBanner_getBaseColorMethod = class_CraftBanner.getMethod("getBaseColor");
class_CraftBanner_getPatternsMethod = class_CraftBanner.getMethod("getPatterns");
class_CraftBanner_setPatternsMethod = class_CraftBanner.getMethod("setPatterns", List.class);
class_CraftBanner_setBaseColorMethod = class_CraftBanner.getMethod("setBaseColor", DyeColor.class);
class_EnumDirection = (Class<Enum>) fixBukkitClass("net.minecraft.server.EnumDirection");
class_BlockPosition_Constructor = class_BlockPosition.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE);
class_EntityPaintingConstructor = class_EntityPainting.getConstructor(class_World, class_BlockPosition, class_EnumDirection);
class_EntityItemFrameConstructor = class_EntityItemFrame.getConstructor(class_World, class_BlockPosition, class_EnumDirection);
// TODO: Server.getEntity(UUID) in 1.11+
class_WorldServer_entitiesByUUIDField = class_WorldServer.getDeclaredField("entitiesByUUID");
class_WorldServer_entitiesByUUIDField.setAccessible(true);
// TODO: World.getNearbyEntities in 1.11+
class_AxisAlignedBB_Constructor = class_AxisAlignedBB.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE);
class_World_getEntitiesMethod = class_World.getMethod("getEntities", class_Entity, class_AxisAlignedBB);
// We don't want to consider new-ish builds as "legacy" and print a warning, so keep a separate flag
boolean current = true;
// Particularly volatile methods that we can live without
try {
try {
// 1.12
class_NBTTagList_getDoubleMethod = class_NBTTagList.getMethod("f", Integer.TYPE);
if (class_NBTTagList_getDoubleMethod.getReturnType() != Double.TYPE) {
throw new Exception("Not 1.12");
}
} catch (Throwable not12) {
// 1.11 and lower
current = false;
class_NBTTagList_getDoubleMethod = class_NBTTagList.getMethod("e", Integer.TYPE);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering NBTTagList.getDouble, loading entities from schematics will not work", ex);
class_NBTTagList_getDoubleMethod = null;
}
try {
// 1.12
try {
if (!current) {
throw new Exception("Not 1.12");
}
class_Entity_jumpingField = class_EntityLiving.getDeclaredField("bd");
class_Entity_jumpingField.setAccessible(true);
class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("be");
class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("bg");
} catch (Throwable not12) {
// 1.11
current = false;
try {
class_Entity_jumpingField = class_EntityLiving.getDeclaredField("bd");
class_Entity_jumpingField.setAccessible(true);
class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("be");
class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("bf");
} catch (Throwable not11) {
// 1.10
try {
class_Entity_jumpingField = class_EntityLiving.getDeclaredField("be");
class_Entity_jumpingField.setAccessible(true);
class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("bf");
class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("bg");
} catch (Throwable not10) {
class_Entity_jumpingField = class_EntityLiving.getDeclaredField("bc");
class_Entity_jumpingField.setAccessible(true);
class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("bd");
class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("be");
}
}
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering entity movement accessors, vehicle control will not work", ex);
class_Entity_jumpingField = null;
class_Entity_moveStrafingField = null;
class_Entity_moveForwardField = null;
}
try {
class_Block_durabilityField = class_Block.getDeclaredField("durability");
class_Block_durabilityField.setAccessible(true);
Class<?> craftMagicNumbers = fixBukkitClass("org.bukkit.craftbukkit.util.CraftMagicNumbers");
class_CraftMagicNumbers_getBlockMethod = craftMagicNumbers.getMethod("getBlock", Material.class);
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering block durability accessor, durability-based block checks will not work", ex);
class_Block_durabilityField = null;
class_CraftMagicNumbers_getBlockMethod = null;
}
try {
// 1.12
try {
// Common to 1.12 and below
class_PacketPlayOutChat = fixBukkitClass("net.minecraft.server.PacketPlayOutChat");
class_ChatComponentText = fixBukkitClass("net.minecraft.server.ChatComponentText");
class_IChatBaseComponent = fixBukkitClass("net.minecraft.server.IChatBaseComponent");
class_ChatComponentText_constructor = class_ChatComponentText.getConstructor(String.class);
// 1.12 specific
class_ChatMessageType = (Class<Enum>) fixBukkitClass("net.minecraft.server.ChatMessageType");
enum_ChatMessageType_GAME_INFO = Enum.valueOf(class_ChatMessageType, "GAME_INFO");
class_PacketPlayOutChat_constructor = class_PacketPlayOutChat.getConstructor(class_IChatBaseComponent, class_ChatMessageType);
} catch (Throwable ex) {
// 1.11 fallback
current = false;
class_PacketPlayOutChat_constructor = class_PacketPlayOutChat.getConstructor(class_IChatBaseComponent, Byte.TYPE);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering action bar methods, action bar messages will not work", ex);
class_PacketPlayOutChat = null;
}
try {
try {
// 1.11
class_CraftWorld_createEntityMethod = class_CraftWorld.getMethod("createEntity", Location.class, Class.class);
class_Consumer = fixBukkitClass("org.bukkit.util.Consumer");
class_CraftWorld_spawnMethod = class_CraftWorld.getMethod("spawn", Location.class, Class.class, class_Consumer, CreatureSpawnEvent.SpawnReason.class);
class_CraftWorld_spawnMethod_isLegacy = false;
} catch (Throwable ignore) {
legacy = true;
class_CraftWorld_spawnMethod_isLegacy = true;
class_CraftWorld_spawnMethod = class_CraftWorld.getMethod("spawn", Location.class, Class.class, CreatureSpawnEvent.SpawnReason.class);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering custom spawn method, spawn reasons will not work", ex);
class_CraftWorld_spawnMethod = null;
class_Consumer = null;
}
try {
class_CraftWorld_getTileEntityAtMethod = class_CraftWorld.getMethod("getTileEntityAt", Integer.TYPE, Integer.TYPE, Integer.TYPE);
class_TileEntity_loadMethod = class_TileEntity.getMethod("a", class_NBTTagCompound);
class_TileEntity_updateMethod = class_TileEntity.getMethod("update");
class_TileEntity_saveMethod = class_TileEntity.getMethod("save", class_NBTTagCompound);
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, handling of tile entities may not work well", ex);
class_TileEntity_loadMethod = null;
class_TileEntity_updateMethod = null;
class_TileEntity_saveMethod = null;
}
try {
class_NBTCompressedStreamTools_loadFileMethod = class_NBTCompressedStreamTools.getMethod("a", InputStream.class);
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, schematics will not load", ex);
}
try {
class_EntityLiving_damageEntityMethod = class_EntityLiving.getMethod("damageEntity", class_DamageSource, Float.TYPE);
class_DamageSource_getMagicSourceMethod = class_DamageSource.getMethod("b", class_Entity, class_Entity);
class_DamageSource_MagicField = class_DamageSource.getField("MAGIC");
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, magic damage will not work, using normal damage instead", ex);
class_EntityLiving_damageEntityMethod = null;
class_DamageSource_getMagicSourceMethod = null;
class_DamageSource_MagicField = null;
}
try {
try {
// 1.12, same as 1.10
class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bB");
if (class_EntityArmorStand_disabledSlotsField.getType() != Integer.TYPE) {
throw new Exception("Looks like 1.11, maybe");
}
} catch (Throwable not12) {
try {
// 1.11
class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bA");
if (class_EntityArmorStand_disabledSlotsField.getType() != Integer.TYPE) {
throw new Exception("Looks like 1.10");
}
} catch (Throwable ignore) {
// 1.10 and earlier
legacy = true;
try {
class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bB");
if (class_EntityArmorStand_disabledSlotsField.getType() != Integer.TYPE) {
throw new Exception("Looks like 1.9");
}
} catch (Throwable ignore2) {
try {
// 1.9.4
class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bA");
} catch (Throwable ignore3) {
// 1.9.2
class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bz");
}
}
}
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, armor stand slots cannot be locked", ex);
class_EntityArmorStand_disabledSlotsField = null;
}
if (class_EntityArmorStand_disabledSlotsField != null) {
class_EntityArmorStand_disabledSlotsField.setAccessible(true);
}
// TODO: Lockable API in 1.11+
try {
try {
// Common
class_ChestLock_Constructor = class_ChestLock.getConstructor(String.class);
class_ChestLock_isEmpty = class_ChestLock.getMethod("a");
class_TileEntityContainer_getLock = class_TileEntityContainer.getMethod("getLock");
// 1.12 only
class_ChestLock_getString = class_ChestLock.getMethod("getKey");
class_TileEntityContainer_setLock = class_TileEntityContainer.getMethod("setLock", class_ChestLock);
} catch (Throwable not12) {
try {
// 1.11
class_ChestLock_getString = class_ChestLock.getMethod("b");
class_TileEntityContainer_setLock = class_TileEntityContainer.getMethod("a", class_ChestLock);
} catch (Throwable ignore) {
// 1.10 and earlier
legacy = true;
class_TileEntityContainer_setLock = class_TileEntityContainer.getMethod("a", class_ChestLock);
class_TileEntityContainer_getLock = class_TileEntityContainer.getMethod("y_");
}
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, chest locking and unlocking will not work", ex);
class_TileEntityContainer_setLock = null;
class_TileEntityContainer_getLock = null;
}
try {
try {
// 1.10 and 1.11
class_PlayerConnection_floatCountField = class_PlayerConnection.getDeclaredField("C");
if (class_PlayerConnection_floatCountField.getType() != Integer.TYPE) {
throw new Exception("Looks like 1.9");
}
class_PlayerConnection_floatCountField.setAccessible(true);
} catch (Throwable ignore) {
// 1.9 and earlier
legacy = true;
class_PlayerConnection_floatCountField = class_PlayerConnection.getDeclaredField("g");
class_PlayerConnection_floatCountField.setAccessible(true);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, player flight exemption will not work", ex);
class_PlayerConnection_floatCountField = null;
}
try {
try {
// 1.11
class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ax");
} catch (Throwable ignore5) {
try {
// 1.10
class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ay"); // ayyyyy lmao
} catch (Throwable ignore4) {
legacy = true;
// 1.8.3
class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ar");
}
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, setting arrow lifespan will not work", ex);
class_EntityArrow_lifeField = null;
}
if (class_EntityArrow_lifeField != null) {
class_EntityArrow_lifeField.setAccessible(true);
}
try {
// 1.9 and up
class_EntityDamageSource_setThornsMethod = class_EntityDamageSource.getMethod("w");
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, thorn damage override to hurt ender dragon will not work", ex);
class_EntityDamageSource_setThornsMethod = null;
}
try {
try {
// 1.12
class_Entity_getTypeMethod = class_Entity.getDeclaredMethod("getSaveID");
class_Entity_saveMethod = class_Entity.getMethod("save", class_NBTTagCompound);
} catch (Throwable not12) {
try {
// 1.10 and 1.11
class_Entity_getTypeMethod = class_Entity.getDeclaredMethod("at");
} catch (Throwable ignore) {
// 1.9 and earlier
legacy = true;
class_Entity_getTypeMethod = class_Entity.getDeclaredMethod("as");
}
class_Entity_saveMethod = class_Entity.getMethod("e", class_NBTTagCompound);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, saving entities to spawn eggs will not work", ex);
class_Entity_getTypeMethod = null;
class_Entity_saveMethod = null;
}
if (class_Entity_getTypeMethod != null) {
class_Entity_getTypeMethod.setAccessible(true);
}
try {
try {
// 1.11
class_ItemStack_consructor = class_ItemStack.getConstructor(class_NBTTagCompound);
} catch (Throwable ignore) {
// 1.10 and earlier
legacy = true;
class_ItemStack_createStackMethod = class_ItemStack.getMethod("createStack", class_NBTTagCompound);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, restoring inventories from schematics will not work", ex);
class_ItemStack_createStackMethod = null;
}
try {
class_EntityArrow_damageField = class_EntityArrow.getDeclaredField("damage");
class_EntityArrow_damageField.setAccessible(true);
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, setting arrow damage will not work", ex);
class_EntityArrow_damageField = null;
}
// TODO: setSilent API in 1.11+
try {
try {
// 1.10 and 1.11
class_Entity_setSilentMethod = class_Entity.getDeclaredMethod("setSilent", Boolean.TYPE);
class_Entity_isSilentMethod = class_Entity.getDeclaredMethod("isSilent");
} catch (Throwable ignore) {
// 1.9 and earlier
legacy = true;
class_Entity_setSilentMethod = class_Entity.getDeclaredMethod("c", Boolean.TYPE);
class_Entity_isSilentMethod = class_Entity.getDeclaredMethod("ad");
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, silent entities will not work", ex);
class_Entity_setSilentMethod = null;
class_Entity_isSilentMethod = null;
}
// TODO: ArmorStand.setGravity in 1.11+
// Different behavior, but less hacky.
try {
try {
// 1.10 and 1.11
class_Entity_setNoGravity = class_Entity.getDeclaredMethod("setNoGravity", Boolean.TYPE);
} catch (Throwable ignore) {
// 1.9 and earlier
legacy = true;
class_ArmorStand_setGravity = class_EntityArmorStand.getDeclaredMethod("setGravity", Boolean.TYPE);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, hacky no-gravity armor stands won't work", ex);
class_Entity_setNoGravity = null;
class_ArmorStand_setGravity = null;
}
// TODO ItemStack.isEmpty in 1.11+
try {
// 1.11
class_ItemStack_isEmptyMethod = class_ItemStack.getMethod("isEmpty");
} catch (Throwable ignore) {
// 1.10 and earlier
legacy = true;
}
} catch (Throwable ex) {
failed = true;
Bukkit.getLogger().log(Level.SEVERE, "An unexpected error occurred initializing Magic", ex);
}
}
public static boolean getFailed() {
return failed;
}
public static boolean isLegacy() {
return legacy;
}
public static Class<?> getVersionedBukkitClass(String newVersion, String oldVersion) {
Class<?> c = getBukkitClass(newVersion);
if (c == null) {
c = getBukkitClass(oldVersion);
if (c == null) {
Bukkit.getLogger().warning("Could not bind to " + newVersion + " or " + oldVersion);
}
}
return c;
}
public static Class<?> getClass(String className) {
Class<?> result = null;
try {
result = NMSUtils.class.getClassLoader().loadClass(className);
} catch (Exception ex) {
result = null;
}
return result;
}
public static Class<?> getBukkitClass(String className) {
Class<?> result = null;
try {
result = fixBukkitClass(className);
} catch (Exception ex) {
result = null;
}
return result;
}
public static Class<?> fixBukkitClass(String className) {
if (!versionPrefix.isEmpty()) {
className = className.replace("org.bukkit.craftbukkit.", "org.bukkit.craftbukkit." + versionPrefix);
className = className.replace("net.minecraft.server.", "net.minecraft.server." + versionPrefix);
}
try {
return NMSUtils.class.getClassLoader().loadClass(className);
} catch (ClassNotFoundException ignored) {
}
}
public static Object getHandle(Server server) {
Object handle = null;
try {
handle = class_CraftServer_getServerMethod.invoke(server);
} catch (Throwable ex) {
handle = null;
}
return handle;
}
public static Object getHandle(ItemStack stack) {
Object handle = null;
try {
handle = class_CraftItemStack_getHandleField.get(stack);
} catch (Throwable ex) {
handle = null;
}
return handle;
}
public static Object getHandle(World world) {
if (world == null) {
return null;
}
Object handle = null;
try {
handle = class_CraftWorld_getHandleMethod.invoke(world);
} catch (Throwable ex) {
ex.printStackTrace();
}
return handle;
}
public static Object getHandle(Entity entity) {
if (entity == null) {
return null;
}
Object handle = null;
try {
handle = class_CraftEntity_getHandleMethod.invoke(entity);
} catch (Throwable ex) {
ex.printStackTrace();
}
return handle;
}
public static Object getHandle(org.bukkit.entity.LivingEntity entity) {
if (entity == null) {
return null;
}
Object handle = null;
try {
handle = class_CraftLivingEntity_getHandleMethod.invoke(entity);
} catch (Throwable ex) {
ex.printStackTrace();
}
return handle;
}
public static boolean isDone(Chunk chunk) {
Object chunkHandle = getHandle(chunk);
boolean done = false;
try {
done = (Boolean) class_Chunk_doneField.get(chunkHandle);
} catch (Throwable ex) {
ex.printStackTrace();
}
return done;
}
public static Object getHandle(Chunk chunk) {
Object handle = null;
try {
handle = class_CraftChunk_getHandleMethod.invoke(chunk);
} catch (Throwable ex) {
ex.printStackTrace();
}
return handle;
}
public static Object getHandle(Player player) {
Object handle = null;
try {
handle = class_CraftPlayer_getHandleMethod.invoke(player);
} catch (Throwable ex) {
ex.printStackTrace();
}
return handle;
}
protected static void sendPacket(Server server, Location source, Collection<? extends Player> players, Object packet) throws Exception {
players = ((players != null && players.size() > 0) ? players : server.getOnlinePlayers());
int viewDistance = Bukkit.getServer().getViewDistance() * 16;
int viewDistanceSquared = viewDistance * viewDistance;
World sourceWorld = source.getWorld();
for (Player player : players) {
Location location = player.getLocation();
if (!location.getWorld().equals(sourceWorld)) {
continue;
}
if (location.distanceSquared(source) <= viewDistanceSquared) {
sendPacket(player, packet);
}
}
}
protected static void sendPacket(Player player, Object packet) throws Exception {
Object playerHandle = getHandle(player);
Field connectionField = playerHandle.getClass().getField("playerConnection");
Object connection = connectionField.get(playerHandle);
Method sendPacketMethod = connection.getClass().getMethod("sendPacket", class_Packet);
sendPacketMethod.invoke(connection, packet);
}
public static int getFacing(BlockFace direction) {
int dir;
switch (direction) {
case SOUTH:
default:
dir = 0;
break;
case WEST:
dir = 1;
break;
case NORTH:
dir = 2;
break;
case EAST:
dir = 3;
break;
}
return dir;
}
public static Entity getBukkitEntity(Object entity) {
if (entity == null) {
return null;
}
try {
Method getMethod = entity.getClass().getMethod("getBukkitEntity");
Object bukkitEntity = getMethod.invoke(entity);
if (!(bukkitEntity instanceof Entity)) {
return null;
}
return (Entity) bukkitEntity;
} catch (Throwable ex) {
ex.printStackTrace();
}
return null;
}
public static Object getTag(Object mcItemStack) {
Object tag = null;
try {
tag = class_ItemStack_tagField.get(mcItemStack);
} catch (Throwable ex) {
ex.printStackTrace();
}
return tag;
}
public static Object getNMSCopy(ItemStack stack) {
Object nms = null;
try {
nms = class_CraftItemStack_copyMethod.invoke(null, stack);
} catch (Throwable ex) {
ex.printStackTrace();
}
return nms;
}
public static ItemStack getCopy(ItemStack stack) {
if (stack == null) {
return null;
}
try {
Object craft = getNMSCopy(stack);
stack = (ItemStack) class_CraftItemStack_mirrorMethod.invoke(null, craft);
} catch (Throwable ex) {
stack = null;
}
return stack;
}
public static ItemStack makeReal(ItemStack stack) {
if (stack == null) {
return null;
}
Object nmsStack = getHandle(stack);
if (nmsStack == null) {
stack = getCopy(stack);
nmsStack = getHandle(stack);
}
if (nmsStack == null) {
return null;
}
try {
Object tag = class_ItemStack_tagField.get(nmsStack);
if (tag == null) {
class_ItemStack_tagField.set(nmsStack, class_NBTTagCompound.newInstance());
}
} catch (Throwable ex) {
ex.printStackTrace();
return null;
}
return stack;
}
public static String getMetaString(ItemStack stack, String tag, String defaultValue) {
String result = getMetaString(stack, tag);
return result == null ? defaultValue : result;
}
public static boolean hasMeta(ItemStack stack, String tag) {
return !NMSUtil19.isEmpty(stack) && getNode(stack, tag) != null;
}
public static Object getTag(ItemStack itemStack) {
Object tag = null;
try {
Object mcItemStack = getHandle(itemStack);
if (mcItemStack == null) {
return null;
}
tag = class_ItemStack_tagField.get(mcItemStack);
} catch (Throwable ex) {
ex.printStackTrace();
}
return tag;
}
public static Object getNode(ItemStack stack, String tag) {
if (NMSUtil19.isEmpty(stack)) {
return null;
}
Object meta = null;
try {
Object craft = getHandle(stack);
if (craft == null) {
return null;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return null;
}
meta = class_NBTTagCompound_getMethod.invoke(tagObject, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static boolean containsNode(Object nbtBase, String tag) {
if (nbtBase == null) {
return false;
}
Boolean result = false;
try {
result = (Boolean) class_NBTTagCompound_hasKeyMethod.invoke(nbtBase, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return result;
}
public static Object getNode(Object nbtBase, String tag) {
if (nbtBase == null) {
return null;
}
Object meta = null;
try {
meta = class_NBTTagCompound_getMethod.invoke(nbtBase, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static Object createNode(Object nbtBase, String tag) {
if (nbtBase == null) {
return null;
}
Object meta = null;
try {
meta = class_NBTTagCompound_getCompoundMethod.invoke(nbtBase, tag);
class_NBTTagCompound_setMethod.invoke(nbtBase, tag, meta);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static Object createNode(ItemStack stack, String tag) {
if (NMSUtil19.isEmpty(stack)) {
return null;
}
Object outputObject = getNode(stack, tag);
if (outputObject == null) {
try {
Object craft = getHandle(stack);
if (craft == null) {
return null;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
tagObject = class_NBTTagCompound.newInstance();
class_ItemStack_tagField.set(craft, tagObject);
}
outputObject = class_NBTTagCompound.newInstance();
class_NBTTagCompound_setMethod.invoke(tagObject, tag, outputObject);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
return outputObject;
}
public static String getMetaString(Object node, String tag, String defaultValue) {
String meta = getMetaString(node, tag);
return meta == null || meta.length() == 0 ? defaultValue : meta;
}
public static String getMetaString(Object node, String tag) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return null;
}
String meta = null;
try {
meta = (String) class_NBTTagCompound_getStringMethod.invoke(node, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static String getMeta(Object node, String tag) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return null;
}
String meta = null;
try {
meta = (String) class_NBTTagCompound_getStringMethod.invoke(node, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static Byte getMetaByte(Object node, String tag) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return null;
}
Byte meta = null;
try {
meta = (Byte) class_NBTTagCompound_getByteMethod.invoke(node, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static Integer getMetaInt(Object node, String tag) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return null;
}
Integer meta = null;
try {
meta = (Integer) class_NBTTagCompound_getIntMethod.invoke(node, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static Boolean getMetaBoolean(Object node, String tag) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return null;
}
Boolean meta = null;
try {
meta = (Boolean) class_NBTTagCompound_getBooleanMethod.invoke(node, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static void setMeta(Object node, String tag, String value) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return;
}
try {
if (value == null || value.length() == 0) {
class_NBTTagCompound_removeMethod.invoke(node, tag);
} else {
class_NBTTagCompound_setStringMethod.invoke(node, tag, value);
}
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void setMetaLong(Object node, String tag, long value) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return;
}
try {
class_NBTTagCompound_setLongMethod.invoke(node, tag, value);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void setMetaBoolean(Object node, String tag, boolean value) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return;
}
try {
class_NBTTagCompound_setBooleanMethod.invoke(node, tag, value);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void setMetaDouble(Object node, String tag, double value) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return;
}
try {
class_NBTTagCompound_setDoubleMethod.invoke(node, tag, value);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void setMetaInt(Object node, String tag, int value) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return;
}
try {
class_NBTTagCompound_setIntMethod.invoke(node, tag, value);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void removeMeta(Object node, String tag) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return;
}
try {
class_NBTTagCompound_removeMethod.invoke(node, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void removeMeta(ItemStack stack, String tag) {
if (NMSUtil19.isEmpty(stack)) {
return;
}
try {
Object craft = getHandle(stack);
if (craft == null) {
return;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return;
}
removeMeta(tagObject, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void setMetaNode(Object node, String tag, Object child) {
if (node == null || !class_NBTTagCompound.isInstance(node)) {
return;
}
try {
if (child == null) {
class_NBTTagCompound_removeMethod.invoke(node, tag);
} else {
class_NBTTagCompound_setMethod.invoke(node, tag, child);
}
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static boolean setMetaNode(ItemStack stack, String tag, Object child) {
if (NMSUtil19.isEmpty(stack)) {
return false;
}
try {
Object craft = getHandle(stack);
if (craft == null) {
return false;
}
Object node = getTag(craft);
if (node == null) {
return false;
}
if (child == null) {
class_NBTTagCompound_removeMethod.invoke(node, tag);
} else {
class_NBTTagCompound_setMethod.invoke(node, tag, child);
}
} catch (Throwable ex) {
ex.printStackTrace();
return false;
}
return true;
}
public static String getMetaString(ItemStack stack, String tag) {
if (NMSUtil19.isEmpty(stack)) {
return null;
}
String meta = null;
try {
Object craft = getHandle(stack);
if (craft == null) {
return null;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return null;
}
meta = (String) class_NBTTagCompound_getStringMethod.invoke(tagObject, tag);
} catch (Throwable ex) {
ex.printStackTrace();
}
return meta;
}
public static void setMeta(ItemStack stack, String tag, String value) {
if (NMSUtil19.isEmpty(stack)) {
return;
}
try {
Object craft = getHandle(stack);
if (craft == null) {
return;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return;
}
class_NBTTagCompound_setStringMethod.invoke(tagObject, tag, value);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static void setMetaBoolean(ItemStack stack, String tag, boolean value) {
if (NMSUtil19.isEmpty(stack)) {
return;
}
try {
Object craft = getHandle(stack);
if (craft == null) {
return;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return;
}
setMetaBoolean(tagObject, tag, value);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
public static boolean getMetaBoolean(ItemStack stack, String tag, boolean defaultValue) {
if (NMSUtil19.isEmpty(stack)) {
return defaultValue;
}
boolean result = defaultValue;
try {
Object craft = getHandle(stack);
if (craft == null) {
return defaultValue;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return defaultValue;
}
Boolean value = getMetaBoolean(tagObject, tag);
result = value == null ? defaultValue : value;
} catch (Throwable ex) {
ex.printStackTrace();
}
return result;
}
public static void addGlow(ItemStack stack) {
if (NMSUtil19.isEmpty(stack)) {
return;
}
ItemMeta meta = stack.getItemMeta();
meta.addEnchant(Enchantment.LUCK, 1, true);
stack.setItemMeta(meta);
}
public static void removeGlow(ItemStack stack) {
if (NMSUtil19.isEmpty(stack)) {
return;
}
ItemMeta meta = stack.getItemMeta();
if (meta.hasEnchant(Enchantment.LUCK)) {
meta.removeEnchant(Enchantment.LUCK);
stack.setItemMeta(meta);
}
}
public static boolean isUnbreakable(ItemStack stack) {
if (NMSUtil19.isEmpty(stack)) {
return false;
}
Boolean unbreakableFlag = null;
try {
Object craft = getHandle(stack);
if (craft == null) {
return false;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return false;
}
unbreakableFlag = getMetaBoolean(tagObject, "Unbreakable");
} catch (Throwable ignored) {
}
return unbreakableFlag != null && unbreakableFlag;
}
public static void makeUnbreakable(ItemStack stack) {
if (NMSUtil19.isEmpty(stack)) {
return;
}
try {
Object craft = getHandle(stack);
if (craft == null) {
return;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return;
}
Object unbreakableFlag = null;
unbreakableFlag = class_NBTTagByte_constructor.newInstance((byte) 1);
class_NBTTagCompound_setMethod.invoke(tagObject, "Unbreakable", unbreakableFlag);
} catch (Throwable ignored) {
}
}
public static void removeUnbreakable(ItemStack stack) {
removeMeta(stack, "Unbreakable");
}
public static void hideFlags(ItemStack stack, byte flags) {
if (NMSUtil19.isEmpty(stack)) {
return;
}
try {
Object craft = getHandle(stack);
if (craft == null) {
return;
}
Object tagObject = getTag(craft);
if (tagObject == null) {
return;
}
Object hideFlag = null;
hideFlag = class_NBTTagByte_constructor.newInstance(flags);
class_NBTTagCompound_setMethod.invoke(tagObject, "HideFlags", hideFlag);
} catch (Throwable ignored) {
}
}
public static boolean createExplosion(Entity entity, World world, double x, double y, double z, float power, boolean setFire, boolean breakBlocks) {
boolean result = false;
if (world == null) {
return false;
}
try {
Object worldHandle = getHandle(world);
if (worldHandle == null) {
return false;
}
Object entityHandle = entity == null ? null : getHandle(entity);
Object explosion = class_World_explodeMethod.invoke(worldHandle, entityHandle, x, y, z, power, setFire, breakBlocks);
Field cancelledField = explosion.getClass().getDeclaredField("wasCanceled");
result = (Boolean) cancelledField.get(explosion);
} catch (Throwable ex) {
ex.printStackTrace();
result = false;
}
return result;
}
public static void makeTemporary(ItemStack itemStack, String message) {
setMeta(itemStack, "temporary", message);
}
public static boolean isTemporary(ItemStack itemStack) {
return hasMeta(itemStack, "temporary");
}
public static void makeUnplaceable(ItemStack itemStack) {
setMeta(itemStack, "unplaceable", "true");
}
public static void removeUnplaceable(ItemStack itemStack) {
removeMeta(itemStack, "unplaceable");
}
public static boolean isUnplaceable(ItemStack itemStack) {
return hasMeta(itemStack, "unplaceable");
}
public static String getTemporaryMessage(ItemStack itemStack) {
return getMetaString(itemStack, "temporary");
}
public static void setReplacement(ItemStack itemStack, ItemStack replacement) {
YamlConfiguration configuration = new YamlConfiguration();
configuration.set("item", replacement);
setMeta(itemStack, "replacement", configuration.saveToString());
}
public static ItemStack getReplacement(ItemStack itemStack) {
String serialized = getMetaString(itemStack, "replacement");
if (serialized == null || serialized.isEmpty()) {
return null;
}
YamlConfiguration configuration = new YamlConfiguration();
ItemStack replacement = null;
try {
configuration.loadFromString(serialized);
replacement = configuration.getItemStack("item");
} catch (Exception ex) {
ex.printStackTrace();
}
return replacement;
}
protected static Object getTagString(String value) {
try {
return class_NBTTagString_consructor.newInstance(value);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Object setStringList(Object nbtBase, String tag, Collection<String> values) {
if (nbtBase == null) {
return null;
}
Object listMeta = null;
try {
listMeta = class_NBTTagList.newInstance();
for (String value : values) {
Object nbtString = getTagString(value);
class_NBTTagList_addMethod.invoke(listMeta, nbtString);
}
class_NBTTagCompound_setMethod.invoke(nbtBase, tag, listMeta);
} catch (Throwable ex) {
ex.printStackTrace();
return null;
}
return listMeta;
}
public static ItemStack getItem(Object itemTag) {
if (itemTag == null) {
return null;
}
ItemStack item = null;
try {
Object nmsStack = null;
if (class_ItemStack_consructor != null) {
nmsStack = class_ItemStack_consructor.newInstance(itemTag);
} else {
nmsStack = class_ItemStack_createStackMethod.invoke(null, itemTag);
}
item = (ItemStack) class_CraftItemStack_mirrorMethod.invoke(null, nmsStack);
} catch (Exception ex) {
ex.printStackTrace();
}
return item;
}
public static ItemStack[] getItems(Object rootTag, String tagName) {
try {
Object itemList = class_NBTTagCompound_getListMethod.invoke(rootTag, tagName, NBT_TYPE_COMPOUND);
Integer size = (Integer) class_NBTTagList_sizeMethod.invoke(itemList);
ItemStack[] items = new ItemStack[size];
for (int i = 0; i < size; i++) {
try {
Object itemData = class_NBTTagList_getMethod.invoke(itemList, i);
if (itemData != null) {
items[i] = getItem(itemData);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
return items;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Object getTileEntityData(Location location) {
if (class_CraftWorld_getTileEntityAtMethod == null || class_TileEntity_saveMethod == null) {
return null;
}
Object data = null;
try {
World world = location.getWorld();
Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ());
if (tileEntity != null) {
data = class_NBTTagCompound.newInstance();
class_TileEntity_saveMethod.invoke(tileEntity, data);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return data;
}
public static Object getTileEntity(Location location) {
if (class_CraftWorld_getTileEntityAtMethod == null) {
return null;
}
Object tileEntity = null;
try {
World world = location.getWorld();
tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ());
} catch (Exception ex) {
ex.printStackTrace();
}
return tileEntity;
}
public static void clearItems(Location location) {
if (class_TileEntity_loadMethod == null || class_TileEntity_updateMethod == null || class_CraftWorld_getTileEntityAtMethod == null || class_TileEntity_saveMethod == null) {
return;
}
if (location == null) {
return;
}
try {
World world = location.getWorld();
if (world == null) {
return;
}
Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ());
if (tileEntity != null) {
Object entityData = class_NBTTagCompound.newInstance();
class_TileEntity_saveMethod.invoke(tileEntity, entityData);
Object itemList = class_NBTTagCompound_getListMethod.invoke(entityData, "Items", NBT_TYPE_COMPOUND);
if (itemList != null) {
List items = (List) class_NBTTagList_list.get(itemList);
items.clear();
}
class_NBTTagCompound_removeMethod.invoke(entityData, "Item");
class_TileEntity_loadMethod.invoke(tileEntity, entityData);
class_TileEntity_updateMethod.invoke(tileEntity);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void setTileEntityData(Location location, Object data) {
if (class_TileEntity_loadMethod == null || class_TileEntity_updateMethod == null || class_CraftWorld_getTileEntityAtMethod == null) {
return;
}
if (location == null || data == null) {
return;
}
try {
World world = location.getWorld();
if (world == null) {
return;
}
Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ());
if (tileEntity == null) {
return;
}
class_NBTTagCompound_setIntMethod.invoke(data, "x", location.getBlockX());
class_NBTTagCompound_setIntMethod.invoke(data, "y", location.getBlockY());
class_NBTTagCompound_setIntMethod.invoke(data, "z", location.getBlockZ());
class_TileEntity_loadMethod.invoke(tileEntity, data);
class_TileEntity_updateMethod.invoke(tileEntity);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Vector getPosition(Object entityData, String tag) {
if (class_NBTTagList_getDoubleMethod == null) {
return null;
}
try {
Object posList = class_NBTTagCompound_getListMethod.invoke(entityData, tag, NBT_TYPE_DOUBLE);
Double x = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 0);
Double y = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 1);
Double z = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 2);
if (x != null && y != null && z != null) {
return new Vector(x, y, z);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Entity getEntity(World world, UUID uuid) {
try {
Object worldHandle = getHandle(world);
final Map<UUID, Entity> entityMap = (Map<UUID, Entity>) class_WorldServer_entitiesByUUIDField.get(worldHandle);
if (entityMap != null) {
Object nmsEntity = entityMap.get(uuid);
if (nmsEntity != null) {
return getBukkitEntity(nmsEntity);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void setEnvironment(World world, World.Environment environment) {
try {
class_CraftWorld_environmentField.set(world, environment);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void playCustomSound(Player player, Location location, String sound, float volume, float pitch) {
try {
Object packet = class_PacketPlayOutCustomSoundEffect_Constructor.newInstance(sound, enum_SoundCategory_PLAYERS, location.getX(), location.getY(), location.getZ(), volume, pitch);
sendPacket(player, packet);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Map<String, Object> getMap(ConfigurationSection section) {
if (section == null) {
return null;
}
if (section instanceof MemorySection) {
try {
Object mapObject = class_MemorySection_mapField.get(section);
if (mapObject instanceof Map) {
return (Map<String, Object>) mapObject;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
// Do it the slow way
Map<String, Object> map = new HashMap<>();
Set<String> keys = section.getKeys(false);
for (String key : keys) {
map.put(key, section.get(key));
}
return map;
}
public static boolean isEmpty(ItemStack itemStack) {
if (itemStack == null || itemStack.getType() == Material.AIR) {
return true;
}
if (class_ItemStack_isEmptyMethod == null) {
return false;
}
try {
Object handle = getHandle(itemStack);
if (handle == null) {
return false;
}
return (Boolean) class_ItemStack_isEmptyMethod.invoke(handle);
} catch (Throwable ex) {
ex.printStackTrace();
}
return false;
}
}