package net.md_5.bungee;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.TimerTask;
import net.md_5.bungee.api.ProxyServer;
public class Metrics extends TimerTask
{
/**
* The current revision number
*/
private final static int REVISION = 5;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/report/%s";
/**
* Interval of time to ping (in minutes)
*/
final static int PING_INTERVAL = 10;
boolean firstPost = true;
@Override
public void run()
{
try
{
// We use the inverse of firstPost because if it is the first time we are posting,
// it is not a interval ping, so it evaluates to FALSE
// Each time thereafter it will evaluate to TRUE, i.e PING!
postPlugin( !firstPost );
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch ( IOException ex )
{
// ProxyServer.getInstance().getLogger().info( "[Metrics] " + ex.getMessage() );
}
}
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(boolean isPing) throws IOException
{
// Construct the post data
final StringBuilder data = new StringBuilder();
data.append( encode( "guid" ) ).append( '=' ).append( encode( BungeeCord.getInstance().config.getUuid() ) );
encodeDataPair( data, "version", ProxyServer.getInstance().getVersion() );
encodeDataPair( data, "server", "0" );
encodeDataPair( data, "players", Integer.toString( ProxyServer.getInstance().getOnlineCount() ) );
encodeDataPair( data, "revision", String.valueOf( REVISION ) );
// If we're pinging, append it
if ( isPing )
{
encodeDataPair( data, "ping", "true" );
}
// Create the url
URL url = new URL( BASE_URL + String.format( REPORT_URL, encode( "BungeeCord" ) ) );
// Connect to the website
URLConnection connection;
connection = url.openConnection();
connection.setDoOutput( true );
final BufferedReader reader;
final String response;
try ( OutputStreamWriter writer = new OutputStreamWriter( connection.getOutputStream() ) )
{
writer.write( data.toString() );
writer.flush();
reader = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
response = reader.readLine();
}
reader.close();
if ( response == null || response.startsWith( "ERR" ) )
{
throw new IOException( response ); //Throw the exception
}
}
/**
* <p>
* Encode a key/value data pair to be used in a HTTP post request. This
* INCLUDES a & so the first key/value pair MUST be included manually,
* e.g:</p>
* <code>
* StringBuffer data = new StringBuffer();
* data.append(encode("guid")).append('=').append(encode(guid));
* encodeDataPair(data, "version", description.getVersion());
* </code>
*
* @param buffer the StringBuilder to append the data pair onto
* @param key the key value
* @param value the value
*/
private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException
{
buffer.append( '&' ).append( encode( key ) ).append( '=' ).append( encode( value ) );
}
/**
* Encode text as UTF-8
*
* @param text the text to encode
* @return the encoded text, as UTF-8
*/
private static String encode(final String text) throws UnsupportedEncodingException
{
return URLEncoder.encode( text, "UTF-8" );
}
}