package net.minelink.bungeeproxy;

import io.netty.channel.AbstractChannel;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.haproxy.HAProxyMessage;
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.netty.HandlerBoss;
import net.md_5.bungee.netty.PacketHandler;
import net.md_5.bungee.netty.PipelineUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.InetSocketAddress;
import java.util.logging.Level;

public class BungeeProxy extends Plugin {
    private static final Field remoteAddressField;
    private static final Field serverChild;
    private static final ChannelInitializer<Channel> bungeeChannelInitializer;
    private static final Method initChannelMethod;
    private static final Field handlerField;

    static {
        try {
            remoteAddressField = AbstractChannel.class.getDeclaredField("remoteAddress");
            remoteAddressField.setAccessible(true);

            serverChild = PipelineUtils.class.getField("SERVER_CHILD");
            serverChild.setAccessible(true);

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(serverChild, serverChild.getModifiers() & ~Modifier.FINAL);

            bungeeChannelInitializer = PipelineUtils.SERVER_CHILD;

            initChannelMethod = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
            initChannelMethod.setAccessible(true);

            handlerField = HandlerBoss.class.getDeclaredField("handler");
            handlerField.setAccessible(true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onEnable() {
        try {
            serverChild.set(null, new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel channel) throws Exception {
                    initChannelMethod.invoke(bungeeChannelInitializer, channel);
                    channel.pipeline().addAfter(PipelineUtils.TIMEOUT_HANDLER, "haproxy-decoder", new HAProxyMessageDecoder());

                    HandlerBoss handlerBoss = new HandlerBoss() {
                        @Override
                        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                            if (msg instanceof HAProxyMessage) {
                                HAProxyMessage message = (HAProxyMessage) msg;
                                remoteAddressField.set(channel, new InetSocketAddress(message.sourceAddress(), message.sourcePort()));
                            } else {
                                super.channelRead(ctx, msg);
                            }
                        }
                    };

                    handlerBoss.setHandler((PacketHandler) handlerField.get(channel.pipeline().get(HandlerBoss.class)));
                    channel.pipeline().replace(PipelineUtils.BOSS_HANDLER, PipelineUtils.BOSS_HANDLER, handlerBoss);
                }
            });
        } catch (Exception e) {
            getLogger().log(Level.SEVERE, e.getMessage(), e);
            getProxy().stop();
        }
    }
}

@@ -699,285 +699,44 @@
     
-private static final Field remoteAddressField;%0A    private static final Field serverChild;%0A    private static final ChannelInitializer%3CChannel%3E bungeeChannelInitializer;%0A    private static final Method initChannelMethod;%0A    private static final Field handlerField;%0A%0A    static
+@Override%0A    public void onEnable()
  %7B%0A 
@@ -752,32 +752,38 @@
 y %7B%0A            
+Field 
 remoteAddressFie
@@ -901,32 +901,38 @@
 );%0A%0A            
+Field 
 serverChild = Pi
@@ -1253,16 +1253,44 @@
         
+ ChannelInitializer%3CChannel%3E
  bungeeC
@@ -1342,32 +1342,39 @@
 D;%0A%0A            
+Method 
 initChannelMetho
@@ -1507,32 +1507,38 @@
 );%0A%0A            
+Field 
 handlerField = H
@@ -1633,156 +1633,8 @@
 e);%0A
-        %7D catch (Exception e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A    %7D%0A%0A    @Override%0A    public void onEnable() %7B%0A        try %7B
 %0A   

Move everything into onEnable()