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 f51dec1f..1d4522c6 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 @@ -152,4 +152,26 @@ public abstract class ProxyServer * instance to fail to boot */ public abstract void start() throws Exception; + + /** + * Register a channel for use with plugin messages. This is required by some + * server / client implementations. + * + * @param channel the channel to register + */ + public abstract void registerChannel(String channel); + + /** + * Unregister a previously registered channel. + * + * @param channel the channel to unregister + */ + public abstract void unregisterChannel(String channel); + + /** + * Get an immutable set of all registered plugin channels. + * + * @return registered plugin channels + */ + public abstract Collection getChannels(); } 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 ded8ae36..c0f038db 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -20,6 +21,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import lombok.Getter; import lombok.Setter; +import lombok.Synchronized; import static net.md_5.bungee.Logger.$; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ReconnectHandler; @@ -34,6 +36,7 @@ import net.md_5.bungee.api.plugin.PluginManager; import net.md_5.bungee.command.*; import net.md_5.bungee.config.YamlConfig; import net.md_5.bungee.packet.DefinedPacket; +import net.md_5.bungee.packet.PacketFAPluginMessage; /** * Main BungeeCord proxy class. @@ -73,7 +76,6 @@ public class BungeeCord extends ProxyServer * Fully qualified connections. */ public Map connections = new ConcurrentHashMap<>(); - public Map> connectionsByServer = new ConcurrentHashMap<>(); /** * Tab list handler */ @@ -91,6 +93,7 @@ public class BungeeCord extends ProxyServer @Getter @Setter private ConfigurationAdapter configurationAdapter = new YamlConfig(); + private final Collection pluginChannels = new HashSet<>(); { @@ -272,8 +275,8 @@ public class BungeeCord extends ProxyServer @Override public Server getServer(String name) { - List users = connectionsByServer.get(name); - return (users != null && !users.isEmpty()) ? users.get(0).getServer() : null; + Collection users = getServers().get(name).getPlayers(); + return (users != null && !users.isEmpty()) ? users.iterator().next().getServer() : null; } @Override @@ -281,4 +284,37 @@ public class BungeeCord extends ProxyServer { return config.getServers(); } + + @Override + @Synchronized("pluginChannels") + public void registerChannel(String channel) + { + pluginChannels.add(channel); + } + + @Override + @Synchronized("pluginChannels") + public void unregisterChannel(String channel) + { + pluginChannels.remove(channel); + } + + @Override + @Synchronized("pluginChannels") + public Collection getChannels() + { + return Collections.unmodifiableCollection(pluginChannels); + } + + public PacketFAPluginMessage registerChannels() + { + StringBuilder sb = new StringBuilder(); + for (String s : getChannels()) + { + sb.append(s); + sb.append('\00'); + } + byte[] payload = sb.substring(0, sb.length() - 1).getBytes(); + return new PacketFAPluginMessage("REGISTER", payload); + } } diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java index 110e53e4..57994e55 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -89,6 +89,9 @@ public class ServerConnection extends GenericConnection implements Server ServerConnection server = new ServerConnection(socket, info, in, out, login); ServerConnectedEvent event = new ServerConnectedEvent(user, server); ProxyServer.getInstance().getPluginManager().callEvent(event); + + out.write(BungeeCord.getInstance().registerChannels().getPacket()); + return server; } catch (KickException ex) { diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 77f622d0..a5405896 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -103,6 +103,8 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer clientEntityId = newServer.loginPacket.entityId; serverEntityId = newServer.loginPacket.entityId; out.write(newServer.loginPacket.getPacket()); + out.write(BungeeCord.getInstance().registerChannels().getPacket()); + upBridge = new UpstreamBridge(); upBridge.start(); } else