Implemented 1.20.5 transfer packet support

This commit is contained in:
RaphiMC 2024-01-18 21:52:04 +01:00
parent 56a691876f
commit f602e4f3fd
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
4 changed files with 98 additions and 12 deletions

View File

@ -19,9 +19,9 @@ package net.raphimc.viaproxy.protocolhack.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import net.raphimc.viabedrock.protocol.providers.TransferProvider;
import net.raphimc.viaproxy.protocolhack.viaproxy.ViaBedrockTransferHolder;
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.proxy.util.CloseAndReturn;
import net.raphimc.viaproxy.proxy.util.TransferDataHolder;
import java.net.InetSocketAddress;
@ -29,7 +29,7 @@ public class ViaProxyTransferProvider extends TransferProvider {
@Override
public void connectToServer(UserConnection user, InetSocketAddress newAddress) {
ViaBedrockTransferHolder.addTempRedirect(ProxyConnection.fromChannel(user.getChannel()).getC2P(), newAddress);
TransferDataHolder.addTempRedirect(ProxyConnection.fromChannel(user.getChannel()).getC2P(), newAddress);
try {
ProxyConnection.fromUserConnection(user).kickClient("§aThe server transferred you to another server §7(§e" + newAddress.getHostName() + ":" + newAddress.getPort() + "§7)§a. Please reconnect to ViaProxy.");
} catch (CloseAndReturn ignored) {

View File

@ -24,6 +24,7 @@ import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.IntendedState;
import net.raphimc.netminecraft.packet.IPacket;
import net.raphimc.netminecraft.packet.impl.handshake.C2SHandshakePacket;
import net.raphimc.vialoader.util.VersionEnum;
@ -34,7 +35,6 @@ import net.raphimc.viaproxy.plugins.events.ConnectEvent;
import net.raphimc.viaproxy.plugins.events.PreConnectEvent;
import net.raphimc.viaproxy.plugins.events.Proxy2ServerHandlerCreationEvent;
import net.raphimc.viaproxy.plugins.events.ProxySessionCreationEvent;
import net.raphimc.viaproxy.protocolhack.viaproxy.ViaBedrockTransferHolder;
import net.raphimc.viaproxy.proxy.packethandler.*;
import net.raphimc.viaproxy.proxy.proxy2server.Proxy2ServerChannelInitializer;
import net.raphimc.viaproxy.proxy.proxy2server.Proxy2ServerHandler;
@ -112,7 +112,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
}
this.proxyConnection.setClientVersion(clientVersion);
this.proxyConnection.setC2pConnectionState(packet.intendedState);
this.proxyConnection.setC2pConnectionState(packet.intendedState.getConnectionState());
if (clientVersion == VersionEnum.UNKNOWN || !VersionEnum.OFFICIAL_SUPPORTED_PROTOCOLS.contains(clientVersion)) {
this.proxyConnection.kickClient("§cYour client version is not supported by ViaProxy!");
@ -158,8 +158,8 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
}
}
if (serverVersion.equals(VersionEnum.bedrockLatest) && packet.intendedState == ConnectionState.LOGIN && ViaBedrockTransferHolder.hasTempRedirect(this.proxyConnection.getC2P())) {
serverAddress = ViaBedrockTransferHolder.removeTempRedirect(this.proxyConnection.getC2P());
if (packet.intendedState.getConnectionState() == ConnectionState.LOGIN && TransferDataHolder.hasTempRedirect(this.proxyConnection.getC2P())) {
serverAddress = TransferDataHolder.removeTempRedirect(this.proxyConnection.getC2P());
}
final PreConnectEvent preConnectEvent = new PreConnectEvent(serverAddress, serverVersion, clientVersion, this.proxyConnection.getC2P());
@ -172,7 +172,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
final UserOptions userOptions = new UserOptions(classicMpPass, Options.MC_ACCOUNT);
ChannelUtil.disableAutoRead(this.proxyConnection.getC2P());
if (packet.intendedState == ConnectionState.LOGIN && serverVersion.equals(VersionEnumExtension.AUTO_DETECT)) {
if (packet.intendedState.getConnectionState() == ConnectionState.LOGIN && serverVersion.equals(VersionEnumExtension.AUTO_DETECT)) {
SocketAddress finalServerAddress = serverAddress;
CompletableFuture.runAsync(() -> {
final VersionEnum detectedVersion = ProtocolVersionDetector.get(finalServerAddress, clientVersion);
@ -190,7 +190,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
}
}
private void connect(final SocketAddress serverAddress, final VersionEnum serverVersion, final VersionEnum clientVersion, final ConnectionState intendedState, final UserOptions userOptions, final String[] handshakeParts) {
private void connect(final SocketAddress serverAddress, final VersionEnum serverVersion, final VersionEnum clientVersion, final IntendedState intendedState, final UserOptions userOptions, final String[] handshakeParts) {
final Supplier<ChannelHandler> handlerSupplier = () -> ViaProxy.EVENT_MANAGER.call(new Proxy2ServerHandlerCreationEvent(new Proxy2ServerHandler(), false)).getHandler();
final ProxyConnection proxyConnection;
if (serverVersion.equals(VersionEnum.bedrockLatest)) {
@ -201,12 +201,15 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
this.proxyConnection = ViaProxy.EVENT_MANAGER.call(new ProxySessionCreationEvent<>(proxyConnection, false)).getProxySession();
this.proxyConnection.getC2P().attr(ProxyConnection.PROXY_CONNECTION_ATTRIBUTE_KEY).set(this.proxyConnection);
this.proxyConnection.setClientVersion(clientVersion);
this.proxyConnection.setC2pConnectionState(intendedState);
this.proxyConnection.setC2pConnectionState(intendedState.getConnectionState());
this.proxyConnection.setUserOptions(userOptions);
this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection));
this.proxyConnection.getPacketHandlers().add(new CustomPayloadPacketHandler(this.proxyConnection));
this.proxyConnection.getPacketHandlers().add(new CompressionPacketHandler(this.proxyConnection));
this.proxyConnection.getPacketHandlers().add(new LoginPacketHandler(this.proxyConnection));
if (clientVersion.isNewerThanOrEqualTo(VersionEnum.r1_20_5)) {
this.proxyConnection.getPacketHandlers().add(new TransferPacketHandler(this.proxyConnection));
}
if (clientVersion.isNewerThanOrEqualTo(VersionEnum.r1_20_2) || serverVersion.isNewerThanOrEqualTo(VersionEnum.r1_20_2)) {
this.proxyConnection.getPacketHandlers().add(new ConfigurationPacketHandler(this.proxyConnection));
}
@ -240,7 +243,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
final C2SHandshakePacket newHandshakePacket = new C2SHandshakePacket(clientVersion.getOriginalVersion(), String.join("\0", handshakeParts), port, intendedState);
this.proxyConnection.getChannel().writeAndFlush(newHandshakePacket).addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, (ChannelFutureListener) f2 -> {
if (f2.isSuccess()) {
this.proxyConnection.setP2sConnectionState(intendedState);
this.proxyConnection.setP2sConnectionState(intendedState.getConnectionState());
}
});

View File

@ -0,0 +1,83 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2021-2024 RK_01/RaphiMC 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 net.raphimc.viaproxy.proxy.packethandler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.packet.IPacket;
import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.netminecraft.packet.impl.configuration.S2CConfigTransfer1_20_5;
import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.proxy.util.TransferDataHolder;
import java.net.InetSocketAddress;
import java.util.List;
public class TransferPacketHandler extends PacketHandler {
private final int transferId;
public TransferPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection);
this.transferId = MCPackets.S2C_TRANSFER.getId(this.proxyConnection.getClientVersion().getVersion());
}
@Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) {
if (unknownPacket.packetId == this.transferId) {
final S2CConfigTransfer1_20_5 transfer = new S2CConfigTransfer1_20_5();
transfer.read(Unpooled.wrappedBuffer(unknownPacket.data));
this.handleTransfer(transfer);
final ByteBuf transferToViaProxy = Unpooled.buffer();
this.createTransferPacket().write(transferToViaProxy);
this.proxyConnection.getC2P().writeAndFlush(transferToViaProxy).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
return false;
}
} else if (packet instanceof S2CConfigTransfer1_20_5 transfer) {
this.handleTransfer(transfer);
this.proxyConnection.getC2P().writeAndFlush(this.createTransferPacket()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
return false;
}
return true;
}
private void handleTransfer(final S2CConfigTransfer1_20_5 transfer) {
final InetSocketAddress newAddress = new InetSocketAddress(transfer.host, transfer.port);
TransferDataHolder.addTempRedirect(this.proxyConnection.getC2P(), newAddress);
}
private S2CConfigTransfer1_20_5 createTransferPacket() {
if (!(ViaProxy.getCurrentProxyServer().getChannel().localAddress() instanceof InetSocketAddress bindAddress)) {
throw new IllegalArgumentException("ViaProxy bind address must be an InetSocketAddress");
}
if (!(this.proxyConnection.getC2P().localAddress() instanceof InetSocketAddress clientAddress)) {
throw new IllegalArgumentException("Client address must be an InetSocketAddress");
}
return new S2CConfigTransfer1_20_5(clientAddress.getHostString(), bindAddress.getPort());
}
}

View File

@ -15,7 +15,7 @@
* 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 net.raphimc.viaproxy.protocolhack.viaproxy;
package net.raphimc.viaproxy.proxy.util;
import io.netty.channel.Channel;
@ -24,7 +24,7 @@ import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ViaBedrockTransferHolder {
public class TransferDataHolder {
private static final Map<InetAddress, InetSocketAddress> TEMP_REDIRECTS = new ConcurrentHashMap<>();