From 0f5f77127b7da831ef2434e015564aa823df3bbe Mon Sep 17 00:00:00 2001 From: Sotr Date: Fri, 25 May 2018 21:42:27 +0800 Subject: [PATCH] Connect bStats --- .../akarin/server/core/MetricsBootstrap.java | 52 ++++++++++++ .../server/mixin/core/MixinMetrics.java | 82 +++++++++++++++++++ .../server/mixin/core/MixinPaperConfig.java | 31 +++++++ .../main/resources/mixins.akarin.core.json | 2 + work/Paper | 2 +- 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 sources/src/main/java/io/akarin/server/core/MetricsBootstrap.java create mode 100644 sources/src/main/java/io/akarin/server/mixin/core/MixinMetrics.java create mode 100644 sources/src/main/java/io/akarin/server/mixin/core/MixinPaperConfig.java diff --git a/sources/src/main/java/io/akarin/server/core/MetricsBootstrap.java b/sources/src/main/java/io/akarin/server/core/MetricsBootstrap.java new file mode 100644 index 000000000..ac3a3d82b --- /dev/null +++ b/sources/src/main/java/io/akarin/server/core/MetricsBootstrap.java @@ -0,0 +1,52 @@ +package io.akarin.server.core; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; + +import com.destroystokyo.paper.Metrics; + +import net.minecraft.server.MinecraftServer; + +public abstract class MetricsBootstrap { + // Dragged from 'PaperMetrics' cause it's a private subclass, this will be called from mixined 'PaperConfig' class + public static void startMetrics() { + // Get the config file + File configFile = new File(new File((File) MinecraftServer.getServer().options.valueOf("plugins"), "bStats"), "config.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + + // Check if the config file exists + if (!config.isSet("serverUuid")) { + + // Add default values + config.addDefault("enabled", true); + // Every server gets it's unique random id. + config.addDefault("serverUuid", UUID.randomUUID().toString()); + // Should failed request be logged? + config.addDefault("logFailedRequests", false); + + // Inform the server owners about bStats + config.options().header( + "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + + "To honor their work, you should not disable it.\n" + + "This has nearly no effect on the server performance!\n" + + "Check out https://bStats.org/ to learn more :)" + ).copyDefaults(true); + try { + config.save(configFile); + } catch (IOException ignored) { + ; + } + } + // Load the data + String serverUUID = config.getString("serverUuid"); + boolean logFailedRequests = config.getBoolean("logFailedRequests", false); + // Only start Metrics, if it's enabled in the config + if (config.getBoolean("enabled", true)) { + new Metrics("Akarin", serverUUID, logFailedRequests, Bukkit.getLogger()); // Paper -> Akarin + } + } +} diff --git a/sources/src/main/java/io/akarin/server/mixin/core/MixinMetrics.java b/sources/src/main/java/io/akarin/server/mixin/core/MixinMetrics.java new file mode 100644 index 000000000..cc8f2780f --- /dev/null +++ b/sources/src/main/java/io/akarin/server/mixin/core/MixinMetrics.java @@ -0,0 +1,82 @@ +package io.akarin.server.mixin.core; + +import java.util.List; + +import org.bukkit.Bukkit; +import io.akarin.api.LogWrapper; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import com.destroystokyo.paper.Metrics; +import com.destroystokyo.paper.Metrics.CustomChart; + +@Mixin(value = Metrics.class, remap = false) +public class MixinMetrics { + // The url to which the data is sent - bukkit/Torch (keep our old name) + @Shadow @Mutable @Final public static String URL = "https://bStats.org/submitData/bukkit"; + + // The name of the server software + @Shadow @Final private String name; + + // A list with all custom charts + @Shadow @Final private List charts; + + /** + * Injects the plugin specific data - insert version + * + * @return The plugin specific data. + */ + @Overwrite + private JSONObject getPluginData() { + JSONObject data = new JSONObject(); + + data.put("pluginName", name); // Append the name of the server software + data.put("pluginVersion", Metrics.class.getPackage().getImplementationVersion() != null ? Metrics.class.getPackage().getImplementationVersion() : "unknown"); // Akarin + JSONArray customCharts = new JSONArray(); + data.put("customCharts", customCharts); + + return data; + } + + // The uuid of the server + @Shadow @Final private String serverUUID; + + /** + * Gets the server specific data - insert minecraft data + * + * @return The server specific data. + */ + @Overwrite + private JSONObject getServerData() { + // Minecraft specific data + int playerAmount = Bukkit.getOnlinePlayers().size(); + int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; + String bukkitVersion = org.bukkit.Bukkit.getVersion(); + bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1); + LogWrapper.logger.warn("Akarin debug: " + URL); + + JSONObject data = new JSONObject(); + data.put("playerAmount", playerAmount); + data.put("onlineMode", onlineMode); + data.put("bukkitVersion", bukkitVersion); + + // OS specific data + String osName = System.getProperty("os.name"); + String osArch = System.getProperty("os.arch"); + String osVersion = System.getProperty("os.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + data.put("serverUUID", serverUUID); + + data.put("osName", osName); + data.put("osArch", osArch); + data.put("osVersion", osVersion); + data.put("coreCount", coreCount); + + return data; + } +} diff --git a/sources/src/main/java/io/akarin/server/mixin/core/MixinPaperConfig.java b/sources/src/main/java/io/akarin/server/mixin/core/MixinPaperConfig.java new file mode 100644 index 000000000..7e9e8fed3 --- /dev/null +++ b/sources/src/main/java/io/akarin/server/mixin/core/MixinPaperConfig.java @@ -0,0 +1,31 @@ +package io.akarin.server.mixin.core; + +import java.util.Map; + +import org.bukkit.command.Command; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import com.destroystokyo.paper.PaperConfig; + +import io.akarin.server.core.MetricsBootstrap; +import net.minecraft.server.MinecraftServer; + +@Mixin(value = PaperConfig.class, remap = false) +public class MixinPaperConfig { + @Shadow static Map commands; + @Shadow private static boolean metricsStarted; + + @Overwrite + public static void registerCommands() { + for (Map.Entry entry : commands.entrySet()) { + MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Paper", entry.getValue()); + } + + if (!metricsStarted) { + MetricsBootstrap.startMetrics(); + metricsStarted = true; + } + } +} diff --git a/sources/src/main/resources/mixins.akarin.core.json b/sources/src/main/resources/mixins.akarin.core.json index f0a1d5d7d..3a1b9e5c8 100644 --- a/sources/src/main/resources/mixins.akarin.core.json +++ b/sources/src/main/resources/mixins.akarin.core.json @@ -9,6 +9,8 @@ "DummyEula", "Watchcat", + "MixinMetrics", + "MixinPaperConfig", "MixinVersionCommand", "MixinMinecraftServer" ] diff --git a/work/Paper b/work/Paper index e3924e565..caedc8f27 160000 --- a/work/Paper +++ b/work/Paper @@ -1 +1 @@ -Subproject commit e3924e56583d52cc4cd2cdef90c05d96ebf30e7c +Subproject commit caedc8f27880512b2df9f7032cfbb4a5059cefb1