mirror of
https://github.com/ViaVersion/ViaFabricPlus.git
synced 2025-02-12 01:01:23 +01:00
Removed ClientConnection#connect overwrite
This commit is contained in:
parent
3e62e7b5fb
commit
d5876090c0
@ -28,6 +28,7 @@ public interface IClientConnection {
|
||||
|
||||
void viafabricplus_setupPreNettyEncryption();
|
||||
|
||||
InetSocketAddress viafabricplus_capturedAddress();
|
||||
void viafabricplus_captureAddress(final InetSocketAddress socketAddress);
|
||||
|
||||
void viafabricplus_enableZLibCompression();
|
||||
|
@ -17,40 +17,16 @@
|
||||
*/
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.connection.UserConnectionImpl;
|
||||
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
|
||||
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
|
||||
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.platform.viabedrock.DisconnectHandler;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.PingEncapsulationCodec;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.RakMessageEncapsulationCodec;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
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.VFPPreNettyDecoder;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.vialegacy.VFPPreNettyEncoder;
|
||||
import de.florianmichael.viafabricplus.protocolhack.replacement.ViaFabricPlusVLBViaDecodeHandler;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.RakNetClientConnection;
|
||||
import de.florianmichael.vialoadingbase.ViaLoadingBase;
|
||||
import de.florianmichael.vialoadingbase.event.PipelineReorderEvent;
|
||||
import de.florianmichael.vialoadingbase.netty.NettyConstants;
|
||||
import de.florianmichael.vialoadingbase.netty.VLBViaEncodeHandler;
|
||||
import de.florianmichael.vialoadingbase.platform.InternalProtocolList;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.epoll.Epoll;
|
||||
import io.netty.channel.epoll.EpollDatagramChannel;
|
||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
import io.netty.channel.epoll.EpollSocketChannel;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.network.NetworkSide;
|
||||
import net.minecraft.network.encryption.PacketDecryptor;
|
||||
import net.minecraft.network.encryption.PacketEncryptor;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
@ -58,19 +34,13 @@ import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Lazy;
|
||||
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
|
||||
import net.raphimc.viabedrock.netty.*;
|
||||
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 org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
@ -79,7 +49,6 @@ import java.net.InetSocketAddress;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@Mixin(ClientConnection.class)
|
||||
public abstract class MixinClientConnection extends SimpleChannelInboundHandler<Packet<?>> implements IClientConnection {
|
||||
@ -90,9 +59,6 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
|
||||
|
||||
@Shadow public abstract void channelActive(ChannelHandlerContext context) throws Exception;
|
||||
|
||||
@Shadow @Final public static Lazy<EpollEventLoopGroup> EPOLL_CLIENT_IO_GROUP;
|
||||
@Shadow @Final public static Lazy<NioEventLoopGroup> CLIENT_IO_GROUP;
|
||||
|
||||
@Unique
|
||||
private Cipher viafabricplus_decryptionCipher;
|
||||
|
||||
@ -119,107 +85,14 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Mojang, FlorianMichael as EnZaXD
|
||||
* @reason Hack Netty Pipeline (do cursed shit)
|
||||
*/
|
||||
@Overwrite
|
||||
public static ClientConnection connect(InetSocketAddress address, boolean useEpoll) {
|
||||
final ClientConnection clientConnection = new ClientConnection(NetworkSide.CLIENTBOUND);
|
||||
@Inject(method = "connect", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Lazy;get()Ljava/lang/Object;", shift = At.Shift.BEFORE), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private static void captureAddress(InetSocketAddress address, boolean useEpoll, CallbackInfoReturnable<ClientConnection> cir, final ClientConnection clientConnection, Class class_, Lazy lazy) {
|
||||
((IClientConnection) clientConnection).viafabricplus_captureAddress(address);
|
||||
|
||||
final Class<? extends AbstractChannel> channelType = Epoll.isAvailable() && useEpoll ? EpollSocketChannel.class : NioSocketChannel.class;
|
||||
final Lazy<? extends MultithreadEventLoopGroup> lazy = Epoll.isAvailable() && useEpoll ? EPOLL_CLIENT_IO_GROUP : CLIENT_IO_GROUP;
|
||||
|
||||
final boolean rakNet = ProtocolHack.getForcedVersions().containsKey(address) ?
|
||||
(ProtocolHack.getForcedVersions().get(address).getVersion() == BedrockProtocolVersion.bedrockLatest.getVersion()) :
|
||||
ProtocolHack.getTargetVersion().isEqualTo(BedrockProtocolVersion.bedrockLatest);
|
||||
|
||||
Bootstrap nettyBoostrap = new Bootstrap();
|
||||
nettyBoostrap = nettyBoostrap.group(lazy.get());
|
||||
nettyBoostrap = nettyBoostrap.handler(new ChannelInitializer<>() {
|
||||
@Override
|
||||
protected void initChannel(@NotNull Channel channel) throws Exception {
|
||||
try {
|
||||
if (rakNet) {
|
||||
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());
|
||||
} else {
|
||||
channel.config().setOption(ChannelOption.TCP_NODELAY, true);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
ChannelPipeline channelPipeline = channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30));
|
||||
ClientConnection.addHandlers(channelPipeline, NetworkSide.CLIENTBOUND);
|
||||
|
||||
channelPipeline.addLast("packet_handler", clientConnection);
|
||||
|
||||
if (channel instanceof SocketChannel || rakNet) {
|
||||
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(clientConnection);
|
||||
|
||||
new ProtocolPipelineImpl(user);
|
||||
|
||||
channel.pipeline().addBefore("encoder", NettyConstants.HANDLER_ENCODER_NAME, new VLBViaEncodeHandler(user));
|
||||
channel.pipeline().addBefore("decoder", NettyConstants.HANDLER_DECODER_NAME, new ViaFabricPlusVLBViaDecodeHandler(user));
|
||||
|
||||
if (rakNet) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (ProtocolHack.getTargetVersion(channel).isOlderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
|
||||
user.getProtocolInfo().getPipeline().add(PreNettyBaseProtocol.INSTANCE);
|
||||
|
||||
channel.pipeline().addBefore("prepender", PreNettyConstants.HANDLER_ENCODER_NAME, new VFPPreNettyEncoder(user));
|
||||
channel.pipeline().addBefore("splitter", PreNettyConstants.HANDLER_DECODER_NAME, new VFPPreNettyDecoder(user));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (rakNet) {
|
||||
nettyBoostrap = nettyBoostrap.channelFactory(channelType == EpollSocketChannel.class ? RakChannelFactory.client(EpollDatagramChannel.class) : RakChannelFactory.client(NioDatagramChannel.class));
|
||||
} else {
|
||||
nettyBoostrap = nettyBoostrap.channel(channelType);
|
||||
if (ProtocolHack.getForcedVersions().containsKey(address) ? (ProtocolHack.getForcedVersions().get(address).getVersion() == BedrockProtocolVersion.bedrockLatest.getVersion()) : ProtocolHack.getTargetVersion().isEqualTo(BedrockProtocolVersion.bedrockLatest)) {
|
||||
RakNetClientConnection.connect(clientConnection, address, lazy, class_);
|
||||
cir.setReturnValue(clientConnection);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
return clientConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -239,11 +112,15 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
|
||||
|
||||
@Override
|
||||
public void viafabricplus_setupPreNettyEncryption() {
|
||||
this.encrypted = true;
|
||||
this.channel.pipeline().addBefore(PreNettyConstants.HANDLER_DECODER_NAME, "decrypt", new PacketDecryptor(this.viafabricplus_decryptionCipher));
|
||||
this.channel.pipeline().addBefore(PreNettyConstants.HANDLER_ENCODER_NAME, "encrypt", new PacketEncryptor(this.viafabricplus_encryptionCipher));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress viafabricplus_capturedAddress() {
|
||||
return viafabricplus_capturedAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viafabricplus_captureAddress(InetSocketAddress socketAddress) {
|
||||
viafabricplus_capturedAddress = socketAddress;
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base;
|
||||
|
||||
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
|
||||
import de.florianmichael.viafabricplus.injection.reference.ClientConnectionReference;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(targets = "net.minecraft.network.ClientConnection$1")
|
||||
public class MixinClientConnection_1 {
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
ClientConnection field_11663;
|
||||
|
||||
@Inject(method = "initChannel", at = @At("TAIL"))
|
||||
public void hackNettyPipeline(Channel channel, CallbackInfo ci) {
|
||||
if (channel instanceof SocketChannel) {
|
||||
ClientConnectionReference.hackNettyPipeline(field_11663, channel, ((IClientConnection) field_11663).viafabricplus_capturedAddress());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.florianmichael.viafabricplus.injection.reference;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.connection.UserConnectionImpl;
|
||||
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.protocolhack.constants.PreNettyConstants;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.vialegacy.VFPPreNettyDecoder;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.vialegacy.VFPPreNettyEncoder;
|
||||
import de.florianmichael.viafabricplus.protocolhack.replacement.ViaFabricPlusVLBViaDecodeHandler;
|
||||
import de.florianmichael.vialoadingbase.netty.NettyConstants;
|
||||
import de.florianmichael.vialoadingbase.netty.VLBViaEncodeHandler;
|
||||
import io.netty.channel.Channel;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.baseprotocols.PreNettyBaseProtocol;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class ClientConnectionReference {
|
||||
|
||||
public static void hackNettyPipeline(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);
|
||||
|
||||
System.out.println("Hacking Netty Pipeline (ViaVersion)");
|
||||
|
||||
channel.pipeline().addBefore("encoder", NettyConstants.HANDLER_ENCODER_NAME, new VLBViaEncodeHandler(user));
|
||||
channel.pipeline().addBefore("decoder", NettyConstants.HANDLER_DECODER_NAME, new ViaFabricPlusVLBViaDecodeHandler(user));
|
||||
|
||||
if (ProtocolHack.getTargetVersion(channel).isOlderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
|
||||
user.getProtocolInfo().getPipeline().add(PreNettyBaseProtocol.INSTANCE);
|
||||
|
||||
channel.pipeline().addBefore("prepender", PreNettyConstants.HANDLER_ENCODER_NAME, new VFPPreNettyEncoder(user));
|
||||
channel.pipeline().addBefore("splitter", PreNettyConstants.HANDLER_DECODER_NAME, new VFPPreNettyDecoder(user));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.florianmichael.viafabricplus.protocolhack.platform.viabedrock;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import de.florianmichael.viafabricplus.injection.reference.ClientConnectionReference;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.protocolhack.constants.BedrockRakNetConstants;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.library_fix.FixedUnconnectedPingEncoder;
|
||||
import de.florianmichael.viafabricplus.protocolhack.platform.viabedrock.library_fix.FixedUnconnectedPongDecoder;
|
||||
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.util.Lazy;
|
||||
import net.raphimc.viabedrock.netty.BatchLengthCodec;
|
||||
import net.raphimc.viabedrock.netty.PacketEncapsulationCodec;
|
||||
import net.raphimc.viabedrock.protocol.BedrockBaseProtocol;
|
||||
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 RakNetClientConnection {
|
||||
|
||||
public static void connect(final ClientConnection clientConnection, final InetSocketAddress address, final Lazy<? extends MultithreadEventLoopGroup> lazy, final Class<? extends AbstractChannel> channelType) {
|
||||
Bootstrap nettyBoostrap = new Bootstrap();
|
||||
nettyBoostrap = nettyBoostrap.group(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);
|
||||
|
||||
ClientConnectionReference.hackNettyPipeline(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();
|
||||
}
|
||||
}
|
||||
}
|
@ -149,7 +149,8 @@
|
||||
"fixes.viaversion.protocol1_9to1_8.MixinEntityTracker1_9",
|
||||
"fixes.viaversion.protocol1_9to1_8.MixinMetadataRewriter1_9To1_8",
|
||||
"fixes.viaversion.protocol1_9to1_8.MixinMovementTracker",
|
||||
"fixes.viaversion.protocol1_9to1_8.MixinViaIdleThread"
|
||||
"fixes.viaversion.protocol1_9to1_8.MixinViaIdleThread",
|
||||
"base.MixinClientConnection_1"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
Loading…
Reference in New Issue
Block a user