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 6feae5bee..414210b38 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 @@ * 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-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java b/eco-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java index 02c55dbdb..d2a2f5635 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/ConfiguredPrice.java @@ -1,5 +1,6 @@ package com.willfp.eco.core.price; +import com.willfp.eco.core.Eco; import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.placeholder.context.PlaceholderContext; import com.willfp.eco.core.price.impl.PriceFree; @@ -158,12 +159,27 @@ public ConfiguredPrice deserialize(@NotNull final Config config) { if (!( config.has("value") && config.has("type") - && config.has("display") )) { return null; } - String formatString = config.getString("display"); + String formatString; + + String langConfig = Eco.get().getEcoPlugin().getLangYml() + .getSubsections("price-display") + .stream() + .filter(section -> section.getString("type").equalsIgnoreCase(config.getString("type"))) + .findFirst() + .map(section -> section.getString("display")) + .orElse(null); + + if (langConfig != null) { + formatString = langConfig; + } else if (config.has("display")) { + formatString = config.getString("display"); + } else { + return null; + } Price price = Prices.create( config.getString("value"), 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 dc6b08ebc..599396736 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 @@ -118,6 +118,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 @@ -261,10 +262,13 @@ 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() } + + if (this.configYml.getBool("playerflow")) { + 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 de2c52ed7..e5203244a 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 000000000..d4d43caa3 --- /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/api/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 + } + } +} diff --git a/eco-core/core-plugin/src/main/resources/config.yml b/eco-core/core-plugin/src/main/resources/config.yml index 9cbe797d9..716ad9888 100644 --- a/eco-core/core-plugin/src/main/resources/config.yml +++ b/eco-core/core-plugin/src/main/resources/config.yml @@ -91,3 +91,9 @@ use-immediate-placeholder-translation-for-math: false # faster evaluation times (less CPU usage) at the expense of slightly more memory usage and # less reactive values. math-cache-ttl: 200 + +# If anonymous usage statistics should be tracked. This is very valuable information as it +# helps understand how eco and other plugins are being used by logging player and server +# counts. This is completely anonymous and no personal information is logged. This data +# is primarily used for optimisation and server insights. +playerflow: true diff --git a/eco-core/core-plugin/src/main/resources/lang.yml b/eco-core/core-plugin/src/main/resources/lang.yml index 7d1dc50a4..54bd9317e 100644 --- a/eco-core/core-plugin/src/main/resources/lang.yml +++ b/eco-core/core-plugin/src/main/resources/lang.yml @@ -1 +1,7 @@ -multiple-in-craft: '&l&c! &fThis recipe requires &a%amount%&f of this item.' \ No newline at end of file +multiple-in-craft: '&l&c! &fThis recipe requires &a%amount%&f of this item.' + +# Specify default display names for prices made through ConfiguredPrice#create +# These will override any custom configured price display names. +price-display: + - type: example_type + display: "&e%value% Price" diff --git a/gradle.properties b/gradle.properties index bd5fd3c3b..ff1dc28e6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -version = 6.60.4 +version = 6.61.0 plugin-name = eco kotlin.code.style = official \ No newline at end of file