Disconnect obsolete server connections as quickly as possible.

This commit is contained in:
Andrew Steinborn
2018-10-28 23:00:13 -04:00
parent 940717412d
commit 826eddc754
4 changed files with 24 additions and 7 deletions

View File

@@ -45,7 +45,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
@Override @Override
public boolean beforeHandle() { public boolean beforeHandle() {
if (!serverConn.getPlayer().isActive()) { if (!serverConn.isActive()) {
// Obsolete connection // Obsolete connection
serverConn.disconnect(); serverConn.disconnect();
return true; return true;
@@ -121,7 +121,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
packet.getData()); packet.getData());
server.getEventManager().fire(event) server.getEventManager().fire(event)
.thenAcceptAsync(pme -> { .thenAcceptAsync(pme -> {
if (pme.getResult().isAllowed()) { if (pme.getResult().isAllowed() && serverConn.isActive()) {
smc.write(packet); smc.write(packet);
} }
}, smc.eventLoop()); }, smc.eventLoop());

View File

@@ -117,11 +117,13 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
serverConn.getPlayer().getConnection() serverConn.getPlayer().getConnection()
.setSessionHandler(new ClientPlaySessionHandler(server, serverConn.getPlayer())); .setSessionHandler(new ClientPlaySessionHandler(server, serverConn.getPlayer()));
} else { } else {
// The previous server connection should become obsolete. // If the server we are departing is modded, we must always reset the client's handshake.
// Before we remove it, if the server we are departing is modded, we must always reset the client state.
if (existingConnection.isLegacyForge()) { if (existingConnection.isLegacyForge()) {
serverConn.getPlayer().sendLegacyForgeHandshakeResetPacket(); serverConn.getPlayer().sendLegacyForgeHandshakeResetPacket();
} }
// Shut down the existing server connection.
serverConn.getPlayer().setConnectedServer(null);
existingConnection.disconnect(); existingConnection.disconnect();
} }

View File

@@ -165,9 +165,9 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
public void disconnect() { public void disconnect() {
if (connection != null) { if (connection != null) {
gracefulDisconnect = true;
connection.close(); connection.close();
connection = null; connection = null;
gracefulDisconnect = true;
} }
} }
@@ -230,4 +230,15 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
public void resetLastPingId() { public void resetLastPingId() {
this.lastPingId = -1; this.lastPingId = -1;
} }
/**
* Ensures that this server connection remains "active": the connection is established and not
* closed, the player is still connected to the server, and the player still remains online.
*
* @return whether or not the player is online
*/
boolean isActive() {
return connection != null && !connection.isClosed() && !gracefulDisconnect
&& proxyPlayer.isActive();
}
} }

View File

@@ -443,8 +443,13 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
}); });
} }
public void setConnectedServer(VelocityServerConnection serverConnection) { public void setConnectedServer(@Nullable VelocityServerConnection serverConnection) {
VelocityServerConnection oldConnection = this.connectedServer; VelocityServerConnection oldConnection = this.connectedServer;
this.connectedServer = serverConnection;
if (serverConnection == null) {
return;
}
if (oldConnection != null && !serverConnection.getServerInfo() if (oldConnection != null && !serverConnection.getServerInfo()
.equals(oldConnection.getServerInfo())) { .equals(oldConnection.getServerInfo())) {
this.tryIndex = 0; this.tryIndex = 0;
@@ -452,7 +457,6 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
if (serverConnection == connectionInFlight) { if (serverConnection == connectionInFlight) {
connectionInFlight = null; connectionInFlight = null;
} }
this.connectedServer = serverConnection;
} }
public void sendLegacyForgeHandshakeResetPacket() { public void sendLegacyForgeHandshakeResetPacket() {