From 34de9687e1cc733f39a4f2a44d6fe943e0826d24 Mon Sep 17 00:00:00 2001 From: Troy Frew Date: Tue, 28 Jun 2016 23:00:02 -0400 Subject: [PATCH] Add dynamic server addition/removal api patch (#37) --- ...-dynamic-server-addition-removal-api.patch | 281 ++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 BungeeCord-Patches/0037-Add-dynamic-server-addition-removal-api.patch diff --git a/BungeeCord-Patches/0037-Add-dynamic-server-addition-removal-api.patch b/BungeeCord-Patches/0037-Add-dynamic-server-addition-removal-api.patch new file mode 100644 index 0000000..ccc2ee1 --- /dev/null +++ b/BungeeCord-Patches/0037-Add-dynamic-server-addition-removal-api.patch @@ -0,0 +1,281 @@ +From f003385fe169b5be68b0acdf41a82a55f4140fb8 Mon Sep 17 00:00:00 2001 +From: Troy Frew +Date: Tue, 28 Jun 2016 21:29:25 -0500 +Subject: [PATCH] Add dynamic server addition/removal api. + +The provided methods will not move a player if a server is removed or the server ip/port is changed, however the methods return the old ServerInfo object for you to handle that yourself if needed. + +Thanks to Overcast for the idea + +diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java +index 5a49050..f04e2bf 100644 +--- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java ++++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java +@@ -32,9 +32,83 @@ public interface ProxyConfig + + /** + * Set of all servers. ++ * ++ * @deprecated The returned map may be modified concurrently by the proxy. ++ * The safe alternative is {@link #getServersCopy()}. + */ ++ @Deprecated // Waterfall + Map getServers(); + ++ // Waterfall start - Dynamic server addition/removal api ++ /** ++ * Return all servers registered to this proxy, keyed by name. The returned map ++ * is an immutable snapshot of the actual server collection. It cannot be modified, ++ * and it will not change. ++ * ++ * @return all registered remote server destinations ++ */ ++ Map getServersCopy(); ++ ++ /** ++ * Gets the server info of a server. ++ * ++ * @param name the name of the configured server ++ * @return the server info belonging to the specified server ++ */ ++ ServerInfo getServerInfo(String name); ++ ++ /** ++ * Register the given server to the proxy. ++ * Any currently registered server with the same name will be replaced. ++ * This change is not saved to config.yml ++ * ++ * @return the previously registered server with the same name, or null if there was no such server. ++ */ ++ ServerInfo addServer(ServerInfo server); ++ ++ /** ++ * Register all of the given servers to the proxy. ++ * This change is not saved to config.yml ++ * ++ * @return true if any servers were added or replaced. ++ */ ++ boolean addServers(Collection servers); ++ ++ /** ++ * Un-register the server with the given name from the proxy. ++ * This change is not saved to config.yml ++ * ++ * @return the server that was removed, or null if there is no server with the given name. ++ */ ++ ServerInfo removeServerNamed(String name); ++ ++ /** ++ * Un-register the given server from the proxy. ++ * The server is matched by name only, other fields in the given {@link ServerInfo} are ignored. ++ * This change is not saved to config.yml ++ * ++ * @return the server that was removed, or null if there is no server with a matching name. ++ */ ++ ServerInfo removeServer(ServerInfo server); ++ ++ /** ++ * Un-register servers with any of the given names from the proxy. ++ * This change is not saved to config.yml ++ * ++ * @return true if any servers were removed. ++ */ ++ boolean removeServersNamed(Collection names); ++ ++ /** ++ * Un-register all of the given servers from the proxy. ++ * The servers are matched by name only, other fields in the given {@link ServerInfo} are ignored. ++ * This change is not saved to config.yml ++ * ++ * @return true if any servers were removed. ++ */ ++ boolean removeServers(Collection servers); ++ // Waterfall end ++ + /** + * Does the server authenticate with mojang + */ +diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java +index 11c5b68..1c011d0 100644 +--- a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java ++++ b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java +@@ -93,9 +93,25 @@ public abstract class ProxyServer + * return a fresh map each time. + * + * @return all registered remote server destinations ++ * ++ * @deprecated The returned map is part of the proxy's internal state, ++ * and may be modified concurrently by the proxy. ++ * The safe alternative is {@link #getServersCopy()}. + */ ++ @Deprecated // Waterfall + public abstract Map getServers(); + ++ // Waterfall begin - Cloned servers map ++ /** ++ * Return all servers registered to this proxy, keyed by name. The returned map ++ * is an immutable snapshot of the actual server collection. It cannot be modified, ++ * and it will not change. ++ * ++ * @return all registered remote server destinations ++ */ ++ public abstract Map getServersCopy(); ++ // Waterfall end ++ + /** + * Gets the server info of a server. + * +diff --git a/config/src/main/java/net/md_5/bungee/config/Configuration.java b/config/src/main/java/net/md_5/bungee/config/Configuration.java +index 1366f44..05ec159 100644 +--- a/config/src/main/java/net/md_5/bungee/config/Configuration.java ++++ b/config/src/main/java/net/md_5/bungee/config/Configuration.java +@@ -28,6 +28,13 @@ public final class Configuration + this( new LinkedHashMap(), defaults ); + } + ++ // Waterfall start - Allow configuration objects to be cloned ++ public Configuration(Configuration values, Configuration defaults) ++ { ++ this( values.self, defaults ); ++ } ++ // Waterfall end ++ + private Configuration getSectionFor(String path) + { + int index = path.indexOf( SEPARATOR ); +diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +index fc5ca3a..92ea9b5 100644 +--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java ++++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +@@ -559,10 +559,18 @@ public class BungeeCord extends ProxyServer + return config.getServers(); + } + ++ // Waterfall start ++ @Override ++ public Map getServersCopy() ++ { ++ return config.getServersCopy(); ++ } ++ // Waterfall end ++ + @Override + public ServerInfo getServerInfo(String name) + { +- return getServers().get( name ); ++ return config.getServerInfo( name ); // Waterfall + } + + @Override +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 db9ebbd..112420a 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 +@@ -1,6 +1,7 @@ + package net.md_5.bungee.conf; + + import com.google.common.base.Preconditions; ++import com.google.common.collect.ImmutableMap; // Waterfall + import gnu.trove.map.TMap; + import java.io.File; + import java.io.IOException; +@@ -11,6 +12,7 @@ import java.util.UUID; + import java.util.logging.Level; + import javax.imageio.ImageIO; + import lombok.Getter; ++import lombok.Synchronized; // Waterfall + + import net.md_5.bungee.BungeeCord; + import net.md_5.bungee.api.Favicon; +@@ -61,6 +63,7 @@ public abstract class Configuration implements ProxyConfig + private Favicon favicon; + private int compressionThreshold = 256; + ++ @Synchronized("servers") // Waterfall + public void load() + { + ConfigurationAdapter adapter = ProxyServer.getInstance().getConfigurationAdapter(); +@@ -100,7 +103,7 @@ public abstract class Configuration implements ProxyConfig + servers = new CaseInsensitiveMap<>( newServers ); + } else + { +- Map oldServers = this.servers; ++ Map oldServers = getServersCopy(); + this.servers = new CaseInsensitiveMap<>(newServers); + + for ( ServerInfo oldServer : oldServers.values() ) +@@ -158,4 +161,71 @@ public abstract class Configuration implements ProxyConfig + { + return favicon; + } ++ ++ // Waterfall start ++ @Override ++ @Synchronized("servers") ++ public Map getServersCopy() { ++ return ImmutableMap.copyOf( servers ); ++ } ++ ++ @Override ++ @Synchronized("servers") ++ public ServerInfo getServerInfo(String name) ++ { ++ return this.servers.get( name ); ++ } ++ ++ @Override ++ @Synchronized("servers") ++ public ServerInfo addServer(ServerInfo server) ++ { ++ return this.servers.put( server.getName(), server ); ++ } ++ ++ @Override ++ @Synchronized("servers") ++ public boolean addServers(Collection servers) ++ { ++ boolean changed = false; ++ for ( ServerInfo server : servers ) ++ { ++ if ( server != this.servers.put( server.getName(), server ) ) changed = true; ++ } ++ return changed; ++ } ++ ++ @Override ++ @Synchronized("servers") ++ public ServerInfo removeServerNamed(String name) ++ { ++ return this.servers.remove( name ); ++ } ++ ++ @Override ++ @Synchronized("servers") ++ public ServerInfo removeServer(ServerInfo server) ++ { ++ return this.servers.remove( server.getName() ); ++ } ++ ++ @Override ++ @Synchronized("servers") ++ public boolean removeServersNamed(Collection names) ++ { ++ return this.servers.keySet().removeAll( names ); ++ } ++ ++ @Override ++ @Synchronized("servers") ++ public boolean removeServers(Collection servers) ++ { ++ boolean changed = false; ++ for ( ServerInfo server : servers ) ++ { ++ if ( null != this.servers.remove( server.getName() ) ) changed = true; ++ } ++ return changed; ++ } ++ // Waterfall end + } +-- +2.7.4 (Apple Git-66) +