From 760e926bec4e8f6799abdf222dc9289ca87e9401 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Sat, 7 Dec 2024 14:33:28 +0100 Subject: [PATCH] Initial commit --- .gitignore | 38 +++++++ .idea/.gitignore | 3 + .idea/encodings.xml | 7 ++ .idea/misc.xml | 14 +++ .idea/vcs.xml | 6 ++ README.md | 31 ++++++ pom.xml | 41 ++++++++ src/main/java/eu/m724/mstats/MStats.java | 125 +++++++++++++++++++++++ 8 files changed, 265 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/eu/m724/mstats/MStats.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7ace097 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..676a2d9 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +### Instructions +In `pom.xml`: +```xml + + eu.m724 + mstats-spigot + +``` + +In `plugin.yml`: +```yaml +libraries: + - eu.m724:mstats-spigot +``` + +In main class: + +```java +import eu.m724.mstats.MStats; +import org.bukkit.plugin.java.JavaPlugin; + +public class MyPlugin extends JavaPlugin { + @Override + public void onEnable() { + // it's recommended that this is the last line of onEnable + + int mStatsId = 1; // replace this of course with your plugin ID + MStats.init(this, mStatsId); + } +} +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..751ac12 --- /dev/null +++ b/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + eu.m724 + mstats-spigot + 0.1.0-SNAPSHOT + + + 21 + 21 + UTF-8 + 1.21.1-R0.1-SNAPSHOT + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + m724-repo + https://git.m724.eu/api/packages/Minecon724/maven + + + + + + org.spigotmc + spigot-api + ${project.spigot.version} + provided + + + + + scm:git:git@git.m724.eu:Minecon724/mstats-spigot.git + + \ No newline at end of file diff --git a/src/main/java/eu/m724/mstats/MStats.java b/src/main/java/eu/m724/mstats/MStats.java new file mode 100644 index 0000000..dd24c71 --- /dev/null +++ b/src/main/java/eu/m724/mstats/MStats.java @@ -0,0 +1,125 @@ +package eu.m724.mstats; + +import com.google.gson.*; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +public class MStats extends BukkitRunnable { + private static final int VERSION = 1; + + private BukkitTask task; + private final Map registeredPlugins = new HashMap<>(); + private final Plugin plugin; + private final Logger logger = Logger.getLogger("mStats"); + private String token = ""; + + private static MStats INSTANCE; + + public MStats(Plugin plugin) { + this.plugin = plugin; + } + + public static void init(Plugin plugin, int id) { + if (INSTANCE != null && INSTANCE.plugin.isEnabled()) { + INSTANCE.registeredPlugins.put(plugin, id); + return; + } + + var mStats = new MStats(plugin); + mStats.registeredPlugins.put(plugin, id); + mStats.init(); + } + + private void init() { + if (INSTANCE != null) { + logger.info("Plugin crashed. Restarting mStats."); + task.cancel(); + // some plugins may have registered before the one that crashed + this.registeredPlugins.putAll(INSTANCE.registeredPlugins); + } + + INSTANCE = this; + + // a scheduler starts running the first tick after everything was loaded + task = new BukkitRunnable() { + @Override + public void run() { + firstRun(); + } + }.runTaskLater(plugin, 0); + + logger.info("mStats running as " + plugin.getName()); + } + + private void firstRun() { + for (Plugin plugin : this.registeredPlugins.keySet()) { + if (!plugin.isEnabled()) { + // remove broken plugins + this.registeredPlugins.remove(plugin); + } + } + + task.cancel(); + task = this.runTaskTimerAsynchronously(plugin, 0, 72000); + } + + // TODO don't send this every time + @Override + public void run() { + var json = new JsonObject(); + var pla = new JsonArray(); + registeredPlugins.forEach((key, value) -> { + var o1 = new JsonObject(); + o1.addProperty("id", value); + o1.addProperty("version", key.getDescription().getVersion()); + pla.add(o1); + }); + + json.add("plugins", pla); + json.addProperty("serverVersion", plugin.getServer().getVersion()); + json.addProperty("statsVersion", VERSION); + + HttpRequest request; + try { + request = HttpRequest + .newBuilder(new URI("http://localhost:8080/api/server/heartbeat")) + .POST(HttpRequest.BodyPublishers.ofString(new Gson().toJson(json))) + .header("X-Server-Token", token) + .build(); + } catch (URISyntaxException e) { throw new RuntimeException(e); } + + try (HttpClient httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NEVER).build()) { + httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(resp -> { + JsonObject response = JsonParser.parseString(resp.body()).getAsJsonObject(); + + if (response.has("message")) { + logger.info("Message from metrics server: " + response.get("message").getAsString()); + } + + if (resp.statusCode() != 200) { + logger.severe("Unable to contact metrics. It's not known why. " + resp.statusCode()); + logger.severe(resp.body()); + return; + } + + if (response.has("token")) { + this.token = response.get("token").getAsString(); + } + + if (response.has("version")) { + // TODO + } + }); + } + } +}