Fix some suboptimal behavior in invoking KickedFromServerEvent.

Previously, the event would only fire when a player was kicked from the
current server they were on. Now, under certain cases, it can be fired
even if the player was already connected to a server.

To faciliate this, a new result (Notify) was introduced. This result
will "do the right thing" if the player is kicked from the current
server or is trying to connect to a different server than the one they
were on.
This commit is contained in:
Andrew Steinborn
2018-10-28 03:32:18 -04:00
parent 1310cd2c53
commit 070631902a
2 changed files with 83 additions and 27 deletions

View File

@@ -4,6 +4,9 @@ import com.google.common.base.Preconditions;
import com.google.gson.JsonObject;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.player.KickedFromServerEvent;
import com.velocitypowered.api.event.player.KickedFromServerEvent.DisconnectPlayer;
import com.velocitypowered.api.event.player.KickedFromServerEvent.Notify;
import com.velocitypowered.api.event.player.KickedFromServerEvent.RedirectPlayer;
import com.velocitypowered.api.event.player.PlayerModInfoEvent;
import com.velocitypowered.api.event.player.PlayerSettingsChangedEvent;
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
@@ -336,9 +339,9 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
private void handleConnectionException(RegisteredServer rs, @Nullable Component kickReason,
Component friendlyReason) {
boolean alreadyConnected =
connectedServer != null && connectedServer.getServerInfo().equals(rs.getServerInfo());
// There can't be any connection in flight now.
connectionInFlight = null;
if (connectedServer == null) {
// The player isn't yet connected to a server.
Optional<RegisteredServer> nextServer = getNextServerToTry();
@@ -347,30 +350,33 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
} else {
connection.closeWith(Disconnect.create(friendlyReason));
}
} else if (connectedServer.getServerInfo().equals(rs.getServerInfo())) {
} else if (kickReason != null) {
// Already connected to the server being disconnected from.
if (kickReason != null) {
server.getEventManager().fire(
new KickedFromServerEvent(this, rs, kickReason, !alreadyConnected, friendlyReason))
.thenAcceptAsync(event -> {
if (event.getResult() instanceof KickedFromServerEvent.DisconnectPlayer) {
KickedFromServerEvent.DisconnectPlayer res = (KickedFromServerEvent.DisconnectPlayer) event
.getResult();
connection.closeWith(Disconnect.create(res.getReason()));
} else if (event.getResult() instanceof KickedFromServerEvent.RedirectPlayer) {
KickedFromServerEvent.RedirectPlayer res = (KickedFromServerEvent.RedirectPlayer) event
.getResult();
createConnectionRequest(res.getServer()).fireAndForget();
KickedFromServerEvent originalEvent = new KickedFromServerEvent(this, rs, kickReason,
!connectedServer.getServer().equals(rs), friendlyReason);
server.getEventManager().fire(originalEvent)
.thenAcceptAsync(event -> {
if (event.getResult() instanceof DisconnectPlayer) {
DisconnectPlayer res = (DisconnectPlayer) event.getResult();
connection.closeWith(Disconnect.create(res.getReason()));
} else if (event.getResult() instanceof RedirectPlayer) {
RedirectPlayer res = (RedirectPlayer) event.getResult();
createConnectionRequest(res.getServer()).fireAndForget();
} else if (event.getResult() instanceof Notify) {
Notify res = (Notify) event.getResult();
if (event.kickedDuringServerConnect()) {
sendMessage(res.getMessage());
} else {
// In case someone gets creative, assume we want to disconnect the player.
connection.closeWith(Disconnect.create(friendlyReason));
connection.closeWith(Disconnect.create(res.getMessage()));
}
}, connection.eventLoop());
} else {
connection.closeWith(Disconnect.create(friendlyReason));
}
} else {
// In case someone gets creative, assume we want to disconnect the player.
connection.closeWith(Disconnect.create(friendlyReason));
}
}, connection.eventLoop());
} else {
connection.write(Chat.createClientbound(friendlyReason));
connection.closeWith(Disconnect.create(friendlyReason));
}
}