mirror of
https://github.com/JonasunderscoreJones/McWebserver.git
synced 2025-10-23 19:39:19 +02:00
simple api
This commit is contained in:
parent
ca0be55429
commit
8f8820db65
14 changed files with 437 additions and 39 deletions
|
@ -2,6 +2,7 @@ package me.jonasjones.mcwebserver;
|
|||
|
||||
import com.roxstudio.utils.CUrl;
|
||||
import me.jonasjones.mcwebserver.config.ModConfigs;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.ApiHandler;
|
||||
import me.jonasjones.mcwebserver.web.ServerHandler;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -9,7 +10,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static me.jonasjones.mcwebserver.config.ModConfigs.WEB_PORT;
|
||||
import static me.jonasjones.mcwebserver.config.ModConfigs.*;
|
||||
|
||||
public class McWebserver implements ModInitializer {
|
||||
// This logger is used to write text to the console and the log file.
|
||||
|
@ -18,44 +19,26 @@ public class McWebserver implements ModInitializer {
|
|||
public static String MOD_ID = "mcwebserver";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
public static final Logger VERBOSELOGGER = LoggerFactory.getLogger(MOD_ID + " - VERBOSE LOGGER");
|
||||
private static ServerHandler webserver = new ServerHandler();
|
||||
public static Thread webserverthread = new Thread(webserver);
|
||||
public static boolean mcserveractive = true;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
|
||||
// register configs
|
||||
ModConfigs.registerConfigs();
|
||||
|
||||
LOGGER.info("McWebserver initialized!");
|
||||
|
||||
|
||||
webserverthread.start();
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
if (!mcserveractive) {
|
||||
sleep(2);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
CUrl curl = new CUrl("http://localhost:" + WEB_PORT + "/index.html").timeout(1, 1);
|
||||
curl.exec();
|
||||
sleep(1);
|
||||
}
|
||||
LOGGER.info("Webserver Stopped!");
|
||||
break;
|
||||
} else {
|
||||
sleep(2);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void sleep(int seconds) {
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(seconds);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
if (SERVER_API_ENABLED) {
|
||||
//start collecting api info
|
||||
ApiHandler.startHandler();
|
||||
LOGGER.info("Server API enabled!");
|
||||
}
|
||||
}
|
||||
|
||||
if (ADV_API_ENABLED) {
|
||||
//start collecting advanced api info
|
||||
ApiHandler.startAdvHandler();
|
||||
LOGGER.info("Advanced Server API enabled!");
|
||||
}
|
||||
|
||||
ServerHandler.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ public class ModConfigs {
|
|||
public static String WEB_ROOT;
|
||||
public static String WEB_FILE_ROOT;
|
||||
public static String WEB_FILE_404;
|
||||
public static Boolean SERVER_API_ENABLED;
|
||||
public static Boolean ADV_API_ENABLED;
|
||||
public static String WEB_FILE_NOSUPPORT;
|
||||
public static Boolean VERBOSE = false; //needs to be set to false since the verbose logger is called before config file is fully loaded
|
||||
|
||||
|
@ -40,6 +42,8 @@ public class ModConfigs {
|
|||
config.addKeyValuePair(new Pair<>("web.root", "webserver/"), "the root directory of the webserver, starting from the main server directory");
|
||||
config.addKeyValuePair(new Pair<>("web.file.root", "index.html"), "the name of the html file for the homepage");
|
||||
config.addKeyValuePair(new Pair<>("web.file.404", "404.html"), "the name of the html file for 404 page");
|
||||
config.addKeyValuePair(new Pair<>("web.api", true), "whether or not the webserver api should be enabled or not");
|
||||
config.addKeyValuePair(new Pair<>("web.api.adv", true), "whether or not the api should expose information such as player coordinates and inventory");
|
||||
config.addKeyValuePair(new Pair<>("web.file.notSupported", "not_supported.html"), "the name of the html file for 'not supported' page");
|
||||
config.addKeyValuePair(new Pair<>("logger.verbose", true), "whether or not to log verbose output");
|
||||
}
|
||||
|
@ -50,6 +54,8 @@ public class ModConfigs {
|
|||
WEB_ROOT = CONFIG.getOrDefault("web.root", "webserver/");
|
||||
WEB_FILE_ROOT = CONFIG.getOrDefault("web.file.root", "index.html");
|
||||
WEB_FILE_404 = CONFIG.getOrDefault("web.file.404", "404.html");
|
||||
SERVER_API_ENABLED = CONFIG.getOrDefault("web.api", true);
|
||||
ADV_API_ENABLED = CONFIG.getOrDefault("web.api.adv", true);
|
||||
WEB_FILE_NOSUPPORT = CONFIG.getOrDefault("web.file.notSupported", "not_supported.html");
|
||||
VERBOSE = CONFIG.getOrDefault("logger.verbose", true);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package me.jonasjones.mcwebserver.mixin;
|
||||
|
||||
import me.jonasjones.mcwebserver.McWebserver;
|
||||
import me.jonasjones.mcwebserver.web.ServerHandler;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -12,6 +13,6 @@ public class WebserverStopMixin {
|
|||
@Inject(at = @At("HEAD"), method = "shutdown")
|
||||
private void init(CallbackInfo info) {
|
||||
McWebserver.LOGGER.info("Stopping Webserver...");
|
||||
McWebserver.mcserveractive = false;
|
||||
ServerHandler.mcserveractive = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package me.jonasjones.mcwebserver.web;
|
|||
import me.jonasjones.mcwebserver.config.ModConfigs;
|
||||
import me.jonasjones.mcwebserver.McWebserver;
|
||||
import me.jonasjones.mcwebserver.util.VerboseLogger;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.ApiHandler;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.ApiRequests;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.ApiRequestsUtil;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
|
@ -20,9 +23,10 @@ import java.nio.file.Path;
|
|||
import java.time.Instant;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import static me.jonasjones.mcwebserver.McWebserver.mcserveractive;
|
||||
import static me.jonasjones.mcwebserver.web.ServerHandler.mcserveractive;
|
||||
import static me.jonasjones.mcwebserver.web.api.v1.ApiHandler.isApiRequest;
|
||||
|
||||
public class HTTPServer implements Runnable {
|
||||
public class HttpServer implements Runnable {
|
||||
static Path WEB_ROOT;
|
||||
static final String DEFAULT_FILE = ModConfigs.WEB_FILE_ROOT;
|
||||
static final String FILE_NOT_FOUND = ModConfigs.WEB_FILE_404;
|
||||
|
@ -44,6 +48,7 @@ public class HTTPServer implements Runnable {
|
|||
|
||||
// Client Connection via Socket Class
|
||||
private final Socket connect;
|
||||
private Boolean isApiRequest = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
|
@ -53,7 +58,7 @@ public class HTTPServer implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
public HTTPServer(Socket c) {
|
||||
public HttpServer(Socket c) {
|
||||
connect = c;
|
||||
}
|
||||
|
||||
|
@ -65,12 +70,13 @@ public class HTTPServer implements Runnable {
|
|||
|
||||
// we listen until user halts server execution
|
||||
while (mcserveractive) {
|
||||
HTTPServer myServer = new HTTPServer(serverConnect.accept());
|
||||
HttpServer myServer = new HttpServer(serverConnect.accept());
|
||||
|
||||
VerboseLogger.info("Connection opened. (" + Instant.now() + ")");
|
||||
|
||||
// create dedicated thread to manage the client connection
|
||||
Thread thread = new Thread(myServer);
|
||||
thread.setName("McWebserver-worker");
|
||||
thread.start();
|
||||
|
||||
}
|
||||
|
@ -108,6 +114,7 @@ public class HTTPServer implements Runnable {
|
|||
|
||||
// we support only GET and HEAD methods, we check
|
||||
if (!method.equals("GET") && !method.equals("HEAD")) {
|
||||
isApiRequest = false;
|
||||
VerboseLogger.info("501 Not Implemented : " + method + " method.");
|
||||
|
||||
// we return the not supported file to the client
|
||||
|
@ -127,8 +134,50 @@ public class HTTPServer implements Runnable {
|
|||
// file
|
||||
dataOut.write(fileData, 0, fileData.length);
|
||||
dataOut.flush();
|
||||
} else if (isApiRequest(fileRequested)) {
|
||||
isApiRequest = true;
|
||||
|
||||
// Set appropriate response headers
|
||||
dataOut.write("HTTP/1.1 200 OK\r\n".getBytes(StandardCharsets.UTF_8));
|
||||
dataOut.write("Date: %s\r\n".formatted(Instant.now()).getBytes(StandardCharsets.UTF_8));
|
||||
if (fileRequested.equals("/api/v1/servericon")) {
|
||||
dataOut.write("Content-Type: image/png\r\n".getBytes(StandardCharsets.UTF_8));
|
||||
// Get server icon from ApiHandler
|
||||
byte[] serverIcon = ApiRequestsUtil.getServerIcon();
|
||||
int contentLength = serverIcon.length;
|
||||
|
||||
dataOut.write(("Content-Length: " + contentLength + "\r\n").getBytes(StandardCharsets.UTF_8));
|
||||
dataOut.write("\r\n".getBytes(StandardCharsets.UTF_8)); // Blank line before content
|
||||
|
||||
// Send server icon
|
||||
dataOut.write(serverIcon, 0, contentLength);
|
||||
dataOut.flush();
|
||||
} else {
|
||||
dataOut.write("Content-Type: application/json\r\n".getBytes(StandardCharsets.UTF_8));
|
||||
String jsonString = "";
|
||||
try {
|
||||
// Get JSON data from ApiHandler
|
||||
jsonString = ApiHandler.handle(fileRequested);
|
||||
} catch (Exception e) {
|
||||
VerboseLogger.error("Error getting JSON data from ApiHandler: " + e.getMessage());
|
||||
jsonString = ApiRequests.internalServerError();
|
||||
}
|
||||
|
||||
|
||||
byte[] jsonBytes = jsonString.getBytes(StandardCharsets.UTF_8);
|
||||
int contentLength = jsonBytes.length;
|
||||
|
||||
dataOut.write(("Content-Length: " + contentLength + "\r\n").getBytes(StandardCharsets.UTF_8));
|
||||
dataOut.write("\r\n".getBytes(StandardCharsets.UTF_8)); // Blank line before content
|
||||
|
||||
// Send JSON data
|
||||
dataOut.write(jsonBytes, 0, contentLength);
|
||||
dataOut.flush();
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
isApiRequest = false;
|
||||
// GET or HEAD method
|
||||
if (fileRequested.endsWith("/")) {
|
||||
fileRequested += DEFAULT_FILE;
|
||||
|
@ -164,6 +213,8 @@ public class HTTPServer implements Runnable {
|
|||
|
||||
} catch (NoSuchFileException e) {
|
||||
try {
|
||||
assert out != null;
|
||||
assert dataOut != null;
|
||||
fileNotFound(out, dataOut, fileRequested);
|
||||
} catch (IOException ioe) {
|
||||
VerboseLogger.error("Error with file not found exception : " + ioe.getMessage());
|
||||
|
@ -175,6 +226,7 @@ public class HTTPServer implements Runnable {
|
|||
try {
|
||||
in.close();
|
||||
out.close();
|
||||
assert dataOut != null;
|
||||
dataOut.close();
|
||||
connect.close(); // we close socket connection
|
||||
} catch (Exception e) {
|
||||
|
@ -193,7 +245,9 @@ public class HTTPServer implements Runnable {
|
|||
|
||||
// return supported MIME Types
|
||||
private String getContentType(String fileRequested) {
|
||||
if (fileRequested.endsWith(".htm") || fileRequested.endsWith(".html"))
|
||||
if (isApiRequest) {
|
||||
return "application/json";
|
||||
} else if (fileRequested.endsWith(".htm") || fileRequested.endsWith(".html"))
|
||||
return "text/html";
|
||||
else if (fileRequested.endsWith(".css"))
|
||||
return "text/css";
|
|
@ -1,21 +1,60 @@
|
|||
package me.jonasjones.mcwebserver.web;
|
||||
|
||||
|
||||
import com.roxstudio.utils.CUrl;
|
||||
import me.jonasjones.mcwebserver.config.ModConfigs;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static me.jonasjones.mcwebserver.McWebserver.LOGGER;
|
||||
import static me.jonasjones.mcwebserver.config.ModConfigs.WEB_PORT;
|
||||
|
||||
public class ServerHandler implements Runnable {
|
||||
public static Socket socket = new Socket();
|
||||
|
||||
private static final ServerHandler webserver = new ServerHandler();
|
||||
public static Thread webserverthread = new Thread(webserver);
|
||||
|
||||
public static boolean mcserveractive = true;
|
||||
|
||||
public static void start() {
|
||||
webserverthread.setName("McWebserver-webserver");
|
||||
webserverthread.start();
|
||||
Thread serverthread = new Thread(() -> {
|
||||
while (true) {
|
||||
if (!mcserveractive) {
|
||||
sleep(2);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
CUrl curl = new CUrl("http://localhost:" + WEB_PORT + "/api/v1/dummy").timeout(1, 1); // a truly awful way of stopping this thread
|
||||
curl.exec();
|
||||
sleep(1);
|
||||
}
|
||||
LOGGER.info("Webserver Stopped!");
|
||||
break;
|
||||
} else {
|
||||
sleep(2);
|
||||
}
|
||||
}
|
||||
});
|
||||
serverthread.setName("McWebserver-main");
|
||||
serverthread.start();
|
||||
}
|
||||
|
||||
private static void sleep(int seconds) {
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(seconds);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if (ModConfigs.IS_ENABLED) {
|
||||
LOGGER.info("Starting Webserver...");
|
||||
|
||||
new HTTPServer(socket);
|
||||
HTTPServer.main();
|
||||
new HttpServer(socket);
|
||||
HttpServer.main();
|
||||
} else {
|
||||
LOGGER.info("Webserver disabled in the config file.");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
|
||||
public class ApiHandler {
|
||||
|
||||
public static Boolean isApiRequest(String request) {
|
||||
return request.startsWith("/api/v1/");
|
||||
}
|
||||
public static String handle(String request) {
|
||||
switch (request.replace("/api/v1/", "")) {
|
||||
// Simple API Requests
|
||||
case "motd" -> {
|
||||
return ApiRequests.singleValueRequest(ApiRequestsUtil.getMOTD());
|
||||
}
|
||||
case "serverip" -> {
|
||||
return ApiRequests.singleValueRequest(ApiRequestsUtil.getSERVER_IP());
|
||||
}
|
||||
case "serverport" -> {
|
||||
return ApiRequests.singleValueRequest(String.valueOf(ApiRequestsUtil.getSERVER_PORT()));
|
||||
}
|
||||
case "servername" -> {
|
||||
return ApiRequests.singleValueRequest(ApiRequestsUtil.getSERVER_NAME());
|
||||
}
|
||||
case "serverversion" -> {
|
||||
return ApiRequests.singleValueRequest(ApiRequestsUtil.getSERVER_VERSION());
|
||||
}
|
||||
case "loaderversion" -> {
|
||||
return ApiRequests.singleValueRequest(ApiRequestsUtil.getLOADER_VERSION());
|
||||
}
|
||||
case "currentplayercount" -> {
|
||||
return ApiRequests.singleValueRequest(String.valueOf(ApiRequestsUtil.getCURRENT_PLAYER_COUNT()));
|
||||
}
|
||||
case "defaultgamemode" -> {
|
||||
return ApiRequests.singleValueRequest(ApiRequestsUtil.getDEFAULT_GAME_MODE().toString());
|
||||
}
|
||||
case "maxplayercount" -> {
|
||||
return ApiRequests.singleValueRequest(String.valueOf(ApiRequestsUtil.getMAX_PLAYER_COUNT()));
|
||||
}
|
||||
case "playernames" -> {
|
||||
return ApiRequests.playerNamesRequest();
|
||||
}
|
||||
case "servermetadata" -> {
|
||||
return ApiRequests.serverMetadataRequest();
|
||||
}
|
||||
case "ticks" -> {
|
||||
return ApiRequests.singleValueRequest(String.valueOf(ApiRequestsUtil.getTICKS()));
|
||||
}
|
||||
case "ticktime" -> {
|
||||
return ApiRequests.singleValueRequest(String.valueOf(ApiRequestsUtil.getTICK_TIME()));
|
||||
}
|
||||
case "timereference" -> {
|
||||
return ApiRequests.singleValueRequest(String.valueOf(ApiRequestsUtil.getTIME_REFERENCE()));
|
||||
}
|
||||
case "getall" -> {
|
||||
return ApiRequests.serverGetAllRequest();
|
||||
}
|
||||
default -> {
|
||||
return ApiRequests.badRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void startHandler() {
|
||||
//This is a really awful way of collection all this info. Please don't kill me.
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
if (server.isRunning()) {
|
||||
ApiRequestsUtil.setMOTD(server.getServerMotd());
|
||||
ApiRequestsUtil.setSERVER_IP(server.getServerIp());
|
||||
ApiRequestsUtil.setSERVER_PORT(server.getServerPort());
|
||||
ApiRequestsUtil.setSERVER_NAME(server.getName());
|
||||
ApiRequestsUtil.setSERVER_VERSION(server.getVersion());
|
||||
ApiRequestsUtil.setCURRENT_PLAYER_COUNT(server.getCurrentPlayerCount());
|
||||
ApiRequestsUtil.setDEFAULT_GAME_MODE(server.getDefaultGameMode());
|
||||
ApiRequestsUtil.setMAX_PLAYER_COUNT(server.getMaxPlayerCount());
|
||||
ApiRequestsUtil.setSERVER_METADATA(server.getServerMetadata());
|
||||
ApiRequestsUtil.setTICKS(server.getTicks());
|
||||
ApiRequestsUtil.setTICK_TIME(server.getTickTime());
|
||||
ApiRequestsUtil.setTIME_REFERENCE(server.getTimeReference());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void startAdvHandler() {
|
||||
//This is a really awful way of collection all this info. Please don't kill me.
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
if (server.isRunning()) {
|
||||
ApiRequestsUtil.setSERVER_PLAYER_ENTITY_LIST(server.getPlayerManager().getPlayerList());
|
||||
ApiRequestsUtil.setSERVER_RESOURCE_PACK_PROFILE_COLLECTION(server.getDataPackManager().getProfiles());
|
||||
ApiRequestsUtil.setSERVER_ADVANCEMENT_COLLECTION(server.getAdvancementLoader().getAdvancements());
|
||||
ApiRequestsUtil.setSERVER_BOSSBAR_COLLECTION(server.getBossBarManager().getAll());
|
||||
ApiRequestsUtil.getSERVER_PLAYER_ENTITY_LIST().forEach(serverPlayerEntity -> {
|
||||
|
||||
});
|
||||
//SERVER_PLAYER_ENTITY_LIST = server.getPlayerInteractionManager().getPlayerList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class ApiRequests {
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
public static String singleValueRequest(String value) {
|
||||
return "[\"" + value + "\"]";
|
||||
}
|
||||
|
||||
public static String playerNamesRequest() {
|
||||
return gson.toJsonTree(ApiRequestsUtil.convertPlayerList(ApiRequestsUtil.getSERVER_METADATA().players().get().sample())).getAsJsonArray().toString();
|
||||
}
|
||||
|
||||
public static String serverMetadataRequest() {
|
||||
return gson.toJson(ApiRequestsUtil.serverMetadata());
|
||||
}
|
||||
|
||||
public static String serverGetAllRequest() {
|
||||
return gson.toJson(ApiRequestsUtil.getAll());
|
||||
}
|
||||
|
||||
public static String badRequest() {
|
||||
return "{\"error\":{\"status\":400,\"message\":\"Bad Request\"}}";
|
||||
}
|
||||
|
||||
public static String internalServerError() {
|
||||
return "{\"error\":{\"status\":500,\"message\":\"Internal Server Error\"}}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.json.ApiServerInfo;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.json.ApiServerMetadata;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.json.ApiServerMetadataPlayer;
|
||||
import me.jonasjones.mcwebserver.web.api.v1.json.ApiServerMetadataPlayers;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.advancement.Advancement;
|
||||
import net.minecraft.entity.boss.CommandBossBar;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.server.ServerMetadata;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.world.GameMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static me.jonasjones.mcwebserver.config.ModConfigs.WEB_PORT;
|
||||
|
||||
public class ApiRequestsUtil {
|
||||
@Getter @Setter
|
||||
private static String MOTD;
|
||||
@Getter @Setter
|
||||
private static String SERVER_IP;
|
||||
@Getter @Setter
|
||||
private static int SERVER_PORT;
|
||||
@Getter @Setter
|
||||
private static String SERVER_NAME;
|
||||
@Getter @Setter
|
||||
private static String SERVER_VERSION;
|
||||
@Getter @Setter
|
||||
private static int CURRENT_PLAYER_COUNT;
|
||||
@Getter @Setter
|
||||
private static GameMode DEFAULT_GAME_MODE;
|
||||
@Getter
|
||||
private static final String LOADER_VERSION = FabricLoader.getInstance().getModContainer("fabricloader").get().getMetadata().getVersion().getFriendlyString();
|
||||
@Getter @Setter
|
||||
private static int MAX_PLAYER_COUNT;
|
||||
@Getter @Setter
|
||||
private static ServerMetadata SERVER_METADATA;
|
||||
@Getter @Setter
|
||||
private static int TICKS;
|
||||
@Getter @Setter
|
||||
private static float TICK_TIME;
|
||||
@Getter @Setter
|
||||
private static long TIME_REFERENCE;
|
||||
@Getter @Setter
|
||||
private static List<ServerPlayerEntity> SERVER_PLAYER_ENTITY_LIST = new ArrayList<>();
|
||||
@Getter @Setter
|
||||
private static Collection<ResourcePackProfile> SERVER_RESOURCE_PACK_PROFILE_COLLECTION = new ArrayList<>();
|
||||
@Getter @Setter
|
||||
private static Collection<Advancement> SERVER_ADVANCEMENT_COLLECTION = new ArrayList<>();
|
||||
@Getter @Setter
|
||||
private static Collection<CommandBossBar> SERVER_BOSSBAR_COLLECTION = new ArrayList<>();
|
||||
private static final ApiServerInfo apiServerInfo = new ApiServerInfo();
|
||||
private static final ApiServerMetadata apiServerMetadata = new ApiServerMetadata();
|
||||
private static final ApiServerMetadataPlayers apiServerMetadataPlayers = new ApiServerMetadataPlayers();
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
|
||||
public static JsonObject serverMetadata() {
|
||||
apiServerMetadataPlayers.setMAX(ApiRequestsUtil.getSERVER_METADATA().players().get().max());
|
||||
apiServerMetadataPlayers.setONLINE(ApiRequestsUtil.getSERVER_METADATA().players().get().online());
|
||||
apiServerMetadataPlayers.setSAMPLE(convertPlayerList(ApiRequestsUtil.getSERVER_METADATA().players().get().sample()));
|
||||
|
||||
apiServerMetadata.setDESCRIPTION(ApiRequestsUtil.getSERVER_METADATA().description().getString());
|
||||
apiServerMetadata.setPLAYERS(JsonParser.parseString(gson.toJson(apiServerMetadataPlayers)).getAsJsonObject());
|
||||
apiServerMetadata.setVERSION((JsonObject) JsonParser.parseString("{\"version\":\"" + ApiRequestsUtil.getSERVER_METADATA().version().get().gameVersion() + "\",\"protocol\":" + ApiRequestsUtil.getSERVER_METADATA().version().get().protocolVersion() + "}"));
|
||||
if (ApiRequestsUtil.getSERVER_METADATA().favicon().isPresent()) {
|
||||
if (!ApiRequestsUtil.getSERVER_IP().equals("")) {
|
||||
apiServerMetadata.setFAVICON("http://" + ApiRequestsUtil.getSERVER_IP() + ":" + WEB_PORT + "/api/v1/servericon");
|
||||
} else {
|
||||
apiServerMetadata.setFAVICON("/api/v1/servericon");
|
||||
}
|
||||
} else {
|
||||
apiServerMetadata.setFAVICON(""); // if favicon doesn't exist
|
||||
}
|
||||
|
||||
apiServerMetadata.setSECURE_CHAT_EINFORCED(ApiRequestsUtil.getSERVER_METADATA().secureChatEnforced());
|
||||
|
||||
return JsonParser.parseString(gson.toJson(apiServerMetadata)).getAsJsonObject();
|
||||
}
|
||||
|
||||
public static ArrayList<ApiServerMetadataPlayer> convertPlayerList(List<GameProfile> list) {
|
||||
ArrayList<ApiServerMetadataPlayer> players = new ArrayList<>();
|
||||
for (GameProfile profile : list) {
|
||||
ApiServerMetadataPlayer player = new ApiServerMetadataPlayer();
|
||||
player.setID(profile.getId().toString());
|
||||
player.setNAME(profile.getName());
|
||||
//player.setPROPERTIES(profile.getProperties().toString()); //Add support for the properties later
|
||||
player.setLEGACY(profile.isLegacy());
|
||||
players.add(player);
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
public static JsonObject getAll() {
|
||||
apiServerInfo.setSERVER_IP(ApiRequestsUtil.getSERVER_IP());
|
||||
apiServerInfo.setSERVER_PORT(ApiRequestsUtil.getSERVER_PORT());
|
||||
apiServerInfo.setSERVER_NAME(ApiRequestsUtil.getSERVER_NAME());
|
||||
apiServerInfo.setDEFAULT_GAME_MODE(ApiRequestsUtil.getDEFAULT_GAME_MODE().toString());
|
||||
apiServerInfo.setLOADER_VERSION(LOADER_VERSION);
|
||||
apiServerInfo.setMETADATA(serverMetadata());
|
||||
apiServerInfo.setTICKS(ApiRequestsUtil.getTICKS());
|
||||
apiServerInfo.setTICK_TIME(ApiRequestsUtil.getTICK_TIME());
|
||||
apiServerInfo.setTIME_REFERENCE(ApiRequestsUtil.getTIME_REFERENCE());
|
||||
|
||||
return gson.toJsonTree(apiServerInfo).getAsJsonObject();
|
||||
}
|
||||
|
||||
public static byte[] getServerIcon() {
|
||||
return ApiRequestsUtil.getSERVER_METADATA().favicon().get().iconBytes();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1.json;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
public class ApiServerInfo {
|
||||
private String SERVER_IP;
|
||||
private int SERVER_PORT;
|
||||
private String SERVER_NAME;
|
||||
private String DEFAULT_GAME_MODE;
|
||||
private String LOADER_VERSION;
|
||||
private JsonObject METADATA;
|
||||
private int TICKS;
|
||||
private float TICK_TIME;
|
||||
private long TIME_REFERENCE;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1.json;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
public class ApiServerMetadata {
|
||||
private String DESCRIPTION;
|
||||
private JsonObject PLAYERS;
|
||||
private JsonObject VERSION;
|
||||
private String FAVICON;
|
||||
private Boolean SECURE_CHAT_EINFORCED;
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1.json;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
public class ApiServerMetadataPlayer {
|
||||
private String ID;
|
||||
private String NAME;
|
||||
private String PROPERTIES;
|
||||
private Boolean LEGACY;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1.json;
|
||||
|
||||
public class ApiServerMetadataPlayerProperty {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package me.jonasjones.mcwebserver.web.api.v1.json;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Setter
|
||||
public class ApiServerMetadataPlayers {
|
||||
private int MAX;
|
||||
private int ONLINE;
|
||||
private ArrayList<ApiServerMetadataPlayer> SAMPLE;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue