diff --git a/api/src/main/java/com/velocitypowered/api/proxy/ConnectionRequestBuilder.java b/api/src/main/java/com/velocitypowered/api/proxy/ConnectionRequestBuilder.java index e8e522c5d..40728d67f 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/ConnectionRequestBuilder.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/ConnectionRequestBuilder.java @@ -69,6 +69,13 @@ public interface ConnectionRequestBuilder { * @return the reason why the user could not connect to the server */ Optional getReason(); + + /** + * Returns the server we actually tried to connect to. + * + * @return the server we actually tried to connect to + */ + RegisteredServer getAttemptedConnection(); } /** diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java index 117d1c15d..d5348ee19 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java @@ -88,7 +88,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { @Override public boolean handle(Disconnect packet) { - resultFuture.complete(ConnectionRequestResults.forDisconnect(packet)); + resultFuture.complete(ConnectionRequestResults.forDisconnect(packet, serverConn.getServer())); serverConn.disconnect(); return true; } @@ -103,7 +103,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler { public boolean handle(ServerLoginSuccess packet) { if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN && !informationForwarded) { - resultFuture.complete(ConnectionRequestResults.forDisconnect(MODERN_IP_FORWARDING_FAILURE)); + resultFuture.complete(ConnectionRequestResults.forDisconnect(MODERN_IP_FORWARDING_FAILURE, + serverConn.getServer())); serverConn.disconnect(); return true; } @@ -132,7 +133,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { server.getEventManager() .fire(new ServerConnectedEvent(serverConn.getPlayer(), serverConn.getServer())) .whenCompleteAsync((x, error) -> { - resultFuture.complete(ConnectionRequestResults.SUCCESSFUL); + resultFuture.complete(ConnectionRequestResults.successful(serverConn.getServer())); smc.setSessionHandler(new BackendPlaySessionHandler(server, serverConn)); serverConn.getPlayer().setConnectedServer(serverConn); smc.getChannel().config().setAutoRead(true); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java index 0eae3f0c8..7e9227a78 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java @@ -254,7 +254,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation, * * @return whether or not the player is online */ - boolean isActive() { + public boolean isActive() { return connection != null && !connection.isClosed() && !gracefulDisconnect && proxyPlayer.isActive(); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index ad32a68ec..40f9273e6 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -355,15 +355,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { } } - private void handleConnectionException(RegisteredServer rs, @Nullable Component kickReason, - Component friendlyReason) { + private void handleConnectionException(RegisteredServer rs, + @Nullable Component kickReason, Component friendlyReason) { if (connectedServer == null) { // The player isn't yet connected to a server. Optional nextServer = getNextServerToTry(rs); if (nextServer.isPresent()) { // There can't be any connection in flight now. resetInFlightConnection(); - createConnectionRequest(nextServer.get()).fireAndForget(); } else { disconnect(friendlyReason); @@ -388,8 +387,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { } } - private void handleKickEvent(KickedFromServerEvent originalEvent, - Component friendlyReason) { + private void handleKickEvent(KickedFromServerEvent originalEvent, Component friendlyReason) { server.getEventManager().fire(originalEvent) .thenAcceptAsync(event -> { // There can't be any connection in flight now. @@ -628,7 +626,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { Optional initialCheck = checkServer(toConnect); if (initialCheck.isPresent()) { return CompletableFuture - .completedFuture(ConnectionRequestResults.plainResult(initialCheck.get())); + .completedFuture(ConnectionRequestResults.plainResult(initialCheck.get(), toConnect)); } // Otherwise, initiate the connection. @@ -639,7 +637,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { if (!connectTo.isPresent()) { return CompletableFuture.completedFuture( ConnectionRequestResults - .plainResult(ConnectionRequestBuilder.Status.CONNECTION_CANCELLED) + .plainResult(ConnectionRequestBuilder.Status.CONNECTION_CANCELLED, toConnect) ); } @@ -647,7 +645,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { Optional lastCheck = checkServer(rs); if (lastCheck.isPresent()) { return CompletableFuture - .completedFuture(ConnectionRequestResults.plainResult(lastCheck.get())); + .completedFuture(ConnectionRequestResults.plainResult(lastCheck.get(), rs)); } VelocityRegisteredServer vrs = (VelocityRegisteredServer) rs; @@ -663,10 +661,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { return connect() .whenCompleteAsync((status, throwable) -> { if (throwable != null) { - handleConnectionException(toConnect, throwable); + // TODO: The exception handling from this is not very good. Find a better way. + handleConnectionException(status != null ? status.getAttemptedConnection() + : toConnect, throwable); return; } + System.out.println(status); + switch (status.getStatus()) { case ALREADY_CONNECTED: sendMessage(ConnectionMessages.ALREADY_CONNECTED); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionRequestResults.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionRequestResults.java index 20dfddc62..d6768b8c2 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionRequestResults.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionRequestResults.java @@ -1,6 +1,9 @@ package com.velocitypowered.proxy.connection.util; import com.velocitypowered.api.proxy.ConnectionRequestBuilder; +import com.velocitypowered.api.proxy.ConnectionRequestBuilder.Result; +import com.velocitypowered.api.proxy.ConnectionRequestBuilder.Status; +import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.proxy.protocol.packet.Disconnect; import java.util.Optional; import net.kyori.text.Component; @@ -8,20 +11,23 @@ import net.kyori.text.serializer.ComponentSerializers; public class ConnectionRequestResults { - public static final ConnectionRequestBuilder.Result SUCCESSFUL = plainResult( - ConnectionRequestBuilder.Status.SUCCESS); - private ConnectionRequestResults() { throw new AssertionError(); } + public static Result successful(RegisteredServer server) { + return plainResult(Status.SUCCESS, server); + } + /** * Returns a plain result (one with a status but no reason). * @param status the status to use + * @param server the server to use * @return the result */ public static ConnectionRequestBuilder.Result plainResult( - ConnectionRequestBuilder.Status status) { + ConnectionRequestBuilder.Status status, + RegisteredServer server) { return new ConnectionRequestBuilder.Result() { @Override public ConnectionRequestBuilder.Status getStatus() { @@ -32,20 +38,28 @@ public class ConnectionRequestResults { public Optional getReason() { return Optional.empty(); } + + @Override + public RegisteredServer getAttemptedConnection() { + return server; + } }; } - public static ConnectionRequestBuilder.Result forDisconnect(Disconnect disconnect) { + public static ConnectionRequestBuilder.Result forDisconnect(Disconnect disconnect, + RegisteredServer server) { Component deserialized = ComponentSerializers.JSON.deserialize(disconnect.getReason()); - return forDisconnect(deserialized); + return forDisconnect(deserialized, server); } /** * Returns a disconnect result with a reason. * @param component the reason for disconnecting from the server + * @param server the server to use * @return the result */ - public static ConnectionRequestBuilder.Result forDisconnect(Component component) { + public static ConnectionRequestBuilder.Result forDisconnect(Component component, + RegisteredServer server) { return new ConnectionRequestBuilder.Result() { @Override public ConnectionRequestBuilder.Status getStatus() { @@ -56,6 +70,11 @@ public class ConnectionRequestResults { public Optional getReason() { return Optional.of(component); } + + @Override + public RegisteredServer getAttemptedConnection() { + return server; + } }; } }