Skip to content

Commit

Permalink
Fixed Listening to Handshake Packets & ServerPingRecord (#2933)
Browse files Browse the repository at this point in the history
Fixed Listening to Handshake Packets

Fixes #2647
  • Loading branch information
LOOHP authored Jun 3, 2024
1 parent 1325ec6 commit 720bb83
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection;

import io.netty.channel.Channel;
Expand All @@ -31,7 +30,7 @@ final class ChannelProtocolUtil {
.declaringClassExactType(networkManagerClass)
.build());

BiFunction<Channel, PacketType.Sender, Object> baseResolver = null;
BiFunction<Channel, PacketType.Sender, PacketType.Protocol> baseResolver = null;
if (attributeKeys.isEmpty()) {
// since 1.20.5 the protocol is stored as final field in de-/encoder
baseResolver = new Post1_20_5WrappedResolver();
Expand Down Expand Up @@ -75,10 +74,10 @@ final class ChannelProtocolUtil {
}

// decorate the base resolver by wrapping its return value into our packet type value
PROTOCOL_RESOLVER = baseResolver.andThen(nmsProtocol -> PacketType.Protocol.fromVanilla((Enum<?>) nmsProtocol));
PROTOCOL_RESOLVER = baseResolver;
}

private static final class Pre1_20_2DirectResolver implements BiFunction<Channel, PacketType.Sender, Object> {
private static final class Pre1_20_2DirectResolver implements BiFunction<Channel, PacketType.Sender, PacketType.Protocol> {

private final AttributeKey<Object> attributeKey;

Expand All @@ -87,12 +86,12 @@ public Pre1_20_2DirectResolver(AttributeKey<Object> attributeKey) {
}

@Override
public Object apply(Channel channel, PacketType.Sender sender) {
return channel.attr(this.attributeKey).get();
public PacketType.Protocol apply(Channel channel, PacketType.Sender sender) {
return PacketType.Protocol.fromVanilla((Enum<?>) channel.attr(this.attributeKey).get());
}
}

private static final class Post1_20_2WrappedResolver implements BiFunction<Channel, PacketType.Sender, Object> {
private static final class Post1_20_2WrappedResolver implements BiFunction<Channel, PacketType.Sender, PacketType.Protocol> {

private final AttributeKey<Object> serverBoundKey;
private final AttributeKey<Object> clientBoundKey;
Expand All @@ -106,15 +105,15 @@ public Post1_20_2WrappedResolver(AttributeKey<Object> serverBoundKey, AttributeK
}

@Override
public Object apply(Channel channel, PacketType.Sender sender) {
public PacketType.Protocol apply(Channel channel, PacketType.Sender sender) {
AttributeKey<Object> key = this.getKeyForSender(sender);
Object codecData = channel.attr(key).get();
if (codecData == null) {
return null;
}

FieldAccessor protocolAccessor = this.getProtocolAccessor(codecData.getClass());
return protocolAccessor.get(codecData);
return PacketType.Protocol.fromVanilla((Enum<?>) protocolAccessor.get(codecData));
}

private AttributeKey<Object> getKeyForSender(PacketType.Sender sender) {
Expand All @@ -141,22 +140,26 @@ private FieldAccessor getProtocolAccessor(Class<?> codecClass) {
/**
* Since 1.20.5 the protocol is stored as final field in de-/encoder
*/
private static final class Post1_20_5WrappedResolver implements BiFunction<Channel, PacketType.Sender, Object> {
private static final class Post1_20_5WrappedResolver implements BiFunction<Channel, PacketType.Sender, PacketType.Protocol> {

// lazy initialized when needed
private Function<Object, Object> serverProtocolAccessor;
private Function<Object, Object> clientProtocolAccessor;

@Override
public Object apply(Channel channel, PacketType.Sender sender) {
public PacketType.Protocol apply(Channel channel, PacketType.Sender sender) {
String key = this.getKeyForSender(sender);
Object codecHandler = channel.pipeline().get(key);
if (codecHandler == null) {
String unconfiguratedKey = this.getUnconfiguratedKeyForSender(sender);
if (channel.pipeline().get(unconfiguratedKey) != null) {
return PacketType.Protocol.HANDSHAKING;
}
return null;
}

Function<Object, Object> protocolAccessor = this.getProtocolAccessor(codecHandler.getClass(), sender);
return protocolAccessor.apply(codecHandler);
return PacketType.Protocol.fromVanilla((Enum<?>) protocolAccessor.apply(codecHandler));
}

private Function<Object, Object> getProtocolAccessor(Class<?> codecHandler, PacketType.Sender sender) {
Expand Down Expand Up @@ -187,6 +190,17 @@ private String getKeyForSender(PacketType.Sender sender) {
}
}

private String getUnconfiguratedKeyForSender(PacketType.Sender sender) {
switch (sender) {
case SERVER:
return "outbound_config";
case CLIENT:
return "inbound_config";
default:
throw new IllegalArgumentException("Illegal packet sender " + sender.name());
}
}

private Function<Object, Object> getProtocolAccessor(Class<?> codecHandler) {
Class<?> protocolInfoClass = MinecraftReflection.getProtocolInfoClass();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private static void initialize() {

DATA_WRAPPER = AutoWrapper.wrap(ServerData.class, SERVER_DATA_CLASS);
SAMPLE_WRAPPER = AutoWrapper.wrap(PlayerSample.class, PLAYER_SAMPLE_CLASS);
FAVICON_WRAPPER = AutoWrapper.wrap(Favicon.class, MinecraftReflection.getMinecraftClass("network.protocol.status.ServerPing$a"));
FAVICON_WRAPPER = AutoWrapper.wrap(Favicon.class, MinecraftReflection.getMinecraftClass("network.protocol.status.ServerPing$a", "network.protocol.status.ServerStatus$Favicon"));

PROFILE_LIST_CONVERTER = BukkitConverters.getListConverter(BukkitConverters.getWrappedGameProfileConverter());

Expand Down

0 comments on commit 720bb83

Please sign in to comment.