77
88import javax .annotation .Nonnull ;
99import javax .annotation .Nullable ;
10+ import java .lang .invoke .MethodHandle ;
11+ import java .lang .invoke .MethodHandles ;
12+ import java .lang .invoke .MethodType ;
1013import java .lang .reflect .Constructor ;
1114import java .lang .reflect .InvocationTargetException ;
1215import java .lang .reflect .Method ;
@@ -250,32 +253,52 @@ private static String getCraftBukkitPath() {
250253 * <p>Should generally be used via {@link CompoundTag} rather than directly.</p>
251254 */
252255 public static class CompoundSession {
253- private static final Method hasKey ;
254-
255- private static final Method remove ;
256- private static final Method setBoolean ;
257- private static final Method getBoolean ;
256+ private static final MethodHandle hasKey ;
257+ private static final MethodHandle remove ;
258+ private static final MethodHandle setString ;
259+ private static final MethodHandle getString ;
260+ private static final MethodHandle setBoolean ;
261+ private static final MethodHandle getBoolean ;
258262
259263 private final Object handle ;
260264
261265 static {
262- Method hasTagKey = null ;
263- Method removeM =null ;
264- Method setBooleanM = null ;
265- Method getBooleanM = null ;
266+ MethodHandle hasTagKey = null ;
267+ MethodHandle removeM = null ;
268+ MethodHandle setStringM = null ;
269+ MethodHandle getStringM = null ;
270+ MethodHandle setBooleanM = null ;
271+ MethodHandle getBooleanM = null ;
266272 try {
267273 final Class <?> nbtTag = Class .forName (getNbtTagPath ());
268-
269- hasTagKey = nbtTag .getMethod ("hasKey" , String .class );
274+ /* hasTagKey = nbtTag.getMethod("hasKey", String.class);
270275 removeM = nbtTag.getMethod("remove", String.class);
271276
277+ setStringM = nbtTag.getMethod("setString", String.class, String.class);
278+ getStringM = nbtTag.getMethod("getString", String.class);
272279 setBooleanM = nbtTag.getMethod("setBoolean", String.class, boolean.class);
273- getBooleanM = nbtTag .getMethod ("getBoolean" , String .class );
274- } catch (ClassNotFoundException | NoSuchMethodException e ) {
280+ getBooleanM = nbtTag.getMethod("getBoolean", String.class);*/
281+ MethodHandles .Lookup lookup = MethodHandles .lookup ();
282+ hasTagKey = lookup .findVirtual (nbtTag , "hasKey" ,
283+ MethodType .methodType (boolean .class , String .class ));
284+ removeM = lookup .findVirtual (nbtTag , "remove" ,
285+ MethodType .methodType (void .class , String .class ));
286+ setStringM = lookup .findVirtual (nbtTag , "setString" ,
287+ MethodType .methodType (void .class , String .class , String .class ));
288+ getStringM = lookup .findVirtual (nbtTag , "getString" ,
289+ MethodType .methodType (String .class , String .class ));
290+ setBooleanM = lookup .findVirtual (nbtTag , "setBoolean" ,
291+ MethodType .methodType (void .class , String .class , boolean .class ));
292+ getBooleanM = lookup .findVirtual (nbtTag , "getBoolean" ,
293+ MethodType .methodType (boolean .class , String .class ));
294+
295+ } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e ) {
275296 logger .logError (e , () -> "Failed to bind NBT methods" );
276297 }
277- remove = removeM ;
298+ remove = removeM ;
278299 hasKey = hasTagKey ;
300+ setString = setStringM ;
301+ getString = getStringM ;
279302 setBoolean = setBooleanM ;
280303 getBoolean = getBooleanM ;
281304
@@ -311,12 +334,12 @@ Object getHandle() {
311334 * @param key the NBT key to check
312335 * @return {@code true} if the key exists, otherwise {@code false}
313336 */
314- public boolean hasKey (@ Nonnull String key ) {
337+ public boolean hasKey (@ Nonnull final String key ) {
315338 if (hasKey == null ) return false ;
316339
317340 try {
318341 return (boolean ) hasKey .invoke (handle , key );
319- } catch (IllegalAccessException | InvocationTargetException e ) {
342+ } catch (Throwable e ) {
320343 logger .logError (e , () -> "Failed to check if the compound have the key." );
321344 }
322345 return false ;
@@ -328,13 +351,15 @@ public boolean hasKey(@Nonnull String key) {
328351 *
329352 * @param key the NBT key to remove.
330353 */
331- public void remove (@ Nonnull String key ) {
354+ public void remove (@ Nonnull final String key ) {
332355 if (remove == null ) return ;
333356
334357 try {
335358 remove .invoke (handle , key );
336359 } catch (IllegalAccessException | InvocationTargetException e ) {
337360 logger .logError (e , () -> "Failed to check if the compound have the key." );
361+ } catch (Throwable e ) {
362+ throw new RuntimeException (e );
338363 }
339364 }
340365
@@ -344,12 +369,12 @@ public void remove(@Nonnull String key) {
344369 * @param key the key to set
345370 * @param value the boolean value to assign
346371 */
347- public void setBoolean (@ Nonnull String key , boolean value ) {
372+ public void setBoolean (@ Nonnull final String key , final boolean value ) {
348373 if (setBoolean == null ) return ;
349374
350375 try {
351376 setBoolean .invoke (handle , key , value );
352- } catch (IllegalAccessException | InvocationTargetException e ) {
377+ } catch (Throwable e ) {
353378 logger .logError (e , () -> "Failed to set boolean value from reflection" );
354379 }
355380 }
@@ -360,12 +385,12 @@ public void setBoolean(@Nonnull String key, boolean value) {
360385 * @param key the key of the boolean value
361386 * @return the stored boolean value, or {@code false} if unavailable
362387 */
363- public boolean getBoolean (@ Nonnull String key ) {
388+ public boolean getBoolean (@ Nonnull final String key ) {
364389 if (getBoolean == null ) return false ;
365390
366391 try {
367392 return (boolean ) getBoolean .invoke (handle , key );
368- } catch (IllegalAccessException | InvocationTargetException e ) {
393+ } catch (Throwable e ) {
369394 logger .logError (e , () -> "Failed to retrieve boolean value from reflection" );
370395 }
371396 return false ;
0 commit comments