Skip to content

Instantly share code, notes, and snippets.

@jamezrin
Last active May 3, 2016 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamezrin/2dc8c14ce0c75c565e376e3daf0bbf76 to your computer and use it in GitHub Desktop.
Save jamezrin/2dc8c14ce0c75c565e376e3daf0bbf76 to your computer and use it in GitHub Desktop.
This is a ping utility based on https://gist.github.com/zh32/2b8f00ba6f7cdabef74d
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.net.InetSocketAddress;
public class PingExample {
private static Gson gson = new Gson();
public static void main(String[] args) {
try {
new ServerListPing(new InetSocketAddress("127.0.0.1", 25565)) {
@Override
public void onResponse(String json, int time) {
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(json);
JsonObject object = element.getAsJsonObject();
JsonObject version = object.getAsJsonObject("version");
int protocol = version.get("protocol").getAsInt();
switch (protocol) {
case 47:
case 5:
case 4: {
StatusResponse17 response = gson.fromJson(element, StatusResponse17.class);
break;
}
default: {
StatusResponse19 response = gson.fromJson(element, StatusResponse19.class);
}
}
}
};
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
public abstract class ServerListPing {
private final InetSocketAddress host;
private final int timeout;
public ServerListPing(InetSocketAddress host, int timeout) throws IOException {
this.host = host;
this.timeout = timeout;
Socket socket = new Socket();
OutputStream outputStream;
DataOutputStream dataOutputStream;
InputStream inputStream;
InputStreamReader inputStreamReader;
socket.setSoTimeout(this.timeout);
socket.connect(host, timeout);
outputStream = socket.getOutputStream();
dataOutputStream = new DataOutputStream(outputStream);
inputStream = socket.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
ByteArrayOutputStream b = new ByteArrayOutputStream();
DataOutputStream handshake = new DataOutputStream(b);
handshake.writeByte(0x00); //packet id for handshake
writeVarInt(handshake, 4); //protocol version
writeVarInt(handshake, this.host.getHostString().length()); //host length
handshake.writeBytes(this.host.getHostString()); //host string
handshake.writeShort(host.getPort()); //port
writeVarInt(handshake, 1); //state (1 for handshake)
writeVarInt(dataOutputStream, b.size()); //prepend size
dataOutputStream.write(b.toByteArray()); //write handshake packet
dataOutputStream.writeByte(0x01); //size is only 1
dataOutputStream.writeByte(0x00); //packet id for ping
DataInputStream dataInputStream = new DataInputStream(inputStream);
int size = readVarInt(dataInputStream); //size of packet
int id = readVarInt(dataInputStream); //packet id
if (id == -1) {
socket.close();
throw new IOException("Premature end of stream.");
}
if (id != 0x00) { //we want a status response
socket.close();
throw new IOException("Invalid packetID");
}
int length = readVarInt(dataInputStream); //length of json string
if (length == -1) {
socket.close();
throw new IOException("Premature end of stream.");
}
if (length == 0) {
socket.close();
throw new IOException("Invalid string length.");
}
byte[] in = new byte[length];
dataInputStream.readFully(in); //read json string
String json = new String(in);
long now = System.currentTimeMillis();
dataOutputStream.writeByte(0x09); //size of packet
dataOutputStream.writeByte(0x01); //0x01 for ping
dataOutputStream.writeLong(now); //time!?
readVarInt(dataInputStream);
id = readVarInt(dataInputStream);
if (id == -1) {
socket.close();
throw new IOException("Premature end of stream.");
}
if (id != 0x01) {
socket.close();
throw new IOException("Invalid packetID");
}
long pingtime = dataInputStream.readLong(); //read response
onResponse(json, (int) (now - pingtime));
dataOutputStream.close();
outputStream.close();
inputStreamReader.close();
inputStream.close();
socket.close();
}
public ServerListPing(InetSocketAddress host) throws IOException {
this(host, 7000);
}
private int readVarInt(DataInputStream in) throws IOException {
int i = 0;
int j = 0;
while (true) {
int k = in.readByte();
i |= (k & 0x7F) << j++ * 7;
if (j > 5) throw new RuntimeException("VarInt too big");
if ((k & 0x80) != 128) break;
}
return i;
}
private void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
while (true) {
if ((paramInt & 0xFFFFFF80) == 0) {
out.writeByte(paramInt);
return;
}
out.writeByte(paramInt & 0x7F | 0x80);
paramInt >>>= 7;
}
}
public InetSocketAddress getHost() {
return host;
}
public int getTimeout() {
return timeout;
}
public abstract void onResponse(String json, int time);
}
import java.util.List;
public class StatusResponse17 {
private String description;
private PingPlayers players;
private PingVersion version;
private String favicon;
private int time;
public String getDescription() {
return description;
}
public PingPlayers getPlayers() {
return players;
}
public PingVersion getVersion() {
return version;
}
public String getFavicon() {
return favicon;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public class PingPlayers {
private int max;
private int online;
private List<PingPlayer> sample;
public int getMax() {
return max;
}
public int getOnline() {
return online;
}
public List<PingPlayer> getSample() {
return sample;
}
}
public class PingPlayer {
private String name;
private String id;
public String getName() {
return name;
}
public String getId() {
return id;
}
}
public class PingVersion {
private String name;
private int protocol;
public String getName() {
return name;
}
public int getProtocol() {
return protocol;
}
}
}
import java.util.List;
public class StatusResponse17 {
private String description;
private PingPlayers players;
private PingVersion version;
private String favicon;
private int time;
public String getDescription() {
return description;
}
public PingPlayers getPlayers() {
return players;
}
public PingVersion getVersion() {
return version;
}
public String getFavicon() {
return favicon;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public class PingPlayers {
private int max;
private int online;
private List<PingPlayer> sample;
public int getMax() {
return max;
}
public int getOnline() {
return online;
}
public List<PingPlayer> getSample() {
return sample;
}
}
public class PingPlayer {
private String name;
private String id;
public String getName() {
return name;
}
public String getId() {
return id;
}
}
public class PingVersion {
private String name;
private int protocol;
public String getName() {
return name;
}
public int getProtocol() {
return protocol;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment