From e88419b06c03155162d84b267eaa8e083c8e4258 Mon Sep 17 00:00:00 2001 From: FlorianMichael <60033407+FlorianMichael@users.noreply.github.com> Date: Fri, 7 Apr 2023 02:13:33 +0200 Subject: [PATCH] fixed Compression issues --- gradle.properties | 4 +- .../mixin/base/MixinClientConnection.java | 17 +- .../mixin/base/MixinClientConnection_1.java | 4 +- .../protocolhack/PipelineInjector.java | 146 ------------------ .../protocolhack/ProtocolHack.java | 67 +++++++- .../ViaFabricPlusVLBPipeline.java | 127 +++++++++++++++ .../constants/BedrockRakNetConstants.java | 29 ---- .../constants/PreNettyConstants.java | 23 --- .../ViaFabricPlusPreNettyLengthCodec.java | 55 ------- .../ViaFabricPlusVLBBaseVersionProvider.java | 2 +- .../replacement/ViaFabricPlusVLBViaCodec.java | 47 ------ src/main/resources/viafabricplus.mixins.json | 4 +- 12 files changed, 207 insertions(+), 318 deletions(-) delete mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/PipelineInjector.java create mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/ViaFabricPlusVLBPipeline.java delete mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/BedrockRakNetConstants.java delete mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/PreNettyConstants.java delete mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/platform/vialegacy/ViaFabricPlusPreNettyLengthCodec.java rename src/main/java/de/florianmichael/viafabricplus/protocolhack/{replacement => provider/vialoadingbase}/ViaFabricPlusVLBBaseVersionProvider.java (94%) delete mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/replacement/ViaFabricPlusVLBViaCodec.java diff --git a/gradle.properties b/gradle.properties index 11741b0f..e73ed253 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ maven_group=de.florianmichael archives_base_name=viafabricplus # base lib -vialoadingbase_version=ae89fec4ab +vialoadingbase_version=82885d5880 raknet_transport_version=1.0.0.CR1-SNAPSHOT # viaversion (and required) libs @@ -23,7 +23,7 @@ viabackwards_version=4.7.0-23w14a-SNAPSHOT snake_yml_version=2.0 # raphimc libs -vialegacy_version=2.2.11 +vialegacy_version=2.2.12-SNAPSHOT viaaprilfools_version=2.0.6 viabedrock_version=0.0.1-SNAPSHOT minecraftauth_version=2.0.1 diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection.java index cf0fb75b..c767966e 100644 --- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection.java +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection.java @@ -20,10 +20,8 @@ package de.florianmichael.viafabricplus.injection.mixin.base; import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback; import de.florianmichael.viafabricplus.event.DisconnectConnectionCallback; import de.florianmichael.viafabricplus.injection.access.IClientConnection; -import de.florianmichael.viafabricplus.protocolhack.constants.PreNettyConstants; -import de.florianmichael.viafabricplus.protocolhack.constants.BedrockRakNetConstants; import de.florianmichael.viafabricplus.protocolhack.ProtocolHack; -import de.florianmichael.viafabricplus.protocolhack.PipelineInjector; +import de.florianmichael.viafabricplus.protocolhack.ViaFabricPlusVLBPipeline; import de.florianmichael.vialoadingbase.ViaLoadingBase; import de.florianmichael.vialoadingbase.netty.event.CompressionReorderEvent; import io.netty.channel.*; @@ -75,6 +73,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler< @Inject(method = "setCompressionThreshold", at = @At("RETURN")) private void reorderCompression(int compressionThreshold, boolean rejectBad, CallbackInfo ci) { channel.pipeline().fireUserEventTriggered(new CompressionReorderEvent()); + System.out.println(channel.pipeline().names()); } @Inject(method = "setupEncryption", at = @At("HEAD"), cancellable = true) @@ -91,7 +90,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler< ((IClientConnection) clientConnection).viafabricplus_captureAddress(address); if (ProtocolHack.getForcedVersions().containsKey(address) ? (ProtocolHack.getForcedVersions().get(address).getVersion() == BedrockProtocolVersion.bedrockLatest.getVersion()) : ProtocolHack.getTargetVersion().isEqualTo(BedrockProtocolVersion.bedrockLatest)) { - PipelineInjector.connectRakNet(clientConnection, address, lazy, class_); + ProtocolHack.connectRakNet(clientConnection, address, lazy, class_); cir.setReturnValue(clientConnection); } } @@ -114,8 +113,8 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler< @Override public void viafabricplus_setupPreNettyEncryption() { - this.channel.pipeline().addBefore(PreNettyConstants.VIA_LEGACY_CODEC_NAME, "decrypt", new PacketDecryptor(this.viafabricplus_decryptionCipher)); - this.channel.pipeline().addBefore(PreNettyConstants.VIA_LEGACY_CODEC_NAME, "encrypt", new PacketEncryptor(this.viafabricplus_encryptionCipher)); + this.channel.pipeline().addBefore(ViaFabricPlusVLBPipeline.VIA_LEGACY_DECODER_HANDLER_NAME, "decrypt", new PacketDecryptor(this.viafabricplus_decryptionCipher)); + this.channel.pipeline().addBefore(ViaFabricPlusVLBPipeline.VIA_LEGACY_ENCODER_HANDLER_NAME, "encrypt", new PacketEncryptor(this.viafabricplus_encryptionCipher)); } @Override @@ -133,7 +132,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler< if (this.viafabricplus_compressionEnabled) throw new IllegalStateException("Compression is already enabled"); this.viafabricplus_compressionEnabled = true; - this.channel.pipeline().addBefore(BedrockRakNetConstants.BATCH_LENGTH_HANDLER_NAME, BedrockRakNetConstants.COMPRESSION_HANDLER_NAME, new ZLibCompression()); + this.channel.pipeline().addBefore(ViaFabricPlusVLBPipeline.BATCH_LENGTH_HANDLER_NAME, ViaFabricPlusVLBPipeline.COMPRESSION_HANDLER_NAME, new ZLibCompression()); } @Override @@ -141,7 +140,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler< if (this.viafabricplus_compressionEnabled) throw new IllegalStateException("Compression is already enabled"); this.viafabricplus_compressionEnabled = true; - this.channel.pipeline().addBefore(BedrockRakNetConstants.BATCH_LENGTH_HANDLER_NAME, BedrockRakNetConstants.COMPRESSION_HANDLER_NAME, new SnappyCompression()); + this.channel.pipeline().addBefore(ViaFabricPlusVLBPipeline.BATCH_LENGTH_HANDLER_NAME, ViaFabricPlusVLBPipeline.COMPRESSION_HANDLER_NAME, new SnappyCompression()); } @Override @@ -149,6 +148,6 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler< if (this.encrypted) throw new IllegalStateException("Encryption is already enabled"); this.encrypted = true; - this.channel.pipeline().addAfter(BedrockRakNetConstants.FRAME_ENCAPSULATION_HANDLER_NAME, BedrockRakNetConstants.ENCRYPTION_HANDLER_NAME, new AesEncryption(secretKey)); + this.channel.pipeline().addAfter(ViaFabricPlusVLBPipeline.FRAME_ENCAPSULATION_HANDLER_NAME, ViaFabricPlusVLBPipeline.ENCRYPTION_HANDLER_NAME, new AesEncryption(secretKey)); } } diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection_1.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection_1.java index 7f68d207..836bf668 100644 --- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection_1.java +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinClientConnection_1.java @@ -18,7 +18,7 @@ package de.florianmichael.viafabricplus.injection.mixin.base; import de.florianmichael.viafabricplus.injection.access.IClientConnection; -import de.florianmichael.viafabricplus.protocolhack.PipelineInjector; +import de.florianmichael.viafabricplus.protocolhack.ProtocolHack; import io.netty.channel.Channel; import io.netty.channel.socket.SocketChannel; import net.minecraft.network.ClientConnection; @@ -39,7 +39,7 @@ public class MixinClientConnection_1 { @Inject(method = "initChannel", at = @At("TAIL")) public void hackNettyPipeline(Channel channel, CallbackInfo ci) { if (channel instanceof SocketChannel) { - PipelineInjector.hookProtocolHack(field_11663, channel, ((IClientConnection) field_11663).viafabricplus_capturedAddress()); + ProtocolHack.hookProtocolHack(field_11663, channel, ((IClientConnection) field_11663).viafabricplus_capturedAddress()); } } } diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/PipelineInjector.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/PipelineInjector.java deleted file mode 100644 index 52d9d245..00000000 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/PipelineInjector.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus - * Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.florianmichael.viafabricplus.protocolhack; - -import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.connection.UserConnectionImpl; -import com.viaversion.viaversion.protocol.ProtocolPipelineImpl; -import de.florianmichael.viafabricplus.protocolhack.constants.BedrockRakNetConstants; -import de.florianmichael.viafabricplus.protocolhack.constants.PreNettyConstants; -import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.DisconnectHandler; -import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.PingEncapsulationCodec; -import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.RakMessageEncapsulationCodec; -import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.library_fix.FixedUnconnectedPingEncoder; -import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.library_fix.FixedUnconnectedPongDecoder; -import de.florianmichael.viafabricplus.protocolhack.platform.vialegacy.ViaFabricPlusPreNettyLengthCodec; -import de.florianmichael.viafabricplus.protocolhack.replacement.ViaFabricPlusVLBViaCodec; -import de.florianmichael.vialoadingbase.netty.NettyConstants; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.*; -import io.netty.channel.epoll.EpollDatagramChannel; -import io.netty.channel.epoll.EpollSocketChannel; -import io.netty.channel.socket.nio.NioDatagramChannel; -import io.netty.handler.timeout.ReadTimeoutHandler; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.NetworkSide; -import net.minecraft.network.SizePrepender; -import net.minecraft.util.Lazy; -import net.raphimc.viabedrock.netty.BatchLengthCodec; -import net.raphimc.viabedrock.netty.PacketEncapsulationCodec; -import net.raphimc.viabedrock.protocol.BedrockBaseProtocol; -import net.raphimc.vialegacy.api.LegacyProtocolVersion; -import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.baseprotocols.PreNettyBaseProtocol; -import org.cloudburstmc.netty.channel.raknet.RakChannelFactory; -import org.cloudburstmc.netty.channel.raknet.RakClientChannel; -import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption; -import org.cloudburstmc.netty.handler.codec.raknet.common.UnconnectedPingEncoder; -import org.cloudburstmc.netty.handler.codec.raknet.common.UnconnectedPongDecoder; -import org.jetbrains.annotations.NotNull; - -import java.net.InetSocketAddress; -import java.util.concurrent.ThreadLocalRandom; - -public class PipelineInjector { - - /** - * This method adds the channel handlers required for ViaVersion, ViaBackwards, ViaAprilFools and ViaLegacy, it also tracks the Via and Minecraft Connection - */ - public static void hookProtocolHack(final ClientConnection connection, final Channel channel, final InetSocketAddress address) { - if (ProtocolHack.getForcedVersions().containsKey(address)) { - channel.attr(ProtocolHack.FORCED_VERSION).set(ProtocolHack.getForcedVersions().get(address)); - ProtocolHack.getForcedVersions().remove(address); - } - final UserConnection user = new UserConnectionImpl(channel, true); - channel.attr(ProtocolHack.LOCAL_VIA_CONNECTION).set(user); - channel.attr(ProtocolHack.LOCAL_MINECRAFT_CONNECTION).set(connection); - - new ProtocolPipelineImpl(user); - - channel.pipeline().addBefore("decoder", NettyConstants.VIA_CODEC_NAME, new ViaFabricPlusVLBViaCodec(user)); - - if (ProtocolHack.getTargetVersion(channel).isOlderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { - user.getProtocolInfo().getPipeline().add(PreNettyBaseProtocol.INSTANCE); - - channel.pipeline().addBefore("splitter", PreNettyConstants.VIA_LEGACY_CODEC_NAME, new ViaFabricPlusPreNettyLengthCodec(user)); - } - - // MC Pipeline doesn't like codecs - channel.pipeline().remove("prepender"); - channel.pipeline().addAfter("splitter", "prepender", new SizePrepender()); - } - - /** - * This method represents the rak net connection for bedrock edition, it's a replacement of the ClientConnection#connect method - */ - public static void connectRakNet(final ClientConnection clientConnection, final InetSocketAddress address, final Lazy lazy, final Class channelType) { - Bootstrap nettyBoostrap = new Bootstrap(); - nettyBoostrap = nettyBoostrap.group((EventLoopGroup) lazy.get()); - nettyBoostrap = nettyBoostrap.handler(new ChannelInitializer<>() { - @Override - protected void initChannel(@NotNull Channel channel) throws Exception { - try { - channel.config().setOption(RakChannelOption.RAK_PROTOCOL_VERSION, 11); - channel.config().setOption(RakChannelOption.RAK_CONNECT_TIMEOUT, 4_000L); - channel.config().setOption(RakChannelOption.RAK_SESSION_TIMEOUT, 30_000L); - channel.config().setOption(RakChannelOption.RAK_GUID, ThreadLocalRandom.current().nextLong()); - } catch (Exception ignored) { - } - ChannelPipeline channelPipeline = channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)); - ClientConnection.addHandlers(channelPipeline, NetworkSide.CLIENTBOUND); - - channelPipeline.addLast("packet_handler", clientConnection); - - PipelineInjector.hookProtocolHack(clientConnection, channel, address); - final UserConnection user = channel.attr(ProtocolHack.LOCAL_VIA_CONNECTION).get(); - - user.getProtocolInfo().getPipeline().add(BedrockBaseProtocol.INSTANCE); - - channel.pipeline().replace("splitter", BedrockRakNetConstants.BATCH_LENGTH_HANDLER_NAME, new BatchLengthCodec()); - - channel.pipeline().addBefore(BedrockRakNetConstants.BATCH_LENGTH_HANDLER_NAME, BedrockRakNetConstants.DISCONNECT_HANDLER_NAME, new DisconnectHandler()); - channel.pipeline().addAfter(BedrockRakNetConstants.DISCONNECT_HANDLER_NAME, BedrockRakNetConstants.FRAME_ENCAPSULATION_HANDLER_NAME, new RakMessageEncapsulationCodec()); - channel.pipeline().addAfter(BedrockRakNetConstants.BATCH_LENGTH_HANDLER_NAME, BedrockRakNetConstants.PACKET_ENCAPSULATION_HANDLER_NAME, new PacketEncapsulationCodec()); - - channel.pipeline().remove("prepender"); - channel.pipeline().remove("timeout"); - - // Pinging in RakNet is something different - if (ProtocolHack.getRakNetPingSessions().contains(address)) { - { // Temporary fix for the ping encoder - final RakClientChannel rakChannel = (RakClientChannel) channel; - - rakChannel.parent().pipeline().replace(UnconnectedPingEncoder.NAME, UnconnectedPingEncoder.NAME, new FixedUnconnectedPingEncoder(rakChannel)); - rakChannel.parent().pipeline().replace(UnconnectedPongDecoder.NAME, UnconnectedPongDecoder.NAME, new FixedUnconnectedPongDecoder(rakChannel)); - } - - channel.pipeline().replace(BedrockRakNetConstants.FRAME_ENCAPSULATION_HANDLER_NAME, BedrockRakNetConstants.PING_ENCAPSULATION_HANDLER_NAME, new PingEncapsulationCodec(address)); - - channel.pipeline().remove(BedrockRakNetConstants.PACKET_ENCAPSULATION_HANDLER_NAME); - channel.pipeline().remove(BedrockRakNetConstants.BATCH_LENGTH_HANDLER_NAME); - } - } - }); - nettyBoostrap = nettyBoostrap.channelFactory(channelType == EpollSocketChannel.class ? RakChannelFactory.client(EpollDatagramChannel.class) : RakChannelFactory.client(NioDatagramChannel.class)); - - if (ProtocolHack.getRakNetPingSessions().contains(address)) { - nettyBoostrap.bind(new InetSocketAddress(0)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE).syncUninterruptibly(); - } else { - nettyBoostrap.connect(address.getAddress(), address.getPort()).syncUninterruptibly(); - } - } -} diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/ProtocolHack.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/ProtocolHack.java index 48d56b86..0f63db87 100644 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/ProtocolHack.java +++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/ProtocolHack.java @@ -20,6 +20,8 @@ package de.florianmichael.viafabricplus.protocolhack; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.VersionProvider; +import com.viaversion.viaversion.connection.UserConnectionImpl; +import com.viaversion.viaversion.protocol.ProtocolPipelineImpl; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; import de.florianmichael.viafabricplus.ViaFabricPlus; @@ -35,15 +37,22 @@ import de.florianmichael.viafabricplus.protocolhack.provider.viabedrock.ViaFabri import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.*; import de.florianmichael.viafabricplus.protocolhack.provider.viaversion.ViaFabricPlusHandItemProvider; import de.florianmichael.viafabricplus.protocolhack.provider.viaversion.ViaFabricPlusMovementTransmitterProvider; -import de.florianmichael.viafabricplus.protocolhack.replacement.ViaFabricPlusVLBBaseVersionProvider; +import de.florianmichael.viafabricplus.protocolhack.provider.vialoadingbase.ViaFabricPlusVLBBaseVersionProvider; import de.florianmichael.vialoadingbase.ViaLoadingBase; import de.florianmichael.vialoadingbase.model.ComparableProtocolVersion; import de.florianmichael.vialoadingbase.model.Platform; -import io.netty.channel.Channel; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.epoll.EpollDatagramChannel; +import io.netty.channel.epoll.EpollSocketChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.util.AttributeKey; import net.minecraft.SharedConstants; import net.minecraft.client.MinecraftClient; import net.minecraft.network.ClientConnection; +import net.minecraft.network.NetworkSide; +import net.minecraft.util.Lazy; import net.raphimc.viaaprilfools.api.AprilFoolsProtocolVersion; import net.raphimc.viabedrock.api.BedrockProtocolVersion; import net.raphimc.viabedrock.protocol.providers.BlobCacheProvider; @@ -55,9 +64,13 @@ import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.provide import net.raphimc.vialegacy.protocols.release.protocol1_3_1_2to1_2_4_5.providers.OldAuthProvider; import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.providers.EncryptionProvider; import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher; +import org.cloudburstmc.netty.channel.raknet.RakChannelFactory; +import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption; +import org.jetbrains.annotations.NotNull; import java.net.InetSocketAddress; import java.util.*; +import java.util.concurrent.ThreadLocalRandom; public class ProtocolHack { public final static AttributeKey LOCAL_VIA_CONNECTION = AttributeKey.newInstance("viafabricplus-via-connection"); @@ -99,6 +112,56 @@ public class ProtocolHack { return ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(version); } + /** + * This method adds the channel handlers required for ViaVersion, ViaBackwards, ViaAprilFools and ViaLegacy, it also tracks the Via and Minecraft Connection + */ + public static void hookProtocolHack(final ClientConnection connection, final Channel channel, final InetSocketAddress address) { + if (ProtocolHack.getForcedVersions().containsKey(address)) { + channel.attr(ProtocolHack.FORCED_VERSION).set(ProtocolHack.getForcedVersions().get(address)); + ProtocolHack.getForcedVersions().remove(address); + } + final UserConnection user = new UserConnectionImpl(channel, true); + channel.attr(ProtocolHack.LOCAL_VIA_CONNECTION).set(user); + channel.attr(ProtocolHack.LOCAL_MINECRAFT_CONNECTION).set(connection); + + new ProtocolPipelineImpl(user); + + channel.pipeline().addLast(new ViaFabricPlusVLBPipeline(user, address, ProtocolHack.getTargetVersion(channel))); + } + + /** + * This method represents the rak net connection for bedrock edition, it's a replacement of the ClientConnection#connect method + */ + public static void connectRakNet(final ClientConnection clientConnection, final InetSocketAddress address, final Lazy lazy, final Class channelType) { + Bootstrap nettyBoostrap = new Bootstrap(); + nettyBoostrap = nettyBoostrap.group((EventLoopGroup) lazy.get()); + nettyBoostrap = nettyBoostrap.handler(new ChannelInitializer<>() { + @Override + protected void initChannel(@NotNull Channel channel) throws Exception { + try { + channel.config().setOption(RakChannelOption.RAK_PROTOCOL_VERSION, 11); + channel.config().setOption(RakChannelOption.RAK_CONNECT_TIMEOUT, 4_000L); + channel.config().setOption(RakChannelOption.RAK_SESSION_TIMEOUT, 30_000L); + channel.config().setOption(RakChannelOption.RAK_GUID, ThreadLocalRandom.current().nextLong()); + } catch (Exception ignored) { + } + ChannelPipeline channelPipeline = channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)); + ClientConnection.addHandlers(channelPipeline, NetworkSide.CLIENTBOUND); + + channelPipeline.addLast("packet_handler", clientConnection); + + hookProtocolHack(clientConnection, channel, address); + } + }); + nettyBoostrap = nettyBoostrap.channelFactory(channelType == EpollSocketChannel.class ? RakChannelFactory.client(EpollDatagramChannel.class) : RakChannelFactory.client(NioDatagramChannel.class)); + + if (ProtocolHack.getRakNetPingSessions().contains(address)) { + nettyBoostrap.bind(new InetSocketAddress(0)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE).syncUninterruptibly(); + } else { + nettyBoostrap.connect(address.getAddress(), address.getPort()).syncUninterruptibly(); + } + } + public ProtocolHack() { ViaLoadingBase.ViaLoadingBaseBuilder builder = ViaLoadingBase.ViaLoadingBaseBuilder.create(); diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/ViaFabricPlusVLBPipeline.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/ViaFabricPlusVLBPipeline.java new file mode 100644 index 00000000..da77496f --- /dev/null +++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/ViaFabricPlusVLBPipeline.java @@ -0,0 +1,127 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus + * Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.florianmichael.viafabricplus.protocolhack; + +import com.viaversion.viaversion.api.connection.UserConnection; +import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.DisconnectHandler; +import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.PingEncapsulationCodec; +import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.RakMessageEncapsulationCodec; +import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.library_fix.FixedUnconnectedPingEncoder; +import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.library_fix.FixedUnconnectedPongDecoder; +import de.florianmichael.vialoadingbase.model.ComparableProtocolVersion; +import de.florianmichael.vialoadingbase.netty.VLBPipeline; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPipeline; +import net.raphimc.viabedrock.api.BedrockProtocolVersion; +import net.raphimc.viabedrock.netty.BatchLengthCodec; +import net.raphimc.viabedrock.netty.PacketEncapsulationCodec; +import net.raphimc.viabedrock.protocol.BedrockBaseProtocol; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import net.raphimc.vialegacy.netty.PreNettyLengthPrepender; +import net.raphimc.vialegacy.netty.PreNettyLengthRemover; +import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.baseprotocols.PreNettyBaseProtocol; +import org.cloudburstmc.netty.channel.raknet.RakClientChannel; +import org.cloudburstmc.netty.handler.codec.raknet.common.UnconnectedPingEncoder; +import org.cloudburstmc.netty.handler.codec.raknet.common.UnconnectedPongDecoder; + +import java.net.InetSocketAddress; + +public class ViaFabricPlusVLBPipeline extends VLBPipeline { + public final static String DISCONNECT_HANDLER_NAME = "disconnect_handler"; + public final static String FRAME_ENCAPSULATION_HANDLER_NAME = "frame_encapsulation"; + public final static String PING_ENCAPSULATION_HANDLER_NAME = "ping_encapsulation"; + public final static String PACKET_ENCAPSULATION_HANDLER_NAME = "packet_encapsulation"; + public final static String BATCH_LENGTH_HANDLER_NAME = "batch_length"; + public final static String COMPRESSION_HANDLER_NAME = "compression"; + public final static String ENCRYPTION_HANDLER_NAME = "encryption"; + + public static final String VIA_LEGACY_DECODER_HANDLER_NAME = "via-legacy-decoder"; + public static final String VIA_LEGACY_ENCODER_HANDLER_NAME = "via-legacy-encoder"; + + private final InetSocketAddress address; + private final ComparableProtocolVersion version; + + public ViaFabricPlusVLBPipeline(UserConnection info, final InetSocketAddress address, final ComparableProtocolVersion version) { + super(info); + + this.address = address; + this.version = version; + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + super.handlerAdded(ctx); + + final ChannelPipeline pipeline = ctx.channel().pipeline(); + + if (this.version.isOlderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { + getInfo().getProtocolInfo().getPipeline().add(PreNettyBaseProtocol.INSTANCE); + + pipeline.addBefore("splitter", VIA_LEGACY_DECODER_HANDLER_NAME, new PreNettyLengthPrepender(getInfo())); + pipeline.addBefore("prepender", VIA_LEGACY_ENCODER_HANDLER_NAME, new PreNettyLengthRemover(getInfo())); + } + + if (this.version.isEqualTo(BedrockProtocolVersion.bedrockLatest)) { + getInfo().getProtocolInfo().getPipeline().add(BedrockBaseProtocol.INSTANCE); + + pipeline.replace("splitter", BATCH_LENGTH_HANDLER_NAME, new BatchLengthCodec()); + + pipeline.addBefore(BATCH_LENGTH_HANDLER_NAME, DISCONNECT_HANDLER_NAME, new DisconnectHandler()); + pipeline.addAfter(DISCONNECT_HANDLER_NAME, FRAME_ENCAPSULATION_HANDLER_NAME, new RakMessageEncapsulationCodec()); + pipeline.addAfter(BATCH_LENGTH_HANDLER_NAME, PACKET_ENCAPSULATION_HANDLER_NAME, new PacketEncapsulationCodec()); + + pipeline.remove("prepender"); + pipeline.remove("timeout"); + + // Pinging in RakNet is something different + if (ProtocolHack.getRakNetPingSessions().contains(address)) { + { // Temporary fix for the ping encoder + final RakClientChannel rakChannel = (RakClientChannel) ctx.channel(); + + rakChannel.parent().pipeline().replace(UnconnectedPingEncoder.NAME, UnconnectedPingEncoder.NAME, new FixedUnconnectedPingEncoder(rakChannel)); + rakChannel.parent().pipeline().replace(UnconnectedPongDecoder.NAME, UnconnectedPongDecoder.NAME, new FixedUnconnectedPongDecoder(rakChannel)); + } + + pipeline.replace(FRAME_ENCAPSULATION_HANDLER_NAME, PING_ENCAPSULATION_HANDLER_NAME, new PingEncapsulationCodec(address)); + + pipeline.remove(PACKET_ENCAPSULATION_HANDLER_NAME); + pipeline.remove(BATCH_LENGTH_HANDLER_NAME); + } + } + } + + @Override + public String getDecoderHandlerName() { + return "decoder"; + } + + @Override + public String getEncoderHandlerName() { + return "encoder"; + } + + @Override + public String getDecompressionHandlerName() { + return "decompress"; + } + + @Override + public String getCompressionHandlerName() { + return "compress"; + } +} diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/BedrockRakNetConstants.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/BedrockRakNetConstants.java deleted file mode 100644 index 07600cf8..00000000 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/BedrockRakNetConstants.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus - * Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.florianmichael.viafabricplus.protocolhack.constants; - -public class BedrockRakNetConstants { - - public static final String DISCONNECT_HANDLER_NAME = "disconnect_handler"; - public static final String FRAME_ENCAPSULATION_HANDLER_NAME = "frame_encapsulation"; - public static final String PING_ENCAPSULATION_HANDLER_NAME = "ping_encapsulation"; - public static final String PACKET_ENCAPSULATION_HANDLER_NAME = "packet_encapsulation"; - public static final String BATCH_LENGTH_HANDLER_NAME = "batch_length"; - public static final String COMPRESSION_HANDLER_NAME = "compression"; - public static final String ENCRYPTION_HANDLER_NAME = "encryption"; -} diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/PreNettyConstants.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/PreNettyConstants.java deleted file mode 100644 index 07433433..00000000 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/constants/PreNettyConstants.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus - * Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.florianmichael.viafabricplus.protocolhack.constants; - -public class PreNettyConstants { - - public static final String VIA_LEGACY_CODEC_NAME = "vialegacy-pre-netty-length-codecc"; -} diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/platform/vialegacy/ViaFabricPlusPreNettyLengthCodec.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/platform/vialegacy/ViaFabricPlusPreNettyLengthCodec.java deleted file mode 100644 index 812226b2..00000000 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/platform/vialegacy/ViaFabricPlusPreNettyLengthCodec.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus - * Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.florianmichael.viafabricplus.protocolhack.platform.vialegacy; - -import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.type.Type; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import net.raphimc.vialegacy.netty.PreNettyLengthCodec; - -import java.util.List; - -public class ViaFabricPlusPreNettyLengthCodec extends PreNettyLengthCodec { - - public ViaFabricPlusPreNettyLengthCodec(UserConnection user) { - super(user); - } - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - if (Via.getManager().isDebug()) { - if (!in.isReadable() || in.readableBytes() <= 0) { - return; - } - Via.getPlatform().getLogger().info("Decoding pre netty packet: " + in.copy().readUnsignedByte()); - } - super.decode(ctx, in, out); - } - - @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) { - if (Via.getManager().isDebug()) { - final ByteBuf myBuf = in.copy(); - Type.VAR_INT.readPrimitive(myBuf); // length - Via.getPlatform().getLogger().info("Encoding pre netty packet: " + (Type.VAR_INT.readPrimitive(myBuf) & 255)); - } - super.encode(ctx, in, out); - } -} diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/replacement/ViaFabricPlusVLBBaseVersionProvider.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/vialoadingbase/ViaFabricPlusVLBBaseVersionProvider.java similarity index 94% rename from src/main/java/de/florianmichael/viafabricplus/protocolhack/replacement/ViaFabricPlusVLBBaseVersionProvider.java rename to src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/vialoadingbase/ViaFabricPlusVLBBaseVersionProvider.java index 557d48f3..c8945f06 100644 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/replacement/ViaFabricPlusVLBBaseVersionProvider.java +++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/vialoadingbase/ViaFabricPlusVLBBaseVersionProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package de.florianmichael.viafabricplus.protocolhack.replacement; +package de.florianmichael.viafabricplus.protocolhack.provider.vialoadingbase; import com.viaversion.viaversion.api.connection.UserConnection; import de.florianmichael.viafabricplus.protocolhack.ProtocolHack; diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/replacement/ViaFabricPlusVLBViaCodec.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/replacement/ViaFabricPlusVLBViaCodec.java deleted file mode 100644 index e4f5b5e3..00000000 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/replacement/ViaFabricPlusVLBViaCodec.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus - * Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.florianmichael.viafabricplus.protocolhack.replacement; - -import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.exception.CancelCodecException; -import com.viaversion.viaversion.util.PipelineUtil; -import de.florianmichael.vialoadingbase.netty.VLBViaCodec; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; - -import java.util.List; -import java.util.logging.Level; - -public class ViaFabricPlusVLBViaCodec extends VLBViaCodec { - - public ViaFabricPlusVLBViaCodec(UserConnection info) { - super(info); - } - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List out) throws Exception { - try { - super.decode(ctx, bytebuf, out); - } catch (Throwable e) { - if (PipelineUtil.containsCause(e, CancelCodecException.class)) throw e; - Via.getPlatform().getLogger().log(Level.SEVERE, "ViaLoadingBase Packet Error occurred", e); - e.printStackTrace(); - } - } -} diff --git a/src/main/resources/viafabricplus.mixins.json b/src/main/resources/viafabricplus.mixins.json index 7787c11b..cb6a8b51 100644 --- a/src/main/resources/viafabricplus.mixins.json +++ b/src/main/resources/viafabricplus.mixins.json @@ -122,6 +122,7 @@ "fixes.vialegacy.MixinExtensionProtocolMetadataStorage", "fixes.vialegacy.MixinProtocol1_8to1_7_6_10", "fixes.vialegacy.MixinProtocolc0_30toc0_30cpe", + "fixes.vialegacy.MixinViaLegacyConfig", "fixes.vialoadingbase.MixinVLBViaConfig", "fixes.viaversion.MixinCommonBoss", "fixes.viaversion.MixinProtocolVersion", @@ -149,8 +150,7 @@ "fixes.viaversion.protocol1_9to1_8.MixinViaIdleThread", "jsonwebtoken.MixinClasses", "jsonwebtoken.MixinDefaultCompressionCodecResolver", - "jsonwebtoken.MixinDefaultJwtParserBuilder", - "fixes.vialegacy.MixinViaLegacyConfig" + "jsonwebtoken.MixinDefaultJwtParserBuilder" ], "injectors": { "defaultRequire": 1