mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Merge pull request #2107 from WalshyDev/feature/metrics-module
Metrics!
This commit is contained in:
commit
d69ef1effb
@ -24,6 +24,7 @@
|
||||
|
||||
#### Additions
|
||||
* Added "Bone Block -> Bone meal" recipe to the Grind Stone
|
||||
* Added a [Metrics module](https://github.com/Slimefun/MetricsModule) which allows us to deploy changes to metrics (bStats) without another Slimefun build.
|
||||
|
||||
#### Changes
|
||||
* Refactored and reworked the Generator API
|
||||
|
11
pom.xml
11
pom.xml
@ -327,6 +327,17 @@
|
||||
<version>1.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.konghq</groupId>
|
||||
<artifactId>unirest-java</artifactId>
|
||||
<version>3.8.06</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc</groupId>
|
||||
<artifactId>paperlib</artifactId>
|
||||
|
@ -2,17 +2,16 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
|
||||
import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import io.papermc.lib.PaperLib;
|
||||
|
||||
class VersionsCommand extends SubCommand {
|
||||
@ -42,8 +41,11 @@ class VersionsCommand extends SubCommand {
|
||||
sender.sendMessage(ChatColors.color("&aCS-CoreLib &2v" + SlimefunPlugin.getCSCoreLibVersion()));
|
||||
sender.sendMessage(ChatColors.color("&aSlimefun &2v" + SlimefunPlugin.getVersion()));
|
||||
|
||||
if (SlimefunPlugin.getMetricsService().getVersion() != null)
|
||||
sender.sendMessage(ChatColors.color("&aMetrics: &2#" + SlimefunPlugin.getMetricsService().getVersion() + ')'));
|
||||
|
||||
if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) {
|
||||
sender.sendMessage(ChatColor.YELLOW + "Backwards compatiblity enabled!");
|
||||
sender.sendMessage(ChatColor.YELLOW + "Backwards compatibility enabled!");
|
||||
}
|
||||
|
||||
sender.sendMessage("");
|
||||
|
@ -0,0 +1,239 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.JsonNode;
|
||||
import kong.unirest.Unirest;
|
||||
import kong.unirest.UnirestException;
|
||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* This Class represents a Metrics Service that sends data to https://bstats.org/
|
||||
* This data is used to analyse the usage of this {@link Plugin}.
|
||||
* <p>
|
||||
* You can find more info in the README file of this Project on GitHub. <br>
|
||||
* <b>Note:</b> To start the metrics you will need to be calling {@link #start()}
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
* @author WalshyDev
|
||||
*/
|
||||
public class MetricsService {
|
||||
|
||||
private static final String REPO_NAME = "MetricsModule";
|
||||
private static final String GH_API = "https://api.github.com/repos/Slimefun/" + REPO_NAME;
|
||||
private static final String GH_REPO_RELEASES = "https://github.com/Slimefun/" + REPO_NAME
|
||||
+ "/releases/download";
|
||||
|
||||
private final SlimefunPlugin plugin;
|
||||
private final File parentFolder;
|
||||
private final File metricFile;
|
||||
|
||||
private URLClassLoader moduleClassLoader;
|
||||
private String metricVersion = null;
|
||||
private boolean newlyDownloaded = false;
|
||||
|
||||
static {
|
||||
Unirest.config()
|
||||
.concurrency(2, 1)
|
||||
.setDefaultHeader("User-Agent", "MetricsModule Auto-Updater")
|
||||
.setDefaultHeader("Accept", "application/vnd.github.v3+json")
|
||||
.enableCookieManagement(false)
|
||||
.cookieSpec("ignoreCookies");
|
||||
}
|
||||
|
||||
public MetricsService(SlimefunPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
this.parentFolder = new File(plugin.getDataFolder(), "cache" + File.separatorChar + "modules");
|
||||
if (!parentFolder.exists())
|
||||
parentFolder.mkdirs();
|
||||
|
||||
this.metricFile = new File(parentFolder, REPO_NAME + ".jar");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method loads the metric module and starts the metrics collection.
|
||||
*/
|
||||
public void start() {
|
||||
if (!metricFile.exists()) {
|
||||
plugin.getLogger().info(REPO_NAME + " does not exist, downloading...");
|
||||
if (!download(getLatestVersion())) {
|
||||
plugin.getLogger().warning("Failed to start metrics as the file could not be downloaded.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Load the jar file into a child class loader using the SF PluginClassLoader
|
||||
// as a parent.
|
||||
moduleClassLoader = URLClassLoader.newInstance(new URL[] { metricFile.toURI().toURL() },
|
||||
plugin.getClass().getClassLoader());
|
||||
Class<?> cl = moduleClassLoader.loadClass("dev.walshy.sfmetrics.MetricsModule");
|
||||
|
||||
metricVersion = cl.getPackage().getImplementationVersion();
|
||||
|
||||
// If it has not been newly downloaded, auto-updates are on AND there's a new version
|
||||
// then cleanup, download and start
|
||||
if (!newlyDownloaded
|
||||
&& hasAutoUpdates()
|
||||
&& checkForUpdate(metricVersion)
|
||||
) {
|
||||
plugin.getLogger().info("Cleaning up and re-loading Metrics.");
|
||||
cleanUp();
|
||||
start();
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, we're good to start this.
|
||||
Method start = cl.getDeclaredMethod("start");
|
||||
String version = cl.getPackage().getImplementationVersion();
|
||||
|
||||
// This is required to be sync due to bStats.
|
||||
Slimefun.runSync(() -> {
|
||||
try {
|
||||
start.invoke(null);
|
||||
plugin.getLogger().info("Metrics build #" + version + " started.");
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to start metrics.", e);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.WARNING,
|
||||
"Failed to load the metrics module. Maybe the jar is corrupt?", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will close the child classloader and mark all the resources held under this no longer
|
||||
* in use, they will be cleaned up the next GC run.
|
||||
*/
|
||||
public void cleanUp() {
|
||||
try {
|
||||
if (this.moduleClassLoader != null)
|
||||
this.moduleClassLoader.close();
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().log(Level.WARNING,
|
||||
"Could not clean up module class loader. Some memory may have been leaked.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a new update and compares it against the current version.
|
||||
* If there is a new version available then this returns true.
|
||||
*
|
||||
* @param currentVersion The current version which is being used.
|
||||
* @return True if there is an update available.
|
||||
*/
|
||||
public boolean checkForUpdate(String currentVersion) {
|
||||
if (currentVersion == null || !PatternUtils.NUMERIC.matcher(currentVersion).matches()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int latest = getLatestVersion();
|
||||
if (latest > Integer.parseInt(currentVersion)) {
|
||||
return download(latest);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the latest version available as an int.
|
||||
* This is an internal method used by {@link #checkForUpdate(String)}.
|
||||
* If it cannot get the version for whatever reason this will return 0, effectively always
|
||||
* being behind.
|
||||
*
|
||||
* @return The latest version as an integer or -1 if it failed to fetch.
|
||||
*/
|
||||
private int getLatestVersion() {
|
||||
try {
|
||||
HttpResponse<JsonNode> response = Unirest.get(GH_API + "/releases/latest")
|
||||
.asJson();
|
||||
if (!response.isSuccess()) return -1;
|
||||
|
||||
JsonNode node = response.getBody();
|
||||
|
||||
if (node == null) return -1;
|
||||
|
||||
return node.getObject().getInt("tag_name");
|
||||
} catch (UnirestException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to fetch latest builds for SFMetrics");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the version specified to Slimefun's data folder.
|
||||
*
|
||||
* @param version The version to download.
|
||||
*/
|
||||
private boolean download(int version) {
|
||||
File f = new File(parentFolder, "Metrics-" + version + ".jar");
|
||||
|
||||
try {
|
||||
plugin.getLogger().info("# Starting download of MetricsModule build: #" + version);
|
||||
AtomicInteger lastPercentPosted = new AtomicInteger();
|
||||
HttpResponse<File> response = Unirest.get(GH_REPO_RELEASES + "/" + version
|
||||
+ "/" + REPO_NAME + ".jar")
|
||||
.downloadMonitor((b, fileName, bytesWritten, totalBytes) -> {
|
||||
int percent = (int) (20 * (Math.round((((double) bytesWritten / totalBytes) * 100) / 20)));
|
||||
|
||||
if (percent != 0 && percent != lastPercentPosted.get()) {
|
||||
plugin.getLogger().info("# Downloading... " + percent + "% " +
|
||||
"(" + bytesWritten + "/" + totalBytes + " bytes)");
|
||||
lastPercentPosted.set(percent);
|
||||
}
|
||||
})
|
||||
.asFile(f.getPath());
|
||||
if (response.isSuccess()) {
|
||||
plugin.getLogger().info("Successfully downloaded " + REPO_NAME + " build: " + version);
|
||||
|
||||
// Replace the metric file with the new one
|
||||
Files.move(f.toPath(), metricFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
metricVersion = String.valueOf(version);
|
||||
newlyDownloaded = true;
|
||||
return true;
|
||||
}
|
||||
} catch (UnirestException e) {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to fetch the latest jar file from the" +
|
||||
" builds page. Perhaps GitHub is down.");
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to replace the old metric file with the " +
|
||||
"new one. Please do this manually! Error: {0}", e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently downloaded metric version. This CAN change! It may be null or an
|
||||
* older version before it has downloaded a newer one.
|
||||
*
|
||||
* @return The current version or null if not loaded.
|
||||
*/
|
||||
@Nullable
|
||||
public String getVersion() {
|
||||
return metricVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the current server has metric auto-updates enabled.
|
||||
*
|
||||
* @return True if the current server has metric auto-updates enabled.
|
||||
*/
|
||||
public boolean hasAutoUpdates() {
|
||||
return SlimefunPlugin.instance().getConfig().getBoolean("metrics.auto-update");
|
||||
}
|
||||
}
|
@ -10,6 +10,9 @@ import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import kong.unirest.JsonNode;
|
||||
import kong.unirest.json.JSONArray;
|
||||
import kong.unirest.json.JSONObject;
|
||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
|
||||
class ContributionsConnector extends GitHubConnector {
|
||||
@ -57,10 +60,10 @@ class ContributionsConnector extends GitHubConnector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(JsonElement element) {
|
||||
public void onSuccess(JsonNode element) {
|
||||
finished = true;
|
||||
if (element.isJsonArray()) {
|
||||
computeContributors(element.getAsJsonArray());
|
||||
if (element.isArray()) {
|
||||
computeContributors(element.getArray());
|
||||
}
|
||||
else {
|
||||
Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", element);
|
||||
@ -82,13 +85,13 @@ class ContributionsConnector extends GitHubConnector {
|
||||
return "/contributors?per_page=100&page=" + page;
|
||||
}
|
||||
|
||||
private void computeContributors(JsonArray array) {
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
JsonObject object = array.get(i).getAsJsonObject();
|
||||
private void computeContributors(JSONArray array) {
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject object = array.getJSONObject(i);
|
||||
|
||||
String name = object.get("login").getAsString();
|
||||
int commits = object.get("contributions").getAsInt();
|
||||
String profile = object.get("html_url").getAsString();
|
||||
String name = object.getString("login");
|
||||
int commits = object.getInt("contributions");
|
||||
String profile = object.getString("html_url");
|
||||
|
||||
if (!blacklist.contains(name)) {
|
||||
github.addContributor(aliases.getOrDefault(name, name), profile, role, commits);
|
||||
|
@ -4,19 +4,18 @@ import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.JsonNode;
|
||||
import kong.unirest.Unirest;
|
||||
import kong.unirest.UnirestException;
|
||||
import kong.unirest.json.JSONException;
|
||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
|
||||
abstract class GitHubConnector {
|
||||
@ -34,7 +33,7 @@ abstract class GitHubConnector {
|
||||
|
||||
public abstract String getURLSuffix();
|
||||
|
||||
public abstract void onSuccess(JsonElement element);
|
||||
public abstract void onSuccess(JsonNode element);
|
||||
|
||||
public void onFailure() {
|
||||
// Don't do anything by default
|
||||
@ -48,58 +47,51 @@ abstract class GitHubConnector {
|
||||
}
|
||||
|
||||
try {
|
||||
URL website = new URL("https://api.github.com/repos/" + repository + getURLSuffix());
|
||||
HttpResponse<JsonNode> resp = Unirest
|
||||
.get("https://api.github.com/repos/" + repository + getURLSuffix())
|
||||
.header("User-Agent", "Slimefun4 (https://github.com/Slimefun)")
|
||||
.asJson();
|
||||
|
||||
URLConnection connection = website.openConnection();
|
||||
connection.setConnectTimeout(8000);
|
||||
connection.addRequestProperty("Accept-Charset", "UTF-8");
|
||||
connection.addRequestProperty("User-Agent", "Slimefun 4 GitHub Agent (by TheBusyBiscuit)");
|
||||
connection.setDoOutput(true);
|
||||
|
||||
try (ReadableByteChannel channel = Channels.newChannel(connection.getInputStream())) {
|
||||
try (FileOutputStream stream = new FileOutputStream(file)) {
|
||||
stream.getChannel().transferFrom(channel, 0, Long.MAX_VALUE);
|
||||
parseData();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (resp.isSuccess()) {
|
||||
onSuccess(resp.getBody());
|
||||
writeCacheFile(resp.getBody());
|
||||
} else
|
||||
Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}",
|
||||
repository + getURLSuffix());
|
||||
} catch (UnirestException e) {
|
||||
if (github.isLoggingEnabled()) {
|
||||
Slimefun.getLogger().log(Level.WARNING, "Could not connect to GitHub in time.");
|
||||
}
|
||||
|
||||
if (hasData()) {
|
||||
parseData();
|
||||
}
|
||||
else {
|
||||
onFailure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasData() {
|
||||
return getFile().exists();
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void parseData() {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(getFile()), StandardCharsets.UTF_8))) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
// It has the cached file, let's just read that then
|
||||
if (file.exists()) {
|
||||
JsonNode cache = readCacheFile();
|
||||
if (cache != null) {
|
||||
onSuccess(cache);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JsonElement element = new JsonParser().parse(builder.toString());
|
||||
onSuccess(element);
|
||||
}
|
||||
catch (IOException x) {
|
||||
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while parsing GitHub-Data for Slimefun " + SlimefunPlugin.getVersion());
|
||||
// If the request failed and it failed to read the cache then call onFailure.
|
||||
onFailure();
|
||||
}
|
||||
}
|
||||
|
||||
private JsonNode readCacheFile() {
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
|
||||
return new JsonNode(br.readLine());
|
||||
} catch (IOException | JSONException e) {
|
||||
Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0}",
|
||||
file.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeCacheFile(JsonNode node) {
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
fos.write(node.toString().getBytes(StandardCharsets.UTF_8));
|
||||
} catch (IOException e) {
|
||||
Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import kong.unirest.JsonNode;
|
||||
import kong.unirest.json.JSONArray;
|
||||
import kong.unirest.json.JSONElement;
|
||||
import kong.unirest.json.JSONObject;
|
||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
|
||||
class GitHubIssuesTracker extends GitHubConnector {
|
||||
@ -25,15 +29,15 @@ class GitHubIssuesTracker extends GitHubConnector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(JsonElement element) {
|
||||
if (element.isJsonArray()) {
|
||||
JsonArray array = element.getAsJsonArray();
|
||||
public void onSuccess(JsonNode element) {
|
||||
if (element.isArray()) {
|
||||
JSONArray array = element.getArray();
|
||||
|
||||
int issues = 0;
|
||||
int pullRequests = 0;
|
||||
|
||||
for (JsonElement elem : array) {
|
||||
JsonObject obj = elem.getAsJsonObject();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject obj = array.getJSONObject(i);
|
||||
|
||||
if (obj.has("pull_request")) {
|
||||
pullRequests++;
|
||||
|
@ -17,6 +17,8 @@ import io.github.thebusybiscuit.slimefun4.core.services.localization.Translators
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
||||
import kong.unirest.JsonNode;
|
||||
import kong.unirest.json.JSONObject;
|
||||
|
||||
/**
|
||||
* This Service is responsible for grabbing every {@link Contributor} to this project
|
||||
@ -108,11 +110,11 @@ public class GitHubService {
|
||||
connectors.add(new GitHubConnector(this, repository) {
|
||||
|
||||
@Override
|
||||
public void onSuccess(JsonElement element) {
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
forks = object.get("forks").getAsInt();
|
||||
stars = object.get("stargazers_count").getAsInt();
|
||||
lastUpdate = NumberUtils.parseGitHubDate(object.get("pushed_at").getAsString());
|
||||
public void onSuccess(JsonNode element) {
|
||||
JSONObject object = element.getObject();
|
||||
forks = object.getInt("forks");
|
||||
stars = object.getInt("stargazers_count");
|
||||
lastUpdate = NumberUtils.parseGitHubDate(object.getString("pushed_at"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,27 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bstats.bukkit.Metrics.AdvancedPie;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class AddonsChart extends AdvancedPie {
|
||||
|
||||
AddonsChart() {
|
||||
super("installed_addons", () -> {
|
||||
Map<String, Integer> addons = new HashMap<>();
|
||||
|
||||
for (Plugin plugin : SlimefunPlugin.getInstalledAddons()) {
|
||||
if (plugin.isEnabled()) {
|
||||
addons.put(plugin.getName(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
return addons;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics.SimplePie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class AutoUpdaterChart extends SimplePie {
|
||||
|
||||
AutoUpdaterChart() {
|
||||
super("auto_updates", () -> {
|
||||
boolean enabled = SlimefunPlugin.getUpdater().isEnabled();
|
||||
return enabled ? "enabled" : "disabled";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bstats.bukkit.Metrics.AdvancedPie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class CommandChart extends AdvancedPie {
|
||||
|
||||
CommandChart() {
|
||||
super("commands_ran", () -> {
|
||||
Map<String, Integer> commands = new HashMap<>();
|
||||
|
||||
for (Map.Entry<SubCommand, Integer> entry : SlimefunPlugin.getCommand().getCommandUsage().entrySet()) {
|
||||
commands.put("/sf " + entry.getKey().getName(), entry.getValue());
|
||||
}
|
||||
|
||||
return commands;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics.SimplePie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class CompatibilityModeChart extends SimplePie {
|
||||
|
||||
CompatibilityModeChart() {
|
||||
super("compatibility_mode", () -> {
|
||||
boolean enabled = SlimefunPlugin.getRegistry().isBackwardsCompatible();
|
||||
return enabled ? "enabled" : "disabled";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics.SimplePie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class GuideLayoutChart extends SimplePie {
|
||||
|
||||
GuideLayoutChart() {
|
||||
super("guide_layout", () -> {
|
||||
boolean book = SlimefunPlugin.getCfg().getBoolean("guide.default-view-book");
|
||||
|
||||
return book ? "Book" : "Chest GUI";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
/**
|
||||
* This Class represents a Metrics Service that sends data to https://bstats.org/
|
||||
* This data is used to analyse the usage of this {@link Plugin}.
|
||||
*
|
||||
* You can find more info in the README file of this Project on GitHub.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
*/
|
||||
public class MetricsService {
|
||||
|
||||
private final SlimefunPlugin plugin;
|
||||
|
||||
/**
|
||||
* This creates a new {@link MetricsService}. The constructor does not set up
|
||||
* anything related to bStats yet, that happens in the {@link MetricsService#start()} method.
|
||||
*
|
||||
* @param plugin
|
||||
* The instance of our {@link SlimefunPlugin}
|
||||
*/
|
||||
public MetricsService(SlimefunPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method intializes and starts the metrics collection.
|
||||
*/
|
||||
public void start() {
|
||||
Metrics metrics = new Metrics(plugin, 4574);
|
||||
|
||||
if (SlimefunPlugin.getUpdater().getBranch().isOfficial()) {
|
||||
// We really do not need this data if it is an unofficially modified build...
|
||||
metrics.addCustomChart(new AutoUpdaterChart());
|
||||
}
|
||||
|
||||
metrics.addCustomChart(new ResourcePackChart());
|
||||
metrics.addCustomChart(new SlimefunVersionChart());
|
||||
metrics.addCustomChart(new ServerLanguageChart());
|
||||
metrics.addCustomChart(new PlayerLanguageChart());
|
||||
metrics.addCustomChart(new ResearchesEnabledChart());
|
||||
metrics.addCustomChart(new GuideLayoutChart());
|
||||
metrics.addCustomChart(new AddonsChart());
|
||||
metrics.addCustomChart(new CommandChart());
|
||||
metrics.addCustomChart(new ServerSizeChart());
|
||||
metrics.addCustomChart(new CompatibilityModeChart());
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bstats.bukkit.Metrics.AdvancedPie;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class PlayerLanguageChart extends AdvancedPie {
|
||||
|
||||
PlayerLanguageChart() {
|
||||
super("player_languages", () -> {
|
||||
Map<String, Integer> languages = new HashMap<>();
|
||||
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
Language language = SlimefunPlugin.getLocalization().getLanguage(p);
|
||||
boolean supported = SlimefunPlugin.getLocalization().isLanguageLoaded(language.getId());
|
||||
|
||||
String lang = supported ? language.getId() : "Unsupported Language";
|
||||
languages.merge(lang, 1, Integer::sum);
|
||||
}
|
||||
|
||||
return languages;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics.SimplePie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class ResearchesEnabledChart extends SimplePie {
|
||||
|
||||
ResearchesEnabledChart() {
|
||||
super("servers_with_researches_enabled", () -> {
|
||||
boolean enabled = SlimefunPlugin.getRegistry().isFreeCreativeResearchingEnabled();
|
||||
return enabled ? "enabled" : "disabled";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics.SimplePie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class ResourcePackChart extends SimplePie {
|
||||
|
||||
ResourcePackChart() {
|
||||
super("resourcepack", () -> {
|
||||
String version = SlimefunPlugin.getItemTextureService().getVersion();
|
||||
|
||||
if (version != null && version.startsWith("v")) {
|
||||
return version + " (Official)";
|
||||
}
|
||||
else if (SlimefunPlugin.getItemTextureService().isActive()) {
|
||||
return "Custom / Modified";
|
||||
}
|
||||
else {
|
||||
return "None";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics.SimplePie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class ServerLanguageChart extends SimplePie {
|
||||
|
||||
ServerLanguageChart() {
|
||||
super("language", () -> {
|
||||
Language language = SlimefunPlugin.getLocalization().getDefaultLanguage();
|
||||
boolean supported = SlimefunPlugin.getLocalization().isLanguageLoaded(language.getId());
|
||||
return supported ? language.getId() : "Unsupported Language";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import org.bstats.bukkit.Metrics.SimplePie;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
class ServerSizeChart extends SimplePie {
|
||||
|
||||
ServerSizeChart() {
|
||||
super("server_size", () -> {
|
||||
int players = Bukkit.getOnlinePlayers().size();
|
||||
|
||||
if (players < 10) {
|
||||
return "0-10";
|
||||
}
|
||||
|
||||
if (players < 25) {
|
||||
return "10-25";
|
||||
}
|
||||
|
||||
if (players < 50) {
|
||||
return "25-50";
|
||||
}
|
||||
|
||||
if (players < 100) {
|
||||
return "50-100";
|
||||
}
|
||||
|
||||
if (players < 200) {
|
||||
return "100-200";
|
||||
}
|
||||
|
||||
if (players < 300) {
|
||||
return "200-300";
|
||||
}
|
||||
|
||||
return "300+";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bstats.bukkit.Metrics.DrilldownPie;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class SlimefunVersionChart extends DrilldownPie {
|
||||
|
||||
SlimefunVersionChart() {
|
||||
super("slimefun_version", () -> {
|
||||
Map<String, Map<String, Integer>> outerMap = new HashMap<>();
|
||||
Map<String, Integer> innerMap = new HashMap<>();
|
||||
|
||||
innerMap.put(SlimefunPlugin.getVersion(), 1);
|
||||
outerMap.put(SlimefunPlugin.getUpdater().getBranch().getName(), innerMap);
|
||||
|
||||
return outerMap;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
/**
|
||||
* This package contains everything related to bStats Metrics
|
||||
*/
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.metrics;
|
@ -41,7 +41,7 @@ import io.github.thebusybiscuit.slimefun4.core.services.PerWorldSettingsService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.PermissionsService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.UpdaterService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.metrics.MetricsService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.MetricsService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService;
|
||||
import io.github.thebusybiscuit.slimefun4.core.services.profiler.SlimefunProfiler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
|
||||
@ -196,7 +196,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
||||
networkManager = new NetworkManager(networkSize);
|
||||
|
||||
// Setting up bStats
|
||||
metricsService.start();
|
||||
new Thread(metricsService::start).start();
|
||||
|
||||
// Starting the Auto-Updater
|
||||
if (config.getBoolean("options.auto-update")) {
|
||||
@ -367,6 +367,8 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
||||
// Create a new backup zip
|
||||
backupService.run();
|
||||
|
||||
metricsService.cleanUp();
|
||||
|
||||
// Prevent Memory Leaks
|
||||
// These static Maps should be removed at some point...
|
||||
AContainer.processing = null;
|
||||
@ -564,6 +566,16 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
||||
return instance.updaterService;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the {@link MetricsService} of Slimefun.
|
||||
* It is used to handle sending metric information to bStats.
|
||||
*
|
||||
* @return The {@link MetricsService} for Slimefun
|
||||
*/
|
||||
public static MetricsService getMetricsService() {
|
||||
return instance.metricsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the {@link GitHubService} of Slimefun.
|
||||
* It is used to retrieve data from GitHub repositories.
|
||||
|
@ -6,7 +6,7 @@ options:
|
||||
|
||||
auto-update: true
|
||||
backwards-compatibility: true
|
||||
chat-prefix: '&a&lSlimefun 4 &7>'
|
||||
chat-prefix: '&a&lSlimefun 4&7> '
|
||||
armor-update-interval: 10
|
||||
enable-armor-effects: true
|
||||
auto-save-delay-in-minutes: 10
|
||||
@ -40,6 +40,9 @@ items:
|
||||
backpacks: true
|
||||
soulbound: true
|
||||
|
||||
metrics:
|
||||
auto-update: true
|
||||
|
||||
research-ranks:
|
||||
- Chicken
|
||||
- Cow
|
||||
|
Loading…
Reference in New Issue
Block a user