Updated to NetMinecraft 3.0.0

This commit is contained in:
RaphiMC 2024-09-12 19:52:56 +02:00
parent 36b276f7e7
commit 7807407402
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
22 changed files with 214 additions and 510 deletions

View File

@ -95,10 +95,10 @@ dependencies {
exclude group: "com.google.code.gson", module: "gson" exclude group: "com.google.code.gson", module: "gson"
} }
include "net.lenni0451.commons:swing:1.6.0" include "net.lenni0451.commons:swing:1.6.0"
include("net.raphimc.netminecraft:all:2.5.1-SNAPSHOT") { include("net.raphimc.netminecraft:all:3.0.0-SNAPSHOT") {
exclude group: "com.google.code.gson", module: "gson" exclude group: "com.google.code.gson", module: "gson"
} }
include("net.raphimc:MinecraftAuth:4.1.0") { include("net.raphimc:MinecraftAuth:4.1.1-SNAPSHOT") {
exclude group: "com.google.code.gson", module: "gson" exclude group: "com.google.code.gson", module: "gson"
exclude group: "org.slf4j", module: "slf4j-api" exclude group: "org.slf4j", module: "slf4j-api"
} }

View File

@ -22,7 +22,7 @@ import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder; import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
import net.raphimc.netminecraft.constants.MCPipeline; import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.connection.MinecraftChannelInitializer; import net.raphimc.netminecraft.netty.connection.MinecraftChannelInitializer;
import net.raphimc.netminecraft.packet.registry.PacketRegistryUtil; import net.raphimc.netminecraft.packet.registry.DefaultPacketRegistry;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.plugins.events.Client2ProxyChannelInitializeEvent; import net.raphimc.viaproxy.plugins.events.Client2ProxyChannelInitializeEvent;
import net.raphimc.viaproxy.plugins.events.types.ITyped; import net.raphimc.viaproxy.plugins.events.types.ITyped;
@ -56,7 +56,7 @@ public class Client2ProxyChannelInitializer extends MinecraftChannelInitializer
} }
super.initChannel(channel); super.initChannel(channel);
channel.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getHandshakingRegistry(false)); channel.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(new DefaultPacketRegistry(false, -1));
if (ViaProxy.EVENT_MANAGER.call(new Client2ProxyChannelInitializeEvent(ITyped.Type.POST, channel, false)).isCancelled()) { if (ViaProxy.EVENT_MANAGER.call(new Client2ProxyChannelInitializeEvent(ITyped.Type.POST, channel, false)).isCancelled()) {
channel.close(); channel.close();

View File

@ -28,7 +28,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.IntendedState; import net.raphimc.netminecraft.constants.IntendedState;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.impl.handshaking.C2SHandshakingClientIntentionPacket; import net.raphimc.netminecraft.packet.impl.handshaking.C2SHandshakingClientIntentionPacket;
import net.raphimc.viabedrock.api.BedrockProtocolVersion; import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.vialegacy.api.LegacyProtocolVersion; import net.raphimc.vialegacy.api.LegacyProtocolVersion;
@ -63,7 +63,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> { public class Client2ProxyHandler extends SimpleChannelInboundHandler<Packet> {
private ProxyConnection proxyConnection; private ProxyConnection proxyConnection;
@ -87,7 +87,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
} }
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, IPacket packet) throws Exception { protected void channelRead0(ChannelHandlerContext ctx, Packet packet) throws Exception {
if (this.proxyConnection.isClosed()) return; if (this.proxyConnection.isClosed()) return;
if (this.proxyConnection.getC2pConnectionState() == ConnectionState.HANDSHAKING) { if (this.proxyConnection.getC2pConnectionState() == ConnectionState.HANDSHAKING) {

View File

@ -29,9 +29,8 @@ import io.netty.buffer.Unpooled;
import net.raphimc.minecraftauth.step.bedrock.StepMCChain; import net.raphimc.minecraftauth.step.bedrock.StepMCChain;
import net.raphimc.minecraftauth.step.java.StepPlayerCertificates; import net.raphimc.minecraftauth.step.java.StepPlayerCertificates;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket1_19_3; import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket1_20_2; import net.raphimc.netminecraft.packet.impl.login.C2SLoginKeyPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginKeyPacket1_19;
import net.raphimc.viabedrock.api.BedrockProtocolVersion; import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.viabedrock.protocol.storage.AuthChainData; import net.raphimc.viabedrock.protocol.storage.AuthChainData;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
@ -80,7 +79,7 @@ public class ExternalInterface {
if (proxyConnection.getClientVersion().equals(ProtocolVersion.v1_19)) { if (proxyConnection.getClientVersion().equals(ProtocolVersion.v1_19)) {
loginHelloKeySignature = playerCertificates.getLegacyPublicKeySignature(); loginHelloKeySignature = playerCertificates.getLegacyPublicKeySignature();
} }
proxyConnection.setLoginHelloPacket(new C2SLoginHelloPacket1_20_2(proxyConnection.getGameProfile().getName(), expiresAt, publicKey, loginHelloKeySignature, proxyConnection.getGameProfile().getId())); proxyConnection.setLoginHelloPacket(new C2SLoginHelloPacket(proxyConnection.getGameProfile().getName(), expiresAt, publicKey, loginHelloKeySignature, proxyConnection.getGameProfile().getId()));
user.put(new ChatSession1_19_0(uuid, privateKey, new ProfileKey(expiresAtMillis, publicKeyBytes, playerCertificates.getLegacyPublicKeySignature()))); user.put(new ChatSession1_19_0(uuid, privateKey, new ProfileKey(expiresAtMillis, publicKeyBytes, playerCertificates.getLegacyPublicKeySignature())));
user.put(new ChatSession1_19_1(uuid, privateKey, new ProfileKey(expiresAtMillis, publicKeyBytes, keySignature))); user.put(new ChatSession1_19_1(uuid, privateKey, new ProfileKey(expiresAtMillis, publicKeyBytes, keySignature)));
@ -101,9 +100,7 @@ public class ExternalInterface {
} }
proxyConnection.getLoginHelloPacket().name = proxyConnection.getGameProfile().getName(); proxyConnection.getLoginHelloPacket().name = proxyConnection.getGameProfile().getName();
if (proxyConnection.getLoginHelloPacket() instanceof C2SLoginHelloPacket1_19_3) { proxyConnection.getLoginHelloPacket().uuid = proxyConnection.getGameProfile().getId();
((C2SLoginHelloPacket1_19_3) proxyConnection.getLoginHelloPacket()).uuid = proxyConnection.getGameProfile().getId();
}
} }
public static void joinServer(final String serverIdHash, final ProxyConnection proxyConnection) throws InterruptedException, ExecutionException { public static void joinServer(final String serverIdHash, final ProxyConnection proxyConnection) throws InterruptedException, ExecutionException {
@ -127,7 +124,7 @@ public class ExternalInterface {
} }
} }
public static void signNonce(final byte[] nonce, final C2SLoginKeyPacket1_19 packet, final ProxyConnection proxyConnection) throws InterruptedException, ExecutionException, SignatureException { public static void signNonce(final byte[] nonce, final C2SLoginKeyPacket packet, final ProxyConnection proxyConnection) throws InterruptedException, ExecutionException, SignatureException {
Logger.u_info("auth", proxyConnection, "Requesting nonce signature"); Logger.u_info("auth", proxyConnection, "Requesting nonce signature");
final UserConnection user = proxyConnection.getUserConnection(); final UserConnection user = proxyConnection.getUserConnection();

View File

@ -20,15 +20,17 @@ package net.raphimc.viaproxy.proxy.packethandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket; import net.raphimc.netminecraft.packet.impl.common.S2CCustomPayloadPacket;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import java.util.List; import java.util.List;
public class BrandCustomPayloadPacketHandler extends CustomPayloadPacketHandler { public class BrandCustomPayloadPacketHandler extends PacketHandler {
private static final String BRAND_CHANNEL = "minecraft:brand"; private static final String BRAND_CHANNEL = "minecraft:brand";
private static final String LEGACY_BRAND_CHANNEL = "MC|Brand"; private static final String LEGACY_BRAND_CHANNEL = "MC|Brand";
@ -38,26 +40,29 @@ public class BrandCustomPayloadPacketHandler extends CustomPayloadPacketHandler
} }
@Override @Override
public ByteBuf handleP2S(UnknownPacket packet, String channel, ByteBuf data, List<ChannelFutureListener> listeners) throws Exception { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) throws Exception {
if (Key.namespaced(channel).equals(BRAND_CHANNEL) || channel.equals(LEGACY_BRAND_CHANNEL)) { if (packet instanceof S2CCustomPayloadPacket customPayloadPacket) {
String brand; if (Key.namespaced(customPayloadPacket.channel).equals(BRAND_CHANNEL) || customPayloadPacket.channel.equals(LEGACY_BRAND_CHANNEL)) {
try { final ByteBuf data = Unpooled.wrappedBuffer(customPayloadPacket.data);
brand = PacketTypes.readString(data, Short.MAX_VALUE); String brand;
} catch (Exception e) { try {
if (this.proxyConnection.getServerVersion().newerThan(ProtocolVersion.v1_20)) { brand = PacketTypes.readString(data, Short.MAX_VALUE);
throw e; } catch (Exception e) {
} else { // <=1.20 clients ignore errors if (this.proxyConnection.getServerVersion().newerThan(ProtocolVersion.v1_20)) {
brand = "Unknown"; throw e;
} else { // <=1.20 clients ignore errors
brand = "Unknown";
}
} }
} final String newBrand = "ViaProxy (" + this.proxyConnection.getClientVersion().getName() + ") -> " + brand + " §r(" + this.proxyConnection.getServerVersion().getName() + ")";
final String newBrand = "ViaProxy (" + this.proxyConnection.getClientVersion().getName() + ") -> " + brand + " §r(" + this.proxyConnection.getServerVersion().getName() + ")";
final ByteBuf newData = Unpooled.buffer(); final ByteBuf newData = Unpooled.buffer();
PacketTypes.writeString(newData, newBrand); PacketTypes.writeString(newData, newBrand);
return newData; customPayloadPacket.data = ByteBufUtil.getBytes(newData);
}
} }
return super.handleP2S(packet, channel, data, listeners); return super.handleP2S(packet, listeners);
} }
} }

