Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/main/java/de/ytendx/haproxy/tinyprotocol/Reflection.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import de.ytendx.haproxy.HAProxySpigotImplementor;
import org.bukkit.Bukkit;

/**
Expand Down Expand Up @@ -73,9 +75,11 @@ public interface FieldAccessor<T> {
}

// Deduce the net.minecraft.server.v* package
private static String OBC_PREFIX = Bukkit.getServer().getClass().getPackage().getName();
private static String VERSION = OBC_PREFIX.replace("org.bukkit.craftbukkit", "").replace(".", "");
private static String NMS_PREFIX = OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server");
public static String OBC_PREFIX = Bukkit.getServer().getClass().getPackage().getName();
public static String VERSION = OBC_PREFIX.replace("org.bukkit.craftbukkit", "").replace(".", "");
public static String NMS_PREFIX = (Reflection.isNewerPackage() ?
OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server").replace(VERSION, "") :
OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server"));

// Variable replacement
private static Pattern MATCH_VARIABLE = Pattern.compile("\\{([^\\}]+)\\}");
Expand Down Expand Up @@ -366,13 +370,18 @@ private static Class<?> getCanonicalClass(String canonicalName) {
}
}

public static boolean isNewerPackage(){
HAProxySpigotImplementor.getPlugin(HAProxySpigotImplementor.class).getLogger().info(VERSION + " | " + Reflection.NMS_PREFIX + " | " + OBC_PREFIX);
return VERSION.contains("17") || VERSION.contains("18") || VERSION.contains("19") || VERSION.contains("20");
}

/**
* Expand variables such as "{nms}" and "{obc}" to their corresponding packages.
*
* @param name - the full name of the class.
* @return The expanded string.
*/
private static String expandVariables(String name) {
public static String expandVariables(String name) {
StringBuffer output = new StringBuffer();
Matcher matcher = MATCH_VARIABLE.matcher(name);

Expand All @@ -382,7 +391,7 @@ private static String expandVariables(String name) {

// Expand all detected variables
if ("nms".equalsIgnoreCase(variable))
replacement = NMS_PREFIX;
replacement = isNewerPackage() ? "net.minecraft.server" : NMS_PREFIX;
else if ("obc".equalsIgnoreCase(variable))
replacement = OBC_PREFIX;
else if ("version".equalsIgnoreCase(variable))
Expand Down
53 changes: 28 additions & 25 deletions src/main/java/de/ytendx/haproxy/tinyprotocol/TinyProtocol.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package de.ytendx.haproxy.tinyprotocol;

import de.ytendx.haproxy.HAProxySpigotImplementor;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.sql.Ref;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;

import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.haproxy.HAProxyMessage;
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
import org.bukkit.Bukkit;
Expand All @@ -22,16 +29,19 @@
* @author Kristian // Love ya <3 ~ytendx
*/
public class TinyProtocol {
private static final AtomicInteger ID = new AtomicInteger(0);

// Looking up ServerConnection
private static final Class<Object> minecraftServerClass = Reflection.getUntypedClass("{nms}.MinecraftServer");
private static final Class<Object> serverConnectionClass = Reflection.getUntypedClass("{nms}.ServerConnection");
private static final Class<Object> serverConnectionClass = Reflection.getUntypedClass("{nms}" + (Reflection.isNewerPackage() ? ".network" : "") + ".ServerConnection");
private static final Reflection.FieldAccessor<Object> getMinecraftServer = Reflection.getField("{obc}.CraftServer", minecraftServerClass, 0);
private static final Reflection.FieldAccessor<Object> getServerConnection = Reflection.getField(minecraftServerClass, serverConnectionClass, 0);
private static final Reflection.MethodInvoker getNetworkMarkers = Reflection.getTypedMethod(serverConnectionClass, null, List.class, serverConnectionClass);
private static final Reflection.FieldAccessor<List> networkManagersFieldAccessor;

static {
networkManagersFieldAccessor = Reflection.isNewerPackage() ? Reflection.getField(serverConnectionClass, List.class, 0) : null;
}

private static final Class<Object> networkManager = Reflection.getUntypedClass("{nms}.NetworkManager");
private static final Class<Object> networkManager = Reflection.getUntypedClass(Reflection.isNewerPackage() ? "net.minecraft.network.NetworkManager" : "{nms}.NetworkManager");
private static final Reflection.FieldAccessor<SocketAddress> socketAddressFieldAccessor = Reflection.getField(networkManager, SocketAddress.class, 0);
// List of network markers
private List<Object> networkManagers;
Expand All @@ -42,10 +52,6 @@ public class TinyProtocol {
private ChannelInitializer<Channel> beginInitProtocol;
private ChannelInitializer<Channel> endInitProtocol;

// Current handler name
private String handlerName;

protected volatile boolean closed;
protected Plugin plugin;

/**
Expand All @@ -57,10 +63,8 @@ public class TinyProtocol {
*/
public TinyProtocol(final Plugin plugin) {
this.plugin = plugin;

// Compute handler name
this.handlerName = getHandlerName();


//Useless logging -> plugin.getLogger().info(Reflection.isNewerPackage() + " | " + Reflection.NMS_PREFIX);

try {
plugin.getLogger().info("Proceeding with the server channel injection...");
Expand All @@ -86,12 +90,22 @@ private void createServerChannelHandler() {
@Override
protected void initChannel(Channel channel) throws Exception {
try {
if (Reflection.isNewerPackage()){
synchronized (networkManagers) {
// Adding the decoder to the pipeline
channel.pipeline().addFirst("haproxy-decoder", new HAProxyMessageDecoder());
// Adding the proxy message handler to the pipeline too
channel.pipeline().addAfter("haproxy-decoder", "haproxy-handler", HAPROXY_MESSAGE_HANDLER);
}
return;
}

// Adding the decoder to the pipeline
channel.pipeline().addAfter("timeout", "haproxy-decoder", new HAProxyMessageDecoder());
// Adding the proxy message handler to the pipeline too
channel.pipeline().addAfter("haproxy-decoder", "haproxy-handler", HAPROXY_MESSAGE_HANDLER);
} catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Cannot inject incomming channel " + channel, e);
plugin.getLogger().log(Level.SEVERE, "Cannot inject incoming channel " + channel, e);
}
}

Expand Down Expand Up @@ -128,7 +142,7 @@ private void registerChannelHandler() {
boolean looking = true;

// We need to synchronize against this list
networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);
networkManagers = Reflection.isNewerPackage() ? networkManagersFieldAccessor.get(serverConnection) : new ArrayList<>();
createServerChannelHandler();

// Find the correct list, or implicitly throw an exception
Expand All @@ -151,17 +165,6 @@ private void registerChannelHandler() {
}
}

/**
* Retrieve the name of the channel injector, default implementation is "tiny-" + plugin name + "-" + a unique ID.
* <p>
* Note that this method will only be invoked once. It is no longer necessary to override this to support multiple instances.
*
* @return A unique channel handler name.
*/
protected String getHandlerName() {
return "haproxy-implementor-tiny-" + plugin.getName() + "-" + ID.incrementAndGet();
}

private final HAProxyMessageHandler HAPROXY_MESSAGE_HANDLER = new HAProxyMessageHandler();

@ChannelHandler.Sharable
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: HAProxyImplementor
author: ytendx
version: 1.1.1
version: 1.1.3
api-version: 1.13
main: de.ytendx.haproxy.HAProxySpigotImplementor
website: https://neoprotect.net/
description: Allows the usage of ip forwarding via the HAProxy Protocol v2/v1
Expand Down