diff --git a/eco-api/src/main/java/com/willfp/eco/core/data/ServerProfile.java b/eco-api/src/main/java/com/willfp/eco/core/data/ServerProfile.java index 6feae5be..414210b3 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/data/ServerProfile.java +++ b/eco-api/src/main/java/com/willfp/eco/core/data/ServerProfile.java @@ -9,6 +9,14 @@ import org.jetbrains.annotations.NotNull; * Profiles save automatically, so there is no need to save after changes. */ public interface ServerProfile extends Profile { + /** + * Get the server ID. + * + * @return The server ID. + */ + @NotNull + String getServerID(); + /** * Load the server profile. * diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt index 9e72dda3..1a309776 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt @@ -117,6 +117,7 @@ import com.willfp.eco.internal.spigot.integrations.shop.ShopDeluxeSellwands import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus import com.willfp.eco.internal.spigot.integrations.shop.ShopZShop +import com.willfp.eco.internal.spigot.metrics.PlayerflowHandler import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy import com.willfp.eco.internal.spigot.recipes.CraftingRecipeListener @@ -259,10 +260,11 @@ abstract class EcoSpigotPlugin : EcoPlugin() { ProfileSaver(this, profileHandler).startTicking() this.scheduler.runTimer( - { getProxy(PacketHandlerProxy::class.java).clearDisplayFrames() }, this.configYml.getInt("display-frame-ttl").toLong(), - this.configYml.getInt("display-frame-ttl").toLong() - ) + this.configYml.getInt("display-frame-ttl").toLong(), + ) { getProxy(PacketHandlerProxy::class.java).clearDisplayFrames() } + + PlayerflowHandler(this.scheduler).startTicking() } override fun handleAfterLoad() { diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/data/EcoProfile.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/data/EcoProfile.kt index de2c52ed..e5203244 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/data/EcoProfile.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/data/EcoProfile.kt @@ -5,7 +5,9 @@ import com.willfp.eco.core.data.PlayerProfile import com.willfp.eco.core.data.Profile import com.willfp.eco.core.data.ServerProfile import com.willfp.eco.core.data.keys.PersistentDataKey +import com.willfp.eco.core.data.keys.PersistentDataKeyType import com.willfp.eco.internal.spigot.data.storage.DataHandler +import com.willfp.eco.util.namespacedKeyOf import java.util.UUID import java.util.concurrent.ConcurrentHashMap @@ -64,11 +66,25 @@ class EcoPlayerProfile( } } +private val serverIDKey = PersistentDataKey( + namespacedKeyOf("eco", "server_id"), + PersistentDataKeyType.STRING, + "" +) + class EcoServerProfile( data: MutableMap, Any>, handler: DataHandler, localHandler: DataHandler ) : EcoProfile(data, serverProfileUUID, handler, localHandler), ServerProfile { + override fun getServerID(): String { + if (this.read(serverIDKey).isBlank()) { + this.write(serverIDKey, UUID.randomUUID().toString()) + } + + return this.read(serverIDKey) + } + override fun toString(): String { return "EcoServerProfile" } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/metrics/PlayerflowHandler.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/metrics/PlayerflowHandler.kt new file mode 100644 index 00000000..ac74c656 --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/metrics/PlayerflowHandler.kt @@ -0,0 +1,45 @@ +package com.willfp.eco.internal.spigot.metrics + +import com.willfp.eco.core.Eco +import com.willfp.eco.core.config.json +import com.willfp.eco.core.data.ServerProfile +import com.willfp.eco.core.scheduling.Scheduler +import org.bukkit.Bukkit +import java.net.URI +import java.net.http.HttpClient +import java.net.http.HttpRequest +import java.net.http.HttpResponse + +private const val PLAYERFLOW_URL = "https://playerflow.auxilor.io/v1/ping" + +private val client = HttpClient.newBuilder().build() + +class PlayerflowHandler( + private val scheduler: Scheduler +) { + internal fun startTicking() { + scheduler.runAsyncTimer(1200L, 1200L) { + makeRequest() + } + } + + private fun makeRequest() { + val body = json { + "uuid" to ServerProfile.load().serverID + "players" to Bukkit.getOnlinePlayers().size + "plugins" to Eco.get().loadedPlugins + }.toPlaintext() + + val request = HttpRequest.newBuilder() + .uri(URI.create(PLAYERFLOW_URL)) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(body)) + .build() + + try { + client.send(request, HttpResponse.BodyHandlers.ofString()) + } catch (e: Exception) { + // Silently fail + } + } +}