View File

@ -28,7 +28,7 @@ import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets; import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.constants.MCPipeline; import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket; import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
@ -51,7 +51,7 @@ public class ChatSignaturePacketHandler extends PacketHandler {
} }
@Override @Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) throws Exception { public boolean handleC2P(Packet packet, List<ChannelFutureListener> listeners) throws Exception {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) { if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) {
final UserConnection user = this.proxyConnection.getUserConnection(); final UserConnection user = this.proxyConnection.getUserConnection();
@ -86,7 +86,7 @@ public class ChatSignaturePacketHandler extends PacketHandler {
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) { if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) {
final UserConnection user = this.proxyConnection.getUserConnection(); final UserConnection user = this.proxyConnection.getUserConnection();

View File

@ -18,17 +18,12 @@
package net.raphimc.viaproxy.proxy.packethandler; package net.raphimc.viaproxy.proxy.packethandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.constants.MCPipeline; import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginCompressionPacket; import net.raphimc.netminecraft.packet.impl.login.S2CLoginCompressionPacket;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginGameProfilePacket1_7; import net.raphimc.netminecraft.packet.impl.login.S2CLoginGameProfilePacket;
import net.raphimc.netminecraft.packet.impl.play.S2CPlaySetCompressionPacket;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.proxy.util.ChannelUtil; import net.raphimc.viaproxy.proxy.util.ChannelUtil;
@ -37,26 +32,16 @@ import java.util.List;
public class CompressionPacketHandler extends PacketHandler { public class CompressionPacketHandler extends PacketHandler {
private final int setCompressionId;
public CompressionPacketHandler(ProxyConnection proxyConnection) { public CompressionPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection); super(proxyConnection);
this.setCompressionId = MCPackets.S2C_SET_COMPRESSION.getId(proxyConnection.getClientVersion().getVersion());
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) { if (packet instanceof S2CPlaySetCompressionPacket setCompressionPacket) {
if (unknownPacket.packetId == this.setCompressionId) { this.proxyConnection.getChannel().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(setCompressionPacket.compressionThreshold);
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data); return false;
final int compressionThreshold = PacketTypes.readVarInt(data); // compression threshold } else if (packet instanceof S2CLoginGameProfilePacket) {
this.proxyConnection.getChannel().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(compressionThreshold);
data.release();
return false;
}
} else if (packet instanceof S2CLoginGameProfilePacket1_7) {
if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_8)) { if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_8)) {
if (ViaProxy.getConfig().getCompressionThreshold() > -1 && this.proxyConnection.getC2P().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).get() == -1) { if (ViaProxy.getConfig().getCompressionThreshold() > -1 && this.proxyConnection.getC2P().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).get() == -1) {
ChannelUtil.disableAutoRead(this.proxyConnection.getChannel()); ChannelUtil.disableAutoRead(this.proxyConnection.getChannel());

View File

@ -19,12 +19,12 @@ package net.raphimc.viaproxy.proxy.packethandler;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.IPacket;
import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.netminecraft.packet.impl.configuration.C2SConfigFinishConfigurationPacket; import net.raphimc.netminecraft.packet.impl.configuration.C2SConfigFinishConfigurationPacket;
import net.raphimc.netminecraft.packet.impl.configuration.S2CConfigFinishConfigurationPacket; import net.raphimc.netminecraft.packet.impl.configuration.S2CConfigFinishConfigurationPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginAcknowledgedPacket; import net.raphimc.netminecraft.packet.impl.login.C2SLoginAcknowledgedPacket;
import net.raphimc.netminecraft.packet.impl.play.C2SPlayConfigurationAcknowledgedPacket;
import net.raphimc.netminecraft.packet.impl.play.S2CPlayStartConfigurationPacket;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.proxy.util.ChannelUtil; import net.raphimc.viaproxy.proxy.util.ChannelUtil;
import net.raphimc.viaproxy.util.logging.Logger; import net.raphimc.viaproxy.util.logging.Logger;
@ -33,30 +33,13 @@ import java.util.List;
public class ConfigurationPacketHandler extends PacketHandler { public class ConfigurationPacketHandler extends PacketHandler {
private final int configurationAcknowledgedId;
private final int startConfigurationId;
public ConfigurationPacketHandler(ProxyConnection proxyConnection) { public ConfigurationPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection); super(proxyConnection);
this.configurationAcknowledgedId = MCPackets.C2S_CONFIGURATION_ACKNOWLEDGED.getId(proxyConnection.getClientVersion().getVersion());
this.startConfigurationId = MCPackets.S2C_START_CONFIGURATION.getId(proxyConnection.getClientVersion().getVersion());
} }
@Override @Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleC2P(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) { if (packet instanceof C2SLoginAcknowledgedPacket) {
if (unknownPacket.packetId == this.configurationAcknowledgedId) {
this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION);
listeners.add(f -> {
if (f.isSuccess()) {
Logger.u_info("session", this.proxyConnection, "Switching to CONFIGURATION state");
this.proxyConnection.setP2sConnectionState(ConnectionState.CONFIGURATION);
ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel());
}
});
}
} else if (packet instanceof C2SLoginAcknowledgedPacket) {
this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION); this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION);
listeners.add(f -> { listeners.add(f -> {
if (f.isSuccess()) { if (f.isSuccess()) {
@ -73,18 +56,25 @@ public class ConfigurationPacketHandler extends PacketHandler {
ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel()); ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel());
} }
}); });
} else if (packet instanceof C2SPlayConfigurationAcknowledgedPacket) {
this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION);
listeners.add(f -> {
if (f.isSuccess()) {
Logger.u_info("session", this.proxyConnection, "Switching to CONFIGURATION state");
this.proxyConnection.setP2sConnectionState(ConnectionState.CONFIGURATION);
ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel());
}
});
} }
return true; return true;
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) { if (packet instanceof S2CConfigFinishConfigurationPacket) {
if (unknownPacket.packetId == this.startConfigurationId) { ChannelUtil.disableAutoRead(this.proxyConnection.getChannel());
ChannelUtil.disableAutoRead(this.proxyConnection.getChannel()); } else if (packet instanceof S2CPlayStartConfigurationPacket) {
}
} else if (packet instanceof S2CConfigFinishConfigurationPacket) {
ChannelUtil.disableAutoRead(this.proxyConnection.getChannel()); ChannelUtil.disableAutoRead(this.proxyConnection.getChannel());
} }

View File

@ -1,105 +0,0 @@
/*
* 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.ByteBufUtil;
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.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import java.util.List;
public abstract class CustomPayloadPacketHandler extends PacketHandler {
private final int s2cCustomPayloadId;
private final int s2cConfigCustomPayloadId;
private final int c2sCustomPayloadId;
private final int c2sConfigCustomPayloadId;
public CustomPayloadPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection);
this.s2cCustomPayloadId = MCPackets.S2C_CUSTOM_PAYLOAD.getId(proxyConnection.getClientVersion().getVersion());
this.s2cConfigCustomPayloadId = MCPackets.S2C_CONFIG_CUSTOM_PAYLOAD.getId(proxyConnection.getClientVersion().getVersion());
this.c2sCustomPayloadId = MCPackets.C2S_CUSTOM_PAYLOAD.getId(proxyConnection.getClientVersion().getVersion());
this.c2sConfigCustomPayloadId = MCPackets.C2S_CONFIG_CUSTOM_PAYLOAD.getId(proxyConnection.getClientVersion().getVersion());
}
@Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) throws Exception {
if (packet instanceof UnknownPacket unknownPacket
&& (unknownPacket.packetId == this.s2cCustomPayloadId && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY
|| unknownPacket.packetId == this.s2cConfigCustomPayloadId && this.proxyConnection.getP2sConnectionState() == ConnectionState.CONFIGURATION)) {
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data);
final String channel = PacketTypes.readString(data, Short.MAX_VALUE); // channel
final ByteBuf newData = this.handleP2S(unknownPacket, channel, data, listeners);
if (newData == data) {
return true;
} else if (newData != null) {
final ByteBuf newCustomPayloadData = Unpooled.buffer();
PacketTypes.writeString(newCustomPayloadData, channel); // channel
newCustomPayloadData.writeBytes(newData);
unknownPacket.data = ByteBufUtil.getBytes(newCustomPayloadData);
return true;
} else {
return false;
}
}
return super.handleP2S(packet, listeners);
}
@Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) throws Exception {
if (packet instanceof UnknownPacket unknownPacket
&& (unknownPacket.packetId == this.c2sCustomPayloadId && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY
|| unknownPacket.packetId == this.c2sConfigCustomPayloadId && this.proxyConnection.getC2pConnectionState() == ConnectionState.CONFIGURATION)) {
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data);
final String channel = PacketTypes.readString(data, Short.MAX_VALUE); // channel
final ByteBuf newData = this.handleC2P(unknownPacket, channel, data, listeners);
if (newData == data) {
return true;
} else if (newData != null) {
final ByteBuf newCustomPayloadData = Unpooled.buffer();
PacketTypes.writeString(newCustomPayloadData, channel); // channel
newCustomPayloadData.writeBytes(newData);
unknownPacket.data = ByteBufUtil.getBytes(newCustomPayloadData);
return true;
} else {
return false;
}
}
return super.handleC2P(packet, listeners);
}
public ByteBuf handleC2P(final UnknownPacket packet, final String channel, final ByteBuf data, final List<ChannelFutureListener> listeners) throws Exception {
return data;
}
public ByteBuf handleP2S(final UnknownPacket packet, final String channel, final ByteBuf data, final List<ChannelFutureListener> listeners) throws Exception {
return data;
}
}

View File

@ -24,7 +24,7 @@ import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPipeline; import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.crypto.AESEncryption; import net.raphimc.netminecraft.netty.crypto.AESEncryption;
import net.raphimc.netminecraft.netty.crypto.CryptUtil; import net.raphimc.netminecraft.netty.crypto.CryptUtil;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.impl.login.*; import net.raphimc.netminecraft.packet.impl.login.*;
import net.raphimc.vialegacy.api.LegacyProtocolVersion; import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.release.r1_6_4tor1_7_2_5.storage.ProtocolMetadataStorage; import net.raphimc.vialegacy.protocol.release.r1_6_4tor1_7_2_5.storage.ProtocolMetadataStorage;
@ -66,26 +66,24 @@ public class LoginPacketHandler extends PacketHandler {
} }
@Override @Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) throws GeneralSecurityException { public boolean handleC2P(Packet packet, List<ChannelFutureListener> listeners) throws GeneralSecurityException {
if (packet instanceof C2SLoginHelloPacket1_7 loginHelloPacket) { if (packet instanceof C2SLoginHelloPacket loginHelloPacket) {
if (this.loginState != LoginState.FIRST_PACKET) throw CloseAndReturn.INSTANCE; if (this.loginState != LoginState.FIRST_PACKET) throw CloseAndReturn.INSTANCE;
this.loginState = LoginState.SENT_HELLO; this.loginState = LoginState.SENT_HELLO;
if (packet instanceof C2SLoginHelloPacket1_19 packet1_19) { if (loginHelloPacket.expiresAt != null && loginHelloPacket.expiresAt.isBefore(Instant.now())) {
if (packet1_19.expiresAt != null && packet1_19.expiresAt.isBefore(Instant.now())) {
throw new IllegalStateException("Expired public key"); throw new IllegalStateException("Expired public key");
} }
}
proxyConnection.setLoginHelloPacket(loginHelloPacket); proxyConnection.setLoginHelloPacket(loginHelloPacket);
if (packet instanceof C2SLoginHelloPacket1_19_3 packet1_19_3) { if (loginHelloPacket.uuid != null) {
proxyConnection.setGameProfile(new GameProfile(packet1_19_3.uuid, loginHelloPacket.name)); proxyConnection.setGameProfile(new GameProfile(loginHelloPacket.uuid, loginHelloPacket.name));
} else { } else {
proxyConnection.setGameProfile(new GameProfile(null, loginHelloPacket.name)); proxyConnection.setGameProfile(new GameProfile(null, loginHelloPacket.name));
} }
if (ViaProxy.getConfig().isProxyOnlineMode() && !ViaProxy.EVENT_MANAGER.call(new ShouldVerifyOnlineModeEvent(this.proxyConnection)).isCancelled()) { if (ViaProxy.getConfig().isProxyOnlineMode() && !ViaProxy.EVENT_MANAGER.call(new ShouldVerifyOnlineModeEvent(this.proxyConnection)).isCancelled()) {
this.proxyConnection.getC2P().writeAndFlush(new S2CLoginHelloPacket1_20_5("", KEY_PAIR.getPublic().getEncoded(), this.verifyToken, true)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); this.proxyConnection.getC2P().writeAndFlush(new S2CLoginHelloPacket("", KEY_PAIR.getPublic().getEncoded(), this.verifyToken, true)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else { } else {
ViaProxy.EVENT_MANAGER.call(new ClientLoggedInEvent(proxyConnection)); ViaProxy.EVENT_MANAGER.call(new ClientLoggedInEvent(proxyConnection));
ExternalInterface.fillPlayerData(this.proxyConnection); ExternalInterface.fillPlayerData(this.proxyConnection);
@ -93,7 +91,7 @@ public class LoginPacketHandler extends PacketHandler {
} }
return false; return false;
} else if (packet instanceof C2SLoginKeyPacket1_7 loginKeyPacket) { } else if (packet instanceof C2SLoginKeyPacket loginKeyPacket) {
if (this.loginState != LoginState.SENT_HELLO) throw CloseAndReturn.INSTANCE; if (this.loginState != LoginState.SENT_HELLO) throw CloseAndReturn.INSTANCE;
this.loginState = LoginState.SENT_KEY; this.loginState = LoginState.SENT_KEY;
@ -103,9 +101,8 @@ public class LoginPacketHandler extends PacketHandler {
this.proxyConnection.kickClient("§cInvalid verify token!"); this.proxyConnection.kickClient("§cInvalid verify token!");
} }
} else { } else {
final C2SLoginKeyPacket1_19 keyPacket = (C2SLoginKeyPacket1_19) packet; final C2SLoginHelloPacket loginHelloPacket = this.proxyConnection.getLoginHelloPacket();
final C2SLoginHelloPacket1_19 helloPacket = (C2SLoginHelloPacket1_19) this.proxyConnection.getLoginHelloPacket(); if (loginHelloPacket.key == null || !CryptUtil.verifySignedNonce(loginHelloPacket.key, this.verifyToken, loginKeyPacket.salt, loginKeyPacket.signature)) {
if (helloPacket.key == null || !CryptUtil.verifySignedNonce(helloPacket.key, this.verifyToken, keyPacket.salt, keyPacket.signature)) {
Logger.u_err("auth", this.proxyConnection, "Invalid verify token"); Logger.u_err("auth", this.proxyConnection, "Invalid verify token");
this.proxyConnection.kickClient("§cInvalid verify token!"); this.proxyConnection.kickClient("§cInvalid verify token!");
} }
@ -140,15 +137,15 @@ public class LoginPacketHandler extends PacketHandler {
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) throws GeneralSecurityException, ExecutionException, InterruptedException { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) throws GeneralSecurityException, ExecutionException, InterruptedException {
if (packet instanceof S2CLoginDisconnectPacket1_7 loginDisconnectPacket) { if (packet instanceof S2CLoginDisconnectPacket loginDisconnectPacket) {
Logger.u_info("server kick", this.proxyConnection, ConsoleFormatter.convert(loginDisconnectPacket.reason.asLegacyFormatString())); Logger.u_info("server kick", this.proxyConnection, ConsoleFormatter.convert(loginDisconnectPacket.reason.asLegacyFormatString()));
} else if (packet instanceof S2CLoginHelloPacket1_7 loginHelloPacket) { } else if (packet instanceof S2CLoginHelloPacket loginHelloPacket) {
final PublicKey publicKey = CryptUtil.decodeRsaPublicKey(loginHelloPacket.publicKey); final PublicKey publicKey = CryptUtil.decodeRsaPublicKey(loginHelloPacket.publicKey);
final SecretKey secretKey = CryptUtil.generateSecretKey(); final SecretKey secretKey = CryptUtil.generateSecretKey();
final String serverHash = new BigInteger(CryptUtil.computeServerIdHash(loginHelloPacket.serverId, publicKey, secretKey)).toString(16); final String serverHash = new BigInteger(CryptUtil.computeServerIdHash(loginHelloPacket.serverId, publicKey, secretKey)).toString(16);
boolean auth = !(packet instanceof S2CLoginHelloPacket1_20_5 packet1_20_5) || packet1_20_5.authenticate; boolean auth = this.proxyConnection.getClientVersion().olderThan(ProtocolVersion.v1_20_5) || loginHelloPacket.authenticate;
if (auth && this.proxyConnection.getServerVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { if (auth && this.proxyConnection.getServerVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
auth = this.proxyConnection.getUserConnection().get(ProtocolMetadataStorage.class).authenticate; auth = this.proxyConnection.getUserConnection().get(ProtocolMetadataStorage.class).authenticate;
} }
@ -159,8 +156,8 @@ public class LoginPacketHandler extends PacketHandler {
final byte[] encryptedSecretKey = CryptUtil.encryptData(publicKey, secretKey.getEncoded()); final byte[] encryptedSecretKey = CryptUtil.encryptData(publicKey, secretKey.getEncoded());
final byte[] encryptedNonce = CryptUtil.encryptData(publicKey, loginHelloPacket.nonce); final byte[] encryptedNonce = CryptUtil.encryptData(publicKey, loginHelloPacket.nonce);
final C2SLoginKeyPacket1_19_3 loginKey = new C2SLoginKeyPacket1_19_3(encryptedSecretKey, encryptedNonce); final C2SLoginKeyPacket loginKey = new C2SLoginKeyPacket(encryptedSecretKey, encryptedNonce);
if (this.proxyConnection.getServerVersion().newerThanOrEqualTo(ProtocolVersion.v1_19) && this.proxyConnection.getLoginHelloPacket() instanceof C2SLoginHelloPacket1_19 && ((C2SLoginHelloPacket1_19) this.proxyConnection.getLoginHelloPacket()).key != null) { if (this.proxyConnection.getServerVersion().newerThanOrEqualTo(ProtocolVersion.v1_19) && this.proxyConnection.getLoginHelloPacket().key != null) {
ExternalInterface.signNonce(loginHelloPacket.nonce, loginKey, this.proxyConnection); ExternalInterface.signNonce(loginHelloPacket.nonce, loginKey, this.proxyConnection);
} }
this.proxyConnection.getChannel().writeAndFlush(loginKey).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); this.proxyConnection.getChannel().writeAndFlush(loginKey).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
@ -172,7 +169,7 @@ public class LoginPacketHandler extends PacketHandler {
} }
return false; return false;
} else if (packet instanceof S2CLoginGameProfilePacket1_7 loginGameProfilePacket) { } else if (packet instanceof S2CLoginGameProfilePacket loginGameProfilePacket) {
final ConnectionState nextState = this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_2) ? ConnectionState.CONFIGURATION : ConnectionState.PLAY; final ConnectionState nextState = this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_2) ? ConnectionState.CONFIGURATION : ConnectionState.PLAY;
this.proxyConnection.setGameProfile(new GameProfile(loginGameProfilePacket.uuid, loginGameProfilePacket.name)); this.proxyConnection.setGameProfile(new GameProfile(loginGameProfilePacket.uuid, loginGameProfilePacket.name));

View File

@ -23,15 +23,14 @@ import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.lenni0451.mcstructs.text.components.StringComponent; import net.lenni0451.mcstructs.text.components.StringComponent;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.packet.IPacket;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket; import net.raphimc.netminecraft.packet.impl.common.C2SCustomPayloadPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginCustomQueryAnswerPacket; import net.raphimc.netminecraft.packet.impl.login.C2SLoginCustomQueryAnswerPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginKeyPacket1_7; import net.raphimc.netminecraft.packet.impl.login.C2SLoginKeyPacket;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginCustomQueryPacket; import net.raphimc.netminecraft.packet.impl.login.S2CLoginCustomQueryPacket;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginDisconnectPacket1_20_3; import net.raphimc.netminecraft.packet.impl.login.S2CLoginDisconnectPacket;
import net.raphimc.netminecraft.packet.impl.play.S2CPlayCustomPayloadPacket;
import net.raphimc.viaproxy.proxy.external_interface.OpenAuthModConstants; import net.raphimc.viaproxy.proxy.external_interface.OpenAuthModConstants;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
@ -45,33 +44,25 @@ import java.util.concurrent.atomic.AtomicInteger;
public class OpenAuthModPacketHandler extends PacketHandler { public class OpenAuthModPacketHandler extends PacketHandler {
private final int c2sCustomPayloadId;
private final int s2cCustomPayloadId;
private final AtomicInteger id = new AtomicInteger(0); private final AtomicInteger id = new AtomicInteger(0);
private final Map<Integer, CompletableFuture<ByteBuf>> customPayloadListener = new ConcurrentHashMap<>(); private final Map<Integer, CompletableFuture<ByteBuf>> customPayloadListener = new ConcurrentHashMap<>();
public OpenAuthModPacketHandler(ProxyConnection proxyConnection) { public OpenAuthModPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection); super(proxyConnection);
this.c2sCustomPayloadId = MCPackets.C2S_CUSTOM_PAYLOAD.getId(proxyConnection.getClientVersion().getVersion());
this.s2cCustomPayloadId = MCPackets.S2C_CUSTOM_PAYLOAD.getId(proxyConnection.getClientVersion().getVersion());
} }
@Override @Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleC2P(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) { if (packet instanceof C2SCustomPayloadPacket customPayloadPacket) {
if (unknownPacket.packetId == this.c2sCustomPayloadId) { final ByteBuf data = Unpooled.wrappedBuffer(customPayloadPacket.data);
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data); if (customPayloadPacket.channel.equals(OpenAuthModConstants.DATA_CHANNEL) && this.handleCustomPayload(PacketTypes.readVarInt(data), data)) {
final String channel = PacketTypes.readString(data, Short.MAX_VALUE); // channel return false;
if (channel.equals(OpenAuthModConstants.DATA_CHANNEL) && this.handleCustomPayload(PacketTypes.readVarInt(data), data)) {
return false;
}
} }
} else if (packet instanceof C2SLoginCustomQueryAnswerPacket loginCustomQueryAnswer) { } else if (packet instanceof C2SLoginCustomQueryAnswerPacket loginCustomQueryAnswer) {
if (loginCustomQueryAnswer.response != null && this.handleCustomPayload(loginCustomQueryAnswer.queryId, Unpooled.wrappedBuffer(loginCustomQueryAnswer.response))) { if (loginCustomQueryAnswer.response != null && this.handleCustomPayload(loginCustomQueryAnswer.queryId, Unpooled.wrappedBuffer(loginCustomQueryAnswer.response))) {
return false; return false;
} }
} else if (packet instanceof C2SLoginKeyPacket1_7 loginKeyPacket) { } else if (packet instanceof C2SLoginKeyPacket loginKeyPacket) {
if (this.proxyConnection.getClientVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) && new String(loginKeyPacket.encryptedNonce, StandardCharsets.UTF_8).equals(OpenAuthModConstants.DATA_CHANNEL)) { // 1.8-1.12.2 OpenAuthMod response handling if (this.proxyConnection.getClientVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) && new String(loginKeyPacket.encryptedNonce, StandardCharsets.UTF_8).equals(OpenAuthModConstants.DATA_CHANNEL)) { // 1.8-1.12.2 OpenAuthMod response handling
final ByteBuf byteBuf = Unpooled.wrappedBuffer(loginKeyPacket.encryptedSecretKey); final ByteBuf byteBuf = Unpooled.wrappedBuffer(loginKeyPacket.encryptedSecretKey);
this.handleCustomPayload(PacketTypes.readVarInt(byteBuf), byteBuf); this.handleCustomPayload(PacketTypes.readVarInt(byteBuf), byteBuf);
@ -96,16 +87,14 @@ public class OpenAuthModPacketHandler extends PacketHandler {
PacketTypes.writeString(disconnectPacketData, channel); PacketTypes.writeString(disconnectPacketData, channel);
PacketTypes.writeVarInt(disconnectPacketData, id); PacketTypes.writeVarInt(disconnectPacketData, id);
disconnectPacketData.writeBytes(data); disconnectPacketData.writeBytes(data);
this.proxyConnection.getC2P().writeAndFlush(new S2CLoginDisconnectPacket1_20_3(new StringComponent("§cYou need to install OpenAuthMod in order to join this server.§k\n" + Base64.getEncoder().encodeToString(ByteBufUtil.getBytes(disconnectPacketData)) + "\n" + OpenAuthModConstants.LEGACY_MAGIC_STRING))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); this.proxyConnection.getC2P().writeAndFlush(new S2CLoginDisconnectPacket(new StringComponent("§cYou need to install OpenAuthMod in order to join this server.§k\n" + Base64.getEncoder().encodeToString(ByteBufUtil.getBytes(disconnectPacketData)) + "\n" + OpenAuthModConstants.LEGACY_MAGIC_STRING))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} }
break; break;
case PLAY: case PLAY:
final ByteBuf customPayloadPacket = Unpooled.buffer(); final ByteBuf responseData = Unpooled.buffer();
PacketTypes.writeVarInt(customPayloadPacket, this.s2cCustomPayloadId); PacketTypes.writeVarInt(responseData, id);
PacketTypes.writeString(customPayloadPacket, channel); // channel responseData.writeBytes(data);
PacketTypes.writeVarInt(customPayloadPacket, id); this.proxyConnection.getC2P().writeAndFlush(new S2CPlayCustomPayloadPacket(channel, ByteBufUtil.getBytes(responseData))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
customPayloadPacket.writeBytes(data);
this.proxyConnection.getC2P().writeAndFlush(customPayloadPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
break; break;
default: default:
throw new IllegalStateException("Can't send a custom payload packet during " + this.proxyConnection.getC2pConnectionState()); throw new IllegalStateException("Can't send a custom payload packet during " + this.proxyConnection.getC2pConnectionState());

View File

@ -18,7 +18,7 @@
package net.raphimc.viaproxy.proxy.packethandler; package net.raphimc.viaproxy.proxy.packethandler;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import java.util.List; import java.util.List;
@ -31,11 +31,11 @@ public abstract class PacketHandler {
this.proxyConnection = proxyConnection; this.proxyConnection = proxyConnection;
} }
public boolean handleC2P(final IPacket packet, final List<ChannelFutureListener> listeners) throws Exception { public boolean handleC2P(final Packet packet, final List<ChannelFutureListener> listeners) throws Exception {
return true; return true;
} }
public boolean handleP2S(final IPacket packet, final List<ChannelFutureListener> listeners) throws Exception { public boolean handleP2S(final Packet packet, final List<ChannelFutureListener> listeners) throws Exception {
return true; return true;
} }

View File

@ -19,15 +19,16 @@ package net.raphimc.viaproxy.proxy.packethandler;
import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.libs.gson.JsonElement;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.lenni0451.mcstructs.text.ATextComponent;
import net.lenni0451.mcstructs.text.serializer.TextComponentSerializer;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets; import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket; import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.netminecraft.packet.impl.play.S2CPlayCustomPayloadPacket;
import net.raphimc.netminecraft.packet.impl.play.S2CPlayResourcePackPacket;
import net.raphimc.netminecraft.packet.impl.play.S2CPlayResourcePackPushPacket;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
@ -47,7 +48,7 @@ public class ResourcePackPacketHandler extends PacketHandler {
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) { if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) {
if (unknownPacket.packetId == this.joinGameId) { if (unknownPacket.packetId == this.joinGameId) {
listeners.add(f -> { listeners.add(f -> {
@ -64,46 +65,17 @@ public class ResourcePackPacketHandler extends PacketHandler {
private void sendResourcePack() { private void sendResourcePack() {
if (!ViaProxy.getConfig().getResourcePackUrl().isBlank()) { if (!ViaProxy.getConfig().getResourcePackUrl().isBlank()) {
this.proxyConnection.getChannel().eventLoop().schedule(() -> { this.proxyConnection.getChannel().eventLoop().schedule(() -> {
if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_3)) { final String url = ViaProxy.getConfig().getResourcePackUrl();
final ByteBuf resourcePackPushPacket = Unpooled.buffer(); final boolean required = Via.getConfig().isForcedUse1_17ResourcePack();
PacketTypes.writeVarInt(resourcePackPushPacket, MCPackets.S2C_RESOURCE_PACK_PUSH.getId(this.proxyConnection.getClientVersion().getVersion())); final ATextComponent message = TextComponentSerializer.LATEST.deserialize(Via.getConfig().get1_17ResourcePackPrompt().toString());
PacketTypes.writeUuid(resourcePackPushPacket, UUID.randomUUID()); // pack id
PacketTypes.writeString(resourcePackPushPacket, ViaProxy.getConfig().getResourcePackUrl()); // url
PacketTypes.writeString(resourcePackPushPacket, ""); // hash
resourcePackPushPacket.writeBoolean(Via.getConfig().isForcedUse1_17ResourcePack()); // required
final JsonElement promptMessage = Via.getConfig().get1_17ResourcePackPrompt();
if (promptMessage != null) {
resourcePackPushPacket.writeBoolean(true); // has message
PacketTypes.writeString(resourcePackPushPacket, promptMessage.toString()); // message
} else {
resourcePackPushPacket.writeBoolean(false); // has message
}
this.proxyConnection.getC2P().writeAndFlush(resourcePackPushPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_8)) {
final ByteBuf resourcePackPacket = Unpooled.buffer();
PacketTypes.writeVarInt(resourcePackPacket, MCPackets.S2C_RESOURCE_PACK.getId(this.proxyConnection.getClientVersion().getVersion()));
PacketTypes.writeString(resourcePackPacket, ViaProxy.getConfig().getResourcePackUrl()); // url
PacketTypes.writeString(resourcePackPacket, ""); // hash
if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
resourcePackPacket.writeBoolean(Via.getConfig().isForcedUse1_17ResourcePack()); // required
final JsonElement promptMessage = Via.getConfig().get1_17ResourcePackPrompt();
if (promptMessage != null) {
resourcePackPacket.writeBoolean(true); // has message
PacketTypes.writeString(resourcePackPacket, promptMessage.toString()); // message
} else {
resourcePackPacket.writeBoolean(false); // has message
}
}
this.proxyConnection.getC2P().writeAndFlush(resourcePackPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_7_2)) {
final byte[] data = ViaProxy.getConfig().getResourcePackUrl().getBytes(StandardCharsets.UTF_8);
final ByteBuf customPayloadPacket = Unpooled.buffer(); if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_3)) {
PacketTypes.writeVarInt(customPayloadPacket, MCPackets.S2C_CUSTOM_PAYLOAD.getId(this.proxyConnection.getClientVersion().getVersion())); this.proxyConnection.getC2P().writeAndFlush(new S2CPlayResourcePackPushPacket(UUID.randomUUID(), url, "", required, message)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
PacketTypes.writeString(customPayloadPacket, "MC|RPack"); // channel } else if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_8)) {
customPayloadPacket.writeShort(data.length); // length this.proxyConnection.getC2P().writeAndFlush(new S2CPlayResourcePackPacket(url, "", required, message)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
customPayloadPacket.writeBytes(data); // data } else if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_7_2)) {
this.proxyConnection.getC2P().writeAndFlush(customPayloadPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); final byte[] data = url.getBytes(StandardCharsets.UTF_8);
this.proxyConnection.getC2P().writeAndFlush(new S2CPlayCustomPayloadPacket("MC|RPack", data)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} }
}, 250, TimeUnit.MILLISECONDS); }, 250, TimeUnit.MILLISECONDS);
} }

View File

@ -17,15 +17,14 @@
*/ */
package net.raphimc.viaproxy.proxy.packethandler; package net.raphimc.viaproxy.proxy.packethandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.impl.common.S2CResourcePackPacket;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.impl.common.S2CResourcePackPopPacket;
import net.raphimc.netminecraft.packet.UnknownPacket; import net.raphimc.netminecraft.packet.impl.common.S2CResourcePackPushPacket;
import net.raphimc.netminecraft.packet.impl.configuration.C2SConfigResourcePackPacket;
import net.raphimc.netminecraft.packet.impl.play.C2SPlayResourcePackPacket;
import net.raphimc.viabedrock.protocol.data.enums.java.ResourcePackAction; import net.raphimc.viabedrock.protocol.data.enums.java.ResourcePackAction;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
@ -36,50 +35,24 @@ import java.util.UUID;
public class ResourcePackSpooferPacketHandler extends PacketHandler { public class ResourcePackSpooferPacketHandler extends PacketHandler {
private final int s2cResourcePackId;
private final int s2cConfigResourcePackId;
private final int resourcePackPushId;
private final int configResourcePackPushId;
private final int resourcePackPopId;
private final int configResourcePackPopId;
private final int c2sResourcePackId;
private final int c2sConfigResourcePackId;
private final Set<UUID> resourcePacks = new HashSet<>(); private final Set<UUID> resourcePacks = new HashSet<>();
public ResourcePackSpooferPacketHandler(ProxyConnection proxyConnection) { public ResourcePackSpooferPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection); super(proxyConnection);
this.s2cResourcePackId = MCPackets.S2C_RESOURCE_PACK.getId(this.proxyConnection.getClientVersion().getVersion());
this.s2cConfigResourcePackId = MCPackets.S2C_CONFIG_RESOURCE_PACK.getId(this.proxyConnection.getClientVersion().getVersion());
this.resourcePackPushId = MCPackets.S2C_RESOURCE_PACK_PUSH.getId(this.proxyConnection.getClientVersion().getVersion());
this.configResourcePackPushId = MCPackets.S2C_CONFIG_RESOURCE_PACK_PUSH.getId(this.proxyConnection.getClientVersion().getVersion());
this.resourcePackPopId = MCPackets.S2C_RESOURCE_PACK_POP.getId(this.proxyConnection.getClientVersion().getVersion());
this.configResourcePackPopId = MCPackets.S2C_CONFIG_RESOURCE_PACK_POP.getId(this.proxyConnection.getClientVersion().getVersion());
this.c2sResourcePackId = MCPackets.C2S_RESOURCE_PACK.getId(this.proxyConnection.getClientVersion().getVersion());
this.c2sConfigResourcePackId = MCPackets.C2S_CONFIG_RESOURCE_PACK.getId(this.proxyConnection.getClientVersion().getVersion());
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket if (packet instanceof S2CResourcePackPushPacket resourcePackPushPacket) {
&& (unknownPacket.packetId == this.resourcePackPushId && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY this.resourcePacks.add(resourcePackPushPacket.packId);
|| unknownPacket.packetId == this.configResourcePackPushId && this.proxyConnection.getP2sConnectionState() == ConnectionState.CONFIGURATION)) { this.sendResponse(resourcePackPushPacket.packId, null, ResourcePackAction.ACCEPTED.ordinal());
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data);
final UUID packId = PacketTypes.readUuid(data); // pack id
this.resourcePacks.add(packId);
this.sendResponse(packId, null, ResourcePackAction.ACCEPTED.ordinal());
for (UUID resourcePack : this.resourcePacks) { for (UUID resourcePack : this.resourcePacks) {
this.sendResponse(resourcePack, null, ResourcePackAction.SUCCESSFULLY_LOADED.ordinal()); this.sendResponse(resourcePack, null, ResourcePackAction.SUCCESSFULLY_LOADED.ordinal());
} }
return false; return false;
} else if (packet instanceof UnknownPacket unknownPacket } else if (packet instanceof S2CResourcePackPopPacket resourcePackPopPacket) {
&& (unknownPacket.packetId == this.resourcePackPopId && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY if (resourcePackPopPacket.packId != null) {
|| unknownPacket.packetId == this.configResourcePackPopId && this.proxyConnection.getP2sConnectionState() == ConnectionState.CONFIGURATION)) { this.resourcePacks.remove(resourcePackPopPacket.packId);
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data);
if (data.readBoolean()) { // has pack id
final UUID packId = PacketTypes.readUuid(data); // pack id
this.resourcePacks.remove(packId);
} else { } else {
this.resourcePacks.clear(); this.resourcePacks.clear();
} }
@ -87,14 +60,9 @@ public class ResourcePackSpooferPacketHandler extends PacketHandler {
this.sendResponse(resourcePack, null, ResourcePackAction.SUCCESSFULLY_LOADED.ordinal()); this.sendResponse(resourcePack, null, ResourcePackAction.SUCCESSFULLY_LOADED.ordinal());
} }
return false; return false;
} else if (packet instanceof UnknownPacket unknownPacket } else if (packet instanceof S2CResourcePackPacket resourcePackPacket) {
&& (unknownPacket.packetId == this.s2cResourcePackId && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY this.sendResponse(null, resourcePackPacket.hash, ResourcePackAction.ACCEPTED.ordinal());
|| unknownPacket.packetId == this.s2cConfigResourcePackId && this.proxyConnection.getP2sConnectionState() == ConnectionState.CONFIGURATION)) { this.sendResponse(null, resourcePackPacket.hash, ResourcePackAction.SUCCESSFULLY_LOADED.ordinal());
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data);
PacketTypes.readString(data, Short.MAX_VALUE); // url
final String hash = PacketTypes.readString(data, 40); // hash
this.sendResponse(null, hash, ResourcePackAction.ACCEPTED.ordinal());
this.sendResponse(null, hash, ResourcePackAction.SUCCESSFULLY_LOADED.ordinal());
return false; return false;
} }
@ -102,15 +70,11 @@ public class ResourcePackSpooferPacketHandler extends PacketHandler {
} }
private void sendResponse(final UUID packId, final String hash, final int status) { private void sendResponse(final UUID packId, final String hash, final int status) {
final ByteBuf resourcePackResponse = Unpooled.buffer(); if (this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) {
PacketTypes.writeVarInt(resourcePackResponse, this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY ? this.c2sResourcePackId : this.c2sConfigResourcePackId); this.proxyConnection.getChannel().writeAndFlush(new C2SPlayResourcePackPacket(status, packId, hash)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_3)) { } else {
PacketTypes.writeUuid(resourcePackResponse, packId); // pack id this.proxyConnection.getChannel().writeAndFlush(new C2SConfigResourcePackPacket(status, packId, hash)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else if (this.proxyConnection.getClientVersion().olderThanOrEqualTo(ProtocolVersion.v1_9)) {
PacketTypes.writeString(resourcePackResponse, hash); // hash
} }
PacketTypes.writeVarInt(resourcePackResponse, status); // status
this.proxyConnection.getChannel().writeAndFlush(resourcePackResponse).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} }
} }

