Fixed disconnecting players in the middle of a backend server reconfiguration (#1669)
This commit is contained in:
@@ -257,7 +257,13 @@ public class ConfigSessionHandler implements MinecraftSessionHandler {
|
|||||||
@Override
|
@Override
|
||||||
public boolean handle(DisconnectPacket packet) {
|
public boolean handle(DisconnectPacket packet) {
|
||||||
serverConn.disconnect();
|
serverConn.disconnect();
|
||||||
|
// If the player receives a DisconnectPacket without a connection to a server in progress,
|
||||||
|
// it means that the backend server has kicked the player during reconfiguration
|
||||||
|
if (serverConn.getPlayer().getConnectionInFlight() != null) {
|
||||||
resultFuture.complete(ConnectionRequestResults.forDisconnect(packet, serverConn.getServer()));
|
resultFuture.complete(ConnectionRequestResults.forDisconnect(packet, serverConn.getServer()));
|
||||||
|
} else {
|
||||||
|
serverConn.getPlayer().handleConnectionException(serverConn.getServer(), packet, true);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
if (player.getConnection().getActiveSessionHandler() instanceof ClientPlaySessionHandler clientPlaySessionHandler) {
|
if (player.getConnection().getActiveSessionHandler() instanceof ClientPlaySessionHandler clientPlaySessionHandler) {
|
||||||
smc.setAutoReading(false);
|
smc.setAutoReading(false);
|
||||||
clientPlaySessionHandler.doSwitch().thenAcceptAsync((unused) -> smc.setAutoReading(true), smc.eventLoop());
|
clientPlaySessionHandler.doSwitch().thenRunAsync(() -> smc.setAutoReading(true), smc.eventLoop());
|
||||||
} else {
|
} else {
|
||||||
// Initial login - the player is already in configuration state.
|
// Initial login - the player is already in configuration state.
|
||||||
server.getEventManager().fireAndForget(new PlayerEnteredConfigurationEvent(player, serverConn));
|
server.getEventManager().fireAndForget(new PlayerEnteredConfigurationEvent(player, serverConn));
|
||||||
|
|||||||
@@ -817,9 +817,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
|
|||||||
createConnectionRequest(res.getServer(), previousConnection).connect()
|
createConnectionRequest(res.getServer(), previousConnection).connect()
|
||||||
.whenCompleteAsync((status, throwable) -> {
|
.whenCompleteAsync((status, throwable) -> {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
handleConnectionException(
|
handleConnectionException(res.getServer(), throwable, true);
|
||||||
status != null ? status.getAttemptedConnection() : res.getServer(), throwable,
|
|
||||||
true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1497,7 +1495,16 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
|
|||||||
VelocityServerConnection con =
|
VelocityServerConnection con =
|
||||||
new VelocityServerConnection(vrs, previousServer, ConnectedPlayer.this, server);
|
new VelocityServerConnection(vrs, previousServer, ConnectedPlayer.this, server);
|
||||||
connectionInFlight = con;
|
connectionInFlight = con;
|
||||||
return con.connect().whenCompleteAsync((result, exception) -> this.resetIfInFlightIs(con),
|
|
||||||
|
return con.connect().whenCompleteAsync((result, exception) -> {
|
||||||
|
if (result != null && !result.isSuccessful() && !result.isSafe()) {
|
||||||
|
handleConnectionException(result.getAttemptedConnection(),
|
||||||
|
// The only way for the reason to be null is if the result is safe
|
||||||
|
DisconnectPacket.create(result.getReasonComponent().orElseThrow(),
|
||||||
|
getProtocolVersion(), connection.getState()), false);
|
||||||
|
}
|
||||||
|
this.resetIfInFlightIs(con);
|
||||||
|
},
|
||||||
connection.eventLoop());
|
connection.eventLoop());
|
||||||
}, connection.eventLoop());
|
}, connection.eventLoop());
|
||||||
});
|
});
|
||||||
@@ -1511,22 +1518,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Result> connect() {
|
public CompletableFuture<Result> connect() {
|
||||||
return this.internalConnect().whenCompleteAsync((status, throwable) -> {
|
return this.internalConnect().thenApply(x -> x);
|
||||||
if (status != null && !status.isSuccessful()) {
|
|
||||||
if (!status.isSafe()) {
|
|
||||||
handleConnectionException(status.getAttemptedConnection(), throwable, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, connection.eventLoop()).thenApply(x -> x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> connectWithIndication() {
|
public CompletableFuture<Boolean> connectWithIndication() {
|
||||||
return internalConnect().whenCompleteAsync((status, throwable) -> {
|
return internalConnect().whenCompleteAsync((status, throwable) -> {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
// TODO: The exception handling from this is not very good. Find a better way.
|
handleConnectionException(toConnect, throwable, true);
|
||||||
handleConnectionException(status != null ? status.getAttemptedConnection() : toConnect,
|
|
||||||
throwable, true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user