mirror of
https://github.com/ViaVersion/ViaProxy.git
synced 2024-11-15 03:25:05 -05:00
Improved transfer handling
This commit is contained in:
parent
2e944a7fb5
commit
9c2a562d19
12 changed files with 97 additions and 50 deletions
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package net.raphimc.viaproxy.plugins.events;
|
package net.raphimc.viaproxy.plugins.events;
|
||||||
|
|
||||||
|
import com.google.common.net.HostAndPort;
|
||||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import net.raphimc.viaproxy.plugins.events.types.EventCancellable;
|
import net.raphimc.viaproxy.plugins.events.types.EventCancellable;
|
||||||
|
@ -28,14 +29,16 @@ public class PreConnectEvent extends EventCancellable {
|
||||||
private SocketAddress serverAddress;
|
private SocketAddress serverAddress;
|
||||||
private ProtocolVersion serverVersion;
|
private ProtocolVersion serverVersion;
|
||||||
private final ProtocolVersion clientVersion;
|
private final ProtocolVersion clientVersion;
|
||||||
|
private final HostAndPort clientHandshakeAddress;
|
||||||
private final Channel clientChannel;
|
private final Channel clientChannel;
|
||||||
|
|
||||||
private String cancelMessage = "§cCould not connect to the backend server! (Server is blacklisted)";
|
private String cancelMessage = "§cCould not connect to the backend server! (Server is blacklisted)";
|
||||||
|
|
||||||
public PreConnectEvent(final SocketAddress serverAddress, final ProtocolVersion serverVersion, final ProtocolVersion clientVersion, final Channel clientChannel) {
|
public PreConnectEvent(final SocketAddress serverAddress, final ProtocolVersion serverVersion, final ProtocolVersion clientVersion, final HostAndPort clientHandshakeAddress, final Channel clientChannel) {
|
||||||
this.serverAddress = serverAddress;
|
this.serverAddress = serverAddress;
|
||||||
this.serverVersion = serverVersion;
|
this.serverVersion = serverVersion;
|
||||||
this.clientVersion = clientVersion;
|
this.clientVersion = clientVersion;
|
||||||
|
this.clientHandshakeAddress = clientHandshakeAddress;
|
||||||
this.clientChannel = clientChannel;
|
this.clientChannel = clientChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +62,10 @@ public class PreConnectEvent extends EventCancellable {
|
||||||
return this.clientVersion;
|
return this.clientVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HostAndPort getClientHandshakeAddress() {
|
||||||
|
return this.clientHandshakeAddress;
|
||||||
|
}
|
||||||
|
|
||||||
public Channel getClientChannel() {
|
public Channel getClientChannel() {
|
||||||
return this.clientChannel;
|
return this.clientChannel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package net.raphimc.viaproxy.proxy.client2proxy;
|
package net.raphimc.viaproxy.proxy.client2proxy;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.net.HostAndPort;
|
||||||
import com.viaversion.viabackwards.protocol.v1_20_5to1_20_3.storage.CookieStorage;
|
import com.viaversion.viabackwards.protocol.v1_20_5to1_20_3.storage.CookieStorage;
|
||||||
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;
|
||||||
|
@ -131,12 +132,11 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
|
|
||||||
if (ViaProxy.getConfig().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.PUBLIC) {
|
if (ViaProxy.getConfig().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.PUBLIC) {
|
||||||
try {
|
try {
|
||||||
if (handshakeParts[0].toLowerCase().contains(".viaproxy.")) {
|
if (!handshakeParts[0].toLowerCase().contains(".viaproxy.")) {
|
||||||
handshakeParts[0] = handshakeParts[0].substring(0, handshakeParts[0].toLowerCase().lastIndexOf(".viaproxy."));
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
final ArrayHelper arrayHelper = ArrayHelper.instanceOf(handshakeParts[0].split(Pattern.quote("_")));
|
final String addressData = handshakeParts[0].substring(0, handshakeParts[0].toLowerCase().lastIndexOf(".viaproxy."));
|
||||||
|
final ArrayHelper arrayHelper = ArrayHelper.instanceOf(addressData.split(Pattern.quote("_")));
|
||||||
if (arrayHelper.getLength() < 3) {
|
if (arrayHelper.getLength() < 3) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
@ -145,20 +145,21 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
if (serverVersion == null) {
|
if (serverVersion == null) {
|
||||||
this.proxyConnection.kickClient("§cWrong domain syntax!\n§cUnknown server version.");
|
this.proxyConnection.kickClient("§cWrong domain syntax!\n§cUnknown server version.");
|
||||||
}
|
}
|
||||||
final String connectIP = arrayHelper.getAsString(0, arrayHelper.getLength() - 3, "_");
|
final String connectAddress = arrayHelper.getAsString(0, arrayHelper.getLength() - 3, "_");
|
||||||
final int connectPort = arrayHelper.getInteger(arrayHelper.getLength() - 2);
|
final int connectPort = arrayHelper.getInteger(arrayHelper.getLength() - 2);
|
||||||
serverAddress = AddressUtil.parse(connectIP + ":" + connectPort, serverVersion);
|
serverAddress = AddressUtil.parse(connectAddress + ":" + connectPort, serverVersion);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
this.proxyConnection.kickClient("§cWrong domain syntax! §6Please use:\n§7address_port_version.viaproxy.hostname");
|
this.proxyConnection.kickClient("§cWrong domain syntax! §6Please use:\n§7address_port_version.viaproxy.hostname");
|
||||||
}
|
}
|
||||||
} else if (ViaProxy.getConfig().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.INTERNAL) {
|
} else if (ViaProxy.getConfig().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.INTERNAL) {
|
||||||
final ArrayHelper arrayHelper = ArrayHelper.instanceOf(handshakeParts[0].split("\7"));
|
final ArrayHelper arrayHelper = ArrayHelper.instanceOf(handshakeParts[0].split("\7"));
|
||||||
final String versionString = arrayHelper.get(1);
|
handshakeParts[0] = arrayHelper.get(0); // Restore the original address
|
||||||
|
final String versionString = arrayHelper.get(2);
|
||||||
serverVersion = ProtocolVersionUtil.fromNameLenient(versionString);
|
serverVersion = ProtocolVersionUtil.fromNameLenient(versionString);
|
||||||
if (serverVersion == null) throw CloseAndReturn.INSTANCE;
|
if (serverVersion == null) throw CloseAndReturn.INSTANCE;
|
||||||
serverAddress = AddressUtil.parse(arrayHelper.get(0), serverVersion);
|
serverAddress = AddressUtil.parse(arrayHelper.get(1), serverVersion);
|
||||||
if (arrayHelper.isIndexValid(2)) {
|
if (arrayHelper.isIndexValid(3)) {
|
||||||
classicMpPass = arrayHelper.getString(2);
|
classicMpPass = arrayHelper.getString(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +174,14 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
serverAddress = TransferDataHolder.removeTempRedirect(this.proxyConnection.getC2P());
|
serverAddress = TransferDataHolder.removeTempRedirect(this.proxyConnection.getC2P());
|
||||||
}
|
}
|
||||||
|
|
||||||
final PreConnectEvent preConnectEvent = new PreConnectEvent(serverAddress, serverVersion, clientVersion, this.proxyConnection.getC2P());
|
HostAndPort clientHandshakeAddress;
|
||||||
|
try {
|
||||||
|
clientHandshakeAddress = HostAndPort.fromParts(handshakeParts[0], packet.port);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
clientHandshakeAddress = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final PreConnectEvent preConnectEvent = new PreConnectEvent(serverAddress, serverVersion, clientVersion, clientHandshakeAddress, this.proxyConnection.getC2P());
|
||||||
if (ViaProxy.EVENT_MANAGER.call(preConnectEvent).isCancelled()) {
|
if (ViaProxy.EVENT_MANAGER.call(preConnectEvent).isCancelled()) {
|
||||||
this.proxyConnection.kickClient(preConnectEvent.getCancelMessage());
|
this.proxyConnection.kickClient(preConnectEvent.getCancelMessage());
|
||||||
}
|
}
|
||||||
|
@ -185,9 +193,10 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
|
|
||||||
if (packet.intendedState.getConnectionState() == ConnectionState.LOGIN && serverVersion.equals(ProtocolTranslator.AUTO_DETECT_PROTOCOL)) {
|
if (packet.intendedState.getConnectionState() == ConnectionState.LOGIN && serverVersion.equals(ProtocolTranslator.AUTO_DETECT_PROTOCOL)) {
|
||||||
SocketAddress finalServerAddress = serverAddress;
|
SocketAddress finalServerAddress = serverAddress;
|
||||||
|
HostAndPort finalClientHandshakeAddress = clientHandshakeAddress;
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
final ProtocolVersion detectedVersion = ProtocolVersionDetector.get(finalServerAddress, clientVersion);
|
final ProtocolVersion detectedVersion = ProtocolVersionDetector.get(finalServerAddress, clientVersion);
|
||||||
this.connect(finalServerAddress, detectedVersion, clientVersion, packet.intendedState, userOptions, handshakeParts);
|
this.connect(finalServerAddress, detectedVersion, clientVersion, packet.intendedState, finalClientHandshakeAddress, userOptions, handshakeParts);
|
||||||
}).exceptionally(t -> {
|
}).exceptionally(t -> {
|
||||||
if (t instanceof ConnectException || t instanceof UnresolvedAddressException) {
|
if (t instanceof ConnectException || t instanceof UnresolvedAddressException) {
|
||||||
this.proxyConnection.kickClient("§cCould not connect to the backend server!");
|
this.proxyConnection.kickClient("§cCould not connect to the backend server!");
|
||||||
|
@ -197,11 +206,11 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.connect(serverAddress, serverVersion, clientVersion, packet.intendedState, userOptions, handshakeParts);
|
this.connect(serverAddress, serverVersion, clientVersion, packet.intendedState, clientHandshakeAddress, userOptions, handshakeParts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connect(final SocketAddress serverAddress, final ProtocolVersion serverVersion, final ProtocolVersion clientVersion, final IntendedState intendedState, final UserOptions userOptions, final String[] handshakeParts) {
|
private void connect(final SocketAddress serverAddress, final ProtocolVersion serverVersion, final ProtocolVersion clientVersion, final IntendedState intendedState, final HostAndPort clientHandshakeAddress, final UserOptions userOptions, final String[] handshakeParts) {
|
||||||
final Supplier<ChannelHandler> handlerSupplier = () -> ViaProxy.EVENT_MANAGER.call(new Proxy2ServerHandlerCreationEvent(new Proxy2ServerHandler(), false)).getHandler();
|
final Supplier<ChannelHandler> handlerSupplier = () -> ViaProxy.EVENT_MANAGER.call(new Proxy2ServerHandlerCreationEvent(new Proxy2ServerHandler(), false)).getHandler();
|
||||||
final ProxyConnection proxyConnection;
|
final ProxyConnection proxyConnection;
|
||||||
if (serverVersion.equals(BedrockProtocolVersion.bedrockLatest)) {
|
if (serverVersion.equals(BedrockProtocolVersion.bedrockLatest)) {
|
||||||
|
@ -212,8 +221,9 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
this.proxyConnection = ViaProxy.EVENT_MANAGER.call(new ProxySessionCreationEvent<>(proxyConnection, false)).getProxySession();
|
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.getC2P().attr(ProxyConnection.PROXY_CONNECTION_ATTRIBUTE_KEY).set(this.proxyConnection);
|
||||||
this.proxyConnection.setClientVersion(clientVersion);
|
this.proxyConnection.setClientVersion(clientVersion);
|
||||||
this.proxyConnection.setC2pConnectionState(intendedState.getConnectionState());
|
this.proxyConnection.setClientHandshakeAddress(clientHandshakeAddress);
|
||||||
this.proxyConnection.setUserOptions(userOptions);
|
this.proxyConnection.setUserOptions(userOptions);
|
||||||
|
this.proxyConnection.setC2pConnectionState(intendedState.getConnectionState());
|
||||||
this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection));
|
this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection));
|
||||||
this.proxyConnection.getPacketHandlers().add(new OpenAuthModPacketHandler(this.proxyConnection));
|
this.proxyConnection.getPacketHandlers().add(new OpenAuthModPacketHandler(this.proxyConnection));
|
||||||
if (ViaProxy.getConfig().shouldSupportSimpleVoiceChat() && serverVersion.newerThan(ProtocolVersion.v1_14) && clientVersion.newerThan(ProtocolVersion.v1_14)) {
|
if (ViaProxy.getConfig().shouldSupportSimpleVoiceChat() && serverVersion.newerThan(ProtocolVersion.v1_14) && clientVersion.newerThan(ProtocolVersion.v1_14)) {
|
||||||
|
@ -236,7 +246,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
this.proxyConnection.getPacketHandlers().add(new ResourcePackPacketHandler(this.proxyConnection));
|
this.proxyConnection.getPacketHandlers().add(new ResourcePackPacketHandler(this.proxyConnection));
|
||||||
this.proxyConnection.getPacketHandlers().add(new UnexpectedPacketHandler(this.proxyConnection));
|
this.proxyConnection.getPacketHandlers().add(new UnexpectedPacketHandler(this.proxyConnection));
|
||||||
|
|
||||||
Logger.u_info("connect", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "[" + clientVersion.getName() + " <-> " + serverVersion.getName() + "] Connecting to " + AddressUtil.toString(serverAddress));
|
Logger.u_info("connect", this.proxyConnection, "[" + clientVersion.getName() + " <-> " + serverVersion.getName() + "] Connecting to " + AddressUtil.toString(serverAddress));
|
||||||
ViaProxy.EVENT_MANAGER.call(new ConnectEvent(this.proxyConnection));
|
ViaProxy.EVENT_MANAGER.call(new ConnectEvent(this.proxyConnection));
|
||||||
|
|
||||||
this.proxyConnection.connectToServer(serverAddress, serverVersion).addListeners((ThrowingChannelFutureListener) f -> {
|
this.proxyConnection.connectToServer(serverAddress, serverVersion).addListeners((ThrowingChannelFutureListener) f -> {
|
||||||
|
@ -258,6 +268,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
|
|
||||||
handshakeParts[0] = address;
|
handshakeParts[0] = address;
|
||||||
final C2SHandshakePacket newHandshakePacket = new C2SHandshakePacket(clientVersion.getOriginalVersion(), String.join("\0", handshakeParts), port, intendedState);
|
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 -> {
|
this.proxyConnection.getChannel().writeAndFlush(newHandshakePacket).addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, (ChannelFutureListener) f2 -> {
|
||||||
if (f2.isSuccess()) {
|
if (f2.isSuccess()) {
|
||||||
this.proxyConnection.setP2sConnectionState(intendedState.getConnectionState());
|
this.proxyConnection.setP2sConnectionState(intendedState.getConnectionState());
|
||||||
|
|
|
@ -31,6 +31,7 @@ import net.raphimc.viaproxy.proxy.util.HAProxyUtil;
|
||||||
import net.raphimc.viaproxy.proxy.util.ThrowingChannelFutureListener;
|
import net.raphimc.viaproxy.proxy.util.ThrowingChannelFutureListener;
|
||||||
import net.raphimc.viaproxy.util.AddressUtil;
|
import net.raphimc.viaproxy.util.AddressUtil;
|
||||||
import net.raphimc.viaproxy.util.logging.Logger;
|
import net.raphimc.viaproxy.util.logging.Logger;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -80,7 +81,7 @@ public class PassthroughClient2ProxyHandler extends SimpleChannelInboundHandler<
|
||||||
final SocketAddress serverAddress = this.getServerAddress();
|
final SocketAddress serverAddress = this.getServerAddress();
|
||||||
|
|
||||||
ChannelUtil.disableAutoRead(this.proxyConnection.getC2P());
|
ChannelUtil.disableAutoRead(this.proxyConnection.getC2P());
|
||||||
Logger.u_info("connect", this.proxyConnection.getC2P().remoteAddress(), null, "[Legacy <-> Legacy] Connecting to " + AddressUtil.toString(serverAddress));
|
Logger.u_log(Level.INFO, "connect", this.proxyConnection.getC2P().remoteAddress(), null, "[Legacy <-> Legacy] Connecting to " + AddressUtil.toString(serverAddress));
|
||||||
|
|
||||||
this.proxyConnection.connect(serverAddress).addListeners((ThrowingChannelFutureListener) f -> {
|
this.proxyConnection.connect(serverAddress).addListeners((ThrowingChannelFutureListener) f -> {
|
||||||
if (f.isSuccess()) {
|
if (f.isSuccess()) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ import java.util.concurrent.TimeoutException;
|
||||||
public class ExternalInterface {
|
public class ExternalInterface {
|
||||||
|
|
||||||
public static void fillPlayerData(final ProxyConnection proxyConnection) {
|
public static void fillPlayerData(final ProxyConnection proxyConnection) {
|
||||||
Logger.u_info("auth", proxyConnection.getC2P().remoteAddress(), proxyConnection.getGameProfile(), "Filling player data");
|
Logger.u_info("auth", proxyConnection, "Filling player data");
|
||||||
try {
|
try {
|
||||||
if (proxyConnection.getUserOptions().account() != null) {
|
if (proxyConnection.getUserOptions().account() != null) {
|
||||||
final Account account = proxyConnection.getUserOptions().account();
|
final Account account = proxyConnection.getUserOptions().account();
|
||||||
|
@ -107,7 +107,7 @@ public class ExternalInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
Logger.u_info("auth", proxyConnection.getC2P().remoteAddress(), proxyConnection.getGameProfile(), "Trying to join online mode server");
|
Logger.u_info("auth", proxyConnection, "Trying to join online mode server");
|
||||||
if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) {
|
if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) {
|
||||||
try {
|
try {
|
||||||
final ByteBuf response = proxyConnection.getPacketHandler(OpenAuthModPacketHandler.class).sendCustomPayload(OpenAuthModConstants.JOIN_CHANNEL, PacketTypes.writeString(Unpooled.buffer(), serverIdHash)).get(6, TimeUnit.SECONDS);
|
final ByteBuf response = proxyConnection.getPacketHandler(OpenAuthModPacketHandler.class).sendCustomPayload(OpenAuthModConstants.JOIN_CHANNEL, PacketTypes.writeString(Unpooled.buffer(), serverIdHash)).get(6, TimeUnit.SECONDS);
|
||||||
|
@ -128,7 +128,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 C2SLoginKeyPacket1_19 packet, final ProxyConnection proxyConnection) throws InterruptedException, ExecutionException, SignatureException {
|
||||||
Logger.u_info("auth", proxyConnection.getC2P().remoteAddress(), proxyConnection.getGameProfile(), "Requesting nonce signature");
|
Logger.u_info("auth", proxyConnection, "Requesting nonce signature");
|
||||||
final UserConnection user = proxyConnection.getUserConnection();
|
final UserConnection user = proxyConnection.getUserConnection();
|
||||||
|
|
||||||
if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) {
|
if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class ConfigurationPacketHandler extends PacketHandler {
|
||||||
this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION);
|
this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION);
|
||||||
listeners.add(f -> {
|
listeners.add(f -> {
|
||||||
if (f.isSuccess()) {
|
if (f.isSuccess()) {
|
||||||
Logger.u_info("session", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Switching to CONFIGURATION state");
|
Logger.u_info("session", this.proxyConnection, "Switching to CONFIGURATION state");
|
||||||
this.proxyConnection.setP2sConnectionState(ConnectionState.CONFIGURATION);
|
this.proxyConnection.setP2sConnectionState(ConnectionState.CONFIGURATION);
|
||||||
ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel());
|
ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel());
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ public class ConfigurationPacketHandler extends PacketHandler {
|
||||||
this.proxyConnection.setC2pConnectionState(ConnectionState.PLAY);
|
this.proxyConnection.setC2pConnectionState(ConnectionState.PLAY);
|
||||||
listeners.add(f -> {
|
listeners.add(f -> {
|
||||||
if (f.isSuccess()) {
|
if (f.isSuccess()) {
|
||||||
Logger.u_info("session", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Configuration finished! Switching to PLAY state");
|
Logger.u_info("session", this.proxyConnection, "Configuration finished! Switching to PLAY state");
|
||||||
this.proxyConnection.setP2sConnectionState(ConnectionState.PLAY);
|
this.proxyConnection.setP2sConnectionState(ConnectionState.PLAY);
|
||||||
ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel());
|
ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel());
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,14 +99,14 @@ public class LoginPacketHandler extends PacketHandler {
|
||||||
|
|
||||||
if (loginKeyPacket.encryptedNonce != null) {
|
if (loginKeyPacket.encryptedNonce != null) {
|
||||||
if (!Arrays.equals(this.verifyToken, CryptUtil.decryptData(KEY_PAIR.getPrivate(), loginKeyPacket.encryptedNonce))) {
|
if (!Arrays.equals(this.verifyToken, CryptUtil.decryptData(KEY_PAIR.getPrivate(), loginKeyPacket.encryptedNonce))) {
|
||||||
Logger.u_err("auth", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Invalid verify token");
|
Logger.u_err("auth", this.proxyConnection, "Invalid verify token");
|
||||||
this.proxyConnection.kickClient("§cInvalid verify token!");
|
this.proxyConnection.kickClient("§cInvalid verify token!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final C2SLoginKeyPacket1_19 keyPacket = (C2SLoginKeyPacket1_19) packet;
|
final C2SLoginKeyPacket1_19 keyPacket = (C2SLoginKeyPacket1_19) packet;
|
||||||
final C2SLoginHelloPacket1_19 helloPacket = (C2SLoginHelloPacket1_19) this.proxyConnection.getLoginHelloPacket();
|
final C2SLoginHelloPacket1_19 helloPacket = (C2SLoginHelloPacket1_19) this.proxyConnection.getLoginHelloPacket();
|
||||||
if (helloPacket.key == null || !CryptUtil.verifySignedNonce(helloPacket.key, this.verifyToken, keyPacket.salt, keyPacket.signature)) {
|
if (helloPacket.key == null || !CryptUtil.verifySignedNonce(helloPacket.key, this.verifyToken, keyPacket.salt, keyPacket.signature)) {
|
||||||
Logger.u_err("auth", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Invalid verify token");
|
Logger.u_err("auth", this.proxyConnection, "Invalid verify token");
|
||||||
this.proxyConnection.kickClient("§cInvalid verify token!");
|
this.proxyConnection.kickClient("§cInvalid verify token!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,12 +119,12 @@ public class LoginPacketHandler extends PacketHandler {
|
||||||
final String serverHash = new BigInteger(CryptUtil.computeServerIdHash("", KEY_PAIR.getPublic(), secretKey)).toString(16);
|
final String serverHash = new BigInteger(CryptUtil.computeServerIdHash("", KEY_PAIR.getPublic(), secretKey)).toString(16);
|
||||||
final GameProfile mojangProfile = AuthLibServices.SESSION_SERVICE.hasJoinedServer(this.proxyConnection.getGameProfile(), serverHash, null);
|
final GameProfile mojangProfile = AuthLibServices.SESSION_SERVICE.hasJoinedServer(this.proxyConnection.getGameProfile(), serverHash, null);
|
||||||
if (mojangProfile == null) {
|
if (mojangProfile == null) {
|
||||||
Logger.u_err("auth", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Invalid session");
|
Logger.u_err("auth", this.proxyConnection, "Invalid session");
|
||||||
this.proxyConnection.kickClient("§cInvalid session! Please restart minecraft (and the launcher) and try again.");
|
this.proxyConnection.kickClient("§cInvalid session! Please restart minecraft (and the launcher) and try again.");
|
||||||
} else {
|
} else {
|
||||||
this.proxyConnection.setGameProfile(mojangProfile);
|
this.proxyConnection.setGameProfile(mojangProfile);
|
||||||
}
|
}
|
||||||
Logger.u_info("auth", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Authenticated as " + this.proxyConnection.getGameProfile().getId().toString());
|
Logger.u_info("auth", this.proxyConnection, "Authenticated as " + this.proxyConnection.getGameProfile().getId().toString());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new RuntimeException("Failed to make session request for user '" + userName + "'!", e);
|
throw new RuntimeException("Failed to make session request for user '" + userName + "'!", e);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ public class LoginPacketHandler extends PacketHandler {
|
||||||
@Override
|
@Override
|
||||||
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) throws GeneralSecurityException, ExecutionException, InterruptedException {
|
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) throws GeneralSecurityException, ExecutionException, InterruptedException {
|
||||||
if (packet instanceof S2CLoginDisconnectPacket1_7 loginDisconnectPacket) {
|
if (packet instanceof S2CLoginDisconnectPacket1_7 loginDisconnectPacket) {
|
||||||
Logger.u_info("server kick", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), ConsoleFormatter.convert(loginDisconnectPacket.reason.asLegacyFormatString()));
|
Logger.u_info("server kick", this.proxyConnection, ConsoleFormatter.convert(loginDisconnectPacket.reason.asLegacyFormatString()));
|
||||||
} else if (packet instanceof S2CLoginKeyPacket1_7 loginKeyPacket) {
|
} else if (packet instanceof S2CLoginKeyPacket1_7 loginKeyPacket) {
|
||||||
final PublicKey publicKey = CryptUtil.decodeRsaPublicKey(loginKeyPacket.publicKey);
|
final PublicKey publicKey = CryptUtil.decodeRsaPublicKey(loginKeyPacket.publicKey);
|
||||||
final SecretKey secretKey = CryptUtil.generateSecretKey();
|
final SecretKey secretKey = CryptUtil.generateSecretKey();
|
||||||
|
@ -176,7 +176,7 @@ public class LoginPacketHandler extends PacketHandler {
|
||||||
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(loginSuccessPacket.uuid, loginSuccessPacket.name));
|
this.proxyConnection.setGameProfile(new GameProfile(loginSuccessPacket.uuid, loginSuccessPacket.name));
|
||||||
Logger.u_info("session", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Connected successfully! Switching to " + nextState + " state");
|
Logger.u_info("session", this.proxyConnection, "Connected successfully! Switching to " + nextState + " state");
|
||||||
|
|
||||||
ChannelUtil.disableAutoRead(this.proxyConnection.getChannel());
|
ChannelUtil.disableAutoRead(this.proxyConnection.getChannel());
|
||||||
listeners.add(f -> {
|
listeners.add(f -> {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import net.raphimc.netminecraft.packet.impl.configuration.S2CConfigTransfer1_20_
|
||||||
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.TransferDataHolder;
|
import net.raphimc.viaproxy.proxy.util.TransferDataHolder;
|
||||||
|
import net.raphimc.viaproxy.util.logging.Logger;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -72,14 +73,18 @@ public class TransferPacketHandler extends PacketHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private S2CConfigTransfer1_20_5 createTransferPacket() {
|
private S2CConfigTransfer1_20_5 createTransferPacket() {
|
||||||
if (!(ViaProxy.getCurrentProxyServer().getChannel().localAddress() instanceof InetSocketAddress bindAddress)) {
|
if (this.proxyConnection.getClientHandshakeAddress() != null) {
|
||||||
throw new IllegalArgumentException("ViaProxy bind address must be an InetSocketAddress");
|
return new S2CConfigTransfer1_20_5(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 S2CConfigTransfer1_20_5(clientAddress.getHostString(), bindAddress.getPort());
|
||||||
}
|
}
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class Proxy2ServerHandler extends SimpleChannelInboundHandler<IPacket> {
|
||||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||||
super.channelInactive(ctx);
|
super.channelInactive(ctx);
|
||||||
|
|
||||||
Logger.u_info("disconnect", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Connection closed");
|
Logger.u_info("disconnect", this.proxyConnection, "Connection closed");
|
||||||
try {
|
try {
|
||||||
this.proxyConnection.getC2P().close();
|
this.proxyConnection.getC2P().close();
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package net.raphimc.viaproxy.proxy.session;
|
package net.raphimc.viaproxy.proxy.session;
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -56,6 +57,16 @@ public class DummyProxyConnection extends ProxyConnection {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HostAndPort getClientHandshakeAddress() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClientHandshakeAddress(HostAndPort clientHandshakeAddress) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GameProfile getGameProfile() {
|
public GameProfile getGameProfile() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package net.raphimc.viaproxy.proxy.session;
|
package net.raphimc.viaproxy.proxy.session;
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -67,6 +68,7 @@ public class ProxyConnection extends NetClient {
|
||||||
private ProtocolVersion serverVersion;
|
private ProtocolVersion serverVersion;
|
||||||
private ProtocolVersion clientVersion;
|
private ProtocolVersion clientVersion;
|
||||||
|
|
||||||
|
private HostAndPort clientHandshakeAddress;
|
||||||
private GameProfile gameProfile;
|
private GameProfile gameProfile;
|
||||||
private C2SLoginHelloPacket1_7 loginHelloPacket;
|
private C2SLoginHelloPacket1_7 loginHelloPacket;
|
||||||
private Key storedSecretKey;
|
private Key storedSecretKey;
|
||||||
|
@ -142,6 +144,14 @@ public class ProxyConnection extends NetClient {
|
||||||
this.clientVersion = clientVersion;
|
this.clientVersion = clientVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HostAndPort getClientHandshakeAddress() {
|
||||||
|
return this.clientHandshakeAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientHandshakeAddress(final HostAndPort clientHandshakeAddress) {
|
||||||
|
this.clientHandshakeAddress = clientHandshakeAddress;
|
||||||
|
}
|
||||||
|
|
||||||
public GameProfile getGameProfile() {
|
public GameProfile getGameProfile() {
|
||||||
return this.gameProfile;
|
return this.gameProfile;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +248,7 @@ public class ProxyConnection extends NetClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void kickClient(final String message) throws CloseAndReturn {
|
public void kickClient(final String message) throws CloseAndReturn {
|
||||||
Logger.u_err("proxy kick", this.c2p.remoteAddress(), this.getGameProfile(), ConsoleFormatter.convert(message));
|
Logger.u_err("proxy kick", this, ConsoleFormatter.convert(message));
|
||||||
|
|
||||||
final ChannelFuture future;
|
final ChannelFuture future;
|
||||||
if (this.c2pConnectionState == ConnectionState.STATUS) {
|
if (this.c2pConnectionState == ConnectionState.STATUS) {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package net.raphimc.viaproxy.util.logging;
|
package net.raphimc.viaproxy.util.logging;
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
|
||||||
import net.raphimc.viaproxy.util.AddressUtil;
|
import net.raphimc.viaproxy.util.AddressUtil;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
@ -43,20 +43,22 @@ public class Logger {
|
||||||
System.setOut(new LoggerPrintStream("STDOUT", SYSOUT));
|
System.setOut(new LoggerPrintStream("STDOUT", SYSOUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void u_info(final String title, final SocketAddress address, final GameProfile gameProfile, final String msg) {
|
public static void u_info(final String title, final ProxyConnection proxyConnection, final String msg) {
|
||||||
u_log(Level.INFO, title, address, gameProfile, msg);
|
u_log(Level.INFO, title, proxyConnection, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void u_err(final String title, final SocketAddress address, final GameProfile gameProfile, final String msg) {
|
public static void u_warn(final String title, final ProxyConnection proxyConnection, final String msg) {
|
||||||
u_log(Level.ERROR, title, address, gameProfile, msg);
|
u_log(Level.WARN, title, proxyConnection, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void u_err(final String title, final UserConnection user, final String msg) {
|
public static void u_err(final String title, final ProxyConnection proxyConnection, final String msg) {
|
||||||
GameProfile gameProfile = null;
|
u_log(Level.INFO, title, proxyConnection, msg);
|
||||||
if (user.getProtocolInfo().getUsername() != null) {
|
}
|
||||||
gameProfile = new GameProfile(user.getProtocolInfo().getUuid(), user.getProtocolInfo().getUsername());
|
|
||||||
}
|
public static void u_log(final Level level, final String title, final ProxyConnection proxyConnection, final String msg) {
|
||||||
u_log(Level.ERROR, title, user.getChannel().remoteAddress(), gameProfile, msg);
|
final SocketAddress address = proxyConnection.getC2P().remoteAddress();
|
||||||
|
final GameProfile gameProfile = proxyConnection.getGameProfile();
|
||||||
|
u_log(level, title, address, gameProfile, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void u_log(final Level level, final String title, final SocketAddress address, final GameProfile gameProfile, final String msg) {
|
public static void u_log(final Level level, final String title, final SocketAddress address, final GameProfile gameProfile, final String msg) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ resource-pack-url: ""
|
||||||
# Allows clients to specify a target server and version using wildcard domains.
|
# Allows clients to specify a target server and version using wildcard domains.
|
||||||
# none: No wildcard domain handling.
|
# none: No wildcard domain handling.
|
||||||
# public: Public wildcard domain handling. Intended for usage by external clients. (Example: address_port_version.viaproxy.127.0.0.1.nip.io)
|
# public: Public wildcard domain handling. Intended for usage by external clients. (Example: address_port_version.viaproxy.127.0.0.1.nip.io)
|
||||||
# internal: Internal wildcard domain handling. Intended for local usage by custom clients. (Example: address:port\7version\7classic-mppass)
|
# internal: Internal wildcard domain handling. Intended for local usage by custom clients. (Example: original-handshake-address\7address:port\7version\7classic-mppass)
|
||||||
wildcard-domain-handling: "none"
|
wildcard-domain-handling: "none"
|
||||||
#
|
#
|
||||||
# Enables handling and rewriting of Simple Voice Chat mod packets.
|
# Enables handling and rewriting of Simple Voice Chat mod packets.
|
||||||
|
|
Loading…
Reference in a new issue