Last active
May 3, 2016 20:09
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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