From 41bb27cf6b3785d1a56ead0de90aec3f9f03e303 Mon Sep 17 00:00:00 2001 From: PiggyPiglet Date: Sat, 14 Feb 2026 20:37:36 +0800 Subject: [PATCH] Add metrics --- .../placeholderapi/PlaceholderAPIPlugin.java | 14 ++++ .../configuration/ConfigManager.java | 10 +++ .../configuration/PlaceholderAPIConfig.java | 39 +++++------ .../metrics/MetricsManager.java | 67 +++++++++++++++++++ .../metrics/MetricsPayload.java | 34 ++++++++++ src/main/resources/config.yml | 1 + 6 files changed, 146 insertions(+), 19 deletions(-) create mode 100644 src/main/java/at/helpch/placeholderapi/metrics/MetricsManager.java create mode 100644 src/main/java/at/helpch/placeholderapi/metrics/MetricsPayload.java diff --git a/src/main/java/at/helpch/placeholderapi/PlaceholderAPIPlugin.java b/src/main/java/at/helpch/placeholderapi/PlaceholderAPIPlugin.java index e3adebd..5eafccb 100644 --- a/src/main/java/at/helpch/placeholderapi/PlaceholderAPIPlugin.java +++ b/src/main/java/at/helpch/placeholderapi/PlaceholderAPIPlugin.java @@ -4,8 +4,10 @@ import at.helpch.placeholderapi.commands.PlaceholderCommandRouter; import at.helpch.placeholderapi.configuration.ConfigManager; import at.helpch.placeholderapi.expansion.manager.CloudExpansionManager; import at.helpch.placeholderapi.expansion.manager.LocalExpansionManager; +import at.helpch.placeholderapi.metrics.MetricsManager; import at.helpch.placeholderapi.updatechecker.UpdateChecker; import com.hypixel.hytale.event.EventPriority; +import com.hypixel.hytale.server.core.HytaleServer; import com.hypixel.hytale.server.core.command.system.CommandSender; import com.hypixel.hytale.server.core.console.ConsoleSender; import com.hypixel.hytale.server.core.event.events.BootEvent; @@ -13,8 +15,12 @@ import com.hypixel.hytale.server.core.event.events.PrepareUniverseEvent; import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent; import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPluginInit; +import com.hypixel.hytale.server.core.task.TaskRegistration; import org.jetbrains.annotations.NotNull; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + public class PlaceholderAPIPlugin extends JavaPlugin { private final ConfigManager configManager = new ConfigManager(this); private final LocalExpansionManager localExpansionManager = new LocalExpansionManager(this); @@ -36,6 +42,14 @@ public class PlaceholderAPIPlugin extends JavaPlugin { protected void setup() { configManager.setup(); + if (configManager.config().metrics()) { + final MetricsManager metricsManager = new MetricsManager(this); + final ScheduledFuture task = (ScheduledFuture) HytaleServer.SCHEDULED_EXECUTOR.scheduleAtFixedRate(() -> { + metricsManager.send(); + }, 30, 30, TimeUnit.SECONDS); + getTaskRegistry().registerTask(task); + } + getEventRegistry().register(PlayerDisconnectEvent.class, localExpansionManager::onQuit); getEventRegistry().register(EventPriority.LAST, BootEvent.class, this::onServerLoad); diff --git a/src/main/java/at/helpch/placeholderapi/configuration/ConfigManager.java b/src/main/java/at/helpch/placeholderapi/configuration/ConfigManager.java index ff5f433..907ea1b 100644 --- a/src/main/java/at/helpch/placeholderapi/configuration/ConfigManager.java +++ b/src/main/java/at/helpch/placeholderapi/configuration/ConfigManager.java @@ -21,6 +21,7 @@ import java.nio.file.*; import java.util.Arrays; import java.util.Map; import java.util.Optional; +import java.util.UUID; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -66,6 +67,15 @@ public final class ConfigManager { final Map data = YAML.load(content); config = GSON.fromJson(GSON.toJsonTree(data), PlaceholderAPIConfig.class); + + if (config.metricsUuid() == null && config.metrics() == null) { + config.metricsUuid(UUID.randomUUID()); + config.metrics(true); + save(); + } else if (config.metricsUuid() == null && config.metrics()) { + config.metricsUuid(UUID.randomUUID()); + save(); + } } public PlaceholderAPIConfig config() { diff --git a/src/main/java/at/helpch/placeholderapi/configuration/PlaceholderAPIConfig.java b/src/main/java/at/helpch/placeholderapi/configuration/PlaceholderAPIConfig.java index 6f61085..a0b2125 100644 --- a/src/main/java/at/helpch/placeholderapi/configuration/PlaceholderAPIConfig.java +++ b/src/main/java/at/helpch/placeholderapi/configuration/PlaceholderAPIConfig.java @@ -24,36 +24,21 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; +import java.util.UUID; public final class PlaceholderAPIConfig { private boolean checkUpdates; private boolean cloudEnabled; private boolean debugMode; + private Boolean metrics; private ExpansionSort cloudSorting; private BooleanValue booleanValue; private String dateFormat; private Map expansions; + private UUID metricsUuid; - public PlaceholderAPIConfig(boolean checkUpdates, boolean cloudEnabled, boolean debugMode, @NotNull ExpansionSort cloudSorting, - @NotNull BooleanValue booleanValue, @NotNull String dateFormat) { - this.checkUpdates = checkUpdates; - this.cloudEnabled = cloudEnabled; - this.debugMode = debugMode; - this.cloudSorting = cloudSorting; - this.booleanValue = booleanValue; - this.dateFormat = dateFormat; - this.expansions = new HashMap<>(); - } + public PlaceholderAPIConfig() { - public PlaceholderAPIConfig(boolean checkUpdates, boolean cloudEnabled, boolean debugMode, @NotNull ExpansionSort cloudSorting, - @NotNull BooleanValue booleanValue, @NotNull String dateFormat, Map expansions) { - this.checkUpdates = checkUpdates; - this.cloudEnabled = cloudEnabled; - this.debugMode = debugMode; - this.cloudSorting = cloudSorting; - this.booleanValue = booleanValue; - this.dateFormat = dateFormat; - this.expansions = expansions; } public boolean checkUpdates() { @@ -76,6 +61,14 @@ public final class PlaceholderAPIConfig { debugMode = value; } + public Boolean metrics() { + return metrics; + } + + public void metrics(final boolean value) { + metrics = value; + } + @NotNull public ExpansionSort cloudSorting() { return cloudSorting; @@ -111,4 +104,12 @@ public final class PlaceholderAPIConfig { public void expansions(@NotNull final Map value) { expansions = value; } + + public UUID metricsUuid() { + return metricsUuid; + } + + public void metricsUuid(@NotNull final UUID metricsUuid) { + this.metricsUuid = metricsUuid; + } } diff --git a/src/main/java/at/helpch/placeholderapi/metrics/MetricsManager.java b/src/main/java/at/helpch/placeholderapi/metrics/MetricsManager.java new file mode 100644 index 0000000..eb41a8e --- /dev/null +++ b/src/main/java/at/helpch/placeholderapi/metrics/MetricsManager.java @@ -0,0 +1,67 @@ +package at.helpch.placeholderapi.metrics; + +import at.helpch.placeholderapi.PlaceholderAPIPlugin; +import at.helpch.placeholderapi.expansion.PlaceholderExpansion; +import at.helpch.placeholderapi.expansion.manager.CloudExpansionManager; +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.hypixel.hytale.common.util.java.ManifestUtil; +import com.hypixel.hytale.server.core.HytaleServer; +import com.hypixel.hytale.server.core.universe.Universe; +import org.jetbrains.annotations.NotNull; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Collectors; + +public class MetricsManager { + private static final String METRICS_URL = "https://ecloud.placeholderapi.com/api/metrics/"; + private static final Gson GSON = new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .create(); + private static final HttpClient CLIENT = HttpClient.newHttpClient(); + + private final PlaceholderAPIPlugin main; + + public MetricsManager(@NotNull final PlaceholderAPIPlugin main) { + this.main = main; + } + + public void send() { + final String pluginVersion = main.getManifest().getVersion().toString(); + final String serverVersion = ManifestUtil.getImplementationVersion(); + final boolean usingEcloud = main.configManager().config().cloudEnabled(); + final List expansionsUsed = main.localExpansionManager().getExpansions().stream() + .map(PlaceholderExpansion::getName) + .toList(); + final Map expansionVersions = main.localExpansionManager().getExpansions().stream() + .collect(Collectors.toUnmodifiableMap(PlaceholderExpansion::getName, PlaceholderExpansion::getVersion)); + final String javaVersion = System.getProperty("java.version"); + final String serverOs = System.getProperty("os.name"); + final int playerCount = Universe.get().getPlayerCount(); + final UUID serverUuid = main.configManager().config().metricsUuid(); + + final MetricsPayload payload = new MetricsPayload(pluginVersion, serverVersion, usingEcloud, expansionsUsed, + expansionVersions, javaVersion, serverOs, playerCount, serverUuid); + + final String json = GSON.toJson(payload); + + final HttpRequest request = HttpRequest.newBuilder(URI.create(METRICS_URL)) + .POST(HttpRequest.BodyPublishers.ofString(json)) + .header("Content-Type", "application/json") + .header("User-Agent", CloudExpansionManager.USER_AGENT) + .build(); + + CLIENT.sendAsync(request, HttpResponse.BodyHandlers.discarding()); + } +} diff --git a/src/main/java/at/helpch/placeholderapi/metrics/MetricsPayload.java b/src/main/java/at/helpch/placeholderapi/metrics/MetricsPayload.java new file mode 100644 index 0000000..bc954e0 --- /dev/null +++ b/src/main/java/at/helpch/placeholderapi/metrics/MetricsPayload.java @@ -0,0 +1,34 @@ +package at.helpch.placeholderapi.metrics; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public final class MetricsPayload { + private final String pluginVersion; + private final String serverVersion; + private final String platform = "HYTALE"; + private final boolean usingEcloud; + private final List expansionsUsed; + private final Map expansionVersions; + private final String javaVersion; + private final String serverOs; + private final int playerCount; + private final UUID serverUuid; + private final String pluginName = "PlaceholderAPI"; + + public MetricsPayload(final String pluginVersion, final String serverVersion, final boolean usingEcloud, + final List expansionsUsed, final Map expansionVersions, + final String javaVersion, final String serverOs, final int playerCount, + final UUID serverUuid) { + this.pluginVersion = pluginVersion; + this.serverVersion = serverVersion; + this.usingEcloud = usingEcloud; + this.expansionsUsed = expansionsUsed; + this.expansionVersions = expansionVersions; + this.javaVersion = javaVersion; + this.serverOs = serverOs; + this.playerCount = playerCount; + this.serverUuid = serverUuid; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 30fa68e..7e5806f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -11,6 +11,7 @@ check_updates: true cloud_enabled: true cloud_sorting: "NAME" +metrics: true boolean_value: true_value: 'yes' false_value: 'no'