From 3505a3f44fdbec29b613902e3cb3e24c23f4f0b3 Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Fri, 2 Aug 2024 11:13:53 +0200 Subject: [PATCH] Host a HTTP server instead of sending data to third party. --- build.gradle | 4 + gradle.properties | 4 +- src/main/java/ct/server/CtServer.java | 80 +++++++++++++++++ .../java/ct/server/CtServerConfigModel.java | 8 ++ src/main/java/ct/server/Ctserver.java | 89 ------------------- .../java/ct/server/ServiceHttpServer.java | 56 ++++++++++++ src/main/resources/fabric.mod.json | 2 +- 7 files changed, 152 insertions(+), 91 deletions(-) create mode 100644 src/main/java/ct/server/CtServer.java create mode 100644 src/main/java/ct/server/CtServerConfigModel.java delete mode 100644 src/main/java/ct/server/Ctserver.java create mode 100644 src/main/java/ct/server/ServiceHttpServer.java diff --git a/build.gradle b/build.gradle index c6e1481..e75a268 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,8 @@ repositories { // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. // See https://docs.gradle.org/current/userguide/declaring_repositories.html // for more information about repositories. + + maven { url 'https://maven.wispforest.io' } } loom { @@ -38,6 +40,8 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + annotationProcessor modImplementation("io.wispforest:owo-lib:${project.owo_version}") } diff --git a/gradle.properties b/gradle.properties index e0adbb5..912efb3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,4 +14,6 @@ maven_group=ct.server archives_base_name=ct-server # Dependencies -fabric_version=0.100.8+1.21 \ No newline at end of file +fabric_version=0.100.8+1.21 + +owo_version=0.12.8-alpha.7+1.21 \ No newline at end of file diff --git a/src/main/java/ct/server/CtServer.java b/src/main/java/ct/server/CtServer.java new file mode 100644 index 0000000..cd84ce1 --- /dev/null +++ b/src/main/java/ct/server/CtServer.java @@ -0,0 +1,80 @@ +package ct.server; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; + +import net.fabricmc.fabric.api.networking.v1.ServerLoginConnectionEvents; +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayerEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.concurrent.CompletableFuture; + + +public class CtServer implements ModInitializer { + public static final String MOD_ID = "ct-server"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + public static final ct.server.CtServerConfig CONFIG = ct.server.CtServerConfig.createAndLoad(); + + private static float currentTps = 0; + private static float currentMspt = 0; + private static int currentPlayerCount = 0; + + private static CtServer INSTANCE; + + public static CtServer getInstance() { + return INSTANCE; + } + + @Override + public void onInitialize() { + INSTANCE = this; + + LOGGER.info("Starting ct-client"); + + ServerTickEvents.END_SERVER_TICK.register(server -> { + currentMspt = server.getAverageTickTime(); + if (currentMspt != 0) { + currentTps = Math.min(20, 1000 / currentMspt); + } + }); + + ServerEntityEvents.ENTITY_LOAD.register((entity, world) -> { + if(entity instanceof ServerPlayerEntity) { + currentPlayerCount = world.getServer().getCurrentPlayerCount(); + } + }); + + ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> { + currentPlayerCount = server.getCurrentPlayerCount() - 1; + }); + + try { + var httpServer = new ServiceHttpServer(); + } catch (IOException e) { + LOGGER.error("Unable to start HTTP server", e); + } + } + + public static float getTPS() { + return currentTps; + } + + public static float getMSPT() { + return currentMspt; + } + + public static int getPlayerCount() { + return currentPlayerCount; + } +} \ No newline at end of file diff --git a/src/main/java/ct/server/CtServerConfigModel.java b/src/main/java/ct/server/CtServerConfigModel.java new file mode 100644 index 0000000..37ca471 --- /dev/null +++ b/src/main/java/ct/server/CtServerConfigModel.java @@ -0,0 +1,8 @@ +package ct.server; + +import io.wispforest.owo.config.annotation.Config; + +@Config(name = "ct-server-config", wrapperName = "CtServerConfig") +public class CtServerConfigModel { + public short httpPort = 25581; +} diff --git a/src/main/java/ct/server/Ctserver.java b/src/main/java/ct/server/Ctserver.java deleted file mode 100644 index d95cf3c..0000000 --- a/src/main/java/ct/server/Ctserver.java +++ /dev/null @@ -1,89 +0,0 @@ -package ct.server; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; - -import net.minecraft.server.MinecraftServer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.*; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.concurrent.CompletableFuture; - - -public class Ctserver implements ModInitializer { - // This logger is used to write text to the console and the log file. - // It is considered best practice to use your mod id as the logger's name. - // That way, it's clear which mod wrote info, warnings, and errors. - public static final Logger LOGGER = LoggerFactory.getLogger("ct-server"); - private int tickCounter = 0; - @Override - public void onInitialize() { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. - - LOGGER.info("Starting ct-client"); - ServerTickEvents.END_SERVER_TICK.register(server -> { - try { - onEndServerTick(server); - } catch (IOException e) { - throw new RuntimeException(e); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } - private void sendPostRequest(String urlString, String tps, String playerCount) throws Exception { - URL url = new URL(urlString); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Content-Type", "text/plain; utf-8"); - con.setRequestProperty("TPS", tps); - con.setRequestProperty("PLAYERCOUNT", playerCount); - con.setRequestProperty("Accept", "text/plain"); - con.setDoOutput(true); - - try (OutputStream os = con.getOutputStream()) { - byte[] input = tps.getBytes(StandardCharsets.UTF_8); - os.write(input, 0, input.length); - } - - int code = con.getResponseCode(); - //LOGGER.info("POST Response Code :: " + code); - con.disconnect(); - } - long zeroTicks = 0; - private void onEndServerTick(MinecraftServer minecraftServer) throws Exception { - tickCounter++; - - if (tickCounter >= 20) { - int playerCount = minecraftServer.getCurrentPlayerCount(); - //LOGGER.info(String.valueOf(playerCount)); - double afterTicks = Instant.now().toEpochMilli(); - double timeBetween = afterTicks - zeroTicks; - double mspt = (timeBetween / 20) ; - double tps = 1000 / mspt; - //LOGGER.info(String.valueOf(timeBetween)); - //LOGGER.info(String.valueOf(mspt)); - //LOGGER.info(String.valueOf(tps)); - if (tps <= 20) { - CompletableFuture.runAsync(() -> { - try { - sendPostRequest("http://us-ky-medium-0004.knijn.one:58926/tps", String.valueOf(tps),String.valueOf(playerCount)); - } catch (Exception e) { - LOGGER.error("Failed to send POST request", e); - } - }); - } - //LOGGER.info("Sent HTTP request"); - tickCounter = 0; - zeroTicks = Instant.now().toEpochMilli(); - } - } - -} \ No newline at end of file diff --git a/src/main/java/ct/server/ServiceHttpServer.java b/src/main/java/ct/server/ServiceHttpServer.java new file mode 100644 index 0000000..513ba0f --- /dev/null +++ b/src/main/java/ct/server/ServiceHttpServer.java @@ -0,0 +1,56 @@ +package ct.server; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.net.InetSocketAddress; + +public class ServiceHttpServer { + private HttpServer server; + + public ServiceHttpServer() throws IOException { + server = HttpServer.create(new InetSocketAddress(CtServer.CONFIG.httpPort()), 0); + server.createContext("/tps", new TPSHandler()); + server.createContext("/mspt", new MSPTHandler()); + server.createContext("/player", new PlayerCountHandler()); + server.setExecutor(null); + + var httpThread = new Thread(() -> server.start()); + httpThread.start(); + } + + static class TPSHandler implements HttpHandler { + @Override + public void handle(HttpExchange t) throws IOException { + var tps = String.valueOf(CtServer.getTPS()); + t.sendResponseHeaders(200, tps.length()); + var body = t.getResponseBody(); + body.write(tps.getBytes()); + body.close(); + } + } + + static class MSPTHandler implements HttpHandler { + @Override + public void handle(HttpExchange t) throws IOException { + var tps = String.valueOf(CtServer.getMSPT()); + t.sendResponseHeaders(200, tps.length()); + var body = t.getResponseBody(); + body.write(tps.getBytes()); + body.close(); + } + } + + static class PlayerCountHandler implements HttpHandler { + @Override + public void handle(HttpExchange t) throws IOException { + var tps = String.valueOf(CtServer.getPlayerCount()); + t.sendResponseHeaders(200, tps.length()); + var body = t.getResponseBody(); + body.write(tps.getBytes()); + body.close(); + } + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b45539f..8f621c6 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -16,7 +16,7 @@ "environment": "*", "entrypoints": { "main": [ - "ct.server.Ctserver" + "ct.server.CtServer" ], "client": [ "ct.server.CtserverClient"