View File

@ -19,17 +19,19 @@ package net.raphimc.viaproxy.proxy.packethandler;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket; import net.raphimc.netminecraft.packet.impl.common.S2CCustomPayloadPacket;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.util.logging.Logger; import net.raphimc.viaproxy.util.logging.Logger;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.List; import java.util.List;
public class SimpleVoiceChatPacketHandler extends CustomPayloadPacketHandler { public class SimpleVoiceChatPacketHandler extends PacketHandler {
private static final String SECRET_CHANNEL = "voicechat:secret"; private static final String SECRET_CHANNEL = "voicechat:secret";
@ -38,38 +40,40 @@ public class SimpleVoiceChatPacketHandler extends CustomPayloadPacketHandler {
} }
@Override @Override
public ByteBuf handleP2S(UnknownPacket packet, String channel, ByteBuf data, List<ChannelFutureListener> listeners) throws Exception { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) throws Exception {
if (Key.namespaced(channel).equals(SECRET_CHANNEL)) { if (packet instanceof S2CCustomPayloadPacket customPayloadPacket) {
try { if (Key.namespaced(customPayloadPacket.channel).equals(SECRET_CHANNEL)) {
final ByteBuf newData = Unpooled.buffer(); final ByteBuf data = Unpooled.wrappedBuffer(customPayloadPacket.data);
PacketTypes.writeUuid(newData, PacketTypes.readUuid(data)); // secret try {
final int port = data.readInt(); // port final ByteBuf newData = Unpooled.buffer();
newData.writeInt(port); PacketTypes.writeUuid(newData, PacketTypes.readUuid(data)); // secret
PacketTypes.writeUuid(newData, PacketTypes.readUuid(data)); // player uuid final int port = data.readInt(); // port
newData.writeByte(data.readByte()); // codec newData.writeInt(port);
newData.writeInt(data.readInt()); // mtu size PacketTypes.writeUuid(newData, PacketTypes.readUuid(data)); // player uuid
newData.writeDouble(data.readDouble()); // voice chat distance newData.writeByte(data.readByte()); // codec
newData.writeInt(data.readInt()); // keep alive newData.writeInt(data.readInt()); // mtu size
newData.writeBoolean(data.readBoolean()); // groups enabled newData.writeDouble(data.readDouble()); // voice chat distance
final String voiceHost = PacketTypes.readString(data, Short.MAX_VALUE); // voice host newData.writeInt(data.readInt()); // keep alive
if (voiceHost.isEmpty()) { newData.writeBoolean(data.readBoolean()); // groups enabled
if (this.proxyConnection.getServerAddress() instanceof InetSocketAddress serverAddress) { final String voiceHost = PacketTypes.readString(data, Short.MAX_VALUE); // voice host
PacketTypes.writeString(newData, new InetSocketAddress(serverAddress.getAddress(), port).toString()); if (voiceHost.isEmpty()) {
if (this.proxyConnection.getServerAddress() instanceof InetSocketAddress serverAddress) {
PacketTypes.writeString(newData, new InetSocketAddress(serverAddress.getAddress(), port).toString());
} else {
throw new IllegalArgumentException("Server address must be an InetSocketAddress");
}
} else { } else {
throw new IllegalArgumentException("Server address must be an InetSocketAddress"); PacketTypes.writeString(newData, voiceHost);
} }
} else { newData.writeBytes(data);
PacketTypes.writeString(newData, voiceHost); customPayloadPacket.data = ByteBufUtil.getBytes(newData);
} catch (Throwable e) {
Logger.LOGGER.error("Failed to handle simple voice chat packet", e);
} }
newData.writeBytes(data);
return newData;
} catch (Throwable e) {
Logger.LOGGER.error("Failed to handle simple voice chat packet", e);
return super.handleP2S(packet, channel, data, listeners);
} }
} }
return super.handleP2S(packet, channel, data, listeners); return super.handleP2S(packet, listeners);
} }
} }

