Support exporting multimc modpack
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2019 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.mod;
|
||||
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface ModAdviser {
|
||||
ModSuggestion advise(String fileName, boolean isDirectory);
|
||||
|
||||
enum ModSuggestion {
|
||||
SUGGESTED,
|
||||
NORMAL,
|
||||
HIDDEN
|
||||
}
|
||||
|
||||
List<String> MODPACK_BLACK_LIST = Lang.immutableListOf(
|
||||
"usernamecache.json", "usercache.json", // Minecraft
|
||||
"launcher_profiles.json", "launcher.pack.lzma", // Minecraft Launcher
|
||||
"pack.json", "launcher.jar", "hmclmc.log", "cache", // HMCL
|
||||
"manifest.json", "minecraftinstance.json", ".curseclient", // Curse
|
||||
"minetweaker.log", // Mods
|
||||
".fabric", ".mixin.out", // Fabric
|
||||
"jars", "logs", "versions", "assets", "libraries", "crash-reports", "NVIDIA", "AMD", "screenshots", "natives", "native", "$native", "server-resource-packs", // Minecraft
|
||||
"downloads", // Curse
|
||||
"asm", "backups", "TCNodeTracker", "CustomDISkins", "data" // Mods
|
||||
);
|
||||
|
||||
List<String> MODPACK_SUGGESTED_BLACK_LIST = Lang.immutableListOf(
|
||||
"fonts", // BetterFonts
|
||||
"saves", "servers.dat", "options.txt", // Minecraft
|
||||
"blueprints" /* BuildCraft */,
|
||||
"optionsof.txt" /* OptiFine */,
|
||||
"journeymap" /* JourneyMap */,
|
||||
"optionsshaders.txt",
|
||||
"mods/VoxelMods");
|
||||
|
||||
static ModAdviser.ModSuggestion suggestMod(String fileName, boolean isDirectory) {
|
||||
if (match(MODPACK_BLACK_LIST, fileName, isDirectory))
|
||||
return ModAdviser.ModSuggestion.HIDDEN;
|
||||
if (match(MODPACK_SUGGESTED_BLACK_LIST, fileName, isDirectory))
|
||||
return ModAdviser.ModSuggestion.NORMAL;
|
||||
else
|
||||
return ModAdviser.ModSuggestion.SUGGESTED;
|
||||
}
|
||||
|
||||
static boolean match(List<String> l, String fileName, boolean isDirectory) {
|
||||
for (String s : l)
|
||||
if (isDirectory) {
|
||||
if (fileName.startsWith(s + "/"))
|
||||
return true;
|
||||
} else if (fileName.equals(s))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import java.util.Properties;
|
||||
*/
|
||||
public final class MultiMCInstanceConfiguration {
|
||||
|
||||
private final String instanceType; // InstanceType
|
||||
private final String name; // name
|
||||
private final String gameVersion; // IntendedVersion
|
||||
private final Integer permGen; // PermGen
|
||||
@@ -68,6 +69,7 @@ public final class MultiMCInstanceConfiguration {
|
||||
|
||||
this.mmcPack = mmcPack;
|
||||
|
||||
instanceType = p.getProperty("InstanceType");
|
||||
autoCloseConsole = Boolean.parseBoolean(p.getProperty("AutoCloseConsole"));
|
||||
gameVersion = mmcPack != null ? mmcPack.getComponents().stream().filter(e -> "net.minecraft".equals(e.getUid())).findAny()
|
||||
.orElseThrow(() -> new IOException("Malformed mmc-pack.json")).getVersion() : p.getProperty("IntendedVersion");
|
||||
@@ -94,6 +96,38 @@ public final class MultiMCInstanceConfiguration {
|
||||
notes = Optional.ofNullable(p.getProperty("notes")).orElse("");
|
||||
}
|
||||
|
||||
public MultiMCInstanceConfiguration(String instanceType, String name, String gameVersion, Integer permGen, String wrapperCommand, String preLaunchCommand, String postExitCommand, String notes, String javaPath, String jvmArgs, boolean fullscreen, Integer width, Integer height, Integer maxMemory, Integer minMemory, boolean showConsole, boolean showConsoleOnError, boolean autoCloseConsole, boolean overrideMemory, boolean overrideJavaLocation, boolean overrideJavaArgs, boolean overrideConsole, boolean overrideCommands, boolean overrideWindow) {
|
||||
this.instanceType = instanceType;
|
||||
this.name = name;
|
||||
this.gameVersion = gameVersion;
|
||||
this.permGen = permGen;
|
||||
this.wrapperCommand = wrapperCommand;
|
||||
this.preLaunchCommand = preLaunchCommand;
|
||||
this.postExitCommand = postExitCommand;
|
||||
this.notes = notes;
|
||||
this.javaPath = javaPath;
|
||||
this.jvmArgs = jvmArgs;
|
||||
this.fullscreen = fullscreen;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.maxMemory = maxMemory;
|
||||
this.minMemory = minMemory;
|
||||
this.showConsole = showConsole;
|
||||
this.showConsoleOnError = showConsoleOnError;
|
||||
this.autoCloseConsole = autoCloseConsole;
|
||||
this.overrideMemory = overrideMemory;
|
||||
this.overrideJavaLocation = overrideJavaLocation;
|
||||
this.overrideJavaArgs = overrideJavaArgs;
|
||||
this.overrideConsole = overrideConsole;
|
||||
this.overrideCommands = overrideCommands;
|
||||
this.overrideWindow = overrideWindow;
|
||||
this.mmcPack = null;
|
||||
}
|
||||
|
||||
public String getInstanceType() {
|
||||
return instanceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The instance's name.
|
||||
*/
|
||||
@@ -260,6 +294,35 @@ public final class MultiMCInstanceConfiguration {
|
||||
return overrideWindow;
|
||||
}
|
||||
|
||||
public Properties toProperties() {
|
||||
Properties p = new Properties();
|
||||
if (instanceType != null) p.setProperty("InstanceType", instanceType);
|
||||
p.setProperty("AutoCloseConsole", Boolean.toString(autoCloseConsole));
|
||||
if (gameVersion != null) p.setProperty("IntendedVersion", gameVersion);
|
||||
if (javaPath != null) p.setProperty("JavaPath", javaPath);
|
||||
if (jvmArgs != null) p.setProperty("JvmArgs", jvmArgs);
|
||||
p.setProperty("LaunchMaximized", Boolean.toString(fullscreen));
|
||||
if (maxMemory != null) p.setProperty("MaxMemAlloc", Integer.toString(maxMemory));
|
||||
if (minMemory != null) p.setProperty("MinMemAlloc", Integer.toString(minMemory));
|
||||
if (height != null) p.setProperty("MinecraftWinHeight", Integer.toString(height));
|
||||
if (width != null) p.setProperty("MinecraftWinWidth", Integer.toString(width));
|
||||
p.setProperty("OverrideCommands", Boolean.toString(overrideCommands));
|
||||
p.setProperty("OverrideConsole", Boolean.toString(overrideConsole));
|
||||
p.setProperty("OverrideJavaArgs", Boolean.toString(overrideJavaArgs));
|
||||
p.setProperty("OverrideJavaLocation", Boolean.toString(overrideJavaLocation));
|
||||
p.setProperty("OverrideMemory", Boolean.toString(overrideMemory));
|
||||
p.setProperty("OverrideWindow", Boolean.toString(overrideWindow));
|
||||
if (permGen != null) p.setProperty("PermGen", Integer.toString(permGen));
|
||||
if (postExitCommand != null) p.setProperty("PostExitCommand", postExitCommand);
|
||||
if (preLaunchCommand != null) p.setProperty("PreLaunchCommand", preLaunchCommand);
|
||||
p.setProperty("ShowConsole", Boolean.toString(showConsole));
|
||||
p.setProperty("ShowConsoleOnError", Boolean.toString(showConsoleOnError));
|
||||
if (wrapperCommand != null) p.setProperty("WrapperCommand", wrapperCommand);
|
||||
if (name != null) p.setProperty("name", name);
|
||||
if (notes != null) p.setProperty("notes", notes);
|
||||
return p;
|
||||
}
|
||||
|
||||
public MultiMCManifest getMmcPack() {
|
||||
return mmcPack;
|
||||
}
|
||||
|
||||
@@ -113,17 +113,25 @@ public final class MultiMCManifest {
|
||||
@SerializedName("important")
|
||||
private final boolean important;
|
||||
|
||||
@SerializedName("dependencyOnly")
|
||||
private final boolean dependencyOnly;
|
||||
|
||||
@SerializedName("uid")
|
||||
private final String uid;
|
||||
|
||||
@SerializedName("version")
|
||||
private final String version;
|
||||
|
||||
public MultiMCManifestComponent(String cachedName, List<MultiMCManifestCachedRequires> cachedRequires, String cachedVersion, boolean important, String uid, String version) {
|
||||
public MultiMCManifestComponent(boolean important, boolean dependencyOnly, String uid, String version) {
|
||||
this(null, null, null, important, dependencyOnly, uid, version);
|
||||
}
|
||||
|
||||
public MultiMCManifestComponent(String cachedName, List<MultiMCManifestCachedRequires> cachedRequires, String cachedVersion, boolean important, boolean dependencyOnly, String uid, String version) {
|
||||
this.cachedName = cachedName;
|
||||
this.cachedRequires = cachedRequires;
|
||||
this.cachedVersion = cachedVersion;
|
||||
this.important = important;
|
||||
this.dependencyOnly = dependencyOnly;
|
||||
this.uid = uid;
|
||||
this.version = version;
|
||||
}
|
||||
@@ -144,6 +152,10 @@ public final class MultiMCManifest {
|
||||
return important;
|
||||
}
|
||||
|
||||
public boolean isDependencyOnly() {
|
||||
return dependencyOnly;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2019 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.mod;
|
||||
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.Zipper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||
|
||||
/**
|
||||
* Export the game to a mod pack file.
|
||||
*/
|
||||
public class MultiMCModpackExportTask extends Task<Void> {
|
||||
private final DefaultGameRepository repository;
|
||||
private final String versionId;
|
||||
private final List<String> whitelist;
|
||||
private final MultiMCInstanceConfiguration configuration;
|
||||
private final File output;
|
||||
|
||||
/**
|
||||
* @param output mod pack file.
|
||||
* @param versionId to locate version.json
|
||||
*/
|
||||
public MultiMCModpackExportTask(DefaultGameRepository repository, String versionId, List<String> whitelist, MultiMCInstanceConfiguration configuration, File output) {
|
||||
this.repository = repository;
|
||||
this.versionId = versionId;
|
||||
this.whitelist = whitelist;
|
||||
this.configuration = configuration;
|
||||
this.output = output;
|
||||
|
||||
onDone().register(event -> {
|
||||
if (event.isFailed()) output.delete();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
ArrayList<String> blackList = new ArrayList<>(ModAdviser.MODPACK_BLACK_LIST);
|
||||
blackList.add(versionId + ".jar");
|
||||
blackList.add(versionId + ".json");
|
||||
Logging.LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
|
||||
try (Zipper zip = new Zipper(output.toPath())) {
|
||||
zip.putDirectory(repository.getRunDirectory(versionId).toPath(), ".minecraft", path -> {
|
||||
if (path.isEmpty())
|
||||
return true;
|
||||
for (String s : blackList)
|
||||
if (path.equals(s))
|
||||
return false;
|
||||
for (String s : whitelist)
|
||||
if (path.equals(s))
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(repository.getResolvedVersion(versionId));
|
||||
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(versionId))
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot parse the version of " + versionId));
|
||||
List<MultiMCManifest.MultiMCManifestComponent> components = new ArrayList<>();
|
||||
components.add(new MultiMCManifest.MultiMCManifestComponent(true, false, "net.minecraft", gameVersion));
|
||||
analyzer.getVersion(FORGE).ifPresent(forgeVersion ->
|
||||
components.add(new MultiMCManifest.MultiMCManifestComponent(false, false, "net.minecraftforge", forgeVersion)));
|
||||
analyzer.getVersion(LITELOADER).ifPresent(liteLoaderVersion ->
|
||||
components.add(new MultiMCManifest.MultiMCManifestComponent(false, false, "com.mumfrey.liteloader", liteLoaderVersion)));
|
||||
analyzer.getVersion(FABRIC).ifPresent(fabricVersion ->
|
||||
components.add(new MultiMCManifest.MultiMCManifestComponent(false, false, "net.fabricmc.fabric-loader", fabricVersion)));
|
||||
MultiMCManifest mmcPack = new MultiMCManifest(1, components);
|
||||
zip.putTextFile(JsonUtils.GSON.toJson(mmcPack), "mmc-pack.json");
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
configuration.toProperties().store(writer, "Auto generated by Hello Minecraft! Launcher");
|
||||
zip.putTextFile(writer.toString(), "instance.cfg");
|
||||
|
||||
zip.putTextFile("", ".packignore");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user