This commit is contained in:
parent
0db74b9c7b
commit
f9f59d5377
|
@ -1,6 +1,7 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'fabric-loom' version '1.7-SNAPSHOT'
|
id 'fabric-loom' version '1.7-SNAPSHOT'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
|
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
version = project.mod_version
|
version = project.mod_version
|
||||||
|
@ -27,6 +28,7 @@ dependencies {
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
|
implementation 'com.google.code.gson:gson:2.10.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@ -51,6 +53,10 @@ java {
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
relocate('com.google.gson', 'cc.crss.mod.deps.gson')
|
||||||
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
from("LICENSE") {
|
from("LICENSE") {
|
||||||
rename { "${it}_${project.base.archivesName.get()}"}
|
rename { "${it}_${project.base.archivesName.get()}"}
|
||||||
|
|
|
@ -1,16 +1,26 @@
|
||||||
package cc.crss.mod;
|
package cc.crss.mod;
|
||||||
|
import cc.crss.mod.api.ApiServer;
|
||||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import cc.crss.mod.util.CommandRegister;
|
import cc.crss.mod.util.CommandRegister;
|
||||||
|
|
||||||
public class CRSSMod implements DedicatedServerModInitializer {
|
public class CRSSMod implements DedicatedServerModInitializer {
|
||||||
|
|
||||||
public static final Logger LOGGER = LogManager.getLogger("crss");
|
public static final Logger LOGGER = LogManager.getLogger("crss");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeServer() {
|
public void onInitializeServer() {
|
||||||
|
|
||||||
LOGGER.info("CRSS initialising.");
|
LOGGER.info("CRSS initialising.");
|
||||||
|
|
||||||
|
ServerLifecycleEvents.SERVER_STARTED.register(ApiServer::createInstance);
|
||||||
|
ServerLifecycleEvents.SERVER_STOPPING.register(server -> {
|
||||||
|
ApiServer srv = ApiServer.getInstance();
|
||||||
|
|
||||||
|
srv.stop();
|
||||||
|
});
|
||||||
|
|
||||||
CommandRegister.registerCommands();
|
CommandRegister.registerCommands();
|
||||||
}
|
}
|
||||||
}
|
}
|
127
src/main/java/cc/crss/mod/api/ApiServer.java
Normal file
127
src/main/java/cc/crss/mod/api/ApiServer.java
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
package cc.crss.mod.api;
|
||||||
|
|
||||||
|
import cc.crss.mod.api.data.ServerInfo;
|
||||||
|
import net.minecraft.MinecraftVersion;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
|
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cc.crss.mod.CRSSMod.LOGGER;
|
||||||
|
|
||||||
|
public class ApiServer {
|
||||||
|
private static ApiServer instance;
|
||||||
|
|
||||||
|
public static MinecraftServer server;
|
||||||
|
|
||||||
|
private Thread thread;
|
||||||
|
|
||||||
|
public ApiServer(MinecraftServer server) {
|
||||||
|
if (instance != null)
|
||||||
|
throw new RuntimeException("API Server already started.");
|
||||||
|
|
||||||
|
ApiServer.server = server;
|
||||||
|
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApiServer getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createInstance(MinecraftServer server) {
|
||||||
|
instance = new ApiServer(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void start() {
|
||||||
|
this.thread = new Thread(
|
||||||
|
new ServerRunnable(25580)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
this.thread.interrupt();
|
||||||
|
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ServerRunnable implements Runnable {
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
public ServerRunnable(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try (ServerSocket serverSocket = new ServerSocket(port)) {
|
||||||
|
System.out.println("Server is listening on port " + port);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Socket clientSocket = serverSocket.accept();
|
||||||
|
|
||||||
|
clientSocket.setTcpNoDelay(true);
|
||||||
|
|
||||||
|
DataInputStream dataInputStream = new DataInputStream(
|
||||||
|
clientSocket.getInputStream()
|
||||||
|
);
|
||||||
|
|
||||||
|
DataOutputStream dataOutputStream = new DataOutputStream(
|
||||||
|
clientSocket.getOutputStream()
|
||||||
|
);
|
||||||
|
|
||||||
|
byte packetId = dataInputStream.readByte();
|
||||||
|
|
||||||
|
switch (packetId) {
|
||||||
|
case 0x00:
|
||||||
|
MinecraftServer server = ApiServer.server;
|
||||||
|
|
||||||
|
ArrayList<String> worlds = new ArrayList<>();
|
||||||
|
|
||||||
|
server.getWorlds().forEach(world -> {
|
||||||
|
worlds.add(world.getDimension().getType().toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
String jsonData = new ServerInfo(
|
||||||
|
server.getVersion(),
|
||||||
|
server.getCurrentPlayerCount(),
|
||||||
|
worlds.toArray(new String[0])
|
||||||
|
).toJson();
|
||||||
|
|
||||||
|
int length = jsonData.length();
|
||||||
|
|
||||||
|
byte[] responseBytes = new byte[1 + 4 + length];
|
||||||
|
|
||||||
|
responseBytes[0] = 0x00;
|
||||||
|
|
||||||
|
responseBytes[1] = (byte) ((length >> 24) & 0xFF);
|
||||||
|
responseBytes[2] = (byte) ((length >> 16) & 0xFF);
|
||||||
|
responseBytes[3] = (byte) ((length >> 8) & 0xFF);
|
||||||
|
responseBytes[4] = (byte) (length & 0xFF);
|
||||||
|
|
||||||
|
System.arraycopy(jsonData.getBytes(), 0, responseBytes, 5, length);
|
||||||
|
|
||||||
|
dataOutputStream.write(responseBytes);
|
||||||
|
dataOutputStream.flush();
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGGER.warn("Received unknown packet: {}", packetId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error("Error starting API server", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/main/java/cc/crss/mod/api/Model.java
Normal file
13
src/main/java/cc/crss/mod/api/Model.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package cc.crss.mod.api;
|
||||||
|
|
||||||
|
import cc.crss.mod.util.JsonUtil;
|
||||||
|
|
||||||
|
public class Model {
|
||||||
|
public String toJson() {
|
||||||
|
return JsonUtil.gson.toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object fromJson(String json, Class<? extends Model> clazz) {
|
||||||
|
return JsonUtil.gson.fromJson(json, clazz);
|
||||||
|
}
|
||||||
|
}
|
39
src/main/java/cc/crss/mod/api/data/ServerInfo.java
Normal file
39
src/main/java/cc/crss/mod/api/data/ServerInfo.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package cc.crss.mod.api.data;
|
||||||
|
|
||||||
|
import cc.crss.mod.api.Model;
|
||||||
|
|
||||||
|
public class ServerInfo extends Model {
|
||||||
|
private String version;
|
||||||
|
private Integer online;
|
||||||
|
private String[] worlds;
|
||||||
|
|
||||||
|
public ServerInfo(String version, Integer online, String[] worlds) {
|
||||||
|
this.version = version;
|
||||||
|
this.online = online;
|
||||||
|
this.worlds = worlds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOnline() {
|
||||||
|
return online;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getWorlds() {
|
||||||
|
return worlds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnline(Integer online) {
|
||||||
|
this.online = online;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorlds(String[] worlds) {
|
||||||
|
this.worlds = worlds;
|
||||||
|
}
|
||||||
|
}
|
11
src/main/java/cc/crss/mod/util/JsonUtil.java
Normal file
11
src/main/java/cc/crss/mod/util/JsonUtil.java
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package cc.crss.mod.util;
|
||||||
|
|
||||||
|
import com.google.gson.FieldNamingPolicy;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
public class JsonUtil {
|
||||||
|
public static Gson gson = new GsonBuilder()
|
||||||
|
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||||
|
.create();
|
||||||
|
}
|
|
@ -8,5 +8,5 @@
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue