From 85e5fb48271ffd323fe1bc22ed5cde11b2fdb004 Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Fri, 19 Jul 2019 13:25:04 -0400 Subject: [PATCH] Allow existing players to be kicked from server if in online-mode Fixes #226 --- .../velocitypowered/proxy/VelocityServer.java | 28 +++++++++++++++---- .../proxy/config/VelocityConfiguration.java | 14 +++++++++- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java index 095fd5e86..3d2d4a40e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java @@ -70,6 +70,7 @@ import java.util.function.IntFunction; import java.util.stream.Collectors; import net.kyori.text.Component; import net.kyori.text.TextComponent; +import net.kyori.text.TranslatableComponent; import net.kyori.text.serializer.gson.GsonComponentSerializer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -454,6 +455,9 @@ public class VelocityServer implements ProxyServer { * @return {@code true} if we can register the connection, {@code false} if not */ public boolean canRegisterConnection(ConnectedPlayer connection) { + if (configuration.isOnlineMode() && configuration.isOnlineModeKickExistingPlayers()) { + return true; + } String lowerName = connection.getUsername().toLowerCase(Locale.US); return !(connectionsByName.containsKey(lowerName) || connectionsByUuid.containsKey(connection.getUniqueId())); @@ -466,12 +470,24 @@ public class VelocityServer implements ProxyServer { */ public boolean registerConnection(ConnectedPlayer connection) { String lowerName = connection.getUsername().toLowerCase(Locale.US); - if (connectionsByName.putIfAbsent(lowerName, connection) != null) { - return false; - } - if (connectionsByUuid.putIfAbsent(connection.getUniqueId(), connection) != null) { - connectionsByName.remove(lowerName, connection); - return false; + + if (!this.configuration.isOnlineModeKickExistingPlayers()) { + if (connectionsByName.putIfAbsent(lowerName, connection) != null) { + return false; + } + if (connectionsByUuid.putIfAbsent(connection.getUniqueId(), connection) != null) { + connectionsByName.remove(lowerName, connection); + return false; + } + } else { + ConnectedPlayer existing = connectionsByUuid.get(connection.getUniqueId()); + if (existing != null) { + existing.disconnect(TranslatableComponent.of("multiplayer.disconnect.duplicate_login")); + } + + // We can now replace the entries as needed. + connectionsByName.put(lowerName, connection); + connectionsByUuid.put(connection.getUniqueId(), connection); } return true; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java index 6fd13239e..48449e079 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -77,6 +77,11 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi @ConfigKey("announce-forge") private boolean announceForge = false; + @Comment({"If enabled (default is false) and the proxy is in online mode, Velocity will kick", + "any existing player who is online if a duplicate connection attempt is made."}) + @ConfigKey("kick-existing-players") + private boolean onlineModeKickExistingPlayers = false; + @Table("[servers]") private final Servers servers; @@ -109,7 +114,8 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi private VelocityConfiguration(String bind, String motd, int showMaxPlayers, boolean onlineMode, boolean announceForge, PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret, - Servers servers, ForcedHosts forcedHosts, Advanced advanced, Query query, Metrics metrics) { + boolean onlineModeKickExistingPlayers, Servers servers, ForcedHosts forcedHosts, + Advanced advanced, Query query, Metrics metrics) { this.bind = bind; this.motd = motd; this.showMaxPlayers = showMaxPlayers; @@ -117,6 +123,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi this.announceForge = announceForge; this.playerInfoForwardingMode = playerInfoForwardingMode; this.forwardingSecret = forwardingSecret; + this.onlineModeKickExistingPlayers = onlineModeKickExistingPlayers; this.servers = servers; this.forcedHosts = forcedHosts; this.advanced = advanced; @@ -425,6 +432,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi toml.getBoolean("announce-forge", false), PlayerInfoForwarding.valueOf(forwardingModeName), forwardingSecret, + toml.getBoolean("kick-existing-players", false), servers, forcedHosts, advanced, @@ -443,6 +451,10 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi return builder.toString(); } + public boolean isOnlineModeKickExistingPlayers() { + return onlineModeKickExistingPlayers; + } + private static class Servers { @IsMap