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 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 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 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 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) fixBukkitClass("net.minecraft.server.EnumSkyBlock"); class_EnumSoundCategory = (Class) 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) 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) 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 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 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 entityMap = (Map) 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 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) mapObject; } } catch (Exception ex) { ex.printStackTrace(); } } // Do it the slow way Map map = new HashMap<>(); Set 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; } }