Compare commits

...

2 Commits

Author SHA1 Message Date
Maurice Eisenblätter 70e3fd9a75
Merge 8d48e74f49 into e1255edb32 2024-04-24 16:30:35 +00:00
Maurice Eisenblätter 8d48e74f49
feat: add support for 1.20.5 2024-04-24 18:30:19 +02:00
5 changed files with 523 additions and 495 deletions

View File

@ -33,7 +33,8 @@ final class ChannelProtocolUtil {
BiFunction<Channel, PacketType.Sender, Object> baseResolver = null; BiFunction<Channel, PacketType.Sender, Object> baseResolver = null;
if (attributeKeys.isEmpty()) { if (attributeKeys.isEmpty()) {
baseResolver = new Post1_20_4WrappedResolver(); // since 1.20.5 the protocol is stored as final field in de-/encoder
baseResolver = new Post1_20_5WrappedResolver();
} else if (attributeKeys.size() == 1) { } else if (attributeKeys.size() == 1) {
// if there is only one attribute key we can assume it's the correct one (1.8 - 1.20.1) // if there is only one attribute key we can assume it's the correct one (1.8 - 1.20.1)
Object protocolKey = Accessors.getFieldAccessor(attributeKeys.get(0)).get(null); Object protocolKey = Accessors.getFieldAccessor(attributeKeys.get(0)).get(null);
@ -137,7 +138,10 @@ final class ChannelProtocolUtil {
} }
} }
private static final class Post1_20_4WrappedResolver implements BiFunction<Channel, PacketType.Sender, Object> { /**
* 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> {
// lazy initialized when needed // lazy initialized when needed
private Function<Object, Object> serverProtocolAccessor; private Function<Object, Object> serverProtocolAccessor;
@ -151,23 +155,11 @@ final class ChannelProtocolUtil {
return null; return null;
} }
Function<Object, Object> protocolAccessor = this.getProtocolAccessor(sender, codecHandler.getClass()); Function<Object, Object> protocolAccessor = this.getProtocolAccessor(codecHandler.getClass(), sender);
return protocolAccessor.apply(codecHandler); return protocolAccessor.apply(codecHandler);
} }
private String getKeyForSender(PacketType.Sender sender) { private Function<Object, Object> getProtocolAccessor(Class<?> codecHandler, PacketType.Sender sender) {
switch (sender) {
case SERVER:
return "encoder";
case CLIENT:
return "decoder";
default:
throw new IllegalArgumentException("Illegal packet sender " + sender.name());
}
}
private Function<Object, Object> getProtocolAccessor(PacketType.Sender sender, Class<?> codecHandler) {
switch (sender) { switch (sender) {
case SERVER: case SERVER:
if (this.serverProtocolAccessor == null) { if (this.serverProtocolAccessor == null) {
@ -184,17 +176,27 @@ final class ChannelProtocolUtil {
} }
} }
private Function<Object, Object> getProtocolAccessor(Class<?> codecHandler) { private String getKeyForSender(PacketType.Sender sender) {
Class<?> protocolInfoClass = MinecraftReflection.getMinecraftClass("network.ProtocolInfo"); switch (sender) {
case SERVER:
return "encoder";
case CLIENT:
return "decoder";
default:
throw new IllegalArgumentException("Illegal packet sender " + sender.name());
}
}
MethodAccessor protocolAccessor = Accessors.getMethodAccessor( private Function<Object, Object> getProtocolAccessor(Class<?> codecHandler) {
FuzzyReflection.fromClass(protocolInfoClass) Class<?> protocolInfoClass = MinecraftReflection.getProtocolInfoClass();
.getMethod(FuzzyMethodContract.newBuilder()
.returnTypeExact(MinecraftReflection.getEnumProtocolClass()) MethodAccessor protocolAccessor = Accessors.getMethodAccessor(FuzzyReflection
.build())); .fromClass(protocolInfoClass)
.getMethodByReturnTypeAndParameters("id", MinecraftReflection.getEnumProtocolClass(), new Class[0]));
FieldAccessor protocolInfoAccessor = Accessors.getFieldAccessor(codecHandler, protocolInfoClass, true); FieldAccessor protocolInfoAccessor = Accessors.getFieldAccessor(codecHandler, protocolInfoClass, true);
// get ProtocolInfo from handler and get EnumProtocol of ProtocolInfo
return (handler) -> { return (handler) -> {
Object protocolInfo = protocolInfoAccessor.get(handler); Object protocolInfo = protocolInfoAccessor.get(handler);
return protocolAccessor.invoke(protocolInfo); return protocolAccessor.invoke(protocolInfo);

View File

@ -31,6 +31,7 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoop; import io.netty.channel.EventLoop;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import org.bukkit.Server; import org.bukkit.Server;
@ -202,9 +203,18 @@ public class NettyChannelInjector implements Injector {
return false; return false;
} }
ChannelPipeline pipeline = this.wrappedChannel.pipeline();
// since 1.20.5 the encoder is renamed to outbound_config only in the handshake phase
String encoderName = pipeline.get("outbound_config") != null
? "outbound_config" : "encoder";
// inject our handlers // inject our handlers
this.wrappedChannel.pipeline().addAfter("encoder", WIRE_PACKET_ENCODER_NAME, WIRE_PACKET_ENCODER); pipeline.addAfter(
this.wrappedChannel.pipeline().addAfter( encoderName,
WIRE_PACKET_ENCODER_NAME,
WIRE_PACKET_ENCODER);
pipeline.addAfter(
"decoder", "decoder",
INTERCEPTOR_NAME, INTERCEPTOR_NAME,
new InboundPacketInterceptor(this, this.channelListener)); new InboundPacketInterceptor(this, this.channelListener));

View File

@ -638,7 +638,8 @@ public final class MinecraftReflection {
} }
public static boolean isBundleDelimiter(Class<?> packetClass) { public static boolean isBundleDelimiter(Class<?> packetClass) {
return Optionals.Equals(getBundleDelimiterClass(), packetClass); Class<?> bundleDelimiterClass = getBundleDelimiterClass().orElse(null);
return bundleDelimiterClass != null && (packetClass.equals(bundleDelimiterClass) || bundleDelimiterClass.isAssignableFrom(packetClass));
} }
public static Optional<Class<?>> getBundleDelimiterClass() { public static Optional<Class<?>> getBundleDelimiterClass() {
@ -1724,4 +1725,8 @@ public final class MinecraftReflection {
public static Class<?> getHolderLookupProviderClass() { public static Class<?> getHolderLookupProviderClass() {
return getMinecraftClass("core.HolderLookup$a" /* Spigot Mappings */, "core.HolderLookup$Provider" /* Mojang Mappings */); return getMinecraftClass("core.HolderLookup$a" /* Spigot Mappings */, "core.HolderLookup$Provider" /* Mojang Mappings */);
} }
public static Class<?> getProtocolInfoClass() {
return getMinecraftClass("network.ProtocolInfo");
}
} }

View File

@ -9,11 +9,16 @@ import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor; import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
/**
* Static getter for the registry access accessor which is need for most of the methods
* since 1.20.5 that access the registry and in form.
*/
public class MinecraftRegistryAccess { public class MinecraftRegistryAccess {
private static MethodAccessor GET_SERVER = null; private static MethodAccessor GET_SERVER = null;
private static MethodAccessor REGISTRY_ACCESS = null; private static MethodAccessor REGISTRY_ACCESS = null;
// lazy initialized
private static Object registryAccess = null; private static Object registryAccess = null;
static { static {
@ -34,6 +39,12 @@ public class MinecraftRegistryAccess {
} }
} }
/**
* Returns the composite global registry access. Equiv. of
* <pre>((CraftServer) Bukkit.getServer()).getServer().registryAccess()</pre>
*
* @return composite registy acesss
*/
public static Object get() { public static Object get() {
if (GET_SERVER == null || REGISTRY_ACCESS == null) { if (GET_SERVER == null || REGISTRY_ACCESS == null) {
return null; return null;