From 7edb66a692fc6f1133f2e99375adda0b7cabee7e Mon Sep 17 00:00:00 2001 From: Tim203 Date: Mon, 31 May 2021 16:57:03 +0200 Subject: [PATCH] Always use Unsafe for Bungeecord --- .../inject/bungee/BungeeInjector.java | 12 +- .../floodgate/util/BungeeReflectionUtils.java | 104 ++++-------------- 2 files changed, 20 insertions(+), 96 deletions(-) diff --git a/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java b/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java index a8d195cc..75bb04ea 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java +++ b/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java @@ -51,21 +51,11 @@ public final class BungeeInjector extends CommonPlatformInjector { Field framePrepender = ReflectionUtils.getField(PipelineUtils.class, "framePrepender"); - if (!BungeeReflectionUtils.isJava16()) { - // we have to remove the final modifier before asking for the value - // because we can't remove it after we got the current value - BungeeReflectionUtils.removeFinal(framePrepender); - } - BungeeCustomPrepender customPrepender = new BungeeCustomPrepender( ReflectionUtils.getCastedValue(null, framePrepender), logger ); - if (BungeeReflectionUtils.isJava16()) { - BungeeReflectionUtils.setJava16Field(null, framePrepender, customPrepender); - } else { - ReflectionUtils.setValue(null, framePrepender, customPrepender); - } + BungeeReflectionUtils.setFieldValue(null, framePrepender, customPrepender); injected = true; return true; diff --git a/bungee/src/main/java/org/geysermc/floodgate/util/BungeeReflectionUtils.java b/bungee/src/main/java/org/geysermc/floodgate/util/BungeeReflectionUtils.java index 6915ff7f..6b177888 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/util/BungeeReflectionUtils.java +++ b/bungee/src/main/java/org/geysermc/floodgate/util/BungeeReflectionUtils.java @@ -26,81 +26,37 @@ package org.geysermc.floodgate.util; import static org.geysermc.floodgate.util.MessageFormatter.format; -import static org.geysermc.floodgate.util.ReflectionUtils.castedInvoke; -import static org.geysermc.floodgate.util.ReflectionUtils.getMethod; -import static org.geysermc.floodgate.util.ReflectionUtils.makeAccessible; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import sun.misc.Unsafe; -// Reflection for just Bungee specific reflection because Bungee doesn't like accessibility :) +// Reflection just for Bungee because Bungee is special :) public class BungeeReflectionUtils { - private static final Field MODIFIERS_FIELD; - private static final Unsafe UNSAFE; + private static final sun.misc.Unsafe UNSAFE; static { - Field modifiersField = null; // Should not be null pre-Java-16 - Unsafe unsafe = null; // Should not be null post-Java-16 try { - modifiersField = Field.class.getDeclaredField("modifiers"); - } catch (NoSuchFieldException ignored) { - try { - modifiersField = fixJava12Support(); - } catch (Exception e) { - if (Constants.DEBUG_MODE) { - e.printStackTrace(); - } - - // At this point, we're probably using Java 16 - try { - Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); - unsafeField.setAccessible(true); - unsafe = (Unsafe) unsafeField.get(null); - } catch (Exception exception) { - throw new RuntimeException(format( - "Cannot initialize required reflection setup :/\nJava version: {}\nVendor: {} ({})", - System.getProperty("java.version"), - System.getProperty("java.vendor"), - System.getProperty("java.vendor.url") - ), exception); - } - } + Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + UNSAFE = (sun.misc.Unsafe) unsafeField.get(null); + } catch (Exception exception) { + throw new RuntimeException(format( + "Cannot initialize required reflection setup :/\nJava version: {}\nVendor: {} ({})", + System.getProperty("java.version"), + System.getProperty("java.vendor"), + System.getProperty("java.vendor.url") + ), exception); } - - MODIFIERS_FIELD = modifiersField; - UNSAFE = unsafe; } - private static Field fixJava12Support() throws Exception { - // Java 12 compatibility, thanks to https://github.com/powermock/powermock/pull/1010 - Method declaredFields = getMethod(Class.class, "getDeclaredFields0", boolean.class); - if (declaredFields == null) { - throw new NoSuchMethodException("Cannot find method getDeclaredFields0"); - } - - Field[] fields = castedInvoke(Field.class, declaredFields, false); - if (fields == null) { - throw new RuntimeException("The Field class cannot have null fields"); - } - - for (Field field : fields) { - if ("modifiers".equals(field.getName())) { - return field; - } - } - return null; - } - - public static boolean isJava16() { - return UNSAFE != null; - } - - public static void setJava16Field(Object object, Field field, Object result) { + public static void setFieldValue(Object object, Field field, Object result) { try { boolean isStatic = Modifier.isStatic(field.getModifiers()); - long offset = isStatic ? UNSAFE.staticFieldOffset(field) : UNSAFE.objectFieldOffset(field); + + long offset = isStatic ? + UNSAFE.staticFieldOffset(field) : + UNSAFE.objectFieldOffset(field); + if (isStatic) { UNSAFE.putObject(UNSAFE.staticFieldBase(field), offset, result); } else { @@ -108,32 +64,10 @@ public class BungeeReflectionUtils { } } catch (Exception e) { throw new RuntimeException(format( - "Cannot initialize required reflection setup :/\nJava version: {}\nVendor: {} ({})", + "Java version: {}\nVendor: {} ({})", System.getProperty("java.version"), System.getProperty("java.vendor"), System.getProperty("java.vendor.url"), e)); } } - - /** - * Remove the final modifier of a specific field - * - * @param field the field to remove the final modifier of - * @return true if succeeded - */ - public static boolean removeFinal(Field field) { - try { - makeAccessible(field); - - int modifiers = field.getModifiers(); - if (Modifier.isFinal(modifiers)) { - makeAccessible(MODIFIERS_FIELD); - MODIFIERS_FIELD.setInt(field, modifiers & ~Modifier.FINAL); - } - return true; - } catch (Exception exception) { - exception.printStackTrace(); - return false; - } - } }