126 lines
4.9 KiB
Java
126 lines
4.9 KiB
Java
package io.gitlab.jfronny.modsmod;
|
|
|
|
import io.gitlab.jfronny.libjf.Libjf;
|
|
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 java.io.IOException;
|
|
import java.net.URL;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.file.FileSystem;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.StandardCopyOption;
|
|
import java.util.Collections;
|
|
import java.util.HashSet;
|
|
|
|
public class ModsMod {
|
|
static HashSet<ModMeta> m;
|
|
static FabricLoader loader;
|
|
public static final String MOD_ID = "modsmod";
|
|
private static final String CACHE_NAME = MOD_ID + "cache";
|
|
public static void prepare() throws IOException {
|
|
loader = FabricLoader.INSTANCE;
|
|
//Load config
|
|
Libjf.registerConfig(MOD_ID, Cfg.class);
|
|
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 {
|
|
Path cfgCache = configDir.resolve(CACHE_NAME + "_basecfg");
|
|
if (Files.exists(cfgCache)) {
|
|
if (Files.isRegularFile(cfgCache)) {
|
|
if (!IOUtil.contentEquals(modsmodCfgFile, cfgCache)) {
|
|
IOUtil.clearDirectory(path);
|
|
}
|
|
}
|
|
else {
|
|
IOUtil.clearDirectory(path);
|
|
}
|
|
}
|
|
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 = new HashSet<>();
|
|
//Generate mods
|
|
for (int i = 0; i < Cfg.modsCount; i++) {
|
|
Path f = path.resolve("f" + (i + 1) + ".jar");
|
|
boolean exists = Files.exists(f);
|
|
FileSystem fs = FileSystemUtil.getJarFileSystem(f, !exists).get();
|
|
m.add(new ModMeta(fs, f.toUri().toURL()));
|
|
//Do not load if cached
|
|
if (exists) {
|
|
if (Cfg.cache) continue;
|
|
else Files.delete(f);
|
|
}
|
|
//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.write(inf.resolve("MANIFEST.MF"), sb.toString().getBytes(StandardCharsets.UTF_8));
|
|
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:parent\": \"modsmod\"");
|
|
}
|
|
sb.append("}");
|
|
sb.append("}");
|
|
Files.write(fs.getPath("fabric.mod.json"), sb.toString().getBytes(StandardCharsets.UTF_8));
|
|
sb.delete(0, sb.length());
|
|
|
|
System.gc();
|
|
}
|
|
FabricLoaderInterface.synchronize(loader);
|
|
}
|
|
|
|
public static void init() {
|
|
for (ModMeta f : m) {
|
|
loadMod(loader, f);
|
|
}
|
|
}
|
|
|
|
private static void loadMod(FabricLoader loader, ModMeta meta) {
|
|
ModCandidate candidate = parseMod(meta.fs.getPath("fabric.mod.json"), meta.url);
|
|
|
|
if (loader.isDevelopmentEnvironment()) {
|
|
candidate = RuntimeModRemapper.remap(Collections.singletonList(candidate), ModResolver.getInMemoryFs()).stream().findFirst().get();
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|