Support new MultiMC modpack

This commit is contained in:
huangyuhui
2018-07-07 00:48:48 +08:00
parent 3fb5048f10
commit a853374a88
4 changed files with 187 additions and 5 deletions

View File

@@ -49,7 +49,8 @@ public final class LibraryDownloadTask extends Task {
setSignificance(TaskSignificance.MODERATE);
task = new FileDownloadTask(NetworkUtils.toURL(url),
file, dependencyManager.getProxy(), new IntegrityCheck("SHA-1", library.getDownload().getSha1()));
file, dependencyManager.getProxy(),
library.getDownload().getSha1() != null ? new IntegrityCheck("SHA-1", library.getDownload().getSha1()) : null);
}
@Override

View File

@@ -58,12 +58,17 @@ public final class MultiMCInstanceConfiguration {
private final boolean overrideCommands; // OverrideCommands
private final boolean overrideWindow; // OverrideWindow
public MultiMCInstanceConfiguration(String defaultName, InputStream contentStream) throws IOException {
private final MultiMCManifest mmcPack;
private MultiMCInstanceConfiguration(String defaultName, InputStream contentStream, MultiMCManifest mmcPack) throws IOException {
Properties p = new Properties();
p.load(contentStream);
this.mmcPack = mmcPack;
autoCloseConsole = Boolean.parseBoolean(p.getProperty("AutoCloseConsole"));
gameVersion = p.getProperty("IntendedVersion");
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");
javaPath = p.getProperty("JavaPath");
jvmArgs = p.getProperty("JvmArgs");
fullscreen = Boolean.parseBoolean(p.getProperty("LaunchMaximized"));
@@ -253,6 +258,10 @@ public final class MultiMCInstanceConfiguration {
return overrideWindow;
}
public MultiMCManifest getMmcPack() {
return mmcPack;
}
public static Modpack readMultiMCModpackManifest(File f) throws IOException {
try (ZipFile zipFile = new ZipFile(f)) {
ZipArchiveEntry firstEntry = zipFile.getEntries().nextElement();
@@ -260,7 +269,8 @@ public final class MultiMCInstanceConfiguration {
ZipArchiveEntry entry = zipFile.getEntry(name + "/instance.cfg");
if (entry == null)
throw new IOException("`instance.cfg` not found, " + f + " is not a valid MultiMC modpack.");
MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, zipFile.getInputStream(entry));
MultiMCManifest manifest = MultiMCManifest.readMultiMCModpackManifest(f);
MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, zipFile.getInputStream(entry), manifest);
return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), cfg);
}
}

View File

@@ -0,0 +1,152 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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 {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.mod;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.jackhuang.hmcl.util.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
@Immutable
public final class MultiMCManifest {
@SerializedName("formatVersion")
private final int formatVersion;
@SerializedName("components")
private final List<MultiMCManifestComponent> components;
public MultiMCManifest(int formatVersion, List<MultiMCManifestComponent> components) {
this.formatVersion = formatVersion;
this.components = components;
}
public int getFormatVersion() {
return formatVersion;
}
public List<MultiMCManifestComponent> getComponents() {
return components;
}
public static MultiMCManifest readMultiMCModpackManifest(File f) throws IOException {
try (ZipFile zipFile = new ZipFile(f)) {
ZipArchiveEntry firstEntry = zipFile.getEntries().nextElement();
String name = StringUtils.substringBefore(firstEntry.getName(), '/');
ZipArchiveEntry entry = zipFile.getEntry(name + "/mmc-pack.json");
if (entry == null)
return null;
String json = IOUtils.readFullyAsString(zipFile.getInputStream(entry));
MultiMCManifest manifest = JsonUtils.fromNonNullJson(json, MultiMCManifest.class);
if (manifest != null && manifest.getComponents() == null)
throw new IOException("mmc-pack.json malformed.");
return manifest;
}
}
public static final class MultiMCManifestCachedRequires {
@SerializedName("equals")
private final String equalsVersion;
@SerializedName("uid")
private final String uid;
@SerializedName("suggests")
private final String suggests;
public MultiMCManifestCachedRequires(String equalsVersion, String uid, String suggests) {
this.equalsVersion = equalsVersion;
this.uid = uid;
this.suggests = suggests;
}
public String getEqualsVersion() {
return equalsVersion;
}
public String getUid() {
return uid;
}
public String getSuggests() {
return suggests;
}
}
public static final class MultiMCManifestComponent {
@SerializedName("cachedName")
private final String cachedName;
@SerializedName("cachedRequires")
private final List<MultiMCManifestCachedRequires> cachedRequires;
@SerializedName("cachedVersion")
private final String cachedVersion;
@SerializedName("important")
private final boolean important;
@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) {
this.cachedName = cachedName;
this.cachedRequires = cachedRequires;
this.cachedVersion = cachedVersion;
this.important = important;
this.uid = uid;
this.version = version;
}
public String getCachedName() {
return cachedName;
}
public List<MultiMCManifestCachedRequires> getCachedRequires() {
return cachedRequires;
}
public String getCachedVersion() {
return cachedVersion;
}
public boolean isImportant() {
return important;
}
public String getUid() {
return uid;
}
public String getVersion() {
return version;
}
}
}

View File

@@ -22,6 +22,7 @@ import com.google.gson.reflect.TypeToken;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.download.GameBuilder;
import org.jackhuang.hmcl.download.game.VersionJsonSaveTask;
import org.jackhuang.hmcl.game.Arguments;
import org.jackhuang.hmcl.game.DefaultGameRepository;
@@ -37,6 +38,7 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
*
@@ -61,7 +63,24 @@ public final class MultiMCModpackInstallTask extends Task {
File json = repository.getModpackConfiguration(name);
if (repository.hasVersion(name) && !json.exists())
throw new IllegalArgumentException("Version " + name + " already exists.");
dependents.add(dependencyManager.gameBuilder().name(name).gameVersion(manifest.getGameVersion()).buildAsync());
GameBuilder builder = dependencyManager.gameBuilder().name(name).gameVersion(manifest.getGameVersion());
if (manifest.getMmcPack() != null) {
Optional<MultiMCManifest.MultiMCManifestComponent> forge = manifest.getMmcPack().getComponents().stream().filter(e -> e.getUid().equals("net.minecraftforge")).findAny();
forge.ifPresent(c -> {
if (c.getVersion() != null)
builder.version("forge", c.getVersion());
});
Optional<MultiMCManifest.MultiMCManifestComponent> liteLoader = manifest.getMmcPack().getComponents().stream().filter(e -> e.getUid().equals("com.mumfrey.liteloader")).findAny();
liteLoader.ifPresent(c -> {
if (c.getVersion() != null)
builder.version("liteloader", c.getVersion());
});
}
dependents.add(builder.buildAsync());
onDone().register(event -> {
if (event.isFailed())
repository.removeVersionFromDisk(name);