Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Listening to Handshake Packets & ServerPingRecord #2933

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change the type here from Object to PacketType.Protocol? Doesn't this only introduce duplicate code since you copied the PacketType.Protocol::fromVanilla method to the resolver implementations?

Copy link
Contributor Author

@LOOHP LOOHP May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

It does create some duplication but as PacketType.Protocol::fromVanilla isn't used everywhere anymore after this change with some cases returning the the packet type directly, I felt like it made sense to make the function return the type directly.

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
Loading