diff --git a/CHANGELOG.md b/CHANGELOG.md
index b13f176..d08f118 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 1.0.11 — Strict Channel Field Resolution in FastLoginPlus Adapter
+
+- Fix `FuzzyReflection.getFieldValue(injector, Channel.class, true)` selecting the **preceding Object-typed `networkManager` field** instead of NettyChannelInjector's actual `Channel channel` field. The wrong bidirectional assignability check caused an inactive/null Channel or ClassCastException when FastLoginPlus examined a Java Premium connection during async Mojang session verification, then logged `disconnected during session verification` and timed the player out.
+- Only match fields whose declared type is assignable to the requested class. This is the reflection rule that prevents unsafe casts; don't fall back to unrelated superclasses like `Object`.
+- Add regression tests against the real NettyChannelInjector and a separate Object-before-Channel fixture. Both tests **fail on v1.0.10 and pass on v1.0.11**.
+- Preserve all previous 1.0.7–1.0.10 transport/encryption/late-handler fixes and do not disable FastLoginPlus or AuthMe authentication.
+
## 1.0.10 — Late-binding race during Java Premium login
- Fix the v1.0.9 startup race where `NetworkManagerInjector.getTemporaryInjector` refuses to associate a valid active PacketEvents pre-login Channel with the generated `TemporaryPlayer` if native `packet_handler` has not appeared yet. FastLoginPlus thus loses its Channel for the whole verification session and aborts as disconnected.
diff --git a/pom.xml b/pom.xml
index 10ebda7..da12042 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.comphenix.protocol
ProtocolLib2PacketEvents
- 1.0.10
+ 1.0.11
jar
ProtocolLib2PacketEvents
diff --git a/src/main/java/com/comphenix/protocol/reflect/FuzzyReflection.java b/src/main/java/com/comphenix/protocol/reflect/FuzzyReflection.java
index 4af4fb7..09d9820 100644
--- a/src/main/java/com/comphenix/protocol/reflect/FuzzyReflection.java
+++ b/src/main/java/com/comphenix/protocol/reflect/FuzzyReflection.java
@@ -45,7 +45,12 @@ public static T getFieldValue(Object instance, Class fieldClass, boolean
if (instance == null) throw new IllegalArgumentException("instance cannot be null");
for (Class> current = instance.getClass(); current != null; current = current.getSuperclass()) {
for (Field field : current.getDeclaredFields()) {
- if (fieldClass.isAssignableFrom(field.getType()) || field.getType().isAssignableFrom(fieldClass)) {
+ // Only accept fields whose declared value can be safely read as
+ // fieldClass. The reverse assignability check incorrectly chose
+ // a preceding Object networkManager field when FastLoginPlus
+ // asked for io.netty.channel.Channel, returning null or throwing
+ // ClassCastException even though the real Channel was present.
+ if (fieldClass.isAssignableFrom(field.getType())) {
try {
if (forceAccess) field.setAccessible(true);
return fieldClass.cast(field.get(instance));
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 1bccbdf..f2687e0 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -10,7 +10,7 @@ main: com.comphenix.protocol.ProtocolLib
version: 5.4.0
author: CyoriaSMP Team
description: A drop-in ProtocolLib compatibility layer powered by PacketEvents.
-p2p-version: 1.0.10
+p2p-version: 1.0.11
protocol-lib-api-version: 5.4.0
depend: [packetevents]
provides: [ProtocolLib]
diff --git a/src/test/java/com/comphenix/protocol/reflect/NettyChannelFieldLookupTest.java b/src/test/java/com/comphenix/protocol/reflect/NettyChannelFieldLookupTest.java
new file mode 100644
index 0000000..fd4a735
--- /dev/null
+++ b/src/test/java/com/comphenix/protocol/reflect/NettyChannelFieldLookupTest.java
@@ -0,0 +1,33 @@
+package com.comphenix.protocol.reflect;
+
+import com.comphenix.protocol.injector.netty.channel.NettyChannelInjector;
+import io.netty.channel.Channel;
+import io.netty.channel.embedded.EmbeddedChannel;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class NettyChannelFieldLookupTest {
+ private static final class OldFieldOrder {
+ private final Object networkManager = new Object();
+ private final Channel channel;
+ OldFieldOrder(Channel channel) { this.channel = channel; }
+ }
+
+ @Test
+ void picksExactChannelInsteadOfObjectWithNativeConnection() {
+ EmbeddedChannel channel = new EmbeddedChannel();
+ try {
+ assertSame(channel, FuzzyReflection.getFieldValue(new OldFieldOrder(channel), Channel.class, true));
+ } finally { channel.finishAndReleaseAll(); }
+ }
+
+ @Test
+ void realNettyInjectorReturnsChannelWhenNativeConnectionNotReady() {
+ EmbeddedChannel channel = new EmbeddedChannel();
+ try {
+ NettyChannelInjector injector = new NettyChannelInjector(null, null, channel, null, null, null);
+ assertSame(channel, FuzzyReflection.getFieldValue(injector, Channel.class, true));
+ } finally { channel.finishAndReleaseAll(); }
+ }
+}