diff --git a/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java b/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java index 7efc4ae5..e63e0768 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java +++ b/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java @@ -59,6 +59,15 @@ public final class ReflectionUtils { return getClass(prefix + "." + className); } + @Nullable + public static Class getPrefixedClassSilently(String className) { + try { + return Class.forName(prefix + "." + className); + } catch (ClassNotFoundException ignored) { + return null; + } + } + /** * Get the class from a class name. Calling this method is equal to calling {@link * Class#forName(String)} where String is the class name.
This method will return null when @@ -485,7 +494,9 @@ public final class ReflectionUtils { * @return the accessibleObject */ public static T makeAccessible(T accessibleObject) { - accessibleObject.setAccessible(true); + if (!accessibleObject.isAccessible()) { + accessibleObject.setAccessible(true); + } return accessibleObject; } } diff --git a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java index 6712ee34..2a763c60 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java +++ b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java @@ -95,7 +95,7 @@ public final class VelocityProxyDataHandler extends CommonDataHandler { logger.info("Floodgate player who is logged in as {} {} joined", player.getCorrectUsername(), player.getCorrectUniqueId()); } - return true; + return super.shouldRemoveHandler(result); } @Override diff --git a/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java b/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java index f879c4ef..0c314854 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java +++ b/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java @@ -26,8 +26,10 @@ package org.geysermc.floodgate.listener; import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue; +import static org.geysermc.floodgate.util.ReflectionUtils.getField; import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType; import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass; +import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClassSilently; import static org.geysermc.floodgate.util.ReflectionUtils.getValue; import com.google.common.cache.Cache; @@ -46,6 +48,7 @@ import io.netty.channel.Channel; import io.netty.util.AttributeKey; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Objects; import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; import org.geysermc.floodgate.api.ProxyFloodgateApi; @@ -56,13 +59,27 @@ import org.geysermc.floodgate.util.VelocityCommandUtil; public final class VelocityListener { private static final Field INITIAL_MINECRAFT_CONNECTION; + private static final Field INITIAL_CONNECTION_DELEGATE; private static final Field CHANNEL; static { Class initialConnection = getPrefixedClass("connection.client.InitialInboundConnection"); - Class minecraftConnection = getPrefixedClass("connection.MinecraftConnection"); INITIAL_MINECRAFT_CONNECTION = getFieldOfType(initialConnection, minecraftConnection); + + // Since Velocity 3.1.0 + Class loginInboundConnection = + getPrefixedClassSilently("connection.client.LoginInboundConnection"); + if (loginInboundConnection != null) { + INITIAL_CONNECTION_DELEGATE = getField(loginInboundConnection, "delegate"); + Objects.requireNonNull( + INITIAL_CONNECTION_DELEGATE, + "initial inbound connection delegate cannot be null" + ); + } else { + INITIAL_CONNECTION_DELEGATE = null; + } + CHANNEL = getFieldOfType(minecraftConnection, Channel.class); } @@ -89,7 +106,14 @@ public final class VelocityListener { FloodgatePlayer player = null; String kickMessage; try { - Object mcConnection = getValue(event.getConnection(), INITIAL_MINECRAFT_CONNECTION); + InboundConnection connection = event.getConnection(); + if (INITIAL_CONNECTION_DELEGATE != null) { + // Velocity 3.1.0 added LoginInboundConnection which is used in the login state, + // but that class doesn't have a Channel field. However, it does have + // InitialInboundConnection as a field + connection = getCastedValue(connection, INITIAL_CONNECTION_DELEGATE); + } + Object mcConnection = getValue(connection, INITIAL_MINECRAFT_CONNECTION); Channel channel = getCastedValue(mcConnection, CHANNEL); player = channel.attr(playerAttribute).get();