From 8021f5845151ff6e956be365ecd0998737222d26 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 23 Jan 2013 16:49:05 +1100 Subject: [PATCH] Implement server ping method. --- .../java/net/md_5/bungee/api/ServerPing.java | 4 +-- .../md_5/bungee/api/event/ProxyPingEvent.java | 13 +++---- .../main/java/net/md_5/bungee/BungeeCord.java | 2 +- .../java/net/md_5/bungee/InitialHandler.java | 21 ++++++++---- .../net/md_5/bungee/ServerConnection.java | 34 +++++++++++++++++-- .../md_5/bungee/packet/PacketInputStream.java | 8 ++++- 6 files changed, 61 insertions(+), 21 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/ServerPing.java b/api/src/main/java/net/md_5/bungee/api/ServerPing.java index d1dda171..e37f9aee 100644 --- a/api/src/main/java/net/md_5/bungee/api/ServerPing.java +++ b/api/src/main/java/net/md_5/bungee/api/ServerPing.java @@ -25,9 +25,9 @@ public class ServerPing /** * Current amount of players on the server. */ - private final String currentPlayers; + private final int currentPlayers; /** * Max amount of players the server will allow. */ - private final String maxPlayers; + private final int maxPlayers; } diff --git a/api/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java b/api/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java index e48e59cf..49c1b5c5 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java @@ -1,30 +1,27 @@ package net.md_5.bungee.api.event; -import java.net.InetSocketAddress; +import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import net.md_5.bungee.api.ServerPing; -import net.md_5.bungee.api.config.ListenerInfo; +import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.plugin.Event; /** * Called when the proxy is pinged with packet 0xFE from the server list. */ @Data +@AllArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class ProxyPingEvent extends Event { /** - * The address of the user pinging. + * The connection asking for a ping response. */ - private final InetSocketAddress remoteAddress; - /** - * The data corresponding to the server which received this ping. - */ - private final ListenerInfo server; + private final PendingConnection connection; /** * The data to respond with. */ 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 fa035ad8..2add6029 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -47,7 +47,7 @@ public class BungeeCord extends ProxyServer /** * Server protocol version. */ - public static final int PROTOCOL_VERSION = 51; + public static final byte PROTOCOL_VERSION = 51; /** * Server game version. */ diff --git a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java index 542e73a1..1c0d86ab 100644 --- a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java @@ -11,11 +11,13 @@ import javax.crypto.SecretKey; import lombok.Getter; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.ServerPing; import net.md_5.bungee.api.config.ListenerInfo; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.LoginEvent; +import net.md_5.bungee.api.event.ProxyPingEvent; import net.md_5.bungee.packet.Packet2Handshake; import net.md_5.bungee.packet.PacketFCEncryptionResponse; import net.md_5.bungee.packet.PacketFDEncryptionRequest; @@ -102,14 +104,19 @@ public class InitialHandler implements Runnable, PendingConnection } catch (IOException ex) { } - Configuration conf = BungeeCord.getInstance().config; + + ServerPing pingevent = new ServerPing(BungeeCord.PROTOCOL_VERSION, BungeeCord.GAME_VERSION, + listener.getMotd(), ProxyServer.getInstance().getPlayers().size(), listener.getMaxPlayers()); + + ProxyServer.getInstance().getPluginManager().callEvent(new ProxyPingEvent(this, pingevent)); + String ping = (newPing) ? ChatColor.COLOR_CHAR + "1" - + "\00" + BungeeCord.PROTOCOL_VERSION - + "\00" + BungeeCord.GAME_VERSION - + "\00" + listener.getMotd() - + "\00" + ProxyServer.getInstance().getPlayers().size() - + "\00" + listener.getMaxPlayers() - : listener.getMotd() + ChatColor.COLOR_CHAR + ProxyServer.getInstance().getPlayers().size() + ChatColor.COLOR_CHAR + listener.getMaxPlayers(); + + "\00" + pingevent.getProtocolVersion() + + "\00" + pingevent.getGameVersion() + + "\00" + pingevent.getMotd() + + "\00" + pingevent.getCurrentPlayers() + + "\00" + pingevent.getMaxPlayers() + : pingevent.getMotd() + ChatColor.COLOR_CHAR + pingevent.getCurrentPlayers() + ChatColor.COLOR_CHAR + pingevent.getMaxPlayers(); throw new KickException(ping); default: if (id == 0xFA) 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 54db34e3..1ab7fb83 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -1,5 +1,7 @@ package net.md_5.bungee; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; @@ -118,9 +120,37 @@ public class ServerConnection extends GenericConnection implements Server } @Override - public void ping(Callback callback) + public void ping(final Callback callback) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + 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(); } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/packet/PacketInputStream.java b/proxy/src/main/java/net/md_5/bungee/packet/PacketInputStream.java index 30a39ac1..a12323aa 100644 --- a/proxy/src/main/java/net/md_5/bungee/packet/PacketInputStream.java +++ b/proxy/src/main/java/net/md_5/bungee/packet/PacketInputStream.java @@ -10,7 +10,7 @@ import net.md_5.mendax.datainput.DataInputPacketReader; * A specialized input stream to parse packets using the Mojang packet * definitions and then return them as a byte array. */ -public class PacketInputStream +public class PacketInputStream implements AutoCloseable { private final DataInputStream dataInput; @@ -35,6 +35,12 @@ public class PacketInputStream return tracker.out.toByteArray(); } + @Override + public void close() throws Exception + { + dataInput.close(); + } + /** * Input stream which will wrap another stream and copy all bytes read to a * {@link ByteArrayOutputStream}.