From def6aa04423a8e571388ab1be2720a24b7bae2c1 Mon Sep 17 00:00:00 2001 From: Hunter S Date: Sat, 20 Jun 2026 21:24:10 -0700 Subject: [PATCH] docs(examples): add Kotlin examples for all platforms - added [platform]\example-plugin\src\main\java\com\example\ExamplePlugin.kt - added [platform]\example-mod\src\main\java\com\example\ExampleMod.kt --- .../main/java/com/example/ExamplePlugin.kt | 44 ++++++++++++++ .../main/java/com/example/ExamplePlugin.kt | 44 ++++++++++++++ .../src/main/java/com/example/ExampleMod.kt | 43 ++++++++++++++ .../main/java/com/example/ExamplePlugin.kt | 45 ++++++++++++++ .../main/java/com/example/ExampleServer.kt | 47 +++++++++++++++ .../src/main/java/com/example/ExampleMod.kt | 34 +++++++++++ .../main/java/com/example/ExamplePlugin.kt | 44 ++++++++++++++ .../main/java/com/example/ExamplePlugin.kt | 57 ++++++++++++++++++ .../main/java/com/example/ExamplePlugin.kt | 58 +++++++++++++++++++ 9 files changed, 416 insertions(+) create mode 100644 bukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt create mode 100644 bungeecord/example-plugin/src/main/java/com/example/ExamplePlugin.kt create mode 100644 fabric/example-mod/src/main/java/com/example/ExampleMod.kt create mode 100644 hytale/example-plugin/src/main/java/com/example/ExamplePlugin.kt create mode 100644 minestom/example-server/src/main/java/com/example/ExampleServer.kt create mode 100644 neoforge/example-mod/src/main/java/com/example/ExampleMod.kt create mode 100644 nukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt create mode 100644 sponge/example-plugin/src/main/java/com/example/ExamplePlugin.kt create mode 100644 velocity/example-plugin/src/main/java/com/example/ExamplePlugin.kt diff --git a/bukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt b/bukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt new file mode 100644 index 00000000..ac6ab52e --- /dev/null +++ b/bukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt @@ -0,0 +1,44 @@ +package com.example + +import dev.faststats.ErrorTracker +import dev.faststats.bukkit.BukkitContext +import dev.faststats.data.Metric +import org.bukkit.plugin.java.JavaPlugin +import java.util.concurrent.atomic.AtomicInteger + +class ExamplePlugin : JavaPlugin() { + private val gameCount = AtomicInteger() + + private val context = BukkitContext.Factory(this, "YOUR_TOKEN_HERE") + .errorTrackerService(ERROR_TRACKER) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .create() + + override fun onEnable() { + context.ready() // start metrics and errors submission + } + + override fun onDisable() { + context.shutdown() // safely shut down configured services + } + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +} diff --git a/bungeecord/example-plugin/src/main/java/com/example/ExamplePlugin.kt b/bungeecord/example-plugin/src/main/java/com/example/ExamplePlugin.kt new file mode 100644 index 00000000..5325aa88 --- /dev/null +++ b/bungeecord/example-plugin/src/main/java/com/example/ExamplePlugin.kt @@ -0,0 +1,44 @@ +package com.example + +import dev.faststats.ErrorTracker +import dev.faststats.bungee.BungeeContext +import dev.faststats.data.Metric +import net.md_5.bungee.api.plugin.Plugin +import java.util.concurrent.atomic.AtomicInteger + +class ExamplePlugin : Plugin() { + private val gameCount = AtomicInteger() + + private val context = BungeeContext.Factory(this, "YOUR_TOKEN_HERE") + .errorTrackerService(ERROR_TRACKER) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .create() + + override fun onEnable() { + context.ready() // start metrics and errors submission + } + + override fun onDisable() { + context.shutdown() // safely shut down configured services + } + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +} diff --git a/fabric/example-mod/src/main/java/com/example/ExampleMod.kt b/fabric/example-mod/src/main/java/com/example/ExampleMod.kt new file mode 100644 index 00000000..62caee46 --- /dev/null +++ b/fabric/example-mod/src/main/java/com/example/ExampleMod.kt @@ -0,0 +1,43 @@ +package com.example + +import dev.faststats.ErrorTracker +import dev.faststats.data.Metric +import dev.faststats.fabric.FabricContext +import net.fabricmc.api.ModInitializer +import java.util.concurrent.atomic.AtomicInteger + +class ExampleMod : ModInitializer { + private val gameCount = AtomicInteger() + + private val context = FabricContext.Factory( + "example-mod", // your mod id as defined in fabric.mod.json + "YOUR_TOKEN_HERE", + ) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .errorTrackerService(ERROR_TRACKER) + .create() + + override fun onInitialize() { + // your actual logic + } + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +} diff --git a/hytale/example-plugin/src/main/java/com/example/ExamplePlugin.kt b/hytale/example-plugin/src/main/java/com/example/ExamplePlugin.kt new file mode 100644 index 00000000..27799c5d --- /dev/null +++ b/hytale/example-plugin/src/main/java/com/example/ExamplePlugin.kt @@ -0,0 +1,45 @@ +package com.example + +import com.hypixel.hytale.server.core.plugin.JavaPlugin +import com.hypixel.hytale.server.core.plugin.JavaPluginInit +import dev.faststats.ErrorTracker +import dev.faststats.data.Metric +import dev.faststats.hytale.HytaleContext +import java.util.concurrent.atomic.AtomicInteger + +class ExamplePlugin(init: JavaPluginInit) : JavaPlugin(init) { + private val gameCount = AtomicInteger() + + private val context = HytaleContext.Factory(this, "YOUR_TOKEN_HERE") + .errorTrackerService(ERROR_TRACKER) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .create() + + override fun setup() { + context.ready() // start metrics and errors submission + } + + override fun shutdown() { + context.shutdown() // safely shut down configured services + } + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +} diff --git a/minestom/example-server/src/main/java/com/example/ExampleServer.kt b/minestom/example-server/src/main/java/com/example/ExampleServer.kt new file mode 100644 index 00000000..b253d1dc --- /dev/null +++ b/minestom/example-server/src/main/java/com/example/ExampleServer.kt @@ -0,0 +1,47 @@ +package com.example + +import dev.faststats.ErrorTracker +import dev.faststats.data.Metric +import dev.faststats.minestom.MinestomContext +import net.minestom.server.MinecraftServer +import java.util.concurrent.atomic.AtomicInteger + +object ExampleServer { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + private val gameCount = AtomicInteger() + + private val context = MinestomContext.Factory("YOUR_TOKEN_HERE") + .errorTrackerService(ERROR_TRACKER) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .create() + + @JvmStatic + fun main(args: Array) { + val server = MinecraftServer.init() + + server.start("0.0.0.0", 25565) + MinecraftServer.getSchedulerManager().buildShutdownTask { shutdown() } + + context.ready() // start metrics and errors submission + } + + fun shutdown() { + context.shutdown() // safely shut down configured services + } + + fun startGame() { + gameCount.incrementAndGet() + } +} diff --git a/neoforge/example-mod/src/main/java/com/example/ExampleMod.kt b/neoforge/example-mod/src/main/java/com/example/ExampleMod.kt new file mode 100644 index 00000000..5ab7c555 --- /dev/null +++ b/neoforge/example-mod/src/main/java/com/example/ExampleMod.kt @@ -0,0 +1,34 @@ +package com.example + +import dev.faststats.ErrorTracker +import dev.faststats.data.Metric +import dev.faststats.neoforge.NeoForgeContext +import net.neoforged.fml.common.Mod +import java.util.concurrent.atomic.AtomicInteger + +@Mod("example_mod") +class ExampleMod { + private val gameCount = AtomicInteger() + + private val context = NeoForgeContext.Factory( + "example_mod", + "YOUR_TOKEN_HERE", + ) + .metrics { factory -> + factory + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + .onFlush { gameCount.set(0) } + .create() + } + .errorTrackerService(ERROR_TRACKER) + .create() + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +} diff --git a/nukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt b/nukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt new file mode 100644 index 00000000..4a3dd8c4 --- /dev/null +++ b/nukkit/example-plugin/src/main/java/com/example/ExamplePlugin.kt @@ -0,0 +1,44 @@ +package com.example + +import cn.nukkit.plugin.PluginBase +import dev.faststats.ErrorTracker +import dev.faststats.data.Metric +import dev.faststats.nukkit.NukkitContext +import java.util.concurrent.atomic.AtomicInteger + +class ExamplePlugin : PluginBase() { + private val gameCount = AtomicInteger() + + private val context = NukkitContext.Factory(this, "YOUR_TOKEN_HERE") + .errorTrackerService(ERROR_TRACKER) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .create() + + override fun onEnable() { + context.ready() // start metrics and errors submission + } + + override fun onDisable() { + context.shutdown() // safely shut down configured services + } + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +} diff --git a/sponge/example-plugin/src/main/java/com/example/ExamplePlugin.kt b/sponge/example-plugin/src/main/java/com/example/ExamplePlugin.kt new file mode 100644 index 00000000..8fc9720c --- /dev/null +++ b/sponge/example-plugin/src/main/java/com/example/ExamplePlugin.kt @@ -0,0 +1,57 @@ +package com.example + +import com.google.inject.Inject +import dev.faststats.ErrorTracker +import dev.faststats.data.Metric +import dev.faststats.sponge.SpongeContext +import org.spongepowered.api.Server +import org.spongepowered.api.event.Listener +import org.spongepowered.api.event.lifecycle.StartedEngineEvent +import org.spongepowered.api.event.lifecycle.StoppingEngineEvent +import org.spongepowered.plugin.builtin.jvm.Plugin +import java.util.concurrent.atomic.AtomicInteger + +@Plugin("example") +class ExamplePlugin { + @Inject + private lateinit var contextBuilder: SpongeContext.Builder + + private val gameCount = AtomicInteger() + private var context: SpongeContext? = null + + @Listener + fun onServerStart(event: StartedEngineEvent) { + val context = contextBuilder + .token("YOUR_TOKEN_HERE") + .errorTrackerService(ERROR_TRACKER) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .create() + this.context = context + context.ready() // start metrics and errors submission + } + + @Listener + fun onServerStop(event: StoppingEngineEvent) { + context?.shutdown() // safely shut down configured services + } + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +} diff --git a/velocity/example-plugin/src/main/java/com/example/ExamplePlugin.kt b/velocity/example-plugin/src/main/java/com/example/ExamplePlugin.kt new file mode 100644 index 00000000..4e78935f --- /dev/null +++ b/velocity/example-plugin/src/main/java/com/example/ExamplePlugin.kt @@ -0,0 +1,58 @@ +package com.example + +import com.google.inject.Inject +import com.velocitypowered.api.event.Subscribe +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent +import com.velocitypowered.api.plugin.Plugin +import dev.faststats.ErrorTracker +import dev.faststats.data.Metric +import dev.faststats.velocity.VelocityContext +import java.util.concurrent.atomic.AtomicInteger + +@Plugin( + id = "example", + name = "Example Plugin", + version = "1.0.0", + url = "https://example.com", + authors = ["Your Name"], +) +class ExamplePlugin @Inject constructor(contextBuilder: VelocityContext.Builder) { + private val gameCount = AtomicInteger() + + private val context = contextBuilder + .token("YOUR_TOKEN_HERE") + .errorTrackerService(ERROR_TRACKER) + // .metrics(Metrics.Factory::create) // Define a minimal metrics instance without any custom metrics + .metrics { factory -> + factory + // Custom metrics require a corresponding data source in your project settings + .addMetric(Metric.number("game_count") { gameCount.get() }) + .addMetric(Metric.string("server_version") { "1.0.0" }) + + // #onFlush is invoked after successful metrics submission + // This is useful for cleaning up cached data + .onFlush { gameCount.set(0) } // reset game count on flush + + .create() + } + .create() + + @Subscribe + fun onProxyInitialize(event: ProxyInitializeEvent) { + context.ready() // start metrics and errors submission + } + + @Subscribe + fun onProxyStop(event: ProxyShutdownEvent) { + context.shutdown() // safely shut down configured services + } + + fun startGame() { + gameCount.incrementAndGet() + } + + companion object { + val ERROR_TRACKER: ErrorTracker = ErrorTracker.contextAware() + } +}