13
0
geforkt von Mirrors/Velocity

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.
Dieser Commit ist enthalten in:
Andrew Steinborn 2018-10-28 03:32:18 -04:00
Ursprung 1310cd2c53
Commit 070631902a
2 geänderte Dateien mit 83 neuen und 27 gelöschten Zeilen

Datei anzeigen

@ -17,16 +17,16 @@ public final class KickedFromServerEvent implements
private final Player player; private final Player player;
private final RegisteredServer server; private final RegisteredServer server;
private final Component originalReason; private final Component originalReason;
private final boolean duringLogin; private final boolean duringServerConnect;
private ServerKickResult result; private ServerKickResult result;
public KickedFromServerEvent(Player player, RegisteredServer server, Component originalReason, public KickedFromServerEvent(Player player, RegisteredServer server, Component originalReason,
boolean duringLogin, Component fancyReason) { boolean duringServerConnect, Component fancyReason) {
this.player = Preconditions.checkNotNull(player, "player"); this.player = Preconditions.checkNotNull(player, "player");
this.server = Preconditions.checkNotNull(server, "server"); this.server = Preconditions.checkNotNull(server, "server");
this.originalReason = Preconditions.checkNotNull(originalReason, "originalReason"); this.originalReason = Preconditions.checkNotNull(originalReason, "originalReason");
this.duringLogin = duringLogin; this.duringServerConnect = duringServerConnect;
this.result = new DisconnectPlayer(fancyReason); this.result = new Notify(fancyReason);
} }
@Override @Override
@ -51,8 +51,25 @@ public final class KickedFromServerEvent implements
return originalReason; return originalReason;
} }
/**
* Returns whether or not the player got kicked while connecting to another server.
*
* @return whether or not the player got kicked
*/
public boolean kickedDuringServerConnect() {
return duringServerConnect;
}
/**
* Returns whether or not the player got kicked while logging in.
*
* @return whether or not the player got kicked
* @deprecated {@link #kickedDuringServerConnect()} has a better name and reflects the actual
* result
*/
@Deprecated
public boolean kickedDuringLogin() { public boolean kickedDuringLogin() {
return duringLogin; return duringServerConnect;
} }
/** /**
@ -124,4 +141,37 @@ public final class KickedFromServerEvent implements
return new RedirectPlayer(server); return new RedirectPlayer(server);
} }
} }
/**
* Notifies the player with the specified message but does nothing else. This is only a valid
* result to use if the player was trying to connect to a different server, otherwise it is
* treated like a {@link DisconnectPlayer} result.
*/
public static final class Notify implements ServerKickResult {
private final Component message;
private Notify(Component message) {
this.message = Preconditions.checkNotNull(message, "message");
}
@Override
public boolean isAllowed() {
return false;
}
public Component getMessage() {
return message;
}
/**
* Notifies the player with the specified message but does nothing else.
*
* @param message the server to send the player to
* @return the redirect result
*/
public static Notify create(Component message) {
return new Notify(message);
}
}
} }

Datei anzeigen

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