View File

@ -20,7 +20,7 @@ package net.raphimc.viaproxy.proxy.packethandler;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.packet.impl.status.S2CStatusPongResponsePacket; import net.raphimc.netminecraft.packet.impl.status.S2CStatusPongResponsePacket;
import net.raphimc.netminecraft.packet.impl.status.S2CStatusResponsePacket; import net.raphimc.netminecraft.packet.impl.status.S2CStatusResponsePacket;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
@ -35,7 +35,7 @@ public class StatusPacketHandler extends PacketHandler {
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof S2CStatusPongResponsePacket) { if (packet instanceof S2CStatusPongResponsePacket) {
listeners.add(ChannelFutureListener.CLOSE); listeners.add(ChannelFutureListener.CLOSE);
} else if (packet instanceof S2CStatusResponsePacket statusResponsePacket && !ViaProxy.getConfig().getCustomMotd().isBlank()) { } else if (packet instanceof S2CStatusResponsePacket statusResponsePacket && !ViaProxy.getConfig().getCustomMotd().isBlank()) {

View File

@ -17,14 +17,8 @@
*/ */
package net.raphimc.viaproxy.proxy.packethandler; package net.raphimc.viaproxy.proxy.packethandler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.packet.IPacket;
import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.netminecraft.packet.impl.common.S2CTransferPacket; import net.raphimc.netminecraft.packet.impl.common.S2CTransferPacket;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
@ -36,55 +30,33 @@ import java.util.List;
public class TransferPacketHandler extends PacketHandler { public class TransferPacketHandler extends PacketHandler {
private final int transferId;
public TransferPacketHandler(ProxyConnection proxyConnection) { public TransferPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection); super(proxyConnection);
this.transferId = MCPackets.S2C_TRANSFER.getId(this.proxyConnection.getClientVersion().getVersion());
} }
@Override @Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleP2S(Packet packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) { if (packet instanceof S2CTransferPacket transferPacket) {
if (unknownPacket.packetId == this.transferId) { final InetSocketAddress newAddress = new InetSocketAddress(transferPacket.host, transferPacket.port);
final S2CTransferPacket transfer = new S2CTransferPacket(); TransferDataHolder.addTempRedirect(this.proxyConnection.getC2P(), newAddress);
transfer.read(Unpooled.wrappedBuffer(unknownPacket.data));
this.handleTransfer(transfer);
final ByteBuf transferToViaProxy = Unpooled.buffer(); if (this.proxyConnection.getClientHandshakeAddress() != null) {
PacketTypes.writeVarInt(transferToViaProxy, this.transferId); transferPacket.host = this.proxyConnection.getClientHandshakeAddress().getHost();
this.createTransferPacket().write(transferToViaProxy); transferPacket.port = this.proxyConnection.getClientHandshakeAddress().getPort();
this.proxyConnection.getC2P().writeAndFlush(transferToViaProxy).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); } else {
return false; Logger.u_warn("transfer", this.proxyConnection, "Client handshake address is invalid, using ViaProxy bind address instead");
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");
}
transferPacket.host = clientAddress.getHostString();
transferPacket.port = bindAddress.getPort();
} }
} else if (packet instanceof S2CTransferPacket transfer) {
this.handleTransfer(transfer);
this.proxyConnection.getC2P().writeAndFlush(this.createTransferPacket()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
return false;
} }
return true; return true;
} }
private void handleTransfer(final S2CTransferPacket transfer) {
final InetSocketAddress newAddress = new InetSocketAddress(transfer.host, transfer.port);
TransferDataHolder.addTempRedirect(this.proxyConnection.getC2P(), newAddress);
}
private S2CTransferPacket createTransferPacket() {
if (this.proxyConnection.getClientHandshakeAddress() != null) {
return new S2CTransferPacket(this.proxyConnection.getClientHandshakeAddress().getHost(), this.proxyConnection.getClientHandshakeAddress().getPort());
} else {
Logger.u_warn("transfer", this.proxyConnection, "Client handshake address is invalid, using ViaProxy bind address instead");
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 S2CTransferPacket(clientAddress.getHostString(), bindAddress.getPort());
}
}
} }

