This commit is contained in:
JFronny 2020-09-07 15:03:15 +02:00
parent 0a170a36a6
commit 7bc94e645b
7 changed files with 87 additions and 41 deletions

View File

@ -5,6 +5,7 @@ variables:
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle
- chmod a+x gradlew
deploy:
stage: deploy

View File

@ -16,11 +16,12 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
// You may need to force-disable transitiveness on them.
modApi("me.sargunvohra.mcmods:autoconfig1u:3.2.2") {
exclude(group: "net.fabricmc.fabric-api")
}
include "me.sargunvohra.mcmods:autoconfig1u:3.2.2"
}
processResources {

View File

@ -0,0 +1,20 @@
package io.gitlab.jfronny.dynres;
import me.sargunvohra.mcmods.autoconfig1u.ConfigData;
import me.sargunvohra.mcmods.autoconfig1u.annotation.Config;
import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.Comment;
@Config(name = "dynres")
public class Cfg implements ConfigData {
@Comment("The port to use for hosting the file. Use 0 for a random one")
public int port = 0;
@Comment("The number of allowed concurrent downloads. Higher values prevent errors on clients but can increase load")
public int maxConnections = 20;
@Comment("The relative path to the resources zip. Expect strange behaviour if changed")
public String resourcesFile = "resources.zip";
@Comment("Set to true to provide a hash to clients. Changes to the pack will require a server restart with this")
public boolean hashResources = false;
}

View File

@ -3,49 +3,66 @@ package io.gitlab.jfronny.dynres;
import com.mojang.brigadier.Command;
import io.gitlab.jfronny.dynres.web.RequestHandler;
import io.gitlab.jfronny.dynres.web.bluemapcore.WebServer;
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
import me.sargunvohra.mcmods.autoconfig1u.serializer.JanksonConfigSerializer;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.gui.FabricGuiEntry;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
import net.minecraft.text.LiteralText;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
//TODO host the pack
@Environment(EnvType.SERVER)
public class DynRes implements DedicatedServerModInitializer {
static WebServer server;
public static final String resFile = "resources.zip";
public static File resFile;
public static Cfg cfg;
public static final String baseLink = "http://127.0.0.1/";
static {
AutoConfig.register(Cfg.class, JanksonConfigSerializer::new);
cfg = AutoConfig.getConfigHolder(Cfg.class).getConfig();
resFile = new File(FabricLoader.getInstance().getGameDir().toFile(), cfg.resourcesFile);
if (!resFile.isFile()) {
FabricGuiEntry.displayCriticalError(new FileNotFoundException("The file " + resFile + " does not exist in the game directory but is required"), true);
}
}
@Override
public void onInitializeServer() {
//TODO allow setting max connections or fixed port
//TODO allow setting custom resources path
File f = new File(FabricLoader.getInstance().getGameDir().toFile(), resFile);
if (!f.isFile()) {
FabricGuiEntry.displayCriticalError(new FileNotFoundException("The file resources.zip does not exist in the game directory but is required"), true);
return;
}
server = new WebServer(0, 20, null, new RequestHandler(f, resFile));
server = new WebServer(cfg.port, cfg.maxConnections, null, new RequestHandler("resources.zip"));
server.start();
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> {
if (dedicated) {
dispatcher.register(CommandManager.literal("dynres").executes(context -> {
context.getSource().sendFeedback(new LiteralText("DynRes is active. Use dynres restart if it breaks"), false);
context.getSource().sendFeedback(new LiteralText("DynRes is active. Use dynres restart to reload"), false);
return Command.SINGLE_SUCCESS;
}));
dispatcher.register(CommandManager.literal("dynres").then(CommandManager.literal("restart")).executes(context -> {
context.getSource().sendFeedback(new LiteralText("Restarting DynRes"), true);
server.start();
context.getSource().sendFeedback(new LiteralText("DynRes restarted"), true);
dispatcher.register(CommandManager.literal("dynres").then(CommandManager.literal("restart").executes(context -> {
try {
context.getSource().sendFeedback(new LiteralText("Restarting DynRes"), true);
cfg = AutoConfig.getConfigHolder(Cfg.class).getConfig();
server.setPort(cfg.port);
server.setMaxConnections(cfg.maxConnections);
resFile = new File(FabricLoader.getInstance().getGameDir().toFile(), cfg.resourcesFile);
server.close();
server.start();
context.getSource().sendFeedback(new LiteralText("DynRes restarted"), true);
}
catch (Exception e) {
e.printStackTrace();
context.getSource().sendError(new LiteralText(e.getMessage()));
}
return Command.SINGLE_SUCCESS;
}));
})));
}
else {
System.err.println("DYNRES SHOULD NOT BE RUN ON INTERNAL SERVERS!");

View File

@ -3,12 +3,15 @@ package io.gitlab.jfronny.dynres.mixin;
import io.gitlab.jfronny.dynres.DynRes;
import net.minecraft.server.dedicated.ServerPropertiesHandler;
import net.minecraft.util.registry.DynamicRegistryManager;
import org.apache.commons.codec.digest.DigestUtils;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
@Mixin(ServerPropertiesHandler.class)
@ -21,17 +24,21 @@ public class ServerPropertiesHandlerMixin {
@Inject(at = @At("RETURN"), method = "<init>(Ljava/util/Properties;Lnet/minecraft/util/registry/DynamicRegistryManager;)V")
public void init(Properties properties, DynamicRegistryManager dynamicRegistryManager, CallbackInfo info) {
System.err.println(resourcePack);
System.err.println(resourcePackHash);
System.err.println(resourcePackSha1);
resourcePack = DynRes.removePort(DynRes.simplifyElement(DynRes.baseLink)) + ":" + DynRes.getPort() + "/" + DynRes.simplifyElement(DynRes.resFile);
resourcePack = DynRes.removePort(DynRes.simplifyElement(DynRes.baseLink)) + ":" + DynRes.getPort() + "/resources.zip";
System.out.println("Pack link: " + resourcePack);
//TODO hash the pack
resourcePackSha1 = "";
if (DynRes.cfg.hashResources) {
try {
FileInputStream fs = new FileInputStream(DynRes.resFile);
resourcePackSha1 = DigestUtils.sha1Hex(fs);
System.out.println("Set hash to " + resourcePackSha1);
fs.close();
} catch (IOException e) {
System.err.println("Failed to get hash, continuing with empty");
e.printStackTrace();
}
}
resourcePackHash = resourcePackSha1;
System.err.println(resourcePack);
System.err.println(resourcePackHash);
System.err.println(resourcePackSha1);
}
}

View File

@ -5,20 +5,13 @@ import io.gitlab.jfronny.dynres.web.bluemapcore.HttpRequest;
import io.gitlab.jfronny.dynres.web.bluemapcore.HttpRequestHandler;
import io.gitlab.jfronny.dynres.web.bluemapcore.HttpResponse;
import io.gitlab.jfronny.dynres.web.bluemapcore.HttpStatusCode;
import org.apache.http.HttpException;
import org.apache.http.MethodNotSupportedException;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
public class RequestHandler implements HttpRequestHandler {
File f;
String r;
@Override
public HttpResponse handle(HttpRequest request) {
@ -38,7 +31,7 @@ public class RequestHandler implements HttpRequestHandler {
resp.addHeader("Content-Type", "application/zip");
try {
FileInputStream fs = new FileInputStream(f);
FileInputStream fs = new FileInputStream(DynRes.resFile);
resp.setData(fs);
return resp;
} catch (FileNotFoundException e) {
@ -49,8 +42,7 @@ public class RequestHandler implements HttpRequestHandler {
return new HttpResponse(HttpStatusCode.NOT_FOUND);
}
public RequestHandler(File file, String relativePath) {
f = file;
public RequestHandler(String relativePath) {
r = relativePath;
}
}

View File

@ -36,8 +36,8 @@ import java.util.concurrent.TimeUnit;
public class WebServer extends Thread {
private final int port;
private final int maxConnections;
private int port;
private int maxConnections;
private final InetAddress bindAdress;
private HttpRequestHandler handler;
@ -101,6 +101,14 @@ public class WebServer extends Thread {
public int getPort() {
return server.getLocalPort();
}
public void setPort(int port) {
this.port = port;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
public void close(){
if (connectionThreads != null) connectionThreads.shutdown();