Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SLP
import com.google.gson.Gson;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.logging.Level;
import lombok.Setter;
import org.bukkit.Bukkit;
/**
*
* @author zh32
*/
public class ServerListPing {
@Setter
private InetSocketAddress host;
@Setter
private int timeout = 2000;
private final static Gson gson = new Gson();
public StatusResponse fetchData() throws IOException {
Socket socket = null;
OutputStream oStr = null;
InputStream inputStream = null;
StatusResponse response = null;
try {
socket = new Socket();
socket.setSoTimeout(timeout);
socket.connect(host, timeout);
oStr = socket.getOutputStream();
DataOutputStream dataOut = new DataOutputStream(oStr);
inputStream = socket.getInputStream();
DataInputStream dIn = new DataInputStream(inputStream);
sendPacket(dataOut, prepareHandshake());
sendPacket(dataOut, preparePing());
response = receiveResponse(dIn);
dIn.close();
dataOut.close();
} catch (Exception ex) {
//you may want to do something here
} finally {
if (oStr != null) {
oStr.close();
}
if (inputStream != null) {
inputStream.close();
}
if (socket != null) {
socket.close();
}
return response;
}
}
private StatusResponse receiveResponse(DataInputStream dIn) throws IOException {
int size = readVarInt(dIn);
int packetId = readVarInt(dIn);
if (packetId != 0x00) {
throw new IOException("Invalid packetId");
}
int stringLength = readVarInt(dIn);
if (stringLength < 1) {
throw new IOException("Invalid string length.");
}
byte[] responseData = new byte[stringLength];
dIn.readFully(responseData);
String jsonString = new String(responseData, Charset.forName("utf-8"));
StatusResponse response = gson.fromJson(jsonString, StatusResponse.class);
return response;
}
private void sendPacket(DataOutputStream out, byte[] data) throws IOException {
writeVarInt(out, data.length);
out.write(data);
}
private byte[] preparePing() throws IOException {
return new byte[] {0x00};
}
private byte[] prepareHandshake() throws IOException {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DataOutputStream handshake = new DataOutputStream(bOut);
bOut.write(0x00); //packet id
writeVarInt(handshake, 4); //protocol version
writeString(handshake, host.getHostString());
handshake.writeShort(host.getPort());
writeVarInt(handshake, 1); //target state 1
return bOut.toByteArray();
}
public void writeString(DataOutputStream out, String string) throws IOException {
writeVarInt(out, string.length());
out.write(string.getBytes(Charset.forName("utf-8")));
}
public 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;
}
public void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
while (true) {
if ((paramInt & 0xFFFFFF80) == 0) {
out.write(paramInt);
return;
}
out.write(paramInt & 0x7F | 0x80);
paramInt >>>= 7;
}
}
}
####################
import java.util.List;
import lombok.Data;
/**
*
* @author zh32 <zh32 at zh32.de>
*/
@Data
public class StatusResponse {
private String description;
private Players players;
private Version version;
private String favicon;
private int time;
@Data
public class Players {
private int max;
private int online;
private List<Player> sample;
}
@Data
public class Player {
private String name;
private String id;
}
@Data
public class Version {
private String name;
private String protocol;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.