View File

@ -19,7 +19,7 @@ package net.raphimc.viaproxy.proxy.packethandler;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import java.util.List; import java.util.List;
@ -31,7 +31,7 @@ public class UnexpectedPacketHandler extends PacketHandler {
} }
@Override @Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleC2P(Packet packet, List<ChannelFutureListener> listeners) {
final ConnectionState connectionState = this.proxyConnection.getC2pConnectionState(); final ConnectionState connectionState = this.proxyConnection.getC2pConnectionState();
if (connectionState.equals(ConnectionState.HANDSHAKING)) { if (connectionState.equals(ConnectionState.HANDSHAKING)) {
throw new IllegalStateException("Unexpected packet in " + connectionState + " state"); throw new IllegalStateException("Unexpected packet in " + connectionState + " state");

View File

@ -30,7 +30,7 @@ import io.netty.handler.proxy.Socks5ProxyHandler;
import net.raphimc.netminecraft.constants.MCPipeline; import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.codec.NoReadFlowControlHandler; import net.raphimc.netminecraft.netty.codec.NoReadFlowControlHandler;
import net.raphimc.netminecraft.netty.connection.MinecraftChannelInitializer; import net.raphimc.netminecraft.netty.connection.MinecraftChannelInitializer;
import net.raphimc.netminecraft.packet.registry.PacketRegistryUtil; import net.raphimc.netminecraft.packet.registry.DefaultPacketRegistry;
import net.raphimc.viabedrock.api.BedrockProtocolVersion; import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.vialoader.netty.VLPipeline; import net.raphimc.vialoader.netty.VLPipeline;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
@ -74,7 +74,7 @@ public class Proxy2ServerChannelInitializer extends MinecraftChannelInitializer
} }
super.initChannel(channel); super.initChannel(channel);
channel.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getHandshakingRegistry(true)); channel.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(new DefaultPacketRegistry(true, proxyConnection.getClientVersion().getVersion()));
channel.pipeline().addLast(new ViaProxyVLPipeline(user, proxyConnection.getServerVersion())); channel.pipeline().addLast(new ViaProxyVLPipeline(user, proxyConnection.getServerVersion()));
channel.pipeline().addAfter(VLPipeline.VIA_CODEC_NAME, "via-" + MCPipeline.FLOW_CONTROL_HANDLER_NAME, new NoReadFlowControlHandler()); channel.pipeline().addAfter(VLPipeline.VIA_CODEC_NAME, "via-" + MCPipeline.FLOW_CONTROL_HANDLER_NAME, new NoReadFlowControlHandler());

