From 0bab27125230a455e4ca9f5664ac7ce02f15feb6 Mon Sep 17 00:00:00 2001 From: Techcable Date: Thu, 28 Jan 2016 15:13:29 -0700 Subject: [PATCH] Allow removing servers or changing addresses on reload Moves all players on the removed server to the default server. Address changes also move the players to the default server. Kicks players on failure to move. Original Issue: https://github.com/WaterfallMC/Waterfall-Old/issues/17 diff --git a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java index 886f3b4c..193d8bce 100644 --- a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java +++ b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java @@ -11,12 +11,15 @@ import java.util.UUID; import java.util.logging.Level; import javax.imageio.ImageIO; import lombok.Getter; + +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.Favicon; import net.md_5.bungee.api.ProxyConfig; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ConfigurationAdapter; import net.md_5.bungee.api.config.ListenerInfo; import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.util.CaseInsensitiveMap; import net.md_5.bungee.util.CaseInsensitiveSet; @@ -105,20 +108,38 @@ public abstract class Configuration implements ProxyConfig servers = new CaseInsensitiveMap<>( newServers ); } else { - for ( ServerInfo oldServer : servers.values() ) - { - // Don't allow servers to be removed - Preconditions.checkArgument( newServers.containsKey( oldServer.getName() ), "Server %s removed on reload!", oldServer.getName() ); - } + Map oldServers = this.servers; - // Add new servers - for ( Map.Entry newServer : newServers.entrySet() ) + for ( ServerInfo oldServer : oldServers.values() ) { - if ( !servers.containsValue( newServer.getValue() ) ) - { - servers.put( newServer.getKey(), newServer.getValue() ); + ServerInfo newServer = newServers.get(oldServer.getName()); + if ((newServer == null || !oldServer.getAddress().equals(newServer.getAddress())) && !oldServer.getPlayers().isEmpty()) { + BungeeCord.getInstance().getLogger().info("Moving players off of server: " + oldServer.getName()); + // The server is being removed, or having it's address changed + for (ProxiedPlayer player : oldServer.getPlayers()) { + ListenerInfo listener = player.getPendingConnection().getListener(); + String destinationName = newServers.get(listener.getDefaultServer()) == null ? listener.getDefaultServer() : listener.getFallbackServer(); + ServerInfo destination = newServers.get(destinationName); + if (destination == null) { + BungeeCord.getInstance().getLogger().severe("Couldn't find server " + listener.getDefaultServer() + " or " + listener.getFallbackServer() + " to put player " + player.getName() + " on"); + player.disconnect(BungeeCord.getInstance().getTranslation("fallback_kick", "Not found on reload")); + continue; + } + player.connect(destination, (success, cause) -> { + if (!success) { + BungeeCord.getInstance().getLogger().log(Level.WARNING, "Failed to connect " + player.getName() + " to " + destination.getName(), cause); + player.disconnect(BungeeCord.getInstance().getTranslation("fallback_kick", cause.getCause().getClass().getName())); + } + }); + } + } else { + // This server isn't new or removed, we'll use bungees behavior of just ignoring + // any changes to info outside of the address, this is not ideal, but the alternative + // requires resetting multiple objects of which have no proper identity + newServers.put(oldServer.getName(), oldServer); } } + this.servers = new CaseInsensitiveMap<>(newServers); } for ( ListenerInfo listener : listeners ) -- 2.21.0