package com.etcfg.etlaunch;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import com.etcfg.etlaunch.ServerStatus.Player;
public class ServerStatusChecker {
public static final String GAMENAME = "gamename";
public static final String SV_PUNKBUSTER = "sv_punkbuster";
public static final String SV_MAXCLIENTS = "sv_maxclients";
public static final String SV_PRIVATECLIENTS = "sv_privateClients";
DatagramSocket datagramSocket;
private static final byte[] REQUEST_BODY = { -1, -1, -1, -1, 103, 101, 116,
115, 116, 97, 116, 117, 115 };
public ServerStatusChecker() throws SocketException {
datagramSocket = new DatagramSocket();
datagramSocket.setSoTimeout(3000);
}
public ServerStatus checkStatus(String adress, int port,
boolean parsePlayers) throws IOException {
byte[] response = new byte[1024 * 4];
DatagramPacket requestPacket = new DatagramPacket(REQUEST_BODY,
REQUEST_BODY.length, InetAddress.getByName(adress), port);
DatagramPacket responsePacket = new DatagramPacket(response,
response.length, InetAddress.getByName(adress), port);
long startTime = System.currentTimeMillis();
try {
datagramSocket.send(requestPacket);
datagramSocket.receive(responsePacket);
} catch (SocketTimeoutException ex) {
ServerStatus serverStatus = new ServerStatus();
serverStatus.setName(adress + ":" + port);
serverStatus.setPing(999);
return serverStatus;
}
long ping = System.currentTimeMillis() - startTime;
ServerStatus serverStatus = new ServerStatus();
serverStatus.setPing((int) ping);
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(
responsePacket.getData(), responsePacket.getOffset(),
responsePacket.getLength());
InputStreamReader inputStreamReader = new InputStreamReader(
arrayInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
bufferedReader.readLine();
// toooooooooo long string.
String parameters = bufferedReader.readLine();
String[] split = parameters.split("\\\\");
Set<ETCVars> etCvars = new HashSet<>();
HashMap<String, String> etCVarsHash = new HashMap<>();
ETCVars[] values = ETCVars.values();
etCvars.addAll(Arrays.asList(values));
for (int i = 1; i < split.length; i += 2) {
String varKey = split[i];
String varValue = split[i + 1];
etCVarsHash.put(varKey, varValue);
// System.out.println(split[i] + " : " + split[i+1]);
Iterator<ETCVars> iterator = etCvars.iterator();
while (iterator.hasNext()) {
ETCVars next = iterator.next();
if (next.name.equals(varKey)) {
next.putValue(serverStatus, varValue);
iterator.remove();
break;
}
}
}
String teamFlagString = etCVarsHash.get("P");
String readLine = bufferedReader.readLine();
int j = 0;
while (true) {
// skip available slot
if (teamFlagString == null)
break;
char teamChar = teamFlagString.charAt(j);
if (teamChar != '-')
break;
else
j++;
}
while (readLine != null) {
StringBuilder sb = new StringBuilder();
Player player = new Player();
int i;
for (i = 0; i < readLine.length(); i++) {
char carChar = readLine.charAt(i);
if (carChar != ' ') {
sb.append(carChar);
} else {
i++;
break;
}
}
player.setXp(Integer.parseInt(sb.toString()));
sb = new StringBuilder();
while (i < readLine.length()) {
char carChar = readLine.charAt(i);
if (carChar != ' ') {
sb.append(carChar);
i++;
} else {
i += 2;
break;
}
}
player.setPing(Integer.parseInt(sb.toString()));
sb = new StringBuilder();
while (i < readLine.length() - 1) {
sb.append(readLine.charAt(i));
i++;
}
player.setName(sb.toString());
while (true) {
if (teamFlagString == null)
break;
char teamChar = teamFlagString.charAt(j);
if (teamChar == '-') {
j++;
continue;
} else {
switch (teamChar) {
case '0':
player.setTeam("Connecting");
break;
case '1':
player.setTeam("Axis");
break;
case '2':
player.setTeam("Allies");
break;
case '3':
player.setTeam("Spectator");
break;
default:
player.setTeam("UNKNOWN");
}
j++;
break;
}
}
serverStatus.getPlayers().add(player);
readLine = bufferedReader.readLine();
}
return serverStatus;
}
public static void main(String[] args) throws UnknownHostException,
IOException {
ServerStatusChecker checker = new ServerStatusChecker();
//
ServerStatus checkStatus = checker.checkStatus("clanserver.etcfg.com",
27960, false);
System.out.println(checkStatus);
}
private enum ETCVars {
GAMENAME(ServerStatusChecker.GAMENAME) {
@Override
public void putValue(ServerStatus status, String value) {
status.setMod(value);
}
},
SV_PUNKBUSTER(ServerStatusChecker.SV_PUNKBUSTER) {
@Override
public void putValue(ServerStatus status, String value) {
status.setPunkbusterEnabled("1".equals(value));
}
},
SV_MAXCLIENTS(ServerStatusChecker.SV_MAXCLIENTS) {
@Override
public void putValue(ServerStatus status, String value) {
int parseInt = Integer.parseInt(value);
status.setMaxPlayers(parseInt);
}
},
SV_PRIVATECLIENTS(ServerStatusChecker.SV_PRIVATECLIENTS) {
@Override
public void putValue(ServerStatus status, String value) {
int parseInt = Integer.parseInt(value);
status.setPrivateSlots(parseInt);
}
},
sv_hostname("sv_hostname") {
@Override
public void putValue(ServerStatus status, String value) {
status.setName(value);
}
},
omnibot_playing("omnibot_playing") {
@Override
public void putValue(ServerStatus status, String value) {
int botNumber = Integer.parseInt(value);
status.setBotsplaying(botNumber);
}
},
mapname("mapname") {
@Override
public void putValue(ServerStatus status, String value) {
status.setMapName(value);
}
},
g_needpass("g_needpass") {
@Override
public void putValue(ServerStatus status, String value) {
status.setPasswordProtected("1".equals(value));
}
},
sl_sv_version("sl_sv_version") {
@Override
public void putValue(ServerStatus status, String value) {
status.setSlacEnabled(true);
}
};
public String name;
ETCVars(String name) {
this.name = name;
}
abstract void putValue(ServerStatus status, String value);
}
}