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 c8961824..35ed11e5 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -6,6 +6,7 @@ import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.AsyncHttpClientConfig; import com.ning.http.client.providers.netty.NettyAsyncHttpProvider; import com.ning.http.client.providers.netty.NettyAsyncHttpProviderConfig; +import gnu.trove.map.TMap; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelException; @@ -27,7 +28,6 @@ import java.util.Map; import java.util.ResourceBundle; import java.util.Timer; import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -53,6 +53,7 @@ import net.md_5.bungee.netty.PipelineUtils; import net.md_5.bungee.packet.DefinedPacket; import net.md_5.bungee.packet.PacketFAPluginMessage; import net.md_5.bungee.scheduler.BungeeThreadPool; +import net.md_5.bungee.util.CaseInsensitiveMap; /** * Main BungeeCord proxy class. @@ -96,7 +97,7 @@ public class BungeeCord extends ProxyServer /** * Fully qualified connections. */ - public Map connections = new ConcurrentHashMap<>(); + public TMap connections = new CaseInsensitiveMap<>(); /** * Tab list handler */ diff --git a/proxy/src/main/java/net/md_5/bungee/config/Configuration.java b/proxy/src/main/java/net/md_5/bungee/config/Configuration.java index 3b7e350c..848cb7ed 100644 --- a/proxy/src/main/java/net/md_5/bungee/config/Configuration.java +++ b/proxy/src/main/java/net/md_5/bungee/config/Configuration.java @@ -1,6 +1,7 @@ package net.md_5.bungee.config; import com.google.common.base.Preconditions; +import gnu.trove.map.TMap; import java.util.Collection; import java.util.Map; import java.util.UUID; @@ -12,6 +13,7 @@ import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.tablist.GlobalPing; import net.md_5.bungee.tablist.Global; import net.md_5.bungee.tablist.ServerUnique; +import net.md_5.bungee.util.CaseInsensitiveMap; /** * Core configuration for the proxy. @@ -43,7 +45,7 @@ public class Configuration /** * Set of all servers. */ - private Map servers; + private TMap servers; /** * Should we check minecraft.net auth. */ @@ -86,7 +88,7 @@ public class Configuration if ( servers == null ) { - servers = newServers; + servers = new CaseInsensitiveMap<>( newServers ); } else { for ( ServerInfo oldServer : servers.values() ) diff --git a/proxy/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java b/proxy/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java new file mode 100644 index 00000000..88773b85 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java @@ -0,0 +1,34 @@ +package net.md_5.bungee.util; + +import gnu.trove.map.hash.TCustomHashMap; +import gnu.trove.strategy.HashingStrategy; +import java.util.Map; + +public class CaseInsensitiveMap extends TCustomHashMap +{ + + private static final HashingStrategy hashingStrategy = new HashingStrategy() + { + @Override + public int computeHashCode(String object) + { + return object.toLowerCase().hashCode(); + } + + @Override + public boolean equals(String o1, String o2) + { + return o1.toLowerCase().equals( o2.toLowerCase() ); + } + }; + + public CaseInsensitiveMap() + { + super( hashingStrategy ); + } + + public CaseInsensitiveMap(Map map) + { + super( hashingStrategy, map ); + } +} diff --git a/proxy/src/test/java/net/md_5/bungee/util/CaseInsensitiveTest.java b/proxy/src/test/java/net/md_5/bungee/util/CaseInsensitiveTest.java new file mode 100644 index 00000000..f29cd85c --- /dev/null +++ b/proxy/src/test/java/net/md_5/bungee/util/CaseInsensitiveTest.java @@ -0,0 +1,19 @@ +package net.md_5.bungee.util; + +import org.junit.Test; +import org.junit.Assert; + +public class CaseInsensitiveTest +{ + + @Test + public void testMaps() + { + Object obj = new Object(); + CaseInsensitiveMap map = new CaseInsensitiveMap<>(); + + map.put( "FOO", obj ); + Assert.assertTrue( map.contains( "foo" ) ); // Assert that it is case insensitive + Assert.assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Asert that case is preserved + } +}