Update to bStats v2 (#4350)

Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
This commit is contained in:
triagonal 2021-09-02 03:33:43 +10:00 committed by GitHub
parent 19ca5186e4
commit b2886969f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 97 deletions

View File

@ -10,6 +10,8 @@ dependencies {
api 'io.papermc:paperlib:1.0.6'
api 'org.bstats:bstats-bukkit:2.2.1'
implementation 'org.spongepowered:configurate-yaml:4.1.2'
implementation 'org.checkerframework:checker-qual:3.14.0'
@ -28,6 +30,7 @@ shadowJar {
dependencies {
include (dependency('io.papermc:paperlib'))
include (dependency('org.bstats:bstats-bukkit'))
include (dependency('org.bstats:bstats-base'))
include (dependency('org.spongepowered:configurate-yaml'))
include (dependency('org.spongepowered:configurate-core'))
include (dependency('org.yaml:snakeyaml'))
@ -39,7 +42,7 @@ shadowJar {
include (project(':providers:1_8Provider'))
}
relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib'
relocate 'org.bstats.bukkit', 'com.earth2me.essentials.metrics'
relocate 'org.bstats', 'com.earth2me.essentials.libs.bstats'
relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate'
relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml'
relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref'

View File

@ -3,40 +3,32 @@ package com.earth2me.essentials.metrics;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.economy.EconomyLayer;
import com.earth2me.essentials.economy.EconomyLayers;
import com.google.common.collect.ImmutableList;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.AdvancedBarChart;
import org.bstats.charts.CustomChart;
import org.bstats.charts.DrilldownPie;
import org.bstats.charts.MultiLineChart;
import org.bstats.charts.SimplePie;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MetricsWrapper {
private static final List<String> KNOWN_FORCED_METRICS = ImmutableList.of(
"ChatControl",
"catserver.server.Metrics");
private static boolean hasWarned = false;
private final Essentials ess;
private final Metrics metrics;
private final JavaPlugin plugin;
private final Map<String, Boolean> commands = new HashMap<>();
private final Plugin plugin;
public MetricsWrapper(final Plugin plugin, final int pluginId, final boolean includeCommands) {
public MetricsWrapper(final JavaPlugin plugin, final int pluginId, final boolean includeCommands) {
this.plugin = plugin;
this.ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials");
this.metrics = new Metrics(plugin, pluginId);
if (metrics.isEnabled()) {
plugin.getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
} else {
plugin.getLogger().info("Metrics disabled per bStats config.");
}
plugin.getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
checkForcedMetrics();
addPermsChart();
addEconomyChart();
addReleaseBranchChart();
@ -51,12 +43,12 @@ public class MetricsWrapper {
commands.put(command, state);
}
public void addCustomChart(final Metrics.CustomChart chart) {
public void addCustomChart(final CustomChart chart) {
metrics.addCustomChart(chart);
}
private void addPermsChart() {
metrics.addCustomChart(new Metrics.DrilldownPie("permsPlugin", () -> {
metrics.addCustomChart(new DrilldownPie("permsPlugin", () -> {
final Map<String, Map<String, Integer>> result = new HashMap<>();
final String handler = ess.getPermissionsHandler().getName();
final Map<String, Integer> backend = new HashMap<>();
@ -67,7 +59,7 @@ public class MetricsWrapper {
}
private void addEconomyChart() {
metrics.addCustomChart(new Metrics.DrilldownPie("econPlugin", () -> {
metrics.addCustomChart(new DrilldownPie("econPlugin", () -> {
final Map<String, Map<String, Integer>> result = new HashMap<>();
final Map<String, Integer> backend = new HashMap<>();
final EconomyLayer layer = EconomyLayers.getSelectedLayer();
@ -83,7 +75,7 @@ public class MetricsWrapper {
}
private void addVersionHistoryChart() {
metrics.addCustomChart(new Metrics.MultiLineChart("versionHistory", () -> {
metrics.addCustomChart(new MultiLineChart("versionHistory", () -> {
final HashMap<String, Integer> result = new HashMap<>();
result.put(plugin.getDescription().getVersion(), 1);
return result;
@ -91,7 +83,7 @@ public class MetricsWrapper {
}
private void addReleaseBranchChart() {
metrics.addCustomChart(new Metrics.SimplePie("releaseBranch", ess.getUpdateChecker()::getVersionBranch));
metrics.addCustomChart(new SimplePie("releaseBranch", ess.getUpdateChecker()::getVersionBranch));
}
private void addCommandsChart() {
@ -99,7 +91,7 @@ public class MetricsWrapper {
markCommand(command, false);
}
metrics.addCustomChart(new Metrics.AdvancedBarChart("commands", () -> {
metrics.addCustomChart(new AdvancedBarChart("commands", () -> {
final Map<String, int[]> result = new HashMap<>();
for (final Map.Entry<String, Boolean> entry : commands.entrySet()) {
if (entry.getValue()) {
@ -112,75 +104,4 @@ public class MetricsWrapper {
}));
}
private boolean isForcedMetricsClass(Class<?> bStatsService) {
for (String identifier : KNOWN_FORCED_METRICS) {
if (bStatsService.getCanonicalName().contains(identifier)) {
return true;
}
}
final JavaPlugin owningPlugin = getProvidingPlugin(bStatsService);
if (owningPlugin != null && KNOWN_FORCED_METRICS.contains(owningPlugin.getName())) {
return true;
}
return false;
}
private void checkForcedMetrics() {
if (hasWarned) return;
hasWarned = true;
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
for (final Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Identifies bStats classes
if (isForcedMetricsClass(service)) {
warnForcedMetrics(service);
} else {
try {
service.getDeclaredField("pluginId"); // Only present in recent bStats classes, which should also have the enabled field unless modified
} catch (final NoSuchFieldException e) {
// Old bStats class found so "enabled" field detection is unreliable.
break;
}
try {
service.getDeclaredField("enabled"); // In some modified forced metrics classes, this will fail
} catch (final NoSuchFieldException e) {
warnForcedMetrics(service);
}
}
} catch (final NoSuchFieldException ignored) {
}
}
});
}
private void warnForcedMetrics(final Class<?> service) {
final Plugin servicePlugin = JavaPlugin.getProvidingPlugin(service);
plugin.getLogger().severe("WARNING: Potential forced metrics collection by plugin '" + servicePlugin.getName() + "' v" + servicePlugin.getDescription().getVersion());
plugin.getLogger().severe("Your server is running a plugin that may not respect bStats' opt-out settings.");
plugin.getLogger().severe("This may cause data to be uploaded to bStats.org for plugins that use bStats, even if you've opted out in the bStats config.");
plugin.getLogger().severe("Please report this to bStats and to the authors of '" + servicePlugin.getName() + "'. (Offending class: " + service.getName() + ")");
}
private JavaPlugin getProvidingPlugin(final Class<?> clazz) {
try {
return JavaPlugin.getProvidingPlugin(clazz);
} catch (final Exception ignored) {
}
final ClassLoader parent = clazz.getClassLoader().getParent();
if (parent.getClass().getName().equals("org.bukkit.plugin.java.PluginClassLoader")) {
try {
final Field pluginField = parent.getClass().getDeclaredField("plugin");
pluginField.setAccessible(true);
return (JavaPlugin) pluginField.get(parent);
} catch (final Exception ignored) {
}
}
return null;
}
}

View File

@ -11,5 +11,5 @@ shadowJar {
dependencies {
include (dependency('org.igniterealtime.smack:smack'))
}
relocate 'org.bstats.bukkit', 'com.earth2me.essentials.metrics'
relocate 'org.bstats', 'com.earth2me.essentials.libs.bstats'
}

View File

@ -3,7 +3,7 @@ package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.IEssentials;
import com.earth2me.essentials.metrics.MetricsWrapper;
import net.ess3.api.IUser;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -56,7 +56,7 @@ public class EssentialsXMPP extends JavaPlugin implements IEssentialsXMPP {
if (metrics == null) {
metrics = new MetricsWrapper(this, 3818, true);
metrics.addCustomChart(new Metrics.SimplePie("config-valid", () -> xmpp.isConfigValid() ? "yes" : "no"));
metrics.addCustomChart(new SimplePie("config-valid", () -> xmpp.isConfigValid() ? "yes" : "no"));
}
}