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 95cbdefb8..c65af53e6 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 @@ -104,6 +104,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { private final CompletableFuture teardownFuture = new CompletableFuture<>(); private @MonotonicNonNull List serversToTry = null; + private boolean explicitlyDisconnected = false; ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection, @Nullable InetSocketAddress virtualHost, boolean onlineMode) { @@ -281,9 +282,20 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { @Override public void disconnect(Component reason) { + if (connection.eventLoop().inEventLoop()) { + disconnect0(reason, false); + } else { + connection.eventLoop().execute(() -> disconnect0(reason, false)); + } + } + + public void disconnect0(Component reason, boolean duringLogin) { logger.info("{} has disconnected: {}", this, LegacyComponentSerializer.legacy().serialize(reason)); + this.explicitlyDisconnected = true; connection.closeWith(Disconnect.create(reason)); + + server.getEventManager().fireAndForget(new DisconnectEvent(this, duringLogin)); } @Override @@ -574,10 +586,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { connectedServer.disconnect(); } boolean isConnected = server.getPlayer(this.getUniqueId()).isPresent(); - server.unregisterConnection(this); - server.getEventManager().fire(new DisconnectEvent(this, !isConnected)) - .thenRun(() -> this.teardownFuture.complete(null)); + if (!this.explicitlyDisconnected) { + server.getEventManager().fire(new DisconnectEvent(this, !isConnected)) + .thenRun(() -> this.teardownFuture.complete(null)); + } } public CompletableFuture getTeardownFuture() { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java index 380fd9831..831304d2b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java @@ -204,7 +204,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { inbound.getVirtualHost().orElse(null), onlineMode); this.connectedPlayer = player; if (!server.canRegisterConnection(player)) { - player.disconnect(VelocityMessages.ALREADY_CONNECTED); + player.disconnect0(VelocityMessages.ALREADY_CONNECTED, true); return CompletableFuture.completedFuture(null); } @@ -246,10 +246,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler { Optional reason = event.getResult().getReason(); if (reason.isPresent()) { - player.disconnect(reason.get()); + player.disconnect0(reason.get(), true); } else { if (!server.registerConnection(player)) { - player.disconnect(VelocityMessages.ALREADY_CONNECTED); + player.disconnect0(VelocityMessages.ALREADY_CONNECTED, true); return; } @@ -269,7 +269,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { .thenRunAsync(() -> { Optional toTry = event.getInitialServer(); if (!toTry.isPresent()) { - player.disconnect(VelocityMessages.NO_AVAILABLE_SERVERS); + player.disconnect0(VelocityMessages.NO_AVAILABLE_SERVERS, true); return; } player.createConnectionRequest(toTry.get()).fireAndForget();