diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ce92dfa..865bc7e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ variables: before_script: - export GRADLE_USER_HOME=`pwd`/.gradle + - chmod a+x gradlew deploy: stage: deploy diff --git a/build.gradle b/build.gradle index 0b480cf..2437eb3 100644 --- a/build.gradle +++ b/build.gradle @@ -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 { diff --git a/src/main/java/io/gitlab/jfronny/dynres/Cfg.java b/src/main/java/io/gitlab/jfronny/dynres/Cfg.java new file mode 100644 index 0000000..0a21f1e --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/dynres/Cfg.java @@ -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; +} diff --git a/src/main/java/io/gitlab/jfronny/dynres/DynRes.java b/src/main/java/io/gitlab/jfronny/dynres/DynRes.java index 926b259..f89d876 100644 --- a/src/main/java/io/gitlab/jfronny/dynres/DynRes.java +++ b/src/main/java/io/gitlab/jfronny/dynres/DynRes.java @@ -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!"); diff --git a/src/main/java/io/gitlab/jfronny/dynres/mixin/ServerPropertiesHandlerMixin.java b/src/main/java/io/gitlab/jfronny/dynres/mixin/ServerPropertiesHandlerMixin.java index 2a0cb6a..1b0f456 100644 --- a/src/main/java/io/gitlab/jfronny/dynres/mixin/ServerPropertiesHandlerMixin.java +++ b/src/main/java/io/gitlab/jfronny/dynres/mixin/ServerPropertiesHandlerMixin.java @@ -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 = "(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); } } diff --git a/src/main/java/io/gitlab/jfronny/dynres/web/RequestHandler.java b/src/main/java/io/gitlab/jfronny/dynres/web/RequestHandler.java index 85187d1..fa856b6 100644 --- a/src/main/java/io/gitlab/jfronny/dynres/web/RequestHandler.java +++ b/src/main/java/io/gitlab/jfronny/dynres/web/RequestHandler.java @@ -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; } } diff --git a/src/main/java/io/gitlab/jfronny/dynres/web/bluemapcore/WebServer.java b/src/main/java/io/gitlab/jfronny/dynres/web/bluemapcore/WebServer.java index 89acb3d..0a86002 100644 --- a/src/main/java/io/gitlab/jfronny/dynres/web/bluemapcore/WebServer.java +++ b/src/main/java/io/gitlab/jfronny/dynres/web/bluemapcore/WebServer.java @@ -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();