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 b42fb4a4..2004d519 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 @@ -2,6 +2,7 @@ package net.md_5.bungee.api; import net.md_5.bungee.api.plugin.PluginManager; import com.google.common.base.Preconditions; +import java.net.InetSocketAddress; import java.util.Collection; import java.util.Map; import java.util.logging.Logger; @@ -75,7 +76,11 @@ public abstract class ProxyServer * * @param name the name to lookup * @return the associated server + * @deprecated in most cases the {@link #getServerInfo(java.lang.String)} + * method should be used, as it will return a server even when no players + * are online. */ + @Deprecated public abstract Server getServer(String name); /** @@ -196,4 +201,14 @@ public abstract class ProxyServer * @return the Minecraft protocol version */ public abstract byte getProtocolVersion(); + + /** + * Factory method to construct an implementation specific server info + * instance. + * + * @param name name of the server + * @param address connectable Minecraft address + port of the server + * @return the constructed instance + */ + public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address); } diff --git a/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java b/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java index 4ed5ddfa..d1474f2e 100644 --- a/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java +++ b/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java @@ -7,6 +7,8 @@ import java.util.Collections; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Synchronized; +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.ServerPing; import net.md_5.bungee.api.connection.ProxiedPlayer; /** @@ -14,7 +16,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; */ @Data @AllArgsConstructor -public class ServerInfo +public abstract class ServerInfo { /** @@ -62,4 +64,19 @@ public class ServerInfo { return Collections.unmodifiableCollection(players); } + + /** + * Send data by any available means to this server. + * + * @param channel the channel to send this data via + * @param data the data to send + */ + public abstract void sendData(String channel, byte[] data); + + /** + * Asynchronously gets the current player count on this server. + * + * @param callback the callback to call when the count has been retrieved. + */ + public abstract void ping(Callback callback); } diff --git a/api/src/main/java/net/md_5/bungee/api/connection/Server.java b/api/src/main/java/net/md_5/bungee/api/connection/Server.java index caa8dd45..f94e5a96 100644 --- a/api/src/main/java/net/md_5/bungee/api/connection/Server.java +++ b/api/src/main/java/net/md_5/bungee/api/connection/Server.java @@ -1,8 +1,8 @@ package net.md_5.bungee.api.connection; import net.md_5.bungee.api.Callback; -import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.config.ServerInfo; /** * Represents a destination which this proxy might connect to. @@ -29,6 +29,9 @@ public interface Server extends Connection * Asynchronously gets the current player count on this server. * * @param callback the callback to call when the count has been retrieved. + * @deprecated use the corresponding method in {@link ServerInfo} for + * clarity */ + @Deprecated public abstract void ping(Callback callback); } 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 4ec7b3e8..c2eb05b8 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -5,6 +5,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.net.InetSocketAddress; import java.net.Socket; import java.util.Collection; import java.util.Collections; @@ -339,4 +340,10 @@ public class BungeeCord extends ProxyServer { return GAME_VERSION; } + + @Override + public ServerInfo constructServerInfo(String name, InetSocketAddress address) + { + return new BungeeServerInfo(name, address); + } } diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java new file mode 100644 index 00000000..74133f81 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java @@ -0,0 +1,76 @@ +package net.md_5.bungee; + +import java.io.DataOutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import lombok.Getter; +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.packet.DefinedPacket; +import net.md_5.bungee.packet.PacketFAPluginMessage; +import net.md_5.bungee.packet.PacketFFKick; +import net.md_5.bungee.packet.PacketInputStream; + +public class BungeeServerInfo extends ServerInfo +{ + + @Getter + private final Queue packetQueue = new ConcurrentLinkedQueue<>(); + + public BungeeServerInfo(String name, InetSocketAddress address) + { + super(name, address); + } + + @Override + public void sendData(String channel, byte[] data) + { + Server server = ProxyServer.getInstance().getServer(getName()); + if (server != null) + { + server.sendData(channel, data); + } else + { + packetQueue.add(new PacketFAPluginMessage(channel, data)); + } + } + + @Override + public void ping(final Callback callback) + { + new Thread() + { + @Override + public void run() + { + try + { + Socket socket = new Socket(); + socket.connect(getAddress()); + try (DataOutputStream out = new DataOutputStream(socket.getOutputStream())) + { + out.write(0xFE); + out.write(0x01); + } + try (PacketInputStream in = new PacketInputStream(socket.getInputStream())) + { + PacketFFKick response = new PacketFFKick(in.readPacket()); + + String[] split = response.message.split("\00"); + + ServerPing ping = new ServerPing(Byte.parseByte(split[1]), split[2], split[3], Integer.parseInt(split[4]), Integer.parseInt(split[5])); + callback.done(ping, null); + } + } catch (Throwable t) + { + callback.done(null, t); + } + } + }.start(); + } +} 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 1ab7fb83..92c79a7d 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -95,6 +95,12 @@ public class ServerConnection extends GenericConnection implements Server out.write(BungeeCord.getInstance().registerChannels().getPacket()); + Queue packetQueue = ((BungeeServerInfo) info).getPacketQueue(); + while (!packetQueue.isEmpty()) + { + out.write(packetQueue.poll().getPacket()); + } + return server; } catch (KickException ex) { @@ -122,35 +128,7 @@ public class ServerConnection extends GenericConnection implements Server @Override public void ping(final Callback callback) { - new Thread() - { - @Override - public void run() - { - try - { - Socket socket = new Socket(); - socket.connect(getAddress()); - try (DataOutputStream out = new DataOutputStream(socket.getOutputStream())) - { - out.write(0xFE); - out.write(0x01); - } - try (PacketInputStream in = new PacketInputStream(socket.getInputStream())) - { - PacketFFKick response = new PacketFFKick(in.readPacket()); - - String[] split = response.message.split("\00"); - - ServerPing ping = new ServerPing(Byte.parseByte(split[1]), split[2], split[3], Integer.parseInt(split[4]), Integer.parseInt(split[5])); - callback.done(ping, null); - } - } catch (Throwable t) - { - callback.done(null, t); - } - } - }.start(); + getInfo().ping(callback); } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java b/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java index fe310faa..7f676993 100644 --- a/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java +++ b/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java @@ -151,7 +151,7 @@ public class YamlConfig implements ConfigurationAdapter String name = entry.getKey(); String addr = get("address", "localhost:25565", val); InetSocketAddress address = Util.getAddr(addr); - ServerInfo info = new ServerInfo(name, address); + ServerInfo info = ProxyServer.getInstance().constructServerInfo(name, address); ret.put(name, info); }