2016-05-12 13:30:22 +02:00
package me.libraryaddict.disguise.utilities ;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Field ;
import java.lang.reflect.InvocationTargetException ;
import java.lang.reflect.Method ;
import java.lang.reflect.Modifier ;
2016-11-30 18:38:43 +01:00
import java.util.ArrayList ;
import java.util.Map ;
2016-05-12 13:30:22 +02:00
import java.util.UUID ;
2016-11-30 18:38:43 +01:00
import java.util.regex.Pattern ;
2016-05-12 13:30:22 +02:00
import org.apache.commons.lang3.tuple.ImmutablePair ;
import org.apache.commons.lang3.tuple.Pair ;
import org.bukkit.Art ;
import org.bukkit.Bukkit ;
import org.bukkit.Location ;
import org.bukkit.Material ;
import org.bukkit.Sound ;
import org.bukkit.World ;
import org.bukkit.entity.Ambient ;
import org.bukkit.entity.Entity ;
import org.bukkit.entity.LivingEntity ;
import org.bukkit.entity.Monster ;
import org.bukkit.entity.Player ;
import org.bukkit.inventory.EquipmentSlot ;
import org.bukkit.inventory.ItemStack ;
import org.bukkit.potion.PotionEffect ;
2016-10-04 15:11:50 +02:00
2016-07-07 12:10:58 +02:00
import com.comphenix.protocol.wrappers.BlockPosition ;
2016-07-08 07:59:30 +02:00
import com.comphenix.protocol.wrappers.EnumWrappers.Direction ;
2016-05-12 13:30:22 +02:00
import com.comphenix.protocol.wrappers.MinecraftKey ;
2016-07-08 07:59:30 +02:00
import com.comphenix.protocol.wrappers.Vector3F ;
2016-11-25 09:21:49 +01:00
import com.comphenix.protocol.wrappers.WrappedBlockData ;
2016-05-12 13:30:22 +02:00
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry ;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer ;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject ;
import com.comphenix.protocol.wrappers.WrappedGameProfile ;
2016-11-30 18:38:43 +01:00
import com.comphenix.protocol.wrappers.WrappedSignedProperty ;
2016-06-18 17:16:32 +02:00
import com.comphenix.protocol.wrappers.WrappedWatchableObject ;
import com.google.common.base.Optional ;
2016-11-30 18:38:43 +01:00
import com.google.gson.Gson ;
2016-05-12 13:30:22 +02:00
import me.libraryaddict.disguise.disguisetypes.DisguiseType ;
2016-11-25 09:21:49 +01:00
public class ReflectionManager {
2016-05-12 13:30:22 +02:00
private static final String bukkitVersion = Bukkit . getServer ( ) . getClass ( ) . getName ( ) . split ( " \\ . " ) [ 3 ] ;
private static final Class < ? > craftItemClass ;
private static Method damageAndIdleSoundMethod ;
private static final Field entitiesField ;
private static final Constructor < ? > boundingBoxConstructor ;
private static final Method setBoundingBoxMethod ;
private static final Method ihmGet ;
private static final Field pingField ;
private static final Field trackerField ;
public static final Field entityCountField ;
2016-11-25 09:21:49 +01:00
static {
for ( Method method : getNmsClass ( " EntityLiving " ) . getDeclaredMethods ( ) ) {
try {
2017-03-19 13:14:45 +01:00
if ( method . getReturnType ( ) = = float . class & & Modifier . isProtected (
method . getModifiers ( ) ) & & method . getParameterTypes ( ) . length = = 0 ) {
2016-05-12 13:30:22 +02:00
Object entity = createEntityInstance ( " Cow " ) ;
method . setAccessible ( true ) ;
float value = ( Float ) method . invoke ( entity ) ;
2016-11-25 09:21:49 +01:00
if ( value = = 0 . 4F ) {
2016-05-12 13:30:22 +02:00
damageAndIdleSoundMethod = method ;
break ;
}
}
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
}
craftItemClass = getCraftClass ( " inventory.CraftItemStack " ) ;
pingField = getNmsField ( " EntityPlayer " , " ping " ) ;
trackerField = getNmsField ( " WorldServer " , " tracker " ) ;
entitiesField = getNmsField ( " EntityTracker " , " trackedEntities " ) ;
ihmGet = getNmsMethod ( " IntHashMap " , " get " , int . class ) ;
2017-03-19 13:14:45 +01:00
boundingBoxConstructor = getNmsConstructor ( " AxisAlignedBB " , double . class , double . class , double . class ,
double . class , double . class , double . class ) ;
2016-05-12 13:30:22 +02:00
setBoundingBoxMethod = getNmsMethod ( " Entity " , " a " , getNmsClass ( " AxisAlignedBB " ) ) ;
entityCountField = getNmsField ( " Entity " , " entityCount " ) ;
entityCountField . setAccessible ( true ) ;
}
2016-11-30 18:38:43 +01:00
public static WrappedGameProfile parseGameProfile ( String toParse ) {
Map < String , Object > response = new Gson ( ) . fromJson ( toParse , Map . class ) ;
String id = ( String ) response . get ( " id " ) ;
if ( ! id . contains ( " - " ) ) {
2017-03-19 13:14:45 +01:00
id = Pattern . compile (
" ([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+) " ) . matcher (
id ) . replaceFirst ( " $1-$2-$3-$4-$5 " ) ;
2016-11-30 18:38:43 +01:00
}
WrappedGameProfile gameProfile = new WrappedGameProfile ( UUID . fromString ( id ) , ( String ) response . get ( " name " ) ) ;
if ( response . containsKey ( " properties " ) ) {
ArrayList < Map < String , String > > properties = ( ArrayList ) response . get ( " properties " ) ;
for ( Map < String , String > s : properties ) {
String gName = null ;
String gValue = null ;
String gSigned = null ;
if ( s . containsKey ( " name " ) )
gName = s . get ( " name " ) ;
if ( s . containsKey ( " value " ) )
gValue = s . get ( " value " ) ;
if ( s . containsKey ( " signature " ) )
gSigned = s . get ( " signature " ) ;
gameProfile . getProperties ( ) . put ( gName , new WrappedSignedProperty ( gName , gValue , gSigned ) ) ;
}
}
return gameProfile ;
}
2016-11-25 09:21:49 +01:00
public static Object createEntityInstance ( String entityName ) {
try {
2016-05-12 13:30:22 +02:00
Class < ? > entityClass = getNmsClass ( " Entity " + entityName ) ;
Object entityObject ;
Object world = getWorldServer ( Bukkit . getWorlds ( ) . get ( 0 ) ) ;
2016-11-25 09:21:49 +01:00
switch ( entityName ) {
2017-03-19 13:14:45 +01:00
case " Player " :
Object minecraftServer = getNmsMethod ( " MinecraftServer " , " getServer " ) . invoke ( null ) ;
Object playerinteractmanager = getNmsClass ( " PlayerInteractManager " ) . getDeclaredConstructor (
getNmsClass ( " World " ) ) . newInstance ( world ) ;
WrappedGameProfile gameProfile = getGameProfile ( null , " Steve " ) ;
entityObject = entityClass . getDeclaredConstructor ( getNmsClass ( " MinecraftServer " ) ,
getNmsClass ( " WorldServer " ) , gameProfile . getHandleType ( ) ,
playerinteractmanager . getClass ( ) ) . newInstance ( minecraftServer , world ,
gameProfile . getHandle ( ) , playerinteractmanager ) ;
break ;
case " EnderPearl " :
entityObject = entityClass . getDeclaredConstructor ( getNmsClass ( " World " ) ,
getNmsClass ( " EntityLiving " ) ) . newInstance ( world , createEntityInstance ( " Cow " ) ) ;
break ;
case " Potion " :
entityObject = entityClass . getDeclaredConstructor ( getNmsClass ( " World " ) , Double . TYPE , Double . TYPE ,
Double . TYPE , getNmsClass ( " ItemStack " ) ) . newInstance ( world , 0d , 0d , 0d ,
getNmsItem ( new ItemStack ( Material . SPLASH_POTION ) ) ) ;
break ;
case " FishingHook " :
entityObject = entityClass . getDeclaredConstructor ( getNmsClass ( " World " ) ,
getNmsClass ( " EntityHuman " ) ) . newInstance ( world , createEntityInstance ( " Player " ) ) ;
break ;
default :
entityObject = entityClass . getDeclaredConstructor ( getNmsClass ( " World " ) ) . newInstance ( world ) ;
break ;
2016-05-12 13:30:22 +02:00
}
return entityObject ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Object getMobEffectList ( int id ) {
2016-05-12 13:30:22 +02:00
Method nmsMethod = getNmsMethod ( " MobEffectList " , " fromId " , Integer . TYPE ) ;
2016-11-25 09:21:49 +01:00
try {
2016-05-12 13:30:22 +02:00
return nmsMethod . invoke ( null , id ) ;
}
2016-11-25 09:21:49 +01:00
catch ( IllegalAccessException | InvocationTargetException e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Object createMobEffect ( PotionEffect effect ) {
2017-03-19 13:14:45 +01:00
return createMobEffect ( effect . getType ( ) . getId ( ) , effect . getDuration ( ) , effect . getAmplifier ( ) ,
effect . isAmbient ( ) , effect . hasParticles ( ) ) ;
2016-05-12 13:30:22 +02:00
}
2016-11-25 09:21:49 +01:00
public static Object createMobEffect ( int id , int duration , int amplification , boolean ambient , boolean particles ) {
try {
2017-03-19 13:14:45 +01:00
return getNmsClass ( " MobEffect " ) . getDeclaredConstructor ( getNmsClass ( " MobEffectList " ) , Integer . TYPE ,
Integer . TYPE , Boolean . TYPE , Boolean . TYPE ) . newInstance ( getMobEffectList ( id ) , duration , amplification ,
ambient , particles ) ;
2016-05-12 13:30:22 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static FakeBoundingBox getBoundingBox ( Entity entity ) {
try {
2016-05-12 13:30:22 +02:00
Object boundingBox = getNmsMethod ( " Entity " , " getBoundingBox " ) . invoke ( getNmsEntity ( entity ) ) ;
double x = 0 , y = 0 , z = 0 ;
int stage = 0 ;
2016-11-25 09:21:49 +01:00
for ( Field field : boundingBox . getClass ( ) . getDeclaredFields ( ) ) {
if ( field . getType ( ) . getSimpleName ( ) . equals ( " double " ) ) {
2016-05-12 13:30:22 +02:00
stage + + ;
2016-11-25 09:21:49 +01:00
switch ( stage ) {
2017-03-19 13:14:45 +01:00
case 1 :
x - = field . getDouble ( boundingBox ) ;
break ;
case 2 :
y - = field . getDouble ( boundingBox ) ;
break ;
case 3 :
z - = field . getDouble ( boundingBox ) ;
break ;
case 4 :
x + = field . getDouble ( boundingBox ) ;
break ;
case 5 :
y + = field . getDouble ( boundingBox ) ;
break ;
case 6 :
z + = field . getDouble ( boundingBox ) ;
break ;
default :
throw new Exception ( " Error while setting the bounding box, more doubles than I thought?? " ) ;
2016-05-12 13:30:22 +02:00
}
}
}
return new FakeBoundingBox ( x , y , z ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Entity getBukkitEntity ( Object nmsEntity ) {
try {
2016-05-12 13:30:22 +02:00
return ( Entity ) getNmsMethod ( " Entity " , " getBukkitEntity " ) . invoke ( nmsEntity ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static ItemStack getBukkitItem ( Object nmsItem ) {
try {
2016-05-12 13:30:22 +02:00
return ( ItemStack ) craftItemClass . getMethod ( " asBukkitCopy " , getNmsClass ( " ItemStack " ) ) . invoke ( null , nmsItem ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static String getBukkitVersion ( ) {
2016-05-12 13:30:22 +02:00
return bukkitVersion ;
}
2016-11-25 09:21:49 +01:00
public static Class < ? > getCraftClass ( String className ) {
try {
2016-05-12 13:30:22 +02:00
return Class . forName ( " org.bukkit.craftbukkit. " + getBukkitVersion ( ) + " . " + className ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Constructor getCraftConstructor ( Class clazz , Class < ? > . . . parameters ) {
try {
2016-05-12 13:30:22 +02:00
Constructor declaredConstructor = clazz . getDeclaredConstructor ( parameters ) ;
declaredConstructor . setAccessible ( true ) ;
return declaredConstructor ;
}
2016-11-25 09:21:49 +01:00
catch ( NoSuchMethodException e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Constructor getCraftConstructor ( String className , Class < ? > . . . parameters ) {
2016-05-12 13:30:22 +02:00
return getCraftConstructor ( getCraftClass ( className ) , parameters ) ;
}
2016-11-25 09:21:49 +01:00
public static String getCraftSound ( Sound sound ) {
try {
2016-05-12 13:30:22 +02:00
return ( String ) getCraftClass ( " CraftSound " ) . getMethod ( " getSound " , Sound . class ) . invoke ( null , sound ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Object getEntityTrackerEntry ( Entity target ) throws Exception {
2016-05-12 13:30:22 +02:00
Object world = getWorldServer ( target . getWorld ( ) ) ;
Object tracker = trackerField . get ( world ) ;
Object trackedEntities = entitiesField . get ( tracker ) ;
return ihmGet . invoke ( trackedEntities , target . getEntityId ( ) ) ;
}
2016-11-25 09:21:49 +01:00
public static Object getMinecraftServer ( ) {
try {
2016-05-12 13:30:22 +02:00
return getCraftMethod ( " CraftServer " , " getServer " ) . invoke ( Bukkit . getServer ( ) ) ;
}
2016-11-25 09:21:49 +01:00
catch ( IllegalAccessException | InvocationTargetException e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static String getEnumArt ( Art art ) {
try {
2016-05-12 13:30:22 +02:00
Object enumArt = getCraftClass ( " CraftArt " ) . getMethod ( " BukkitToNotch " , Art . class ) . invoke ( null , art ) ;
2016-11-25 09:21:49 +01:00
for ( Field field : enumArt . getClass ( ) . getDeclaredFields ( ) ) {
if ( field . getType ( ) = = String . class ) {
2016-05-12 13:30:22 +02:00
return ( String ) field . get ( enumArt ) ;
}
}
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Object getBlockPosition ( int x , int y , int z ) {
try {
2017-03-19 13:14:45 +01:00
return getNmsClass ( " BlockPosition " ) . getDeclaredConstructor ( int . class , int . class , int . class ) . newInstance ( x ,
y , z ) ;
2016-05-12 13:30:22 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Enum getEnumDirection ( int direction ) {
try {
2016-05-12 13:30:22 +02:00
return ( Enum ) getNmsMethod ( " EnumDirection " , " fromType2 " , int . class ) . invoke ( null , direction ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Enum getEnumPlayerInfoAction ( int action ) {
try {
2016-05-12 13:30:22 +02:00
return ( Enum ) getNmsClass ( " PacketPlayOutPlayerInfo$EnumPlayerInfoAction " ) . getEnumConstants ( ) [ action ] ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Object getPlayerInfoData ( Object playerInfoPacket , WrappedGameProfile gameProfile ) {
try {
2017-03-19 13:14:45 +01:00
Object playerListName = getNmsClass ( " ChatComponentText " ) . getDeclaredConstructor ( String . class ) . newInstance (
gameProfile . getName ( ) ) ;
2016-05-12 13:30:22 +02:00
2017-03-19 13:14:45 +01:00
return getNmsClass ( " PacketPlayOutPlayerInfo$PlayerInfoData " ) . getDeclaredConstructor (
getNmsClass ( " PacketPlayOutPlayerInfo " ) , gameProfile . getHandleType ( ) , int . class ,
getNmsClass ( " EnumGamemode " ) , getNmsClass ( " IChatBaseComponent " ) ) . newInstance ( playerInfoPacket ,
gameProfile . getHandle ( ) , 0 , getNmsClass ( " EnumGamemode " ) . getEnumConstants ( ) [ 1 ] , playerListName ) ;
2016-05-12 13:30:22 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static WrappedGameProfile getGameProfile ( Player player ) {
2016-05-12 13:30:22 +02:00
return WrappedGameProfile . fromPlayer ( player ) ;
}
2016-11-25 09:21:49 +01:00
public static WrappedGameProfile getGameProfile ( UUID uuid , String playerName ) {
try {
2016-05-12 13:30:22 +02:00
return new WrappedGameProfile ( uuid ! = null ? uuid : UUID . randomUUID ( ) , playerName ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static WrappedGameProfile getClonedProfile ( WrappedGameProfile gameProfile ) {
2016-06-14 11:08:53 +02:00
return getGameProfileWithThisSkin ( null , gameProfile . getName ( ) , gameProfile ) ;
}
2016-11-25 09:21:49 +01:00
public static WrappedGameProfile getGameProfileWithThisSkin ( UUID uuid , String playerName ,
WrappedGameProfile profileWithSkin ) {
try {
2017-03-19 13:14:45 +01:00
WrappedGameProfile gameProfile = new WrappedGameProfile ( uuid ! = null ? uuid : UUID . randomUUID ( ) ,
playerName ) ;
2016-06-14 11:08:53 +02:00
2017-03-21 07:34:12 +01:00
if ( profileWithSkin ! = null ) {
2017-03-19 13:14:45 +01:00
gameProfile . getProperties ( ) . putAll ( profileWithSkin . getProperties ( ) ) ;
2017-03-21 07:34:12 +01:00
}
2016-06-14 11:08:53 +02:00
2016-05-12 13:30:22 +02:00
return gameProfile ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Class getNmsClass ( String className ) {
try {
2016-05-12 13:30:22 +02:00
return Class . forName ( " net.minecraft.server. " + getBukkitVersion ( ) + " . " + className ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Constructor getNmsConstructor ( Class clazz , Class < ? > . . . parameters ) {
try {
2016-05-12 13:30:22 +02:00
Constructor declaredConstructor = clazz . getDeclaredConstructor ( parameters ) ;
declaredConstructor . setAccessible ( true ) ;
return declaredConstructor ;
}
2016-11-25 09:21:49 +01:00
catch ( NoSuchMethodException e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Constructor getNmsConstructor ( String className , Class < ? > . . . parameters ) {
2016-05-12 13:30:22 +02:00
return getNmsConstructor ( getNmsClass ( className ) , parameters ) ;
}
2016-11-25 09:21:49 +01:00
public static Object getNmsEntity ( Entity entity ) {
try {
2016-05-12 13:30:22 +02:00
return getCraftClass ( " entity.CraftEntity " ) . getMethod ( " getHandle " ) . invoke ( entity ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Field getNmsField ( Class clazz , String fieldName ) {
try {
2016-05-12 13:30:22 +02:00
Field declaredField = clazz . getDeclaredField ( fieldName ) ;
declaredField . setAccessible ( true ) ;
return declaredField ;
}
2016-11-25 09:21:49 +01:00
catch ( NoSuchFieldException e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Field getNmsField ( String className , String fieldName ) {
2016-05-12 13:30:22 +02:00
return getNmsField ( getNmsClass ( className ) , fieldName ) ;
}
2016-11-25 09:21:49 +01:00
public static Object getNmsItem ( ItemStack itemstack ) {
try {
2016-05-12 13:30:22 +02:00
return craftItemClass . getDeclaredMethod ( " asNMSCopy " , ItemStack . class ) . invoke ( null , itemstack ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Method getCraftMethod ( String className , String methodName , Class < ? > . . . parameters ) {
2016-05-12 13:30:22 +02:00
return getCraftMethod ( getCraftClass ( className ) , methodName , parameters ) ;
}
2016-11-25 09:21:49 +01:00
public static Method getCraftMethod ( Class < ? > clazz , String methodName , Class < ? > . . . parameters ) {
try {
2016-05-12 13:30:22 +02:00
Method declaredMethod = clazz . getDeclaredMethod ( methodName , parameters ) ;
declaredMethod . setAccessible ( true ) ;
return declaredMethod ;
}
2016-11-25 09:21:49 +01:00
catch ( NoSuchMethodException e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Method getNmsMethod ( Class < ? > clazz , String methodName , Class < ? > . . . parameters ) {
try {
2016-05-12 13:30:22 +02:00
Method declaredMethod = clazz . getDeclaredMethod ( methodName , parameters ) ;
declaredMethod . setAccessible ( true ) ;
return declaredMethod ;
}
2016-11-25 09:21:49 +01:00
catch ( NoSuchMethodException e ) {
2016-06-18 17:16:32 +02:00
e . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Method getNmsMethod ( String className , String methodName , Class < ? > . . . parameters ) {
2016-05-12 13:30:22 +02:00
return getNmsMethod ( getNmsClass ( className ) , methodName , parameters ) ;
}
2016-11-25 09:21:49 +01:00
public static double getPing ( Player player ) {
try {
2016-05-12 13:30:22 +02:00
return ( double ) pingField . getInt ( ReflectionManager . getNmsEntity ( player ) ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return 0 ;
}
2016-11-25 09:21:49 +01:00
public static float [ ] getSize ( Entity entity ) {
try {
2016-05-12 13:30:22 +02:00
float length = getNmsField ( " Entity " , " length " ) . getFloat ( getNmsEntity ( entity ) ) ;
float width = getNmsField ( " Entity " , " width " ) . getFloat ( getNmsEntity ( entity ) ) ;
float height = ( Float ) getNmsMethod ( " Entity " , " getHeadHeight " ) . invoke ( getNmsEntity ( entity ) ) ;
2017-03-19 13:14:45 +01:00
return new float [ ] { length , width , height } ;
2016-05-12 13:30:22 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static WrappedGameProfile getSkullBlob ( WrappedGameProfile gameProfile ) {
try {
2016-05-12 13:30:22 +02:00
Object minecraftServer = getNmsMethod ( " MinecraftServer " , " getServer " ) . invoke ( null ) ;
2016-11-25 09:21:49 +01:00
for ( Method method : getNmsClass ( " MinecraftServer " ) . getDeclaredMethods ( ) ) {
if ( method . getReturnType ( ) . getSimpleName ( ) . equals ( " MinecraftSessionService " ) ) {
2016-05-12 13:30:22 +02:00
Object session = method . invoke ( minecraftServer ) ;
2017-03-19 13:14:45 +01:00
return WrappedGameProfile . fromHandle (
session . getClass ( ) . getDeclaredMethod ( " fillProfileProperties " , gameProfile . getHandleType ( ) ,
boolean . class ) . invoke ( session , gameProfile . getHandle ( ) , true ) ) ;
2016-05-12 13:30:22 +02:00
}
}
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Float getSoundModifier ( Object entity ) {
try {
2016-05-12 13:30:22 +02:00
damageAndIdleSoundMethod . setAccessible ( true ) ;
return ( Float ) damageAndIdleSoundMethod . invoke ( entity ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ignored ) {
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static WrappedGameProfile grabProfileAddUUID ( String playername ) {
try {
2016-05-12 13:30:22 +02:00
Object minecraftServer = getNmsMethod ( " MinecraftServer " , " getServer " ) . invoke ( null ) ;
2016-11-25 09:21:49 +01:00
for ( Method method : getNmsClass ( " MinecraftServer " ) . getDeclaredMethods ( ) ) {
if ( method . getReturnType ( ) . getSimpleName ( ) . equals ( " GameProfileRepository " ) ) {
2016-05-12 13:30:22 +02:00
Object profileRepo = method . invoke ( minecraftServer ) ;
Object agent = Class . forName ( " com.mojang.authlib.Agent " ) . getDeclaredField ( " MINECRAFT " ) . get ( null ) ;
LibsProfileLookupCaller callback = new LibsProfileLookupCaller ( ) ;
2017-03-19 13:14:45 +01:00
profileRepo . getClass ( ) . getDeclaredMethod ( " findProfilesByNames " , String [ ] . class , agent . getClass ( ) ,
Class . forName ( " com.mojang.authlib.ProfileLookupCallback " ) ) . invoke ( profileRepo ,
new String [ ] { playername } , agent , callback ) ;
2016-05-12 13:30:22 +02:00
2016-11-25 09:21:49 +01:00
if ( callback . getGameProfile ( ) ! = null ) {
2016-05-12 13:30:22 +02:00
return callback . getGameProfile ( ) ;
}
return getGameProfile ( null , playername ) ;
}
}
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static void removePlayer ( Player player ) {
2016-05-12 13:30:22 +02:00
// Some future remove code if needed
}
2016-11-25 09:21:49 +01:00
public static void setBoundingBox ( Entity entity , FakeBoundingBox newBox ) {
try {
2016-05-12 13:30:22 +02:00
Location loc = entity . getLocation ( ) ;
2017-03-19 13:14:45 +01:00
Object boundingBox = boundingBoxConstructor . newInstance ( loc . getX ( ) - newBox . getX ( ) ,
loc . getY ( ) - newBox . getY ( ) , loc . getZ ( ) - newBox . getZ ( ) , loc . getX ( ) + newBox . getX ( ) ,
loc . getY ( ) + newBox . getY ( ) , loc . getZ ( ) + newBox . getZ ( ) ) ;
2016-05-12 13:30:22 +02:00
setBoundingBoxMethod . invoke ( getNmsEntity ( entity ) , boundingBox ) ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-05-12 13:30:22 +02:00
}
}
2016-11-25 09:21:49 +01:00
public static Enum getSoundCategory ( String category ) {
2016-05-12 13:30:22 +02:00
Method method = getNmsMethod ( " SoundCategory " , " a " , String . class ) ;
2016-11-25 09:21:49 +01:00
try {
2016-05-12 13:30:22 +02:00
Enum invoke = ( Enum ) method . invoke ( null , category . toLowerCase ( ) ) ;
2016-11-25 09:21:49 +01:00
if ( invoke = = null ) {
2016-05-12 13:30:22 +02:00
Class < ? > clazz = getNmsClass ( " SoundCategory " ) ;
Enum [ ] enums = clazz ! = null ? ( Enum [ ] ) clazz . getEnumConstants ( ) : null ;
2016-11-25 09:21:49 +01:00
for ( Enum anEnum : enums ! = null ? enums : new Enum [ 0 ] ) {
2016-05-12 13:30:22 +02:00
if ( anEnum . name ( ) . equals ( category . toUpperCase ( ) ) )
return anEnum ;
}
}
return invoke ;
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Enum getSoundCategory ( DisguiseType disguiseType ) {
2016-05-12 13:30:22 +02:00
if ( disguiseType = = DisguiseType . PLAYER )
return getSoundCategory ( " player " ) ;
Class < ? extends Entity > entityClass = disguiseType . getEntityType ( ) . getEntityClass ( ) ;
if ( Monster . class . isAssignableFrom ( entityClass ) )
return getSoundCategory ( " hostile " ) ;
if ( Ambient . class . isAssignableFrom ( entityClass ) )
return getSoundCategory ( " ambient " ) ;
return getSoundCategory ( " neutral " ) ;
}
/ * *
* Creates the NMS object EnumItemSlot from an EquipmentSlot .
*
* @param slot
* @return null if the equipment slot is null
* /
2016-11-25 09:21:49 +01:00
public static Enum createEnumItemSlot ( EquipmentSlot slot ) {
2016-05-12 13:30:22 +02:00
Class < ? > clazz = getNmsClass ( " EnumItemSlot " ) ;
Object [ ] enums = clazz ! = null ? clazz . getEnumConstants ( ) : null ;
if ( enums = = null )
return null ;
2016-11-25 09:21:49 +01:00
switch ( slot ) {
2017-03-19 13:14:45 +01:00
case HAND :
return ( Enum ) enums [ 0 ] ;
case OFF_HAND :
return ( Enum ) enums [ 1 ] ;
case FEET :
return ( Enum ) enums [ 2 ] ;
case LEGS :
return ( Enum ) enums [ 3 ] ;
case CHEST :
return ( Enum ) enums [ 4 ] ;
case HEAD :
return ( Enum ) enums [ 5 ] ;
default :
return null ;
2016-05-12 13:30:22 +02:00
}
}
/ * *
* Creates the Bukkit object EquipmentSlot from an EnumItemSlot object .
*
* @return null if the object isn ' t an nms EnumItemSlot
* /
2016-11-25 09:21:49 +01:00
public static EquipmentSlot createEquipmentSlot ( Object enumItemSlot ) {
try {
2016-05-12 13:30:22 +02:00
Enum nmsSlot = ( Enum ) enumItemSlot ;
2016-11-25 09:21:49 +01:00
switch ( nmsSlot . name ( ) ) {
2017-03-19 13:14:45 +01:00
case " MAINHAND " :
return EquipmentSlot . HAND ;
case " OFFHAND " :
return EquipmentSlot . OFF_HAND ;
case " FEET " :
return EquipmentSlot . FEET ;
case " LEGS " :
return EquipmentSlot . LEGS ;
case " CHEST " :
return EquipmentSlot . CHEST ;
case " HEAD " :
return EquipmentSlot . HEAD ;
2016-05-12 13:30:22 +02:00
}
}
2016-11-25 09:21:49 +01:00
catch ( Exception e ) {
2016-05-12 13:30:22 +02:00
}
return null ;
}
/ * *
* Gets equipment from this entity based on the slot given .
*
* @param slot
* @return null if the disguisedEntity is not an instance of a living entity
* /
2016-11-25 09:21:49 +01:00
public static ItemStack getEquipment ( EquipmentSlot slot , Entity disguisedEntity ) {
2016-05-12 13:30:22 +02:00
if ( ! ( disguisedEntity instanceof LivingEntity ) )
return null ;
2016-11-25 09:21:49 +01:00
switch ( slot ) {
2017-03-19 13:14:45 +01:00
case HAND :
return ( ( LivingEntity ) disguisedEntity ) . getEquipment ( ) . getItemInMainHand ( ) ;
case OFF_HAND :
return ( ( LivingEntity ) disguisedEntity ) . getEquipment ( ) . getItemInOffHand ( ) ;
case FEET :
return ( ( LivingEntity ) disguisedEntity ) . getEquipment ( ) . getBoots ( ) ;
case LEGS :
return ( ( LivingEntity ) disguisedEntity ) . getEquipment ( ) . getLeggings ( ) ;
case CHEST :
return ( ( LivingEntity ) disguisedEntity ) . getEquipment ( ) . getChestplate ( ) ;
case HEAD :
return ( ( LivingEntity ) disguisedEntity ) . getEquipment ( ) . getHelmet ( ) ;
default :
return null ;
2016-05-12 13:30:22 +02:00
}
}
/ * *
* Necessary for 1 . 9
*
* @return
* /
2016-11-25 09:21:49 +01:00
public static String convertSoundEffectToString ( Object soundEffect ) {
try {
2016-05-12 13:30:22 +02:00
Field f_getMinecraftKey = getNmsField ( " SoundEffect " , " b " ) ;
f_getMinecraftKey . setAccessible ( true ) ;
MinecraftKey key = MinecraftKey . fromHandle ( f_getMinecraftKey . get ( soundEffect ) ) ;
return key . getKey ( ) ;
}
2016-11-25 09:21:49 +01:00
catch ( IllegalAccessException e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Object getCraftSoundEffect ( String sound ) {
try {
2016-05-12 13:30:22 +02:00
return getCraftMethod ( " CraftSound " , " getSoundEffect " , String . class ) . invoke ( null , sound ) ;
}
2016-11-25 09:21:49 +01:00
catch ( IllegalAccessException | InvocationTargetException e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
2016-11-26 16:36:57 +01:00
public static Object convertInvalidItem ( Object value ) {
2016-11-25 09:21:49 +01:00
if ( value instanceof Optional ) {
2016-07-07 12:10:58 +02:00
Optional opt = ( Optional ) value ;
if ( ! opt . isPresent ( ) )
return value ;
Object val = opt . get ( ) ;
2016-11-26 16:36:57 +01:00
if ( val instanceof BlockPosition ) {
2016-07-07 12:10:58 +02:00
BlockPosition pos = ( BlockPosition ) val ;
2016-11-25 09:21:49 +01:00
try {
2017-03-19 13:14:45 +01:00
return Optional . of (
getNmsConstructor ( " BlockPosition " , int . class , int . class , int . class ) . newInstance ( pos . getX ( ) ,
pos . getY ( ) , pos . getZ ( ) ) ) ;
2016-07-07 12:10:58 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
ex . printStackTrace ( ) ;
}
2017-03-19 13:14:45 +01:00
} else if ( val instanceof WrappedBlockData ) {
2016-11-25 09:21:49 +01:00
try {
return Optional . of ( ( ( WrappedBlockData ) val ) . getHandle ( ) ) ;
}
catch ( Exception ex ) {
2016-07-07 12:10:58 +02:00
ex . printStackTrace ( ) ;
}
}
2017-03-19 13:14:45 +01:00
} else if ( value instanceof Vector3F ) {
2016-07-08 07:59:30 +02:00
Vector3F angle = ( Vector3F ) value ;
2016-07-07 12:10:58 +02:00
2016-11-25 09:21:49 +01:00
try {
2016-07-08 07:59:30 +02:00
return getNmsConstructor ( " Vector3f " , float . class , float . class , float . class ) . newInstance ( angle . getX ( ) ,
angle . getY ( ) , angle . getZ ( ) ) ;
2016-07-07 12:10:58 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-07-07 12:10:58 +02:00
ex . printStackTrace ( ) ;
}
2017-03-19 13:14:45 +01:00
} else if ( value instanceof Direction ) {
2016-11-25 09:21:49 +01:00
try {
2017-03-19 13:14:45 +01:00
return ( Enum ) getNmsMethod ( " EnumDirection " , " fromType1 " , int . class ) . invoke ( null ,
( ( Direction ) value ) . ordinal ( ) ) ;
2016-07-08 07:59:30 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-07-08 07:59:30 +02:00
ex . printStackTrace ( ) ;
}
2017-03-19 13:14:45 +01:00
} else if ( value instanceof BlockPosition ) {
2016-07-08 12:13:40 +02:00
BlockPosition pos = ( BlockPosition ) value ;
2016-11-25 09:21:49 +01:00
try {
2017-03-19 13:14:45 +01:00
return getNmsConstructor ( " BlockPosition " , int . class , int . class , int . class ) . newInstance ( pos . getX ( ) ,
pos . getY ( ) , pos . getZ ( ) ) ;
2016-07-08 12:13:40 +02:00
}
2016-11-25 09:21:49 +01:00
catch ( Exception ex ) {
2016-07-08 12:13:40 +02:00
ex . printStackTrace ( ) ;
}
2017-03-19 13:14:45 +01:00
} else if ( value instanceof ItemStack ) {
2016-11-26 16:36:57 +01:00
return getNmsItem ( ( ItemStack ) value ) ;
}
2016-07-07 12:10:58 +02:00
return value ;
}
2016-05-12 13:30:22 +02:00
/ * *
* This creates a DataWatcherItem usable with WrappedWatchableObject
*
* @param id
* @param value
* @return
* /
2016-11-25 09:21:49 +01:00
private static Object createDataWatcherItem ( int id , Object value ) {
2016-05-12 13:30:22 +02:00
if ( value = = null )
return null ;
2016-07-07 12:10:58 +02:00
value = convertInvalidItem ( value ) ;
2016-06-18 17:16:32 +02:00
Serializer serializer ;
2016-11-25 09:21:49 +01:00
if ( value instanceof Optional ) {
2016-06-23 11:11:50 +02:00
Optional opt = ( Optional ) value ;
2017-03-19 13:14:45 +01:00
serializer = Registry . get ( ( opt . isPresent ( ) ? getNmsClass ( " IBlockData " ) . isInstance ( opt . get ( ) ) ? getNmsClass (
" IBlockData " ) : opt . get ( ) . getClass ( ) : UUID . class ) , true ) ;
} else {
2016-06-18 17:16:32 +02:00
serializer = Registry . get ( value . getClass ( ) ) ;
}
2016-05-12 13:30:22 +02:00
2016-11-25 09:21:49 +01:00
if ( serializer = = null ) {
2017-03-19 13:14:45 +01:00
throw new IllegalArgumentException (
" Unable to find Serializer for " + value + ( value instanceof Optional & & ( ( Optional ) value ) . isPresent ( ) ? " ( " + ( ( Optional ) value ) . get ( ) . getClass ( ) . getName ( ) + " ) " : " " ) + " ! Are you running the latest version of ProtocolLib? " ) ;
2016-07-07 12:10:58 +02:00
}
2016-05-12 13:30:22 +02:00
WrappedDataWatcherObject watcherObject = new WrappedDataWatcherObject ( id , serializer ) ;
Constructor construct = getNmsConstructor ( " DataWatcher$Item " , getNmsClass ( " DataWatcherObject " ) , Object . class ) ;
2016-11-25 09:21:49 +01:00
try {
2016-05-12 13:30:22 +02:00
return construct . newInstance ( watcherObject . getHandle ( ) , value ) ;
}
2016-11-25 09:21:49 +01:00
catch ( InstantiationException | IllegalAccessException | InvocationTargetException e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static WrappedWatchableObject createWatchable ( int index , Object obj ) {
2016-06-18 17:16:32 +02:00
return new WrappedWatchableObject ( createDataWatcherItem ( index , obj ) ) ;
}
2016-11-25 09:21:49 +01:00
public static int getCombinedId ( int id , int data ) {
2016-05-12 13:30:22 +02:00
return id + ( data < < 12 ) ;
}
2016-11-25 09:21:49 +01:00
public static Pair < Integer , Integer > getFromCombinedId ( int combinedId ) {
2016-05-12 13:30:22 +02:00
int j = combinedId & 4095 ;
int k = combinedId > > 12 & 15 ;
return new ImmutablePair < > ( j , k ) ;
}
2016-11-25 09:21:49 +01:00
public static Object getWorldServer ( World w ) {
try {
2016-05-12 13:30:22 +02:00
return getCraftMethod ( " CraftWorld " , " getHandle " ) . invoke ( w ) ;
}
2016-11-25 09:21:49 +01:00
catch ( IllegalAccessException | InvocationTargetException e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
2016-11-25 09:21:49 +01:00
public static Object getPlayerInteractManager ( World w ) {
2016-05-12 13:30:22 +02:00
Object worldServer = getWorldServer ( w ) ;
2016-11-25 09:21:49 +01:00
try {
2016-05-12 13:30:22 +02:00
return getNmsConstructor ( " PlayerInteractManager " , getNmsClass ( " World " ) ) . newInstance ( worldServer ) ;
}
2016-11-25 09:21:49 +01:00
catch ( InstantiationException | InvocationTargetException | IllegalAccessException e ) {
2016-05-12 13:30:22 +02:00
e . printStackTrace ( ) ;
}
return null ;
}
}