From 05e92993c547c01e6183e305d5b50c90f6bf8e6f Mon Sep 17 00:00:00 2001 From: Gamerboy59 Date: Wed, 29 Dec 2021 22:52:08 +0100 Subject: [PATCH 1/2] Replace deprecated header function --- bukkit/Metrics.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/bukkit/Metrics.java b/bukkit/Metrics.java index 5cc428c..5e72d0c 100644 --- a/bukkit/Metrics.java +++ b/bukkit/Metrics.java @@ -9,9 +9,11 @@ import java.lang.reflect.Method; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -28,6 +30,7 @@ import java.util.zip.GZIPOutputStream; import javax.net.ssl.HttpsURLConnection; import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -51,7 +54,7 @@ public Metrics(JavaPlugin plugin, int serviceId) { // Get the config file File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); File configFile = new File(bStatsFolder, "config.yml"); - YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + FileConfiguration config = YamlConfiguration.loadConfiguration(configFile); if (!config.isSet("serverUuid")) { config.addDefault("enabled", true); config.addDefault("serverUuid", UUID.randomUUID().toString()); @@ -59,14 +62,15 @@ public Metrics(JavaPlugin plugin, int serviceId) { config.addDefault("logSentData", false); config.addDefault("logResponseStatusText", false); // Inform the server owners about bStats + List header = new ArrayList(); + header.add("bStats (https://bStats.org) collects some basic information for plugin authors, like how"); + header.add("many people use their plugin and their total player count. It's recommended to keep bStats"); + header.add("enabled, but if you're not comfortable with this, you can turn this setting off. There is no"); + header.add("performance penalty associated with having metrics enabled, and data sent to bStats is fully"); + header.add("anonymous."); config .options() - .header( - "bStats (https://bStats.org) collects some basic information for plugin authors, like how\n" - + "many people use their plugin and their total player count. It's recommended to keep bStats\n" - + "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n" - + "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n" - + "anonymous.") + .setHeader(header) .copyDefaults(true); try { config.save(configFile); From b9a7fb7b57a94f9720491af7b90685e2ce410afa Mon Sep 17 00:00:00 2001 From: Gamerboy59 Date: Mon, 14 Feb 2022 17:09:50 +0100 Subject: [PATCH 2/2] Check method existance before calling it --- bukkit/Metrics.java | 185 ++++++++++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 75 deletions(-) diff --git a/bukkit/Metrics.java b/bukkit/Metrics.java index 5e72d0c..a3a7b0d 100644 --- a/bukkit/Metrics.java +++ b/bukkit/Metrics.java @@ -1,3 +1,17 @@ +/* + * This Metrics class was auto-generated and can be copied into your project if you are + * not using a build tool like Gradle or Maven for dependency management. + * + * IMPORTANT: You are not allowed to modify this class, except changing the package. + * + * Unallowed modifications include but are not limited to: + * - Remove the option for users to opt-out + * - Change the frequency for data submission + * - Obfuscate the code (every obfucator should allow you to make an exception for specific files) + * - Reformat the code (if you use a linter, add an exception) + * + * Violations will result in a ban of your plugin and account from bStats. + */ package org.bstats.bukkit; import java.io.BufferedReader; @@ -30,7 +44,7 @@ import java.util.zip.GZIPOutputStream; import javax.net.ssl.HttpsURLConnection; import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.FileConfigurationOptions; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -51,10 +65,18 @@ public class Metrics { */ public Metrics(JavaPlugin plugin, int serviceId) { this.plugin = plugin; + Method methodSetHeader = null; + try { + methodSetHeader = FileConfigurationOptions.class.getDeclaredMethod("setHeader", new Class[] { String.class }); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } // Get the config file File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); File configFile = new File(bStatsFolder, "config.yml"); - FileConfiguration config = YamlConfiguration.loadConfiguration(configFile); + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + //FileConfiguration config = YamlConfiguration.loadConfiguration(configFile); if (!config.isSet("serverUuid")) { config.addDefault("enabled", true); config.addDefault("serverUuid", UUID.randomUUID().toString()); @@ -62,16 +84,28 @@ public Metrics(JavaPlugin plugin, int serviceId) { config.addDefault("logSentData", false); config.addDefault("logResponseStatusText", false); // Inform the server owners about bStats - List header = new ArrayList(); - header.add("bStats (https://bStats.org) collects some basic information for plugin authors, like how"); - header.add("many people use their plugin and their total player count. It's recommended to keep bStats"); - header.add("enabled, but if you're not comfortable with this, you can turn this setting off. There is no"); - header.add("performance penalty associated with having metrics enabled, and data sent to bStats is fully"); - header.add("anonymous."); - config + if(methodSetHeader != null) { + List header = new ArrayList(); + header.add("bStats (https://bStats.org) collects some basic information for plugin authors, like how"); + header.add("many people use their plugin and their total player count. It's recommended to keep bStats"); + header.add("enabled, but if you're not comfortable with this, you can turn this setting off. There is no"); + header.add("performance penalty associated with having metrics enabled, and data sent to bStats is fully"); + header.add("anonymous."); + config .options() .setHeader(header) .copyDefaults(true); + } else { + config + .options() + .header( + "bStats (https://bStats.org) collects some basic information for plugin authors, like how\n" + + "many people use their plugin and their total player count. It's recommended to keep bStats\n" + + "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n" + + "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n" + + "anonymous.") + .copyDefaults(true); + } try { config.save(configFile); } catch (IOException ignored) { @@ -143,7 +177,7 @@ private int getPlayerAmount() { public static class MetricsBase { /** The version of the Metrics class. */ - public static final String METRICS_VERSION = "2.2.1"; + public static final String METRICS_VERSION = "3.0.0"; private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics")); @@ -228,6 +262,7 @@ public MetricsBase( this.logResponseStatusText = logResponseStatusText; checkRelocation(); if (enabled) { + // WARNING: Removing the option to opt-out will get your plugin banned from bStats startSubmitting(); } } @@ -364,9 +399,9 @@ private static byte[] compress(final String str) throws IOException { } } - public static class AdvancedBarChart extends CustomChart { + public static class DrilldownPie extends CustomChart { - private final Callable> callable; + private final Callable>> callable; /** * Class constructor. @@ -374,29 +409,33 @@ public static class AdvancedBarChart extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public AdvancedBarChart(String chartId, Callable> callable) { + public DrilldownPie(String chartId, Callable>> callable) { super(chartId); this.callable = callable; } @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { + public JsonObjectBuilder.JsonObject getChartData() throws Exception { JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); + Map> map = callable.call(); if (map == null || map.isEmpty()) { // Null = skip the chart return null; } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().length == 0) { - // Skip this invalid - continue; + boolean reallyAllSkipped = true; + for (Map.Entry> entryValues : map.entrySet()) { + JsonObjectBuilder valueBuilder = new JsonObjectBuilder(); + boolean allSkipped = true; + for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { + valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue()); + allSkipped = false; + } + if (!allSkipped) { + reallyAllSkipped = false; + valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build()); } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); } - if (allSkipped) { + if (reallyAllSkipped) { // Null = skip the chart return null; } @@ -404,7 +443,7 @@ protected JsonObjectBuilder.JsonObject getChartData() throws Exception { } } - public static class SimpleBarChart extends CustomChart { + public static class AdvancedPie extends CustomChart { private final Callable> callable; @@ -414,7 +453,7 @@ public static class SimpleBarChart extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public SimpleBarChart(String chartId, Callable> callable) { + public AdvancedPie(String chartId, Callable> callable) { super(chartId); this.callable = callable; } @@ -427,8 +466,18 @@ protected JsonObjectBuilder.JsonObject getChartData() throws Exception { // Null = skip the chart return null; } + boolean allSkipped = true; for (Map.Entry entry : map.entrySet()) { - valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()}); + if (entry.getValue() == 0) { + // Skip this invalid + continue; + } + allSkipped = false; + valuesBuilder.appendField(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; } return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); } @@ -474,7 +523,7 @@ protected JsonObjectBuilder.JsonObject getChartData() throws Exception { } } - public static class AdvancedPie extends CustomChart { + public static class SimpleBarChart extends CustomChart { private final Callable> callable; @@ -484,7 +533,7 @@ public static class AdvancedPie extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public AdvancedPie(String chartId, Callable> callable) { + public SimpleBarChart(String chartId, Callable> callable) { super(chartId); this.callable = callable; } @@ -497,18 +546,8 @@ protected JsonObjectBuilder.JsonObject getChartData() throws Exception { // Null = skip the chart return null; } - boolean allSkipped = true; for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; + valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()}); } return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); } @@ -548,9 +587,9 @@ public JsonObjectBuilder.JsonObject getRequestJsonObject( protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception; } - public static class SingleLineChart extends CustomChart { + public static class SimplePie extends CustomChart { - private final Callable callable; + private final Callable callable; /** * Class constructor. @@ -558,15 +597,15 @@ public static class SingleLineChart extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public SingleLineChart(String chartId, Callable callable) { + public SimplePie(String chartId, Callable callable) { super(chartId); this.callable = callable; } @Override protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - int value = callable.call(); - if (value == 0) { + String value = callable.call(); + if (value == null || value.isEmpty()) { // Null = skip the chart return null; } @@ -574,9 +613,9 @@ protected JsonObjectBuilder.JsonObject getChartData() throws Exception { } } - public static class SimplePie extends CustomChart { + public static class AdvancedBarChart extends CustomChart { - private final Callable callable; + private final Callable> callable; /** * Class constructor. @@ -584,25 +623,39 @@ public static class SimplePie extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public SimplePie(String chartId, Callable callable) { + public AdvancedBarChart(String chartId, Callable> callable) { super(chartId); this.callable = callable; } @Override protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - String value = callable.call(); - if (value == null || value.isEmpty()) { + JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { // Null = skip the chart return null; } - return new JsonObjectBuilder().appendField("value", value).build(); + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().length == 0) { + // Skip this invalid + continue; + } + allSkipped = false; + valuesBuilder.appendField(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); } } - public static class DrilldownPie extends CustomChart { + public static class SingleLineChart extends CustomChart { - private final Callable>> callable; + private final Callable callable; /** * Class constructor. @@ -610,37 +663,19 @@ public static class DrilldownPie extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public DrilldownPie(String chartId, Callable>> callable) { + public SingleLineChart(String chartId, Callable callable) { super(chartId); this.callable = callable; } @Override - public JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map> map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean reallyAllSkipped = true; - for (Map.Entry> entryValues : map.entrySet()) { - JsonObjectBuilder valueBuilder = new JsonObjectBuilder(); - boolean allSkipped = true; - for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { - valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue()); - allSkipped = false; - } - if (!allSkipped) { - reallyAllSkipped = false; - valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build()); - } - } - if (reallyAllSkipped) { + protected JsonObjectBuilder.JsonObject getChartData() throws Exception { + int value = callable.call(); + if (value == 0) { // Null = skip the chart return null; } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); + return new JsonObjectBuilder().appendField("value", value).build(); } }