feat: import .minecraft modpack. Closes #973.

This commit is contained in:
huanghongxun
2021-09-25 20:24:50 +08:00
parent d075dd27bc
commit 7fd8e0721f
19 changed files with 343 additions and 61 deletions

View File

@@ -17,6 +17,10 @@
*/
package org.jackhuang.hmcl.mod;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.task.Task;
import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
@@ -24,14 +28,14 @@ import java.util.List;
*
* @author huangyuhui
*/
public final class Modpack {
private final String name;
private final String author;
private final String version;
private final String gameVersion;
private final String description;
private final transient Charset encoding;
private final Object manifest;
public abstract class Modpack {
private String name;
private String author;
private String version;
private String gameVersion;
private String description;
private transient Charset encoding;
private Object manifest;
public Modpack() {
this("", null, null, null, null, null, null);
@@ -51,32 +55,54 @@ public final class Modpack {
return name;
}
public Modpack setName(String name) {
this.name = name;
return this;
}
public String getAuthor() {
return author;
}
public Modpack setAuthor(String author) {
this.author = author;
return this;
}
public String getVersion() {
return version;
}
public Modpack setVersion(String version) {
this.version = version;
return this;
}
public String getGameVersion() {
return gameVersion;
}
public Modpack setGameVersion(String gameVersion) {
return new Modpack(name, author, version, gameVersion, description, encoding, manifest);
this.gameVersion = gameVersion;
return this;
}
public String getDescription() {
return description;
}
public Modpack setDescription(String description) {
this.description = description;
return this;
}
public Charset getEncoding() {
return encoding;
}
public Modpack setEncoding(Charset encoding) {
return new Modpack(name, author, version, gameVersion, description, encoding, manifest);
this.encoding = encoding;
return this;
}
public Object getManifest() {
@@ -84,9 +110,12 @@ public final class Modpack {
}
public Modpack setManifest(Object manifest) {
return new Modpack(name, author, version, gameVersion, description, encoding, manifest);
this.manifest = manifest;
return this;
}
public abstract Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name);
public static boolean acceptFile(String path, List<String> blackList, List<String> whiteList) {
if (path.isEmpty())
return true;

View File

@@ -19,11 +19,14 @@ package org.jackhuang.hmcl.mod.curse;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Immutable;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
@@ -122,7 +125,12 @@ public final class CurseManifest {
String json = CompressingUtils.readTextZipEntry(zip, "manifest.json", encoding);
CurseManifest manifest = JsonUtils.fromNonNullJson(json, CurseManifest.class);
return new Modpack(manifest.getName(), manifest.getAuthor(), manifest.getVersion(), manifest.getMinecraft().getGameVersion(),
CompressingUtils.readTextZipEntryQuietly(zip, "modlist.html", encoding).orElse( "No description"), encoding, manifest);
CompressingUtils.readTextZipEntryQuietly(zip, "modlist.html", encoding).orElse( "No description"), encoding, manifest) {
@Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name) {
return new CurseInstallTask(dependencyManager, zipFile, this, manifest, name);
}
};
}
public static final String MINECRAFT_MODPACK = "minecraftModpack";

View File

@@ -19,9 +19,11 @@ package org.jackhuang.hmcl.mod.mcbbs;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.game.LaunchOptions;
import org.jackhuang.hmcl.game.Library;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.*;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -419,7 +421,12 @@ public class McbbsModpackManifest implements Validation {
public Modpack toModpack(Charset encoding) throws IOException {
String gameVersion = addons.stream().filter(x -> MINECRAFT.getPatchId().equals(x.id)).findAny()
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
return new Modpack(name, author, version, gameVersion, description, encoding, this);
return new Modpack(name, author, version, gameVersion, description, encoding, this) {
@Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, java.io.File zipFile, String name) {
return new McbbsModpackLocalInstallTask(dependencyManager, zipFile, this, McbbsModpackManifest.this, name);
}
};
}
public void injectLaunchOptions(LaunchOptions.Builder launchOptions) {

View File

@@ -17,11 +17,14 @@
*/
package org.jackhuang.hmcl.mod.multimc;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -356,7 +359,12 @@ public final class MultiMCInstanceConfiguration {
throw new IOException("`instance.cfg` not found, " + modpackFile + " is not a valid MultiMC modpack.");
try (InputStream instanceStream = Files.newInputStream(instancePath)) {
MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, instanceStream, manifest);
return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), encoding, cfg);
return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), encoding, cfg) {
@Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name) {
return new MultiMCModpackInstallTask(dependencyManager, zipFile, this, cfg, name);
}
};
}
}
}

View File

@@ -18,13 +18,16 @@
package org.jackhuang.hmcl.mod.server;
import com.google.gson.JsonParseException;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.ModpackConfiguration;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.gson.TolerableValidationException;
import org.jackhuang.hmcl.util.gson.Validation;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
@@ -117,7 +120,12 @@ public class ServerModpackManifest implements Validation {
public Modpack toModpack(Charset encoding) throws IOException {
String gameVersion = addons.stream().filter(x -> MINECRAFT.getPatchId().equals(x.id)).findAny()
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
return new Modpack(name, author, version, gameVersion, description, encoding, this);
return new Modpack(name, author, version, gameVersion, description, encoding, this) {
@Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name) {
return new ServerModpackLocalInstallTask(dependencyManager, zipFile, this, ServerModpackManifest.this, name);
}
};
}
/**

View File

@@ -330,6 +330,14 @@ public final class Lang {
return optional.map(Stream::of).orElseGet(Stream::empty);
}
public static <T> Iterable<T> toIterable(Stream<T> stream) {
return stream::iterator;
}
public static <T> Iterable<T> toIterable(Iterator<T> iterator) {
return () -> iterator;
}
/**
* This is a useful function to prevent exceptions being eaten when using CompletableFuture.
* You can write:

View File

@@ -99,6 +99,7 @@ public final class FileUtils {
}
public static String getName(Path path) {
if (path.getFileName() == null) return "";
return StringUtils.removeSuffix(path.getFileName().toString(), "/", "\\");
}