Skip to content

Commit

Permalink
feat(fabric): add fabric support (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
DJtheRedstoner committed Oct 2, 2021
1 parent 90ea00b commit 91094a5
Show file tree
Hide file tree
Showing 21 changed files with 817 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package dev.cubxity.plugins.metrics.api.metric.collector

import dev.cubxity.plugins.metrics.api.metric.data.Metric

const val NANOSECONDS_PER_MILLISECOND: Double = 1E6
const val NANOSECONDS_PER_SECOND: Double = 1E9
const val MILLISECONDS_PER_SECOND: Double = 1E3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ sealed class PlatformType(val name: String) {
// Server implementations
object Bukkit : PlatformType("Bukkit")
object Minestom : PlatformType("Minestom")
object Fabric : PlatformType("Fabric")

// Proxies
object Velocity : PlatformType("Velocity")
Expand Down
96 changes: 96 additions & 0 deletions platforms/fabric/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* This file is part of UnifiedMetrics.
*
* UnifiedMetrics is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* UnifiedMetrics is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with UnifiedMetrics. If not, see <https://www.gnu.org/licenses/>.
*/

plugins {
id("fabric-loom") version "0.9-SNAPSHOT"
id("net.kyori.blossom")
}

dependencies {
// https://fabricmc.net/versions.html
minecraft("com.mojang:minecraft:1.17.1")
mappings("net.fabricmc:yarn:1.17.1+build.61:v2")
modImplementation("net.fabricmc:fabric-loader:0.11.7")

modImplementation("net.fabricmc.fabric-api:fabric-api:0.40.1+1.17")
modImplementation("net.fabricmc:fabric-language-kotlin:1.6.5+kotlin.1.5.31")

api(project(":unifiedmetrics-core"))

include(project(":unifiedmetrics-core"))
include(project(":unifiedmetrics-common"))
include("com.charleskorn.kaml:kaml:0.36.0")
include("com.charleskorn.kaml:kaml-jvm:0.36.0")
include("org.snakeyaml:snakeyaml-engine:2.3")
include(project(":unifiedmetrics-api"))
include(project(":unifiedmetrics-driver-influx"))
include("com.influxdb:influxdb-client-java:3.3.0")
include("com.influxdb:influxdb-client-core:3.3.0")
include("com.influxdb:influxdb-client-utils:3.3.0")
include("com.google.code.findbugs:jsr305:3.0.2")
include("com.squareup.retrofit2:retrofit:2.9.0")
include("com.squareup.okhttp3:okhttp:4.7.2")
include("com.squareup.okio:okio:2.6.0")
include("com.squareup.okhttp3:logging-interceptor:4.7.2")
include("org.apache.commons:commons-csv:1.8")
include("io.reactivex.rxjava2:rxjava:2.2.19")
include("org.reactivestreams:reactive-streams:1.0.3")
include("io.swagger:swagger-annotations:1.6.1")
include("io.gsonfire:gson-fire:1.8.4")
include("com.squareup.retrofit2:converter-scalars:2.9.0")
include("com.squareup.retrofit2:converter-gson:2.9.0")
include(project(":unifiedmetrics-driver-prometheus"))
include("io.prometheus:simpleclient_httpserver:0.12.0")
include("io.prometheus:simpleclient:0.12.0")
include("io.prometheus:simpleclient_tracer_otel:0.12.0")
include("io.prometheus:simpleclient_tracer_common:0.12.0")
include("io.prometheus:simpleclient_tracer_otel_agent:0.12.0")
include("io.prometheus:simpleclient_common:0.12.0")
include("io.prometheus:simpleclient_pushgateway:0.12.0")
}

loom {
runs {
named("server") {
isIdeConfigGenerated = true
}
}
}

tasks {
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}

processResources {
inputs.property("version", project.version)

filesMatching("fabric.mod.json") {
expand("version" to project.version)
}
}

compileJava {
options.encoding = "UTF-8"
options.release.set(8)
}
}

blossom {
replaceTokenIn("src/main/kotlin/dev/cubxity/plugins/metrics/fabric/bootstrap/UnifiedMetricsFabricBootstrap.kt")
replaceToken("@version@", version)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* This file is part of UnifiedMetrics.
*
* UnifiedMetrics is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* UnifiedMetrics is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with UnifiedMetrics. If not, see <https://www.gnu.org/licenses/>.
*/

package dev.cubxity.plugins.metrics.fabric.mixins;

import dev.cubxity.plugins.metrics.fabric.events.TickEvent;
import net.minecraft.server.MinecraftServer;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import static dev.cubxity.plugins.metrics.api.metric.collector.CollectorKt.NANOSECONDS_PER_MILLISECOND;
import static dev.cubxity.plugins.metrics.api.metric.collector.CollectorKt.NANOSECONDS_PER_SECOND;

/**
* Designed to emulate paper's tick event as closely as possible
*/
@Mixin(MinecraftServer.class)
public class MinecraftServerMixin {

private long lastTick = 0;

@Inject(
method = "runServer",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/server/MinecraftServer;setFavicon(Lnet/minecraft/server/ServerMetadata;)V"
)
)
private void onRunServerBeforeLoop(CallbackInfo ci) {
lastTick = System.nanoTime() - ((long) NANOSECONDS_PER_SECOND / 20);
}

@Inject(
method = "runServer",
slice = @Slice(
from = @At(
value = "FIELD",
target = "Lnet/minecraft/server/MinecraftServer;debugStart:Lnet/minecraft/server/MinecraftServer$DebugStart;"
)
),
at = @At(
value = "FIELD",
target = "Lnet/minecraft/server/MinecraftServer;timeReference:J",
opcode = Opcodes.PUTFIELD
)
)
private void onRunServerBeforeTick(CallbackInfo ci) {
lastTick = System.nanoTime();
}

@Inject(
method = "tick",
slice = @Slice(
from = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/snooper/Snooper;update()V"
),
to = @At(
value = "FIELD",
target = "Lnet/minecraft/server/MinecraftServer;lastTickLengths:[J"
)
),
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/profiler/Profiler;pop()V"
)
)
private void onTickEnd(CallbackInfo ci) {
TickEvent.Companion.getEvent().invoker().onTick((double)(System.nanoTime() - lastTick) / NANOSECONDS_PER_MILLISECOND);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of UnifiedMetrics.
*
* UnifiedMetrics is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* UnifiedMetrics is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with UnifiedMetrics. If not, see <https://www.gnu.org/licenses/>.
*/

package dev.cubxity.plugins.metrics.fabric.mixins;

import dev.cubxity.plugins.metrics.fabric.events.ChatEvent;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ServerPlayNetworkHandler.class)
public class ServerPlayNetworkHandlerMixin {

@Inject(method = "handleMessage", at = @At("HEAD"))
private void onHandleMessage(CallbackInfo ci) {
ChatEvent.Companion.getEvent().invoker().onChat();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of UnifiedMetrics.
*
* UnifiedMetrics is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* UnifiedMetrics is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with UnifiedMetrics. If not, see <https://www.gnu.org/licenses/>.
*/

package dev.cubxity.plugins.metrics.fabric.mixins;

import dev.cubxity.plugins.metrics.fabric.events.PingEvent;
import net.minecraft.server.network.ServerQueryNetworkHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ServerQueryNetworkHandler.class)
public class ServerQueryNetworkHandlerMixin {

@Inject(method = "onRequest", at = @At("HEAD"))
private void handleOnRequest(CallbackInfo ci) {
PingEvent.Companion.getEvent().invoker().onPing();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of UnifiedMetrics.
*
* UnifiedMetrics is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* UnifiedMetrics is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with UnifiedMetrics. If not, see <https://www.gnu.org/licenses/>.
*/

package dev.cubxity.plugins.metrics.fabric

import dev.cubxity.plugins.metrics.api.UnifiedMetrics
import dev.cubxity.plugins.metrics.core.plugin.CoreUnifiedMetricsPlugin
import dev.cubxity.plugins.metrics.fabric.bootstrap.UnifiedMetricsFabricBootstrap
import dev.cubxity.plugins.metrics.fabric.metrics.events.EventsCollection
import dev.cubxity.plugins.metrics.fabric.metrics.server.ServerCollection
import dev.cubxity.plugins.metrics.fabric.metrics.tick.TickCollection
import dev.cubxity.plugins.metrics.fabric.metrics.world.WorldCollection
import java.util.concurrent.Executors

class UnifiedMetricsFabricPlugin(
override val bootstrap: UnifiedMetricsFabricBootstrap
): CoreUnifiedMetricsPlugin() {

override fun registerPlatformService(api: UnifiedMetrics) {

}

override fun registerPlatformMetrics() {
super.registerPlatformMetrics()

apiProvider.metricsManager.apply {
with(config.metrics.collectors) {
if (server) registerCollection(ServerCollection(bootstrap))
if (world) registerCollection(WorldCollection(bootstrap))
if (tick) registerCollection(TickCollection())
if (events) registerCollection(EventsCollection())
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* This file is part of UnifiedMetrics.
*
* UnifiedMetrics is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* UnifiedMetrics is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with UnifiedMetrics. If not, see <https://www.gnu.org/licenses/>.
*/

package dev.cubxity.plugins.metrics.fabric.bootstrap

import dev.cubxity.plugins.metrics.api.platform.PlatformType
import dev.cubxity.plugins.metrics.common.UnifiedMetricsBootstrap
import dev.cubxity.plugins.metrics.common.plugin.dispatcher.CurrentThreadDispatcher
import dev.cubxity.plugins.metrics.fabric.UnifiedMetricsFabricPlugin
import dev.cubxity.plugins.metrics.fabric.logger.Log4jLogger
import kotlinx.coroutines.CoroutineDispatcher
import net.fabricmc.api.DedicatedServerModInitializer
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents
import net.fabricmc.loader.api.FabricLoader
import net.minecraft.server.MinecraftServer
import org.apache.logging.log4j.LogManager
import java.nio.file.Path

private const val pluginVersion = "@version@"

class UnifiedMetricsFabricBootstrap : DedicatedServerModInitializer, UnifiedMetricsBootstrap {
private val plugin = UnifiedMetricsFabricPlugin(this)
lateinit var server: MinecraftServer

override val type: PlatformType
get() = PlatformType.Fabric

override val version: String
get() = pluginVersion

override val serverBrand: String
get() = server.serverModName

override val dataDirectory: Path
= FabricLoader.getInstance().configDir.resolve("unifiedmetrics")

override val configDirectory: Path
= FabricLoader.getInstance().configDir.resolve("unifiedmetrics")

override val logger = Log4jLogger(LogManager.getLogger("UnifiedMetrics"))

override val dispatcher: CoroutineDispatcher = CurrentThreadDispatcher

override fun onInitializeServer() {
ServerLifecycleEvents.SERVER_STARTED.register {
server = it
plugin.enable()
}

ServerLifecycleEvents.SERVER_STOPPING.register {
plugin.disable()
}
}
}

0 comments on commit 91094a5

Please sign in to comment.