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

View File

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

View File

@@ -165,9 +165,9 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
public void disconnect() {
if (connection != null) {
gracefulDisconnect = true;
connection.close();
connection = null;
gracefulDisconnect = true;
}
}
@@ -230,4 +230,15 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
public void resetLastPingId() {
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;
this.connectedServer = serverConnection;
if (serverConnection == null) {
return;
}
if (oldConnection != null && !serverConnection.getServerInfo()
.equals(oldConnection.getServerInfo())) {
this.tryIndex = 0;
@@ -452,7 +457,6 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
if (serverConnection == connectionInFlight) {
connectionInFlight = null;
}
this.connectedServer = serverConnection;
}
public void sendLegacyForgeHandshakeResetPacket() {