Support fabric detection
This commit is contained in:
@@ -158,9 +158,9 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
||||
File iconFile = getVersionIconFile(id);
|
||||
if (iconFile.exists())
|
||||
return new Image("file:" + iconFile.getAbsolutePath());
|
||||
else if ("net.minecraft.launchwrapper.Launch".equals(version.getMainClass()))
|
||||
return newImage("/assets/img/furnace.png");
|
||||
else if ("cpw.mods.modlauncher.Launcher".equals(version.getMainClass()))
|
||||
else if ("net.minecraft.launchwrapper.Launch".equals(version.getMainClass())
|
||||
|| version.getMainClass().startsWith("net.fabricmc")
|
||||
|| "cpw.mods.modlauncher.Launcher".equals(version.getMainClass()))
|
||||
return newImage("/assets/img/furnace.png");
|
||||
else
|
||||
return newImage("/assets/img/grass.png");
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jackhuang.hmcl.util.io.ResponseCodeException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class InstallerWizardProvider implements WizardProvider {
|
||||
@@ -56,9 +57,9 @@ public final class InstallerWizardProvider implements WizardProvider {
|
||||
this.version = version;
|
||||
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version);
|
||||
forge = analyzer.getForge().map(Library::getVersion).orElse(null);
|
||||
liteLoader = analyzer.getLiteLoader().map(Library::getVersion).orElse(null);
|
||||
optiFine = analyzer.getOptiFine().map(Library::getVersion).orElse(null);
|
||||
forge = analyzer.get(FORGE).map(Library::getVersion).orElse(null);
|
||||
liteLoader = analyzer.get(LITELOADER).map(Library::getVersion).orElse(null);
|
||||
optiFine = analyzer.get(OPTIFINE).map(Library::getVersion).orElse(null);
|
||||
}
|
||||
|
||||
public Profile getProfile() {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||
import static org.jackhuang.hmcl.util.Lang.handleUncaught;
|
||||
import static org.jackhuang.hmcl.util.Lang.threadPool;
|
||||
import static org.jackhuang.hmcl.util.StringUtils.removePrefix;
|
||||
@@ -55,9 +56,9 @@ public class GameItem extends Control {
|
||||
.thenAcceptAsync(game -> {
|
||||
StringBuilder libraries = new StringBuilder(game);
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(profile.getRepository().getVersion(id));
|
||||
analyzer.getForge().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.forge")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)forge", ""))));
|
||||
analyzer.getLiteLoader().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.liteloader")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)liteloader", ""))));
|
||||
analyzer.getOptiFine().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.optifine")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)optifine", ""))));
|
||||
analyzer.get(FORGE).ifPresent(library -> libraries.append(", ").append(i18n("install.installer.forge")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)forge", ""))));
|
||||
analyzer.get(LITELOADER).ifPresent(library -> libraries.append(", ").append(i18n("install.installer.liteloader")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)liteloader", ""))));
|
||||
analyzer.get(OPTIFINE).ifPresent(library -> libraries.append(", ").append(i18n("install.installer.optifine")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)optifine", ""))));
|
||||
subtitle.set(libraries.toString());
|
||||
}, Platform::runLater)
|
||||
.exceptionally(handleUncaught);
|
||||
|
||||
@@ -36,6 +36,7 @@ import java.util.LinkedList;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class InstallerListPage extends ListPage<InstallerItem> {
|
||||
@@ -66,15 +67,15 @@ public class InstallerListPage extends ListPage<InstallerItem> {
|
||||
};
|
||||
|
||||
itemsProperty().clear();
|
||||
analyzer.getForge().ifPresent(library -> itemsProperty().add(
|
||||
analyzer.get(FORGE).ifPresent(library -> itemsProperty().add(
|
||||
new InstallerItem("Forge", library.getVersion(), () -> {
|
||||
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, "forge", library));
|
||||
}, removeAction.apply(library))));
|
||||
analyzer.getLiteLoader().ifPresent(library -> itemsProperty().add(
|
||||
analyzer.get(LITELOADER).ifPresent(library -> itemsProperty().add(
|
||||
new InstallerItem("LiteLoader", library.getVersion(), () -> {
|
||||
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, "liteloader", library));
|
||||
}, removeAction.apply(library))));
|
||||
analyzer.getOptiFine().ifPresent(library -> itemsProperty().add(
|
||||
analyzer.get(OPTIFINE).ifPresent(library -> itemsProperty().add(
|
||||
new InstallerItem("OptiFine", library.getVersion(), () -> {
|
||||
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, "optifine", library));
|
||||
}, removeAction.apply(library))));
|
||||
|
||||
@@ -80,7 +80,7 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
|
||||
|
||||
public void loadVersion(Profile profile, String id) {
|
||||
libraryAnalyzer = LibraryAnalyzer.analyze(profile.getRepository().getResolvedVersion(id));
|
||||
modded.set(libraryAnalyzer.hasForge() || libraryAnalyzer.hasLiteLoader());
|
||||
modded.set(libraryAnalyzer.hasModLoader());
|
||||
loadMods(profile.getRepository().getModManager(id));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,59 +20,68 @@ package org.jackhuang.hmcl.download;
|
||||
import org.jackhuang.hmcl.game.Library;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class LibraryAnalyzer {
|
||||
private final Library forge;
|
||||
private final Library liteLoader;
|
||||
private final Library optiFine;
|
||||
private final Map<LibraryType, Library> libraries;
|
||||
|
||||
public LibraryAnalyzer(Library forge, Library liteLoader, Library optiFine) {
|
||||
this.forge = forge;
|
||||
this.liteLoader = liteLoader;
|
||||
this.optiFine = optiFine;
|
||||
private LibraryAnalyzer(Map<LibraryType, Library> libraries) {
|
||||
this.libraries = libraries;
|
||||
}
|
||||
|
||||
public Optional<Library> getForge() {
|
||||
return Optional.ofNullable(forge);
|
||||
public Optional<Library> get(LibraryType type) {
|
||||
return Optional.ofNullable(libraries.get(type));
|
||||
}
|
||||
|
||||
public boolean hasForge() {
|
||||
return forge != null;
|
||||
public boolean has(LibraryType type) {
|
||||
return libraries.containsKey(type);
|
||||
}
|
||||
|
||||
public Optional<Library> getLiteLoader() {
|
||||
return Optional.ofNullable(liteLoader);
|
||||
}
|
||||
|
||||
public boolean hasLiteLoader() {
|
||||
return liteLoader != null;
|
||||
}
|
||||
|
||||
public Optional<Library> getOptiFine() {
|
||||
return Optional.ofNullable(optiFine);
|
||||
}
|
||||
|
||||
public boolean hasOptiFine() {
|
||||
return optiFine != null;
|
||||
public boolean hasModLoader() {
|
||||
return Arrays.stream(LibraryType.values())
|
||||
.filter(LibraryType::isModLoader)
|
||||
.anyMatch(this::has);
|
||||
}
|
||||
|
||||
public static LibraryAnalyzer analyze(Version version) {
|
||||
Library forge = null, liteLoader = null, optiFine = null;
|
||||
Map<LibraryType, Library> libraries = new EnumMap<>(LibraryType.class);
|
||||
|
||||
for (Library library : version.getLibraries()) {
|
||||
String groupId = library.getGroupId();
|
||||
String artifactId = library.getArtifactId();
|
||||
if (groupId.equalsIgnoreCase("net.minecraftforge") && artifactId.equalsIgnoreCase("forge"))
|
||||
forge = library;
|
||||
|
||||
if (groupId.equalsIgnoreCase("com.mumfrey") && artifactId.equalsIgnoreCase("liteloader"))
|
||||
liteLoader = library;
|
||||
|
||||
if ((groupId.equalsIgnoreCase("optifine") || groupId.equalsIgnoreCase("net.optifine")) && artifactId.equalsIgnoreCase("optifine"))
|
||||
optiFine = library;
|
||||
for (LibraryType type : LibraryType.values()) {
|
||||
if (type.group.matcher(groupId).matches() && type.artifact.matcher(artifactId).matches()) {
|
||||
libraries.put(type, library);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new LibraryAnalyzer(forge, liteLoader, optiFine);
|
||||
return new LibraryAnalyzer(libraries);
|
||||
}
|
||||
|
||||
public enum LibraryType {
|
||||
FORGE(true, Pattern.compile("net\\.minecraftforge"), Pattern.compile("forge")),
|
||||
LITELOADER(true, Pattern.compile("com\\.mumfrey"), Pattern.compile("liteloader")),
|
||||
OPTIFINE(false, Pattern.compile("(net\\.)?optifine"), Pattern.compile(".*")),
|
||||
FABRIC(true, Pattern.compile("net\\.fabricmc"), Pattern.compile(".*"));
|
||||
|
||||
private final Pattern group, artifact;
|
||||
private final boolean modLoader;
|
||||
|
||||
LibraryType(boolean modLoader, Pattern group, Pattern artifact) {
|
||||
this.modLoader = modLoader;
|
||||
this.group = group;
|
||||
this.artifact = artifact;
|
||||
}
|
||||
|
||||
public boolean isModLoader() {
|
||||
return modLoader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ package org.jackhuang.hmcl.download;
|
||||
import org.jackhuang.hmcl.game.*;
|
||||
import org.jackhuang.hmcl.task.TaskResult;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||
|
||||
public class MaintainTask extends TaskResult<Version> {
|
||||
|
||||
private final Version version;
|
||||
@@ -47,20 +49,20 @@ public class MaintainTask extends TaskResult<Version> {
|
||||
LibraryAnalyzer libraryAnalyzer = LibraryAnalyzer.analyze(version);
|
||||
VersionLibraryBuilder builder = new VersionLibraryBuilder(version);
|
||||
|
||||
if (!libraryAnalyzer.hasForge()) {
|
||||
if (!libraryAnalyzer.has(FORGE)) {
|
||||
builder.removeTweakClass("forge");
|
||||
}
|
||||
|
||||
// Installing Forge will override the Minecraft arguments in json, so LiteLoader and OptiFine Tweaker are being re-added.
|
||||
|
||||
builder.removeTweakClass("liteloader");
|
||||
if (libraryAnalyzer.hasLiteLoader()) {
|
||||
if (libraryAnalyzer.has(LITELOADER)) {
|
||||
builder.addArgument("--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker");
|
||||
}
|
||||
|
||||
builder.removeTweakClass("optifine");
|
||||
if (libraryAnalyzer.hasOptiFine()) {
|
||||
if (!libraryAnalyzer.hasLiteLoader() && !libraryAnalyzer.hasForge()) {
|
||||
if (libraryAnalyzer.has(OPTIFINE)) {
|
||||
if (!libraryAnalyzer.has(LITELOADER) && !libraryAnalyzer.has(FORGE)) {
|
||||
builder.addArgument("--tweakClass", "optifine.OptiFineTweaker");
|
||||
} else {
|
||||
// If forge or LiteLoader installed, OptiFine Forge Tweaker is needed.
|
||||
|
||||
@@ -25,7 +25,9 @@ import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.task.TaskResult;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -66,7 +68,9 @@ public final class OptiFineInstallTask extends TaskResult<Version> {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if ("cpw.mods.modlauncher.Launcher".equals(version.getMainClass()))
|
||||
if (!Arrays.asList("net.minecraft.client.main.Main",
|
||||
"net.minecraft.launchwrapper.Launch")
|
||||
.contains(version.getMainClass()))
|
||||
throw new UnsupportedOptiFineInstallationException();
|
||||
|
||||
String remoteVersion = remote.getGameVersion() + "_" + remote.getSelfVersion();
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package org.jackhuang.hmcl.mod;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
@@ -27,7 +26,6 @@ import javafx.collections.ObservableList;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.gson.Validation;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.io.Unzipper;
|
||||
@@ -254,54 +252,6 @@ public class Datapack {
|
||||
}
|
||||
}
|
||||
|
||||
private static class PackMcMeta implements Validation {
|
||||
|
||||
@SerializedName("pack")
|
||||
private final PackInfo pack;
|
||||
|
||||
public PackMcMeta() {
|
||||
this(new PackInfo());
|
||||
}
|
||||
|
||||
public PackMcMeta(PackInfo packInfo) {
|
||||
this.pack = packInfo;
|
||||
}
|
||||
|
||||
public PackInfo getPackInfo() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() throws JsonParseException {
|
||||
if (pack == null)
|
||||
throw new JsonParseException("pack cannot be null");
|
||||
}
|
||||
|
||||
public static class PackInfo {
|
||||
@SerializedName("pack_format")
|
||||
private final int packFormat;
|
||||
|
||||
@SerializedName("description")
|
||||
private final String description;
|
||||
|
||||
public PackInfo() {
|
||||
this(0, "");
|
||||
}
|
||||
|
||||
public PackInfo(int packFormat, String description) {
|
||||
this.packFormat = packFormat;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getPackFormat() {
|
||||
return packFormat;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String DISABLED_EXT = "disabled";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 com.google.gson.*;
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Immutable
|
||||
public final class FabricModMetadata {
|
||||
private final String name;
|
||||
private final String version;
|
||||
private final String description;
|
||||
private final List<FabricModAuthor> authors;
|
||||
private final Map<String, String> contact;
|
||||
|
||||
public FabricModMetadata() {
|
||||
this("", "", "", Collections.emptyList(), Collections.emptyMap());
|
||||
}
|
||||
|
||||
public FabricModMetadata(String name, String version, String description, List<FabricModAuthor> authors, Map<String, String> contact) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.description = description;
|
||||
this.authors = authors;
|
||||
this.contact = contact;
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||
Path mcmod = fs.getPath("fabric.mod.json");
|
||||
if (Files.notExists(mcmod))
|
||||
throw new IOException("File " + modFile + " is not a Fabric mod.");
|
||||
FabricModMetadata metadata = JsonUtils.fromNonNullJson(IOUtils.readFullyAsString(Files.newInputStream(mcmod)), FabricModMetadata.class);
|
||||
String authors = metadata.authors == null ? "" : metadata.authors.stream().map(author -> author.name).collect(Collectors.joining(", "));
|
||||
return new ModInfo(modManager, modFile, metadata.name, metadata.description,
|
||||
authors, metadata.version, "", metadata.contact != null ? metadata.contact.getOrDefault("homepage", "") : "");
|
||||
}
|
||||
}
|
||||
|
||||
@JsonAdapter(FabricModAuthorSerializer.class)
|
||||
public static final class FabricModAuthor {
|
||||
private final String name;
|
||||
|
||||
public FabricModAuthor() {
|
||||
this("");
|
||||
}
|
||||
|
||||
public FabricModAuthor(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class FabricModAuthorSerializer implements JsonSerializer<FabricModAuthor>, JsonDeserializer<FabricModAuthor> {
|
||||
@Override
|
||||
public FabricModAuthor deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
return json.isJsonPrimitive() ? new FabricModAuthor(json.getAsString()) : new FabricModAuthor(json.getAsJsonObject().getAsJsonPrimitive("name").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(FabricModAuthor src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return src == null ? JsonNull.INSTANCE : new JsonPrimitive(src.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,12 @@ public final class ModManager {
|
||||
}
|
||||
|
||||
try {
|
||||
return RiftModMetadata.fromFile(this, modFile);
|
||||
return FabricModMetadata.fromFile(this, modFile);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
return PackMcMeta.fromFile(this, modFile);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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 com.google.gson.*;
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.gson.Validation;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Immutable
|
||||
public class PackMcMeta implements Validation {
|
||||
|
||||
@SerializedName("pack")
|
||||
private final PackInfo pack;
|
||||
|
||||
public PackMcMeta() {
|
||||
this(new PackInfo());
|
||||
}
|
||||
|
||||
public PackMcMeta(PackInfo packInfo) {
|
||||
this.pack = packInfo;
|
||||
}
|
||||
|
||||
public PackInfo getPackInfo() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() throws JsonParseException {
|
||||
if (pack == null)
|
||||
throw new JsonParseException("pack cannot be null");
|
||||
}
|
||||
|
||||
public static class PackInfo {
|
||||
@SerializedName("pack_format")
|
||||
private final int packFormat;
|
||||
|
||||
@SerializedName("description")
|
||||
private final String description;
|
||||
|
||||
public PackInfo() {
|
||||
this(0, "");
|
||||
}
|
||||
|
||||
public PackInfo(int packFormat, String description) {
|
||||
this.packFormat = packFormat;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getPackFormat() {
|
||||
return packFormat;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||
Path mcmod = fs.getPath("pack.mcmeta");
|
||||
if (Files.notExists(mcmod))
|
||||
throw new IOException("File " + modFile + " is not a resource pack.");
|
||||
PackMcMeta metadata = JsonUtils.fromNonNullJson(IOUtils.readFullyAsString(Files.newInputStream(mcmod)), PackMcMeta.class);
|
||||
return new ModInfo(modManager, modFile, metadata.pack.description, "", "", "", "", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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 com.google.gson.JsonParseException;
|
||||
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Immutable
|
||||
public final class RiftModMetadata {
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final List<String> authors;
|
||||
|
||||
public RiftModMetadata() {
|
||||
this("", "", Collections.emptyList());
|
||||
}
|
||||
|
||||
public RiftModMetadata(String id, String name, List<String> authors) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<String> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||
Path mcmod = fs.getPath("riftmod.json");
|
||||
if (Files.notExists(mcmod))
|
||||
throw new IOException("File " + modFile + " is not a Forge mod.");
|
||||
RiftModMetadata metadata = JsonUtils.fromNonNullJson(IOUtils.readFullyAsString(Files.newInputStream(mcmod)), RiftModMetadata.class);
|
||||
String authors = metadata.getAuthors() == null ? "" : String.join(", ", metadata.getAuthors());
|
||||
return new ModInfo(modManager, modFile, metadata.getName(), "",
|
||||
authors, "", "", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user