2013-09-11 22:53:24 +02:00
|
|
|
package mineplex.bungee.playerCount;
|
2013-09-05 11:12:12 +02:00
|
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.DataInput;
|
|
|
|
import java.io.DataInputStream;
|
|
|
|
import java.io.DataOutput;
|
|
|
|
import java.io.DataOutputStream;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.net.ConnectException;
|
|
|
|
import java.net.InetSocketAddress;
|
|
|
|
import java.net.Socket;
|
|
|
|
import java.net.SocketTimeoutException;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
import net.md_5.bungee.api.config.ListenerInfo;
|
|
|
|
import net.md_5.bungee.api.event.ProxyPingEvent;
|
|
|
|
import net.md_5.bungee.api.plugin.Listener;
|
|
|
|
import net.md_5.bungee.api.plugin.Plugin;
|
|
|
|
import net.md_5.bungee.event.EventHandler;
|
|
|
|
|
2013-09-11 22:53:24 +02:00
|
|
|
public class PlayerCount implements Listener, Runnable
|
2013-09-05 11:12:12 +02:00
|
|
|
{
|
2013-09-11 22:53:24 +02:00
|
|
|
private Plugin _plugin;
|
|
|
|
|
2013-09-05 11:12:12 +02:00
|
|
|
private HashMap<String, InetSocketAddress> _otherBungeeInstances;
|
2013-09-13 07:33:03 +02:00
|
|
|
private int _totalPlayers = -1;
|
2013-09-05 11:12:12 +02:00
|
|
|
private int _totalMaxPlayers;
|
|
|
|
|
|
|
|
private int _tempPlayers;
|
|
|
|
private int _tempMaxPlayers;
|
|
|
|
|
2013-09-11 22:53:24 +02:00
|
|
|
private static Object _serverLock = new Object();
|
|
|
|
|
|
|
|
public PlayerCount(Plugin plugin)
|
2013-09-05 11:12:12 +02:00
|
|
|
{
|
2013-09-11 22:53:24 +02:00
|
|
|
_plugin = plugin;
|
2013-09-05 11:12:12 +02:00
|
|
|
_otherBungeeInstances = new HashMap<String, InetSocketAddress>();
|
|
|
|
|
|
|
|
LoadBungeeServers();
|
|
|
|
|
2013-09-11 22:53:24 +02:00
|
|
|
_plugin.getProxy().getScheduler().schedule(_plugin, this, 1L, 1L, TimeUnit.SECONDS);
|
|
|
|
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
|
2013-09-05 11:12:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void run()
|
2013-09-13 07:33:03 +02:00
|
|
|
{
|
2013-09-11 22:53:24 +02:00
|
|
|
_tempPlayers = _plugin.getProxy().getOnlineCount();
|
2013-09-05 11:12:12 +02:00
|
|
|
_tempMaxPlayers = 0;
|
|
|
|
|
2013-09-11 22:53:24 +02:00
|
|
|
for(ListenerInfo li : _plugin.getProxy().getConfigurationAdapter().getListeners())
|
2013-09-05 11:12:12 +02:00
|
|
|
{
|
|
|
|
_tempMaxPlayers += li.getMaxPlayers();
|
|
|
|
}
|
|
|
|
|
2013-09-11 22:53:24 +02:00
|
|
|
synchronized (_serverLock)
|
2013-09-05 11:12:12 +02:00
|
|
|
{
|
2013-09-11 22:53:24 +02:00
|
|
|
for (InetSocketAddress address : _otherBungeeInstances.values())
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
UpdateServerCount(address);
|
|
|
|
} catch (IOException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2013-09-05 11:12:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_totalPlayers = _tempPlayers;
|
|
|
|
_totalMaxPlayers = _tempMaxPlayers;
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler
|
|
|
|
public void ServerPing(ProxyPingEvent event)
|
|
|
|
{
|
|
|
|
if (!_otherBungeeInstances.containsKey(event.getConnection().getAddress().getAddress().getHostAddress()))
|
|
|
|
{
|
|
|
|
net.md_5.bungee.api.ServerPing serverPing = event.getResponse();
|
|
|
|
event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getProtocolVersion(), serverPing.getGameVersion(), serverPing.getMotd(), _totalPlayers, _totalMaxPlayers));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void UpdateServerCount(InetSocketAddress address) throws IOException
|
|
|
|
{
|
|
|
|
Socket socket = null;
|
|
|
|
DataInputStream dataInputStream = null;
|
|
|
|
DataOutputStream dataOutputStream = null;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
socket = new Socket();
|
2013-09-13 07:33:03 +02:00
|
|
|
socket.setSoTimeout(5000);
|
2013-09-05 11:12:12 +02:00
|
|
|
socket.setTcpNoDelay(true);
|
|
|
|
socket.setTrafficClass(18);
|
|
|
|
socket.connect(address, 3000);
|
|
|
|
dataInputStream = new DataInputStream(socket.getInputStream());
|
|
|
|
dataOutputStream = new DataOutputStream(socket.getOutputStream());
|
|
|
|
|
|
|
|
dataOutputStream.writeByte(254);
|
2013-09-11 22:53:24 +02:00
|
|
|
|
2013-09-13 07:33:03 +02:00
|
|
|
dataOutputStream.writeByte(74);
|
2013-09-05 11:12:12 +02:00
|
|
|
dataOutputStream.writeByte(1);
|
|
|
|
dataOutputStream.writeByte(254);
|
2013-09-13 07:33:03 +02:00
|
|
|
writeString("MC|PingHost", dataOutputStream);
|
2013-09-05 11:12:12 +02:00
|
|
|
dataOutputStream.writeShort(3 + 2 * address.getAddress().getHostName().length() + 4);
|
2013-09-11 22:53:24 +02:00
|
|
|
dataOutputStream.writeByte(74);
|
2013-09-13 07:33:03 +02:00
|
|
|
|
2013-09-05 11:12:12 +02:00
|
|
|
writeString(address.getAddress().getHostName(), dataOutputStream);
|
|
|
|
dataOutputStream.writeInt(address.getPort());
|
|
|
|
|
|
|
|
if (dataInputStream.read() != 255)
|
|
|
|
{
|
2013-09-11 22:53:24 +02:00
|
|
|
System.out.println("Bad message");
|
2013-09-05 11:12:12 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
String var6 = readString(dataInputStream, 256);
|
|
|
|
|
|
|
|
String[] var27;
|
|
|
|
|
|
|
|
if (var6.startsWith("\u00a7") && var6.length() > 1)
|
|
|
|
{
|
|
|
|
var27 = var6.substring(1).split("\u0000");
|
|
|
|
|
|
|
|
_tempPlayers += Integer.parseInt(var27[4]);
|
|
|
|
_tempMaxPlayers += Integer.parseInt(var27[5]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (SocketTimeoutException e)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
catch (ConnectException e)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
2013-09-11 22:53:24 +02:00
|
|
|
System.out.println("[PlayerCount] Error pinging " + address.getHostName() + ":" + address.getPort());
|
2013-09-05 11:12:12 +02:00
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (dataInputStream != null)
|
|
|
|
{
|
|
|
|
dataInputStream.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception exception)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (dataOutputStream != null)
|
|
|
|
{
|
|
|
|
dataOutputStream.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception exception)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (socket != null)
|
|
|
|
{
|
|
|
|
socket.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception exception)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void writeString(String par0Str, DataOutput par1DataOutput) throws IOException
|
|
|
|
{
|
|
|
|
if (par0Str.length() > 32767)
|
|
|
|
{
|
|
|
|
throw new IOException("String too big");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
par1DataOutput.writeShort(par0Str.length());
|
|
|
|
par1DataOutput.writeChars(par0Str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String readString(DataInput par0DataInput, int par1) throws IOException
|
|
|
|
{
|
|
|
|
short var2 = par0DataInput.readShort();
|
|
|
|
|
|
|
|
if (var2 > par1)
|
|
|
|
{
|
|
|
|
throw new IOException("Received string length longer than maximum allowed (" + var2 + " > " + par1 + ")");
|
|
|
|
}
|
|
|
|
else if (var2 < 0)
|
|
|
|
{
|
|
|
|
throw new IOException("Received string length is less than zero! Weird string!");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
StringBuilder var3 = new StringBuilder();
|
|
|
|
|
|
|
|
for (int var4 = 0; var4 < var2; ++var4)
|
|
|
|
{
|
|
|
|
var3.append(par0DataInput.readChar());
|
|
|
|
}
|
|
|
|
|
|
|
|
return var3.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void LoadBungeeServers()
|
|
|
|
{
|
2013-09-11 22:53:24 +02:00
|
|
|
synchronized (_serverLock)
|
|
|
|
{
|
|
|
|
_otherBungeeInstances.clear();
|
|
|
|
}
|
|
|
|
|
2013-09-05 11:12:12 +02:00
|
|
|
FileInputStream fstream = null;
|
|
|
|
BufferedReader br = null;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
File npcFile = new File("bungeeServers.dat");
|
|
|
|
|
|
|
|
if (npcFile.exists())
|
|
|
|
{
|
|
|
|
fstream = new FileInputStream(npcFile);
|
|
|
|
br = new BufferedReader(new InputStreamReader(fstream));
|
|
|
|
|
|
|
|
String line = br.readLine();
|
|
|
|
|
|
|
|
while (line != null)
|
|
|
|
{
|
|
|
|
String address = line.split(":")[0];
|
|
|
|
Integer port = Integer.parseInt(line.split(":")[1]);
|
|
|
|
InetSocketAddress socketAddress = new InetSocketAddress(address, port);
|
2013-09-11 22:53:24 +02:00
|
|
|
|
|
|
|
boolean addAddress = true;
|
|
|
|
|
|
|
|
for (ListenerInfo listenerInfo : _plugin.getProxy().getConfigurationAdapter().getListeners())
|
|
|
|
{
|
|
|
|
if (address.equalsIgnoreCase(listenerInfo.getHost().getAddress().getHostAddress()))
|
|
|
|
{
|
|
|
|
addAddress = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addAddress)
|
|
|
|
{
|
|
|
|
synchronized (_serverLock)
|
|
|
|
{
|
|
|
|
_otherBungeeInstances.put(socketAddress.getAddress().getHostAddress(), socketAddress);
|
|
|
|
}
|
|
|
|
}
|
2013-09-05 11:12:12 +02:00
|
|
|
|
|
|
|
line = br.readLine();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
npcFile.createNewFile();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
System.out.println("Error parsing bungeeServers file.");
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (br != null)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
br.close();
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fstream != null)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
fstream.close();
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|