diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cf5d82c..aa55379 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,11 +6,21 @@ variables: before_script: - export GRADLE_USER_HOME=`pwd`/.gradle -deploy: +build_test: stage: deploy - script: gradle --build-cache assemble + script: + - gradle --build-cache assemble + - cp build/libs/* ./ + - rm *-dev.jar + - mv *.jar latest.jar artifacts: paths: - build/libs + - latest.jar only: - master + +modrinth: + stage: deploy + when: manual + script: gradle --build-cache publishModrinth \ No newline at end of file diff --git a/build.gradle b/build.gradle index dbec2ec..8a4a347 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'fabric-loom' version '0.5-SNAPSHOT' id 'maven-publish' + id "com.modrinth.minotaur" version "1.1.0" } sourceCompatibility = JavaVersion.VERSION_1_8 @@ -11,7 +12,7 @@ version = project.mod_version group = project.maven_group repositories { - maven { url = 'http://maven.fabricmc.net/'; name = "Fabric" } + maven {url = "https://dl.bintray.com/user11681/maven"} maven { url = 'https://jitpack.io' } } @@ -26,19 +27,17 @@ dependencies { // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. // You may need to force-disable transitiveness on them. - modImplementation 'com.github.Arc-blroth:Mixon:-SNAPSHOT' - include 'com.github.Arc-blroth:Mixon:-SNAPSHOT' modCompile "me.sargunvohra.mcmods:autoconfig1u:3.2.0-unstable" include "me.sargunvohra.mcmods:autoconfig1u:3.2.0-unstable" - modApi ("me.shedaniel.cloth:config-2:4.8.1") { + modApi ("me.shedaniel.cloth:config-2:4.8.3") { transitive = false } - include ("me.shedaniel.cloth:config-2:4.8.1") { + include ("me.shedaniel.cloth:config-2:4.8.3") { transitive = false } - modCompile("io.github.prospector:modmenu:1.14.6+build.31") { + modCompile("io.github.prospector:modmenu:1.14.9+build.14") { transitive = false } } @@ -75,23 +74,18 @@ jar { from "LICENSE" } -// configure the maven publication -publishing { - publications { - mavenJava(MavenPublication) { - // add all the jars that should be included when publishing to maven - artifact(remapJar) { - builtBy remapJar - } - artifact(sourcesJar) { - builtBy remapSourcesJar - } - } - } +import com.modrinth.minotaur.TaskModrinthUpload - // select the repositories you want to publish to - repositories { - // uncomment to publish to the local maven - // mavenLocal() +task publishModrinth (type: TaskModrinthUpload){ + token = System.getenv("MODRINTH_API_TOKEN") // Use an environment property! + projectId = '4GhX11Ed' + versionNumber = "${project.mod_version}" + uploadFile = remapJar // This is the java jar task + addGameVersion("${project.minecraft_version}") + addLoader('fabric') + versionName = "[${project.minecraft_version}] ${project.mod_version}" + afterEvaluate { + tasks.publishModrinth.dependsOn(remapJar) + tasks.publishModrinth.dependsOn(sourcesJar) } } diff --git a/gradle.properties b/gradle.properties index 6bc9373..53069d7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,13 +2,13 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html -minecraft_version=1.16.2 -yarn_mappings=1.16.2+build.31 -loader_version=0.9.2+build.206 +minecraft_version=1.16.4 +yarn_mappings=1.16.4+build.7 +loader_version=0.10.8 # Mod Properties -mod_version=1.0 +mod_version=2.0 maven_group=io.gitlab.jfronny archives_base_name=modsmod # Dependencies # check this on https://modmuss50.me/fabric.html -fabric_version=0.19.0+build.398-1.16 +fabric_version=0.26.2+1.16 diff --git a/src/main/java/io/gitlab/jfronny/modsmod/Cfg.java b/src/main/java/io/gitlab/jfronny/modsmod/Cfg.java index 385fdba..9df6534 100644 --- a/src/main/java/io/gitlab/jfronny/modsmod/Cfg.java +++ b/src/main/java/io/gitlab/jfronny/modsmod/Cfg.java @@ -10,7 +10,7 @@ public class Cfg implements ConfigData { @Comment("The amount of mods to generate. Don't set this too high") @RequiresRestart public int modsCount = 263; - @Comment("Show the mods as children of ModsMod in ModMenu. Might also hide from mod count") + @Comment("Show the mods as children of ModsMod in ModMenu") @RequiresRestart public boolean parent = false; @Comment("Cache the generated files. Increases performance. Disable when this stops working to regenerate") diff --git a/src/main/java/io/gitlab/jfronny/modsmod/FabricLoaderInterface.java b/src/main/java/io/gitlab/jfronny/modsmod/FabricLoaderInterface.java new file mode 100644 index 0000000..0cd0462 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/modsmod/FabricLoaderInterface.java @@ -0,0 +1,83 @@ +package io.gitlab.jfronny.modsmod; + +import net.fabricmc.loader.FabricLoader; +import net.fabricmc.loader.ModContainer; +import net.fabricmc.loader.discovery.ModCandidate; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; + +public class FabricLoaderInterface { + public static final Logger logger = LogManager.getLogger("modsmod"); + + private static final Method addModMethod; + private static final Field modsField; + + //private static final Field abstractListModCount; + + static { + try { + addModMethod = FabricLoader.class.getDeclaredMethod("addMod", ModCandidate.class); + addModMethod.setAccessible(true); + + modsField = FabricLoader.class.getDeclaredField("mods"); + modsField.setAccessible(true); + + //abstractListModCount = AbstractList.class.getDeclaredField("modCount"); + //abstractListModCount.setAccessible(true); + } catch (NoSuchMethodException | NoSuchFieldException e) { + logger.error("Failed to get reference to fabric-loader internals. The fabric-loader version may be incompatible with patchwork-runtime.", e); + throw new IllegalStateException(e); + } + } + + public static void synchronize(FabricLoader fabricLoader) { + try { + modsField.set(fabricLoader, Collections.synchronizedList((List)modsField.get(fabricLoader))); + } catch (IllegalAccessException e) { + logger.error("Failed to make mods list synchronized.", e); + throw new IllegalStateException(e); + } + } + + public static void addMod(FabricLoader fabricLoader, ModCandidate modCandidate) { + try { + addModMethod.invoke(fabricLoader, modCandidate); + } catch (IllegalAccessException | InvocationTargetException e) { + logger.error("Failed to inject mod into fabric-loader.", e); + throw new IllegalStateException(e); + } + } + + public static List getMods(FabricLoader fabricLoader) { + try { + return (List) modsField.get(fabricLoader); + } catch (IllegalAccessException e) { + logger.error("Failed to get mods from fabric-loader.", e); + throw new IllegalStateException(e); + } + } + + /*public static int getModCount(FabricLoader fabricLoader) { + try { + return abstractListModCount.getInt(getMods(fabricLoader)); + } catch (IllegalAccessException e) { + logger.error("Failed to get modCount from fabric-loader.", e); + throw new IllegalStateException(e); + } + } + + public static void setModCount(FabricLoader fabricLoader, int modCount) { + try { + abstractListModCount.setInt(getMods(fabricLoader), modCount); + } catch (IllegalAccessException e) { + logger.error("Failed to set modCount in fabric-loader.", e); + throw new IllegalStateException(e); + } + }*/ +} diff --git a/src/main/java/io/gitlab/jfronny/modsmod/ModsModAdapter.java b/src/main/java/io/gitlab/jfronny/modsmod/ModsModAdapter.java new file mode 100644 index 0000000..3f866f0 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/modsmod/ModsModAdapter.java @@ -0,0 +1,14 @@ +package io.gitlab.jfronny.modsmod; + +import net.fabricmc.loader.api.LanguageAdapter; +import net.fabricmc.loader.api.LanguageAdapterException; +import net.fabricmc.loader.api.ModContainer; + +public class ModsModAdapter implements LanguageAdapter { + @Override + public native T create(net.fabricmc.loader.api.ModContainer mod, String value, Class type); + + static { + new PreLaunch().onPrePrePreLaunch(); + } +} diff --git a/src/main/java/io/gitlab/jfronny/modsmod/PreLaunch.java b/src/main/java/io/gitlab/jfronny/modsmod/PreLaunch.java index 9cd8c76..11ad6e6 100644 --- a/src/main/java/io/gitlab/jfronny/modsmod/PreLaunch.java +++ b/src/main/java/io/gitlab/jfronny/modsmod/PreLaunch.java @@ -1,12 +1,17 @@ package io.gitlab.jfronny.modsmod; -import ai.arcblroth.mixon.api.MixonModInjector; -import ai.arcblroth.mixon.api.PrePrePreLaunch; import me.sargunvohra.mcmods.autoconfig1u.AutoConfig; import me.sargunvohra.mcmods.autoconfig1u.serializer.JanksonConfigSerializer; -import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.FabricLoader; +import net.fabricmc.loader.discovery.ModCandidate; +import net.fabricmc.loader.discovery.ModResolver; +import net.fabricmc.loader.discovery.RuntimeModRemapper; +import net.fabricmc.loader.launch.common.FabricLauncherBase; +import net.fabricmc.loader.metadata.LoaderModMetadata; +import net.fabricmc.loader.metadata.ModMetadataParser; +import net.fabricmc.loader.metadata.ParseMetadataException; +import net.fabricmc.loader.util.FileSystemUtil; import org.apache.commons.io.FileUtils; -import org.lwjgl.system.CallbackI; import java.io.File; import java.io.FileOutputStream; @@ -15,17 +20,18 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.Collections; +import java.util.HashSet; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -public class PreLaunch implements PrePrePreLaunch { - @Override +public class PreLaunch { public void onPrePrePreLaunch() { + FabricLoader loader = FabricLoader.INSTANCE; //Load config AutoConfig.register(Cfg.class, JanksonConfigSerializer::new); Cfg cfg = AutoConfig.getConfigHolder(Cfg.class).getConfig(); - Path configDir = FabricLoader.getInstance().getConfigDir(); - MixonModInjector injector = MixonModInjector.getInstance(); + Path configDir = loader.getConfigDir(); String modsmodCfgFileName = "ModsMod.json5"; //make sure the modsmodcache dir is ok File path = new File(configDir.toFile(), "modsmodcache"); @@ -54,10 +60,11 @@ public class PreLaunch implements PrePrePreLaunch { System.err.println("Failed to validate modsmod config cache, caching will not be available"); e.printStackTrace(); } + HashSet m = new HashSet<>(); //Generate mods for (int i = 0; i < cfg.modsCount; i++) { File f = new File(path, "f" + (i + 1) + ".jar"); - injector.addMod(f); + m.add(f); //Do not load if cached if (f.exists()) { if (cfg.cache) continue; @@ -101,5 +108,36 @@ public class PreLaunch implements PrePrePreLaunch { } System.gc(); } + //FabricLoaderInterface.synchronize(loader); + //int oldCount = FabricLoaderInterface.getModCount(loader); + for (File f : m) { + loadMod(loader, f.toPath()); + } + //FabricLoaderInterface.setModCount(loader, oldCount); + } + + private void loadMod(FabricLoader loader, Path modPath) { + ModCandidate candidate = parseMod(modPath); + + if (loader.isDevelopmentEnvironment()) { + candidate = RuntimeModRemapper.remap(Collections.singletonList(candidate), ModResolver.getInMemoryFs()).stream().findFirst().get(); + } + + FabricLoaderInterface.addMod(loader, candidate); + FabricLauncherBase.getLauncher().propose(candidate.getOriginUrl()); + } + + private ModCandidate parseMod(Path modPath) { + try { + FileSystemUtil.FileSystemDelegate jarFs = FileSystemUtil.getJarFileSystem(modPath, false); + + Path modJson = jarFs.get().getPath("fabric.mod.json"); + + LoaderModMetadata info = ModMetadataParser.parseMetadata(FabricLoaderInterface.logger, modJson); + + return new ModCandidate(info, modPath.toUri().toURL(), 0, true); + } catch (IOException | ParseMetadataException e) { + throw new IllegalStateException(e); + } } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 3fa6942..46c058b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -15,17 +15,16 @@ "icon": "assets/modsmod/icon.png", "environment": "*", "entrypoints": { - "mixon:prepreprelaunch": [ - "io.gitlab.jfronny.modsmod.PreLaunch" - ], "modmenu": [ "io.gitlab.jfronny.modsmod.ModMenu" ] - + }, + "languageAdapters": { + "modsmod": "io.gitlab.jfronny.modsmod.ModsModAdapter" }, "depends": { "fabricloader": ">=0.9.2+build.206", "fabric": "*", - "minecraft": "1.16.2" + "minecraft": "*" } }