diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index f00f276c4..de31c8759 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -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"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java index cd1510d37..9942d6f27 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java @@ -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() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java index eaa81fa88..7330a21f9 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java @@ -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); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java index 072ec6915..f89444096 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java @@ -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 { @@ -66,15 +67,15 @@ public class InstallerListPage extends ListPage { }; 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)))); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java index 99c6fc046..5105e1df4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java @@ -80,7 +80,7 @@ public final class ModListPage extends ListPageBase libraries; - public LibraryAnalyzer(Library forge, Library liteLoader, Library optiFine) { - this.forge = forge; - this.liteLoader = liteLoader; - this.optiFine = optiFine; + private LibraryAnalyzer(Map libraries) { + this.libraries = libraries; } - public Optional getForge() { - return Optional.ofNullable(forge); + public Optional 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 getLiteLoader() { - return Optional.ofNullable(liteLoader); - } - - public boolean hasLiteLoader() { - return liteLoader != null; - } - - public Optional 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 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; + } } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java index c0a58dcbc..2c92f37c0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java @@ -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 { private final Version version; @@ -47,20 +49,20 @@ public class MaintainTask extends TaskResult { 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. diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java index 8107d0179..456a70cb0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java @@ -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 { @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(); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java index cfe1d3009..6e7034c4c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java @@ -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"; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/FabricModMetadata.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/FabricModMetadata.java new file mode 100644 index 000000000..6b07b526b --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/FabricModMetadata.java @@ -0,0 +1,94 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2019 huangyuhui 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 . + */ +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 authors; + private final Map contact; + + public FabricModMetadata() { + this("", "", "", Collections.emptyList(), Collections.emptyMap()); + } + + public FabricModMetadata(String name, String version, String description, List authors, Map 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, JsonDeserializer { + @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); + } + } +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModManager.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModManager.java index 020cb12ba..ebe8f9644 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModManager.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModManager.java @@ -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) { } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/PackMcMeta.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/PackMcMeta.java new file mode 100644 index 000000000..b705b637a --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/PackMcMeta.java @@ -0,0 +1,98 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2019 huangyuhui 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 . + */ +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, "", "", "", "", ""); + } + } +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/RiftModMetadata.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/RiftModMetadata.java deleted file mode 100644 index 0a27db2cf..000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/RiftModMetadata.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2019 huangyuhui 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 . - */ -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 authors; - - public RiftModMetadata() { - this("", "", Collections.emptyList()); - } - - public RiftModMetadata(String id, String name, List authors) { - this.id = id; - this.name = name; - this.authors = authors; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public List 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, "", "", ""); - } - } -}