Fabric Loader 0.12.1
This commit is contained in:
parent
264704b602
commit
1327e98044
|
@ -5,6 +5,9 @@ repositories {
|
||||||
name = 'TerraformersMC'
|
name = 'TerraformersMC'
|
||||||
url = 'https://maven.terraformersmc.com/'
|
url = 'https://maven.terraformersmc.com/'
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
url "https://gitlab.com/api/v4/projects/25805200/packages/maven"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -13,7 +16,9 @@ dependencies {
|
||||||
mappings "net.fabricmc:yarn:${project.minecraft_version}+${project.yarn_mappings}:v2"
|
mappings "net.fabricmc:yarn:${project.minecraft_version}+${project.yarn_mappings}:v2"
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
|
|
||||||
download("https://gitlab.com/jfmods/LibJF/-/jobs/artifacts/master/raw/latest-dev.jar?job=build_test", "libjf")
|
include modImplementation("io.gitlab.jfronny.libjf:libjf-config-v0:${project.jfapi_version}")
|
||||||
|
include("io.gitlab.jfronny.libjf:libjf-unsafe-v0:${project.jfapi_version}")
|
||||||
|
include("io.gitlab.jfronny.libjf:libjf-base:${project.jfapi_version}")
|
||||||
|
|
||||||
modImplementation "com.terraformersmc:modmenu:2.0.0-beta.7"
|
modImplementation "com.terraformersmc:modmenu:2.0.14"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
# Done to increase the memory available to gradle.
|
# Done to increase the memory available to gradle.
|
||||||
org.gradle.jvmargs=-Xmx1G
|
org.gradle.jvmargs=-Xmx1G
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://modmuss50.me/fabric.html
|
# check these on https://fabricmc.net/versions.html
|
||||||
minecraft_version=1.17
|
minecraft_version=1.17.1
|
||||||
yarn_mappings=build.1
|
yarn_mappings=build.61
|
||||||
loader_version=0.11.3
|
loader_version=0.12.1
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=2.2.2
|
mod_version=2.3.0
|
||||||
maven_group=io.gitlab.jfronny
|
maven_group=io.gitlab.jfronny
|
||||||
archives_base_name=modsmod
|
archives_base_name=modsmod
|
||||||
|
|
||||||
|
jfapi_version=2.0.1
|
||||||
|
|
||||||
modrinth_id=4GhX11Ed
|
modrinth_id=4GhX11Ed
|
||||||
modrinth_required_dependencies=dOW0jmMj
|
modrinth_required_dependencies=
|
||||||
modrinth_optional_dependencies=wRE7Emzz
|
modrinth_optional_dependencies=wRE7Emzz
|
||||||
curseforge_id=405095
|
curseforge_id=405095
|
||||||
curseforge_required_dependencies=libjf
|
curseforge_required_dependencies=
|
||||||
curseforge_optional_dependencies=modmenu
|
curseforge_optional_dependencies=modmenu
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package io.gitlab.jfronny.modsmod;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.config.Entry;
|
|
||||||
import io.gitlab.jfronny.libjf.config.JfConfig;
|
|
||||||
|
|
||||||
public class Cfg implements JfConfig {
|
|
||||||
@Entry
|
|
||||||
public static int modsCount = 26;
|
|
||||||
@Entry
|
|
||||||
public static boolean parent = false;
|
|
||||||
@Entry
|
|
||||||
public static boolean cache = true;
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package io.gitlab.jfronny.modsmod;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.entry.UltraEarlyInit;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class Entry implements UltraEarlyInit {
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
try {
|
|
||||||
ModsMod.prepare();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +1,70 @@
|
||||||
package io.gitlab.jfronny.modsmod;
|
package io.gitlab.jfronny.modsmod;
|
||||||
|
|
||||||
import net.fabricmc.loader.FabricLoader;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import net.fabricmc.loader.ModContainer;
|
import io.gitlab.jfronny.modsmod.util.IteratorCallbackList;
|
||||||
import net.fabricmc.loader.discovery.ModCandidate;
|
import net.fabricmc.loader.impl.FabricLoaderImpl;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import net.fabricmc.loader.impl.ModContainerImpl;
|
||||||
import org.apache.logging.log4j.Logger;
|
import net.fabricmc.loader.impl.discovery.ModCandidate;
|
||||||
|
import net.fabricmc.loader.impl.metadata.LoaderModMetadata;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FabricLoaderInterface {
|
public class FabricLoaderInterface {
|
||||||
public static final Logger logger = LogManager.getLogger(ModsMod.MOD_ID);
|
private static final Method ADD_MOD_METHOD;
|
||||||
|
private static final Method CREATE_PLAIN_METHOD;
|
||||||
private static final Method addModMethod;
|
private static final Field MODS_FIELD;
|
||||||
private static final Field modsField;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
addModMethod = FabricLoader.class.getDeclaredMethod("addMod", ModCandidate.class);
|
ADD_MOD_METHOD = FabricLoaderImpl.class.getDeclaredMethod("addMod", ModCandidate.class);
|
||||||
addModMethod.setAccessible(true);
|
ADD_MOD_METHOD.setAccessible(true);
|
||||||
|
|
||||||
modsField = FabricLoader.class.getDeclaredField("mods");
|
MODS_FIELD = FabricLoaderImpl.class.getDeclaredField("mods");
|
||||||
modsField.setAccessible(true);
|
MODS_FIELD.setAccessible(true);
|
||||||
|
|
||||||
|
CREATE_PLAIN_METHOD = ModCandidate.class.getDeclaredMethod("createPlain", Path.class, LoaderModMetadata.class, boolean.class, new TypeToken<Collection<ModCandidate>>(){}.getRawType());
|
||||||
|
CREATE_PLAIN_METHOD.setAccessible(true);
|
||||||
} catch (NoSuchMethodException | NoSuchFieldException e) {
|
} 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);
|
ModsMod.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);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void synchronize(FabricLoader fabricLoader) {
|
public static void synchronize(FabricLoaderImpl fabricLoader) {
|
||||||
try {
|
try {
|
||||||
modsField.set(fabricLoader, new IteratorCallbackList((List<ModContainer>)modsField.get(fabricLoader),
|
MODS_FIELD.set(fabricLoader, new IteratorCallbackList<>((List<ModContainerImpl>) MODS_FIELD.get(fabricLoader), modContainers -> {
|
||||||
(s) -> {
|
try {
|
||||||
try {
|
MODS_FIELD.set(fabricLoader, modContainers);
|
||||||
modsField.set(fabricLoader, s);
|
} catch (IllegalAccessException e) {
|
||||||
} catch (IllegalAccessException e) {
|
ModsMod.LOGGER.error("Failed to reset mods field", e);
|
||||||
logger.error("Failed to reset mods field", e);
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
}, ModsMod::loadMods));
|
||||||
}));
|
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
logger.error("Failed to make mods list synchronized.", e);
|
ModsMod.LOGGER.error("Failed to make mods list synchronized.", e);
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addMod(FabricLoader fabricLoader, ModCandidate modCandidate) {
|
public static void addMod(FabricLoaderImpl fabricLoader, ModCandidate modCandidate) {
|
||||||
try {
|
try {
|
||||||
addModMethod.invoke(fabricLoader, modCandidate);
|
ADD_MOD_METHOD.invoke(fabricLoader, modCandidate);
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
logger.error("Failed to inject mod into fabric-loader.", e);
|
ModsMod.LOGGER.error("Failed to inject mod into fabric-loader.", e);
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ModCandidate createPlain(Path path, LoaderModMetadata metadata, boolean requiresRemap, Collection<ModCandidate> nestedMods) {
|
||||||
|
try {
|
||||||
|
return (ModCandidate) CREATE_PLAIN_METHOD.invoke(null, path, metadata, requiresRemap, nestedMods);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
ModsMod.LOGGER.error("Failed to create plain mod container", e);
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
package io.gitlab.jfronny.modsmod;
|
|
||||||
|
|
||||||
import net.fabricmc.loader.util.FileSystemUtil;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.FileSystem;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public class ModMeta {
|
|
||||||
public final FileSystem fs;
|
|
||||||
public final URL url;
|
|
||||||
|
|
||||||
public ModMeta(Path f) throws IOException {
|
|
||||||
this.fs = FileSystemUtil.getJarFileSystem(f, false).get();
|
|
||||||
this.url = f.toUri().toURL();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +1,101 @@
|
||||||
package io.gitlab.jfronny.modsmod;
|
package io.gitlab.jfronny.modsmod;
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.Libjf;
|
import com.google.gson.Gson;
|
||||||
import io.gitlab.jfronny.libjf.entry.UltraEarlyInit;
|
import io.gitlab.jfronny.libjf.config.impl.ConfigHolder;
|
||||||
import net.fabricmc.loader.FabricLoader;
|
import io.gitlab.jfronny.libjf.unsafe.UltraEarlyInit;
|
||||||
import net.fabricmc.loader.discovery.ModCandidate;
|
import io.gitlab.jfronny.modsmod.builder.JsonBuilder;
|
||||||
import net.fabricmc.loader.discovery.ModResolver;
|
import io.gitlab.jfronny.modsmod.builder.ModMeta;
|
||||||
import net.fabricmc.loader.discovery.RuntimeModRemapper;
|
import io.gitlab.jfronny.modsmod.util.IOUtil;
|
||||||
import net.fabricmc.loader.launch.common.FabricLauncherBase;
|
import net.fabricmc.loader.impl.FabricLoaderImpl;
|
||||||
import net.fabricmc.loader.metadata.LoaderModMetadata;
|
import net.fabricmc.loader.impl.metadata.LoaderModMetadata;
|
||||||
import net.fabricmc.loader.metadata.ModMetadataParser;
|
import net.fabricmc.loader.impl.metadata.ModMetadataParser;
|
||||||
import net.fabricmc.loader.metadata.ParseMetadataException;
|
import net.fabricmc.loader.impl.metadata.ParseMetadataException;
|
||||||
import net.fabricmc.loader.util.FileSystemUtil;
|
import net.fabricmc.loader.impl.util.FileSystemUtil;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.FileSystem;
|
import java.nio.file.FileSystem;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.Collections;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
public class ModsMod {
|
public class ModsMod implements UltraEarlyInit {
|
||||||
static final HashSet<ModMeta> m = new HashSet<>();
|
public static final Logger LOGGER = LogManager.getLogger(ModsMod.MOD_ID);
|
||||||
static final FabricLoader loader = FabricLoader.INSTANCE;
|
static final HashSet<ModMeta> MODS = new HashSet<>();
|
||||||
|
static final FabricLoaderImpl LOADER = FabricLoaderImpl.INSTANCE;
|
||||||
|
public static final Gson GSON = new Gson();
|
||||||
public static final String MOD_ID = "modsmod";
|
public static final String MOD_ID = "modsmod";
|
||||||
private static final String CACHE_NAME = MOD_ID + "cache";
|
private static final String CACHE_NAME = MOD_ID + "cache";
|
||||||
public static void prepare() throws IOException {
|
|
||||||
//Load config
|
@Override
|
||||||
Libjf.registerConfig(MOD_ID, Cfg.class);
|
public void init() {
|
||||||
Path configDir = loader.getConfigDir();
|
|
||||||
Path modsmodCfgFile = Libjf.getConfigs().get(MOD_ID).path;
|
|
||||||
//make sure the modsmodcache dir is ok
|
|
||||||
Path path = configDir.resolve(CACHE_NAME);
|
|
||||||
if (!Files.isDirectory(path)) {
|
|
||||||
if (Files.exists(path))
|
|
||||||
Files.delete(path);
|
|
||||||
Files.createDirectories(path);
|
|
||||||
}
|
|
||||||
//remove modsmodcache if the cache is outdated
|
|
||||||
try {
|
try {
|
||||||
Path cfgCache = path.resolve("_basecfg");
|
//Load config
|
||||||
if (Files.exists(cfgCache)) {
|
Path configDir = LOADER.getConfigDir();
|
||||||
if (Files.isRegularFile(cfgCache)) {
|
Path modsmodCfgFile = ConfigHolder.getConfigs().get(MOD_ID).path;
|
||||||
if (!IOUtil.contentEquals(modsmodCfgFile, cfgCache)) {
|
//make sure the modsmodcache dir is ok
|
||||||
|
Path path = configDir.resolve(CACHE_NAME);
|
||||||
|
if (!Files.isDirectory(path)) {
|
||||||
|
if (Files.exists(path))
|
||||||
|
Files.delete(path);
|
||||||
|
Files.createDirectories(path);
|
||||||
|
}
|
||||||
|
//remove modsmodcache if the cache is outdated
|
||||||
|
try {
|
||||||
|
Path cfgCache = path.resolve("_basecfg");
|
||||||
|
if (Files.exists(cfgCache)) {
|
||||||
|
if (Files.isRegularFile(cfgCache)) {
|
||||||
|
if (!IOUtil.contentEquals(modsmodCfgFile, cfgCache)) {
|
||||||
|
IOUtil.clearDirectory(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
IOUtil.clearDirectory(path);
|
IOUtil.clearDirectory(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
Files.copy(modsmodCfgFile, cfgCache, StandardCopyOption.REPLACE_EXISTING);
|
||||||
IOUtil.clearDirectory(path);
|
} catch (IOException e) {
|
||||||
}
|
System.err.println("Failed to validate modsmod config cache, caching will not be available");
|
||||||
}
|
|
||||||
Files.copy(modsmodCfgFile, cfgCache, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Failed to validate modsmod config cache, caching will not be available");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
m.clear();
|
|
||||||
//Generate mods
|
|
||||||
for (int i = 0; i < Cfg.modsCount; i++) {
|
|
||||||
Path f = path.resolve("f" + (i + 1) + ".jar");
|
|
||||||
boolean exists = Files.exists(f);
|
|
||||||
//Do not load if cached
|
|
||||||
if (exists) {
|
|
||||||
if (Cfg.cache) {
|
|
||||||
m.add(new ModMeta(f));
|
|
||||||
continue;
|
|
||||||
} else Files.delete(f);
|
|
||||||
}
|
|
||||||
try (FileSystem fs = FileSystemUtil.getJarFileSystem(f, true).get()) {
|
|
||||||
//META-INF/MANIFEST.MF (java jar file spec)
|
|
||||||
Path inf = fs.getPath("META-INF");
|
|
||||||
Files.createDirectory(inf);
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Manifest-Version: 1.0\n");
|
|
||||||
Files.writeString(inf.resolve("MANIFEST.MF"), sb.toString());
|
|
||||||
sb.delete(0, sb.length());
|
|
||||||
//fabric.mod.json (fabric mod metadata)
|
|
||||||
sb.append("{");
|
|
||||||
sb.append("\"schemaVersion\": 1,");
|
|
||||||
sb.append("\"id\": \"modmod_").append(i + 1).append("\",");
|
|
||||||
sb.append("\"version\": \"1.0\",");
|
|
||||||
sb.append("\"name\": \"ModsMod ").append(i + 1).append("\",");
|
|
||||||
sb.append("\"entrypoints\": {},");
|
|
||||||
sb.append("\"custom\": {");
|
|
||||||
if (Cfg.parent) {
|
|
||||||
sb.append("\"modmenu\": {");
|
|
||||||
sb.append("\"parent\": \"modsmod\"");
|
|
||||||
sb.append("}");
|
|
||||||
}
|
|
||||||
sb.append("}");
|
|
||||||
sb.append("}");
|
|
||||||
Files.writeString(fs.getPath("fabric.mod.json"), sb.toString());
|
|
||||||
sb.delete(0, sb.length());
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
MODS.clear();
|
||||||
System.gc();
|
//Generate mods
|
||||||
|
for (int i = 0; i < ModsModConfig.modsCount; i++) {
|
||||||
m.add(new ModMeta(f));
|
Path f = path.resolve("f" + (i + 1) + ".jar");
|
||||||
}
|
boolean exists = Files.exists(f);
|
||||||
FabricLoaderInterface.synchronize(loader);
|
//Do not load if cached
|
||||||
}
|
if (exists) {
|
||||||
|
if (ModsModConfig.cache) {
|
||||||
public static void init() {
|
MODS.add(new ModMeta(f));
|
||||||
for (ModMeta f : m) {
|
continue;
|
||||||
loadMod(f);
|
} else Files.delete(f);
|
||||||
|
}
|
||||||
|
try (FileSystem fs = FileSystemUtil.getJarFileSystem(f, true).get()) {
|
||||||
|
Path inf = fs.getPath("META-INF");
|
||||||
|
Files.createDirectory(inf);
|
||||||
|
Files.writeString(inf.resolve("MANIFEST.MF"), "Manifest-Version: 1.0\n");
|
||||||
|
JsonBuilder.build(i + 1, ModMeta.getFmj(fs), ModsModConfig.parent);
|
||||||
|
}
|
||||||
|
MODS.add(new ModMeta(f));
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
|
FabricLoaderInterface.synchronize(LOADER);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadMod(ModMeta meta) {
|
public static void loadMods() {
|
||||||
ModCandidate candidate = parseMod(meta.fs.getPath("fabric.mod.json"), meta.url);
|
for (ModMeta meta : MODS) {
|
||||||
|
try {
|
||||||
if (loader.isDevelopmentEnvironment()) {
|
LoaderModMetadata info = ModMetadataParser.parseMetadata(Files.newInputStream(meta.fmj), meta.url.toString(), new ArrayList<>());
|
||||||
candidate = RuntimeModRemapper.remap(Collections.singletonList(candidate), ModResolver.getInMemoryFs()).stream().findFirst().get();
|
FabricLoaderInterface.addMod(LOADER, FabricLoaderInterface.createPlain(meta.rootPath, info, false, new HashSet<>()));
|
||||||
}
|
} catch (IOException | ParseMetadataException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
FabricLoaderInterface.addMod(loader, candidate);
|
}
|
||||||
FabricLauncherBase.getLauncher().propose(candidate.getOriginUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ModCandidate parseMod(Path fabricModJson, URL originUrl) {
|
|
||||||
try {
|
|
||||||
LoaderModMetadata info = ModMetadataParser.parseMetadata(FabricLoaderInterface.logger, fabricModJson);
|
|
||||||
return new ModCandidate(info, originUrl, 0, true);
|
|
||||||
} catch (IOException | ParseMetadataException e) {
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.gitlab.jfronny.modsmod;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.libjf.config.api.JfConfig;
|
||||||
|
import io.gitlab.jfronny.libjf.config.api.Entry;
|
||||||
|
|
||||||
|
public class ModsModConfig implements JfConfig {
|
||||||
|
@Entry
|
||||||
|
public static Boolean parent = false;
|
||||||
|
@Entry
|
||||||
|
public static Boolean cache = true;
|
||||||
|
@Entry
|
||||||
|
public static Integer modsCount = 26;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package io.gitlab.jfronny.modsmod.builder;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.modsmod.ModsMod;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class JsonBuilder {
|
||||||
|
public static void build(int number, Path outputPath, boolean parent) throws IOException {
|
||||||
|
try (BufferedWriter bw = Files.newBufferedWriter(outputPath)) {
|
||||||
|
ModsMod.GSON.toJson(new ModManifest(number, parent), bw);
|
||||||
|
}
|
||||||
|
//String s = ModsMod.GSON.toJson(new ModManifest(number, parent));
|
||||||
|
//ModsMod.LOGGER.info(s);
|
||||||
|
//Files.writeString(outputPath, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static class ModManifest {
|
||||||
|
public final int schemaVersion = 1;
|
||||||
|
public final String id;
|
||||||
|
public final String version = "1.0";
|
||||||
|
public final String name;
|
||||||
|
public final Map<String, ModMenuData> custom = new HashMap<>();
|
||||||
|
|
||||||
|
public ModManifest(int number, boolean parent) {
|
||||||
|
id = "modmod_" + number;
|
||||||
|
name = "ModsMod " + number;
|
||||||
|
if (parent)
|
||||||
|
custom.put("modmenu", new ModMenuData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ModMenuData {
|
||||||
|
public final String parent = "modsmod";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package io.gitlab.jfronny.modsmod.builder;
|
||||||
|
|
||||||
|
import net.fabricmc.loader.impl.util.FileSystemUtil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class ModMeta {
|
||||||
|
public final Path rootPath;
|
||||||
|
public final Path fmj;
|
||||||
|
public final URL url;
|
||||||
|
|
||||||
|
public ModMeta(Path f) throws IOException {
|
||||||
|
this(FileSystemUtil.getJarFileSystem(f, false).get(), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModMeta(FileSystem fs, Path f) throws MalformedURLException {
|
||||||
|
rootPath = fs.getPath("");
|
||||||
|
fmj = getFmj(fs);
|
||||||
|
this.url = f.toUri().toURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Path getFmj(FileSystem fs) {
|
||||||
|
return fs.getPath("fabric.mod.json");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package io.gitlab.jfronny.modsmod;
|
package io.gitlab.jfronny.modsmod.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.MappedByteBuffer;
|
import java.nio.MappedByteBuffer;
|
||||||
|
@ -8,23 +8,12 @@ import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
|
||||||
public class IOUtil {
|
public class IOUtil {
|
||||||
public static void deleteRecursive(Path path) throws IOException {
|
public static void deleteRecursive(Path path) throws IOException {
|
||||||
Files.walkFileTree(path, new FileVisitor<Path>() {
|
Files.walkFileTree(path, new SimpleFileVisitor<>() {
|
||||||
@Override
|
|
||||||
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
|
|
||||||
return FileVisitResult.CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
|
public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
|
||||||
Files.delete(path);
|
Files.delete(path);
|
||||||
return FileVisitResult.CONTINUE;
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileVisitResult visitFileFailed(Path path, IOException e) throws IOException {
|
|
||||||
return FileVisitResult.CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileVisitResult postVisitDirectory(Path path, IOException e) throws IOException {
|
public FileVisitResult postVisitDirectory(Path path, IOException e) throws IOException {
|
||||||
Files.delete(path);
|
Files.delete(path);
|
|
@ -1,18 +1,19 @@
|
||||||
package io.gitlab.jfronny.modsmod;
|
package io.gitlab.jfronny.modsmod.util;
|
||||||
|
|
||||||
import net.fabricmc.loader.ModContainer;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class IteratorCallbackList implements List<ModContainer> {
|
public class IteratorCallbackList<T> implements List<T> {
|
||||||
private final List<ModContainer> containers;
|
private final List<T> containers;
|
||||||
private final Consumer<List<ModContainer>> reset;
|
private final Consumer<List<T>> reset;
|
||||||
|
private final Runnable callback;
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
public IteratorCallbackList(List<ModContainer> base, Consumer<List<ModContainer>> reset) {
|
public IteratorCallbackList(List<T> base, Consumer<List<T>> reset, Runnable callback) {
|
||||||
containers = Collections.synchronizedList(base);
|
containers = Collections.synchronizedList(base);
|
||||||
this.reset = reset;
|
this.reset = reset;
|
||||||
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,9 +33,9 @@ public class IteratorCallbackList implements List<ModContainer> {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Iterator<ModContainer> iterator() {
|
public Iterator<T> iterator() {
|
||||||
if (!modified) {
|
if (!modified) {
|
||||||
ModsMod.init();
|
callback.run();
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
reset.accept(containers);
|
reset.accept(containers);
|
||||||
|
@ -54,7 +55,7 @@ public class IteratorCallbackList implements List<ModContainer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean add(ModContainer modContainer) {
|
public boolean add(T modContainer) {
|
||||||
return containers.add(modContainer);
|
return containers.add(modContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,12 +70,12 @@ public class IteratorCallbackList implements List<ModContainer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(@NotNull Collection<? extends ModContainer> collection) {
|
public boolean addAll(@NotNull Collection<? extends T> collection) {
|
||||||
return containers.addAll(collection);
|
return containers.addAll(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(int i, @NotNull Collection<? extends ModContainer> collection) {
|
public boolean addAll(int i, @NotNull Collection<? extends T> collection) {
|
||||||
return containers.addAll(i, collection);
|
return containers.addAll(i, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ public class IteratorCallbackList implements List<ModContainer> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean retainAll(@NotNull Collection<?> collection) {
|
public boolean retainAll(@NotNull Collection<?> collection) {
|
||||||
return containers.removeAll(collection);
|
return containers.retainAll(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,22 +95,22 @@ public class IteratorCallbackList implements List<ModContainer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModContainer get(int i) {
|
public T get(int i) {
|
||||||
return containers.get(i);
|
return containers.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModContainer set(int i, ModContainer modContainer) {
|
public T set(int i, T modContainer) {
|
||||||
return containers.set(i, modContainer);
|
return containers.set(i, modContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(int i, ModContainer modContainer) {
|
public void add(int i, T modContainer) {
|
||||||
containers.add(i, modContainer);
|
containers.add(i, modContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModContainer remove(int i) {
|
public T remove(int i) {
|
||||||
return containers.remove(i);
|
return containers.remove(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,19 +126,19 @@ public class IteratorCallbackList implements List<ModContainer> {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ListIterator<ModContainer> listIterator() {
|
public ListIterator<T> listIterator() {
|
||||||
return containers.listIterator();
|
return containers.listIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ListIterator<ModContainer> listIterator(int i) {
|
public ListIterator<T> listIterator(int i) {
|
||||||
return containers.listIterator(i);
|
return containers.listIterator(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<ModContainer> subList(int i, int i1) {
|
public List<T> subList(int i, int i1) {
|
||||||
return containers.subList(i, i1);
|
return containers.subList(i, i1);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"ModsMod.jfconfig.title": "ModsMod",
|
"modsmod.jfconfig.title": "ModsMod",
|
||||||
"ModsMod.jfconfig.modsCount": "Mods count",
|
"modsmod.jfconfig.modsCount": "Mods count",
|
||||||
"ModsMod.jfconfig.modsCount.tooltip": "The amount of mods to generate. Don't set this too high",
|
"modsmod.jfconfig.modsCount.tooltip": "The amount of mods to generate. Don't set this too high",
|
||||||
"ModsMod.jfconfig.parent": "Parent",
|
"modsmod.jfconfig.parent": "Parent",
|
||||||
"ModsMod.jfconfig.parent.tooltip": "Show the mods as children of ModsMod in ModMenu",
|
"modsmod.jfconfig.parent.tooltip": "Show the mods as children of ModsMod in ModMenu",
|
||||||
"ModsMod.jfconfig.cache": "Cache",
|
"modsmod.jfconfig.cache": "Cache",
|
||||||
"ModsMod.jfconfig.cache.tooltip": "Cache the generated files. Increases performance. Disable when this stops working to regenerate"
|
"modsmod.jfconfig.cache.tooltip": "Cache the generated files. Increases performance. Disable when this stops working to regenerate"
|
||||||
}
|
}
|
|
@ -15,12 +15,12 @@
|
||||||
"icon": "assets/modsmod/icon.png",
|
"icon": "assets/modsmod/icon.png",
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"libjf:config": ["io.gitlab.jfronny.modsmod.Cfg"],
|
"libjf:config": ["io.gitlab.jfronny.modsmod.ModsModConfig"],
|
||||||
"libjf:early": ["io.gitlab.jfronny.modsmod.Entry"]
|
"libjf:early": ["io.gitlab.jfronny.modsmod.ModsMod"]
|
||||||
},
|
},
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.9.2+build.206",
|
"fabricloader": ">=0.12.0",
|
||||||
"libjf": ">=1.2.0",
|
"libjf-config-v0": ">=2.0",
|
||||||
"minecraft": "*"
|
"minecraft": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue