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();