11package com .gamerforea .eventhelper .util ;
22
3+ import com .gamerforea .eventhelper .EventHelper ;
34import net .minecraft .entity .Entity ;
45import net .minecraft .entity .player .EntityPlayer ;
56import net .minecraft .item .ItemStack ;
67import net .minecraft .world .World ;
78import net .minecraftforge .common .util .ForgeDirection ;
8- import org .bukkit .Bukkit ;
99import org .bukkit .block .BlockFace ;
1010import org .bukkit .entity .Player ;
1111
12- import java .lang .reflect .Method ;
12+ import java .lang .invoke .MethodHandle ;
13+ import java .lang .invoke .MethodHandles ;
14+ import java .lang .invoke .MethodType ;
15+ import javax .annotation .Nullable ;
1316
1417public final class ConvertUtils
1518{
16- private static final Method getBukkitEntity ;
17- private static final Method asCraftMirror ;
19+ private static final MethodHandle getWorld ;
20+ private static final MethodHandle getBukkitEntity ;
21+ private static final MethodHandle asCraftMirror ;
1822
19- public static org .bukkit .entity .Entity toBukkitEntity (Entity entity ) throws Exception
23+ @ Nullable
24+ public static org .bukkit .entity .Entity toBukkitEntity (@ Nullable Entity entity )
2025 {
21- return (org .bukkit .entity .Entity ) getBukkitEntity .invoke (entity );
26+ if (entity == null )
27+ return null ; // TheAndrey: null -> null
28+
29+ try
30+ {
31+ return (org .bukkit .entity .Entity ) getBukkitEntity .bindTo (entity ).invoke ();
32+ }
33+ catch (Throwable e )
34+ {
35+ throw new RuntimeException ("Unable to invoke getBukkitEntity() on " + entity , e );
36+ }
2237 }
2338
24- public static Player toBukkitEntity (EntityPlayer player ) throws Exception
39+ @ Nullable
40+ public static Player toBukkitEntity (@ Nullable EntityPlayer player )
2541 {
26- return (Player ) getBukkitEntity . invoke ( player );
42+ return (Player ) toBukkitEntity (( Entity ) player );
2743 }
2844
29- public static org .bukkit .World toBukkitWorld (World world )
45+ @ Nullable
46+ public static org .bukkit .World toBukkitWorld (@ Nullable World world )
3047 {
31- return Bukkit .getWorld (world .getWorldInfo ().getWorldName ());
48+ if (world == null )
49+ return null ; // TheAndrey: null -> null
50+
51+ try
52+ {
53+ return (org .bukkit .World ) getWorld .bindTo (world ).invoke ();
54+ }
55+ catch (Throwable e )
56+ {
57+ throw new RuntimeException ("Unable to invoke getWorld() on " + world , e );
58+ }
3259 }
3360
34- public static org .bukkit .inventory .ItemStack toBukkitItemStackMirror (ItemStack stack ) throws Exception
61+ @ Nullable
62+ public static org .bukkit .inventory .ItemStack toBukkitItemStackMirror (@ Nullable ItemStack stack )
3563 {
36- return (org .bukkit .inventory .ItemStack ) asCraftMirror .invoke (null , stack );
64+ if (stack == null )
65+ return null ; // TheAndrey: null -> null
66+
67+ try
68+ {
69+ return (org .bukkit .inventory .ItemStack ) asCraftMirror .invoke (stack );
70+ }
71+ catch (Throwable e )
72+ {
73+ throw new RuntimeException ("Unable to invoke asCraftMirror() with " + stack , e );
74+ }
3775 }
3876
3977 public static BlockFace toBukkitFace (ForgeDirection direction )
@@ -52,8 +90,6 @@ public static BlockFace toBukkitFace(ForgeDirection direction)
5290 return BlockFace .WEST ;
5391 case EAST :
5492 return BlockFace .EAST ;
55- case UNKNOWN :
56- return BlockFace .SELF ;
5793 default :
5894 return BlockFace .SELF ;
5995 }
@@ -63,15 +99,24 @@ public static BlockFace toBukkitFace(ForgeDirection direction)
6399 {
64100 try
65101 {
66- getBukkitEntity = Entity .class .getDeclaredMethod ("getBukkitEntity" );
67- getBukkitEntity .setAccessible (true );
102+ // TheAndrey: Use MethodHandles
103+ MethodHandles .Lookup lookup = MethodHandles .publicLookup ();
104+ Class <?> craftWorld = getCraftClass ("CraftWorld" );
105+ Class <?> craftEntity = getCraftClass ("entity.CraftEntity" );
106+ Class <?> craftStack = getCraftClass ("inventory.CraftItemStack" );
68107
69- asCraftMirror = CraftUtils .getCraftClass ("inventory.CraftItemStack" ).getDeclaredMethod ("asCraftMirror" , ItemStack .class );
70- asCraftMirror .setAccessible (true );
108+ getWorld = lookup .findVirtual (World .class , "getWorld" , MethodType .methodType (craftWorld ));
109+ getBukkitEntity = lookup .findVirtual (Entity .class , "getBukkitEntity" , MethodType .methodType (craftEntity ));
110+ asCraftMirror = lookup .findStatic (craftStack , "asCraftMirror" , MethodType .methodType (craftStack , ItemStack .class ));
71111 }
72112 catch (Throwable throwable )
73113 {
74114 throw new RuntimeException ("Failed hooking CraftBukkit methods!" , throwable );
75115 }
76116 }
117+
118+ public static Class <?> getCraftClass (String name ) throws ClassNotFoundException
119+ {
120+ return Class .forName (EventHelper .craftPackage + '.' + name );
121+ }
77122}
0 commit comments