更新
This commit is contained in:
@@ -1,25 +1,6 @@
|
||||
package me.skymc.taboolib.bstats;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -29,16 +10,29 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
*
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !"false".equals(System.getProperty("bstats.relocatecheck"))) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
@@ -50,22 +44,34 @@ public class Metrics {
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
/**
|
||||
* The version of this bStats class
|
||||
*/
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
/**
|
||||
* The url to which the data is sent
|
||||
*/
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Should failed requests be logged?
|
||||
/**
|
||||
* Should failed requests be logged?
|
||||
*/
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// The uuid of the server
|
||||
/**
|
||||
* The uuid of the server
|
||||
*/
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
/**
|
||||
* The plugin
|
||||
*/
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
// A list with all custom charts
|
||||
/**
|
||||
* A list with all custom charts
|
||||
*/
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@@ -103,7 +109,8 @@ public class Metrics {
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// Load the data
|
||||
@@ -114,10 +121,13 @@ public class Metrics {
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
// Our identifier :)
|
||||
service.getField("B_STATS_VERSION");
|
||||
// We aren't the first
|
||||
found = true;
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
@@ -144,22 +154,23 @@ public class Metrics {
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("metrics-schedule-pool-%d").daemon(true).build());
|
||||
executorService.scheduleAtFixedRate(() -> {
|
||||
if (!plugin.isEnabled()) {
|
||||
executorService.shutdown();
|
||||
return;
|
||||
}
|
||||
}, 1000*60*5, 1000*60*30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
/*
|
||||
* Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
* Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
*/
|
||||
Bukkit.getScheduler().runTask(plugin, this::submitData);
|
||||
/*
|
||||
* Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
* WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
* WARNING: Just don't do it!
|
||||
*/
|
||||
}, 5, 30, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,13 +185,16 @@ public class Metrics {
|
||||
String pluginName = plugin.getDescription().getName();
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.put("pluginName", pluginName); // Append the name of the plugin
|
||||
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
// Append the name of the plugin
|
||||
data.put("pluginName", pluginName);
|
||||
// Append the version of the plugin
|
||||
data.put("pluginVersion", pluginVersion);
|
||||
JSONArray customCharts = new JSONArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
JSONObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null) { // If the chart is null, we skip it
|
||||
// If the chart is null, we skip it
|
||||
if (chart == null) {
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
@@ -206,7 +220,8 @@ public class Metrics {
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
// Just use the new method if the Reflection failed
|
||||
playerAmount = Bukkit.getOnlinePlayers().size();
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = org.bukkit.Bukkit.getVersion();
|
||||
@@ -246,20 +261,23 @@ public class Metrics {
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
// Our identifier :)
|
||||
service.getField("B_STATS_VERSION");
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
data.put("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(() -> {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(data);
|
||||
@@ -269,7 +287,7 @@ public class Metrics {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,9 +312,11 @@ public class Metrics {
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
// We gzip our request
|
||||
connection.addRequestProperty("Content-Encoding", "gzip");
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
// We send our data in JSON format
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
@@ -306,7 +326,8 @@ public class Metrics {
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
|
||||
// We don't care about the response - Just send our data :)
|
||||
connection.getInputStream().close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -332,7 +353,9 @@ public class Metrics {
|
||||
*/
|
||||
public static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
/**
|
||||
* The id of the chart
|
||||
*/
|
||||
final String chartId;
|
||||
|
||||
/**
|
||||
@@ -380,7 +403,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
@@ -411,7 +434,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
@@ -455,7 +478,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
@@ -504,7 +527,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
@@ -536,7 +559,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
@@ -581,7 +604,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
@@ -619,7 +642,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
|
||||
Reference in New Issue
Block a user