Skip to content

Commit

Permalink
Update to bStats v2 (EssentialsX#4350)
Browse files Browse the repository at this point in the history
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 1, 2021
1 parent 19ca518 commit b288696
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 97 deletions.
5 changes: 4 additions & 1 deletion Essentials/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand All @@ -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'))
Expand All @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,32 @@
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();
Expand All @@ -51,12 +43,12 @@ public void markCommand(final String command, final boolean state) {
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<>();
Expand All @@ -67,7 +59,7 @@ private void addPermsChart() {
}

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();
Expand All @@ -83,23 +75,23 @@ private void addEconomyChart() {
}

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;
}));
}

private void addReleaseBranchChart() {
metrics.addCustomChart(new Metrics.SimplePie("releaseBranch", ess.getUpdateChecker()::getVersionBranch));
metrics.addCustomChart(new SimplePie("releaseBranch", ess.getUpdateChecker()::getVersionBranch));
}

private void addCommandsChart() {
for (final String command : plugin.getDescription().getCommands().keySet()) {
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()) {
Expand All @@ -112,75 +104,4 @@ private void addCommandsChart() {
}));
}

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;
}
}
2 changes: 1 addition & 1 deletion EssentialsXMPP/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
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;
Expand Down Expand Up @@ -56,7 +56,7 @@ public void onEnable() {

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"));
}
}

Expand Down

0 comments on commit b288696

Please # to comment.