From 5cb5992d446abc34fe3249cfa3a2ae88fce757c8 Mon Sep 17 00:00:00 2001 From: KennyTV <28825609+KennyTV@users.noreply.github.com> Date: Fri, 20 Dec 2019 16:35:10 +0100 Subject: [PATCH] Fix Bungee injection on Java 12+ Fixes #1512 --- .../bungee/platform/BungeeViaInjector.java | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java index edc66c086..7f0c0d76a 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java @@ -9,28 +9,43 @@ import us.myles.ViaVersion.bungee.handlers.BungeeChannelInitializer; import us.myles.ViaVersion.util.ReflectionUtil; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.List; public class BungeeViaInjector implements ViaInjector { + @Override public void inject() throws Exception { try { - try { + Class pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils"); + Field field = pipelineUtils.getDeclaredField("SERVER_CHILD"); + field.setAccessible(true); - Class pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils"); - Field field = pipelineUtils.getDeclaredField("SERVER_CHILD"); - field.setAccessible(true); - // Remove any final stuff - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - - BungeeChannelInitializer newInit = new BungeeChannelInitializer((ChannelInitializer) field.get(null)); - field.set(null, newInit); - } catch (NoSuchFieldException e) { - throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: "); + // Remove the final modifier (unless removed by a fork) + int modifiers = field.getModifiers(); + if (Modifier.isFinal(modifiers)) { + try { + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, modifiers & ~Modifier.FINAL); + } catch (NoSuchFieldException e) { + // Java 12 compatibility *this is fine* + Method getDeclaredFields0 = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class); + getDeclaredFields0.setAccessible(true); + Field[] fields = (Field[]) getDeclaredFields0.invoke(Field.class, false); + for (Field classField : fields) { + if ("modifiers".equals(classField.getName())) { + classField.setAccessible(true); + classField.set(field, modifiers & ~Modifier.FINAL); + break; + } + } + } } + + BungeeChannelInitializer newInit = new BungeeChannelInitializer((ChannelInitializer) field.get(null)); + field.set(null, newInit); } catch (Exception e) { Via.getPlatform().getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version."); throw e; @@ -62,11 +77,6 @@ public class BungeeViaInjector implements ViaInjector { Class pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils"); Field field = pipelineUtils.getDeclaredField("SERVER_CHILD"); field.setAccessible(true); - // Remove any final stuff - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - return (ChannelInitializer) field.get(null); }