View File

@ -21,7 +21,7 @@ import com.google.common.collect.Lists;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.Packet;
import net.raphimc.viaproxy.proxy.packethandler.PacketHandler; import net.raphimc.viaproxy.proxy.packethandler.PacketHandler;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.proxy.util.ExceptionUtil; import net.raphimc.viaproxy.proxy.util.ExceptionUtil;
@ -29,7 +29,7 @@ import net.raphimc.viaproxy.util.logging.Logger;
import java.util.List; import java.util.List;
public class Proxy2ServerHandler extends SimpleChannelInboundHandler<IPacket> { public class Proxy2ServerHandler extends SimpleChannelInboundHandler<Packet> {
private ProxyConnection proxyConnection; private ProxyConnection proxyConnection;
@ -52,7 +52,7 @@ public class Proxy2ServerHandler extends SimpleChannelInboundHandler<IPacket> {
} }
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, IPacket packet) throws Exception { protected void channelRead0(ChannelHandlerContext ctx, Packet packet) throws Exception {
if (this.proxyConnection.isClosed()) return; if (this.proxyConnection.isClosed()) return;
final List<ChannelFutureListener> listeners = Lists.newArrayList(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); final List<ChannelFutureListener> listeners = Lists.newArrayList(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);

View File

@ -25,7 +25,7 @@ import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket1_7; import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket;
import net.raphimc.netminecraft.util.ChannelType; import net.raphimc.netminecraft.util.ChannelType;
import java.net.SocketAddress; import java.net.SocketAddress;
@ -78,12 +78,12 @@ public class DummyProxyConnection extends ProxyConnection {
} }
@Override @Override
public C2SLoginHelloPacket1_7 getLoginHelloPacket() { public C2SLoginHelloPacket getLoginHelloPacket() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void setLoginHelloPacket(C2SLoginHelloPacket1_7 loginHelloPacket) { public void setLoginHelloPacket(C2SLoginHelloPacket loginHelloPacket) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -21,27 +21,21 @@ import com.google.common.net.HostAndPort;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonPrimitive; import com.viaversion.viaversion.libs.gson.JsonPrimitive;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*; import io.netty.channel.*;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import net.lenni0451.mcstructs.nbt.INbtTag;
import net.lenni0451.mcstructs.nbt.tags.CompoundTag;
import net.lenni0451.mcstructs.nbt.tags.StringTag;
import net.lenni0451.mcstructs.text.components.StringComponent; import net.lenni0451.mcstructs.text.components.StringComponent;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.constants.MCPipeline; import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.connection.NetClient; import net.raphimc.netminecraft.netty.connection.NetClient;
import net.raphimc.netminecraft.netty.crypto.AESEncryption; import net.raphimc.netminecraft.netty.crypto.AESEncryption;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.impl.configuration.S2CConfigDisconnectPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket1_7; import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginDisconnectPacket1_20_3; import net.raphimc.netminecraft.packet.impl.login.S2CLoginDisconnectPacket;
import net.raphimc.netminecraft.packet.impl.play.S2CPlayDisconnectPacket;
import net.raphimc.netminecraft.packet.impl.status.S2CStatusResponsePacket; import net.raphimc.netminecraft.packet.impl.status.S2CStatusResponsePacket;
import net.raphimc.netminecraft.packet.registry.PacketRegistryUtil; import net.raphimc.netminecraft.packet.registry.DefaultPacketRegistry;
import net.raphimc.netminecraft.util.ChannelType; import net.raphimc.netminecraft.util.ChannelType;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.cli.ConsoleFormatter; import net.raphimc.viaproxy.cli.ConsoleFormatter;
@ -71,7 +65,7 @@ public class ProxyConnection extends NetClient {
private HostAndPort clientHandshakeAddress; private HostAndPort clientHandshakeAddress;
private GameProfile gameProfile; private GameProfile gameProfile;
private C2SLoginHelloPacket1_7 loginHelloPacket; private C2SLoginHelloPacket loginHelloPacket;
private Key storedSecretKey; private Key storedSecretKey;
private UserConnection userConnection; private UserConnection userConnection;
@ -143,6 +137,7 @@ public class ProxyConnection extends NetClient {
public void setClientVersion(final ProtocolVersion clientVersion) { public void setClientVersion(final ProtocolVersion clientVersion) {
this.clientVersion = clientVersion; this.clientVersion = clientVersion;
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(new DefaultPacketRegistry(false, clientVersion.getVersion()));
} }
public HostAndPort getClientHandshakeAddress() { public HostAndPort getClientHandshakeAddress() {
@ -161,11 +156,11 @@ public class ProxyConnection extends NetClient {
this.gameProfile = gameProfile; this.gameProfile = gameProfile;
} }
public C2SLoginHelloPacket1_7 getLoginHelloPacket() { public C2SLoginHelloPacket getLoginHelloPacket() {
return this.loginHelloPacket; return this.loginHelloPacket;
} }
public void setLoginHelloPacket(final C2SLoginHelloPacket1_7 loginHelloPacket) { public void setLoginHelloPacket(final C2SLoginHelloPacket loginHelloPacket) {
this.loginHelloPacket = loginHelloPacket; this.loginHelloPacket = loginHelloPacket;
} }
@ -203,48 +198,13 @@ public class ProxyConnection extends NetClient {
public void setC2pConnectionState(final ConnectionState connectionState) { public void setC2pConnectionState(final ConnectionState connectionState) {
this.c2pConnectionState = connectionState; this.c2pConnectionState = connectionState;
switch (connectionState) { this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).get().setConnectionState(connectionState);
case HANDSHAKING:
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getHandshakingRegistry(false));
break;
case STATUS:
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getStatusRegistry(false));
break;
case LOGIN:
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getLoginRegistry(false, this.clientVersion.getVersion()));
break;
case CONFIGURATION:
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getConfigurationRegistry(false, this.clientVersion.getVersion()));
break;
case PLAY:
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getPlayRegistry(false, this.clientVersion.getVersion()));
break;
}
} }
public void setP2sConnectionState(final ConnectionState connectionState) { public void setP2sConnectionState(final ConnectionState connectionState) {
this.p2sConnectionState = connectionState; this.p2sConnectionState = connectionState;
switch (connectionState) { if (this.getChannel() != null) {
case HANDSHAKING: this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).get().setConnectionState(connectionState);
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getHandshakingRegistry(true));
break;
case STATUS:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getStatusRegistry(true));
break;
case LOGIN:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getLoginRegistry(true, this.clientVersion.getVersion()));
break;
case CONFIGURATION:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getConfigurationRegistry(true, this.clientVersion.getVersion()));
break;
case PLAY:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getPlayRegistry(true, this.clientVersion.getVersion()));
break;
} }
} }
@ -255,25 +215,11 @@ public class ProxyConnection extends NetClient {
if (this.c2pConnectionState == ConnectionState.STATUS) { if (this.c2pConnectionState == ConnectionState.STATUS) {
future = this.c2p.writeAndFlush(new S2CStatusResponsePacket("{\"players\":{\"max\":0,\"online\":0},\"description\":" + new JsonPrimitive(message) + ",\"version\":{\"protocol\":-1,\"name\":\"ViaProxy\"}}")); future = this.c2p.writeAndFlush(new S2CStatusResponsePacket("{\"players\":{\"max\":0,\"online\":0},\"description\":" + new JsonPrimitive(message) + ",\"version\":{\"protocol\":-1,\"name\":\"ViaProxy\"}}"));
} else if (this.c2pConnectionState == ConnectionState.LOGIN) { } else if (this.c2pConnectionState == ConnectionState.LOGIN) {
future = this.c2p.writeAndFlush(new S2CLoginDisconnectPacket1_20_3(new StringComponent(message))); future = this.c2p.writeAndFlush(new S2CLoginDisconnectPacket(new StringComponent(message)));
} else if (this.c2pConnectionState == ConnectionState.CONFIGURATION) { } else if (this.c2pConnectionState == ConnectionState.CONFIGURATION) {
final ByteBuf disconnectPacket = Unpooled.buffer(); future = this.c2p.writeAndFlush(new S2CConfigDisconnectPacket(new StringComponent(message)));
PacketTypes.writeVarInt(disconnectPacket, MCPackets.S2C_CONFIG_DISCONNECT.getId(this.clientVersion.getVersion()));
if (this.clientVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2)) {
PacketTypes.writeString(disconnectPacket, messageToJson(message));
} else {
PacketTypes.writeUnnamedTag(disconnectPacket, messageToNbt(message));
}
future = this.c2p.writeAndFlush(disconnectPacket);
} else if (this.c2pConnectionState == ConnectionState.PLAY) { } else if (this.c2pConnectionState == ConnectionState.PLAY) {
final ByteBuf disconnectPacket = Unpooled.buffer(); future = this.c2p.writeAndFlush(new S2CPlayDisconnectPacket(new StringComponent(message)));
PacketTypes.writeVarInt(disconnectPacket, MCPackets.S2C_DISCONNECT.getId(this.clientVersion.getVersion()));
if (this.clientVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2)) {
PacketTypes.writeString(disconnectPacket, messageToJson(message));
} else {
PacketTypes.writeUnnamedTag(disconnectPacket, messageToNbt(message));
}
future = this.c2p.writeAndFlush(disconnectPacket);
} else { } else {
future = this.c2p.newSucceededFuture(); future = this.c2p.newSucceededFuture();
} }
@ -286,16 +232,4 @@ public class ProxyConnection extends NetClient {
return !this.c2p.isOpen() || (this.getChannel() != null && !this.getChannel().isOpen()); return !this.c2p.isOpen() || (this.getChannel() != null && !this.getChannel().isOpen());
} }
private static String messageToJson(final String message) {
final JsonObject obj = new JsonObject();
obj.addProperty("text", message);
return obj.toString();
}
private static INbtTag messageToNbt(final String message) {
final CompoundTag tag = new CompoundTag();
tag.add("text", new StringTag(message));
return tag;
}
} }