mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-22 16:29:25 +00:00
Re-added support for BungeeCord 1.18
Metrics showed that more than 33% of the BungeeCord platform users still use a 1.18.x version
This commit is contained in:
@@ -29,7 +29,6 @@ object Versions {
|
|||||||
const val configUtilsVersion = "1.0-SNAPSHOT"
|
const val configUtilsVersion = "1.0-SNAPSHOT"
|
||||||
const val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
const val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
||||||
const val fastutilVersion = "8.5.3"
|
const val fastutilVersion = "8.5.3"
|
||||||
const val lombokVersion = "1.18.20"
|
|
||||||
const val guiceVersion = "5.0.1"
|
const val guiceVersion = "5.0.1"
|
||||||
const val nettyVersion = "4.1.49.Final"
|
const val nettyVersion = "4.1.49.Final"
|
||||||
const val snakeyamlVersion = "1.28"
|
const val snakeyamlVersion = "1.28"
|
||||||
|
|||||||
@@ -25,27 +25,48 @@
|
|||||||
|
|
||||||
package org.geysermc.floodgate.pluginmessage;
|
package org.geysermc.floodgate.pluginmessage;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
|
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
|
||||||
import static org.geysermc.floodgate.util.ReflectionUtils.setValue;
|
import static org.geysermc.floodgate.util.ReflectionUtils.getMethodByName;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.connection.InitialHandler;
|
import net.md_5.bungee.connection.InitialHandler;
|
||||||
import net.md_5.bungee.connection.LoginResult;
|
import net.md_5.bungee.connection.LoginResult;
|
||||||
import net.md_5.bungee.protocol.Property;
|
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||||
import org.geysermc.floodgate.skin.SkinApplier;
|
import org.geysermc.floodgate.skin.SkinApplier;
|
||||||
import org.geysermc.floodgate.skin.SkinData;
|
import org.geysermc.floodgate.skin.SkinData;
|
||||||
|
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public final class BungeeSkinApplier implements SkinApplier {
|
public final class BungeeSkinApplier implements SkinApplier {
|
||||||
private static final Field LOGIN_RESULT;
|
private static final Field LOGIN_RESULT_FIELD;
|
||||||
|
private static final Method SET_PROPERTIES_METHOD;
|
||||||
|
|
||||||
|
private static final Class<?> PROPERTY_CLASS;
|
||||||
|
private static final Constructor<?> PROPERTY_CONSTRUCTOR;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
LOGIN_RESULT = getFieldOfType(InitialHandler.class, LoginResult.class);
|
LOGIN_RESULT_FIELD = getFieldOfType(InitialHandler.class, LoginResult.class);
|
||||||
|
checkNotNull(LOGIN_RESULT_FIELD, "LoginResult field cannot be null");
|
||||||
|
|
||||||
|
SET_PROPERTIES_METHOD = getMethodByName(LoginResult.class, "setProperties", true);
|
||||||
|
|
||||||
|
PROPERTY_CLASS = ReflectionUtils.getClassOrFallbackPrefixed(
|
||||||
|
"protocol.Property", "connection.LoginResult.Property"
|
||||||
|
);
|
||||||
|
|
||||||
|
PROPERTY_CONSTRUCTOR = ReflectionUtils.getConstructor(
|
||||||
|
PROPERTY_CLASS, true,
|
||||||
|
String.class, String.class, String.class
|
||||||
|
);
|
||||||
|
checkNotNull(PROPERTY_CONSTRUCTOR, "Property constructor cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
private final FloodgateLogger logger;
|
private final FloodgateLogger logger;
|
||||||
@@ -71,11 +92,17 @@ public final class BungeeSkinApplier implements SkinApplier {
|
|||||||
if (loginResult == null) {
|
if (loginResult == null) {
|
||||||
// id and name are unused and properties will be overridden
|
// id and name are unused and properties will be overridden
|
||||||
loginResult = new LoginResult(null, null, null);
|
loginResult = new LoginResult(null, null, null);
|
||||||
setValue(handler, LOGIN_RESULT, loginResult);
|
ReflectionUtils.setValue(handler, LOGIN_RESULT_FIELD, loginResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
Property property = new Property("textures", skinData.getValue(), skinData.getSignature());
|
Object property = ReflectionUtils.newInstance(
|
||||||
|
PROPERTY_CONSTRUCTOR,
|
||||||
|
"textures", skinData.getValue(), skinData.getSignature()
|
||||||
|
);
|
||||||
|
|
||||||
loginResult.setProperties(new Property[]{property});
|
Object propertyArray = Array.newInstance(PROPERTY_CLASS, 1);
|
||||||
|
Array.set(propertyArray, 0, property);
|
||||||
|
|
||||||
|
ReflectionUtils.invoke(loginResult, SET_PROPERTIES_METHOD, propertyArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ public final class ReflectionUtils {
|
|||||||
@Setter
|
@Setter
|
||||||
private static String prefix;
|
private static String prefix;
|
||||||
|
|
||||||
|
private static String applyPrefix(String className) {
|
||||||
|
return prefix + "." + className;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a class that is prefixed with the prefix provided in {@link #setPrefix(String)}. Calling
|
* Get a class that is prefixed with the prefix provided in {@link #setPrefix(String)}. Calling
|
||||||
* this method is equal to calling {@link #getClass(String)} with <i>prefix</i>.<i>classname</i>
|
* this method is equal to calling {@link #getClass(String)} with <i>prefix</i>.<i>classname</i>
|
||||||
@@ -56,13 +60,13 @@ public final class ReflectionUtils {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Class<?> getPrefixedClass(String className) {
|
public static Class<?> getPrefixedClass(String className) {
|
||||||
return getClass(prefix + "." + className);
|
return getClass(applyPrefix(className));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Class<?> getPrefixedClassSilently(String className) {
|
public static Class<?> getPrefixedClassSilently(String className) {
|
||||||
try {
|
try {
|
||||||
return Class.forName(prefix + "." + className);
|
return Class.forName(applyPrefix(className));
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -109,6 +113,28 @@ public final class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Class<?> getClassOrFallbackPrefixed(String className, String fallbackClassName) {
|
||||||
|
return getClassOrFallback(applyPrefix(className), applyPrefix(fallbackClassName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> getClassOrFallback(String className, String fallbackClassName) {
|
||||||
|
Class<?> clazz = getClassSilently(className);
|
||||||
|
|
||||||
|
if (clazz != null) {
|
||||||
|
if (Constants.DEBUG_MODE) {
|
||||||
|
System.out.println("Found class (primary): " + clazz.getName());
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do throw an exception when both classes couldn't be found
|
||||||
|
clazz = ReflectionUtils.getClassOrThrow(fallbackClassName);
|
||||||
|
if (Constants.DEBUG_MODE) {
|
||||||
|
System.out.println("Found class (fallback): " + clazz.getName());
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T> Constructor<T> getConstructor(Class<T> clazz, boolean declared, Class<?>... parameters) {
|
public static <T> Constructor<T> getConstructor(Class<T> clazz, boolean declared, Class<?>... parameters) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package org.geysermc.floodgate.util;
|
package org.geysermc.floodgate.util;
|
||||||
|
|
||||||
|
import static org.geysermc.floodgate.util.ReflectionUtils.getClassOrFallback;
|
||||||
import static org.geysermc.floodgate.util.ReflectionUtils.getField;
|
import static org.geysermc.floodgate.util.ReflectionUtils.getField;
|
||||||
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
|
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
|
||||||
import static org.geysermc.floodgate.util.ReflectionUtils.getMethod;
|
import static org.geysermc.floodgate.util.ReflectionUtils.getMethod;
|
||||||
@@ -85,12 +86,12 @@ public class ClassNames {
|
|||||||
|
|
||||||
|
|
||||||
// SpigotInjector
|
// SpigotInjector
|
||||||
MINECRAFT_SERVER = getClassOrFallBack(
|
MINECRAFT_SERVER = getClassOrFallback(
|
||||||
"net.minecraft.server.MinecraftServer",
|
"net.minecraft.server.MinecraftServer",
|
||||||
nmsPackage + "MinecraftServer"
|
nmsPackage + "MinecraftServer"
|
||||||
);
|
);
|
||||||
|
|
||||||
SERVER_CONNECTION = getClassOrFallBack(
|
SERVER_CONNECTION = getClassOrFallback(
|
||||||
"net.minecraft.server.network.ServerConnection",
|
"net.minecraft.server.network.ServerConnection",
|
||||||
nmsPackage + "ServerConnection"
|
nmsPackage + "ServerConnection"
|
||||||
);
|
);
|
||||||
@@ -105,14 +106,14 @@ public class ClassNames {
|
|||||||
craftOfflinePlayerClass, true, craftServerClass, GameProfile.class);
|
craftOfflinePlayerClass, true, craftServerClass, GameProfile.class);
|
||||||
|
|
||||||
// SpigotDataHandler
|
// SpigotDataHandler
|
||||||
Class<?> networkManager = getClassOrFallBack(
|
Class<?> networkManager = getClassOrFallback(
|
||||||
"net.minecraft.network.NetworkManager",
|
"net.minecraft.network.NetworkManager",
|
||||||
nmsPackage + "NetworkManager"
|
nmsPackage + "NetworkManager"
|
||||||
);
|
);
|
||||||
|
|
||||||
SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false);
|
SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false);
|
||||||
|
|
||||||
HANDSHAKE_PACKET = getClassOrFallBack(
|
HANDSHAKE_PACKET = getClassOrFallback(
|
||||||
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol",
|
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol",
|
||||||
nmsPackage + "PacketHandshakingInSetProtocol"
|
nmsPackage + "PacketHandshakingInSetProtocol"
|
||||||
);
|
);
|
||||||
@@ -120,12 +121,12 @@ public class ClassNames {
|
|||||||
HANDSHAKE_HOST = getFieldOfType(HANDSHAKE_PACKET, String.class);
|
HANDSHAKE_HOST = getFieldOfType(HANDSHAKE_PACKET, String.class);
|
||||||
checkNotNull(HANDSHAKE_HOST, "Handshake host");
|
checkNotNull(HANDSHAKE_HOST, "Handshake host");
|
||||||
|
|
||||||
LOGIN_START_PACKET = getClassOrFallBack(
|
LOGIN_START_PACKET = getClassOrFallback(
|
||||||
"net.minecraft.network.protocol.login.PacketLoginInStart",
|
"net.minecraft.network.protocol.login.PacketLoginInStart",
|
||||||
nmsPackage + "PacketLoginInStart"
|
nmsPackage + "PacketLoginInStart"
|
||||||
);
|
);
|
||||||
|
|
||||||
LOGIN_LISTENER = getClassOrFallBack(
|
LOGIN_LISTENER = getClassOrFallback(
|
||||||
"net.minecraft.server.network.LoginListener",
|
"net.minecraft.server.network.LoginListener",
|
||||||
nmsPackage + "LoginListener"
|
nmsPackage + "LoginListener"
|
||||||
);
|
);
|
||||||
@@ -146,14 +147,14 @@ public class ClassNames {
|
|||||||
INIT_UUID = getMethod(LOGIN_LISTENER, "initUUID");
|
INIT_UUID = getMethod(LOGIN_LISTENER, "initUUID");
|
||||||
checkNotNull(INIT_UUID, "initUUID from LoginListener");
|
checkNotNull(INIT_UUID, "initUUID from LoginListener");
|
||||||
|
|
||||||
Class<?> packetListenerClass = getClassOrFallBack(
|
Class<?> packetListenerClass = getClassOrFallback(
|
||||||
"net.minecraft.network.PacketListener",
|
"net.minecraft.network.PacketListener",
|
||||||
nmsPackage + "PacketListener"
|
nmsPackage + "PacketListener"
|
||||||
);
|
);
|
||||||
PACKET_LISTENER = getFieldOfType(networkManager, packetListenerClass);
|
PACKET_LISTENER = getFieldOfType(networkManager, packetListenerClass);
|
||||||
checkNotNull(PACKET_LISTENER, "Packet listener");
|
checkNotNull(PACKET_LISTENER, "Packet listener");
|
||||||
|
|
||||||
LOGIN_HANDLER = getClassOrFallBack(
|
LOGIN_HANDLER = getClassOrFallback(
|
||||||
"net.minecraft.server.network.LoginListener$LoginHandler",
|
"net.minecraft.server.network.LoginListener$LoginHandler",
|
||||||
nmsPackage + "LoginListener$LoginHandler"
|
nmsPackage + "LoginListener$LoginHandler"
|
||||||
);
|
);
|
||||||
@@ -188,25 +189,6 @@ public class ClassNames {
|
|||||||
paperConfig == null ? null : getField(paperConfig, "velocitySupport");
|
paperConfig == null ? null : getField(paperConfig, "velocitySupport");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Class<?> getClassOrFallBack(String className, String fallbackName) {
|
|
||||||
Class<?> clazz = ReflectionUtils.getClassSilently(className);
|
|
||||||
|
|
||||||
if (clazz != null) {
|
|
||||||
if (Constants.DEBUG_MODE) {
|
|
||||||
System.out.println("Found class (primary): " + clazz.getName());
|
|
||||||
}
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do throw an exception when both classes couldn't be found
|
|
||||||
clazz = ReflectionUtils.getClassOrThrow(fallbackName);
|
|
||||||
if (Constants.DEBUG_MODE) {
|
|
||||||
System.out.println("Found class (fallback): " + clazz.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkNotNull(Object toCheck, String objectName) {
|
private static void checkNotNull(Object toCheck, String objectName) {
|
||||||
Preconditions.checkNotNull(toCheck, objectName + " cannot be null");
|
Preconditions.checkNotNull(toCheck, objectName + " cannot be null");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user