mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-01-30 14:39:56 +08:00
feat: show more friendly message if installing mod in InstallerListPage. Closes #996.
This commit is contained in:
parent
ae8600c882
commit
b95119bb0e
@ -346,7 +346,7 @@ install.failed=Version failed to install
|
||||
install.failed.downloading=Failed to install due to some files not downloaded successfully
|
||||
install.failed.downloading.detail=Failed to download file: %s
|
||||
install.failed.downloading.timeout=Timed out while downloading the file: %s
|
||||
install.failed.install_online=Unable to recognize the provided installer file
|
||||
install.failed.install_online=Unable to recognize the provided installer file. If you are installing a mod, go to "Mods" page.
|
||||
install.failed.malformed=The files just downloaded a moment ago is malformed. You may switch to other download provider to resolve this problem.
|
||||
install.failed.optifine_conflict=Fabric, OptiFine and Forge are installed simultaneously on Minecraft 1.13
|
||||
install.failed.version_mismatch=The library requires the game version %s, but the actual version is %s.
|
||||
|
@ -346,7 +346,7 @@ install.failed=安裝失敗
|
||||
install.failed.downloading=安裝失敗,部分檔案未能完成下載
|
||||
install.failed.downloading.detail=未能下載檔案: %s
|
||||
install.failed.downloading.timeout=下載逾時: %s
|
||||
install.failed.install_online=無法識別要安裝的軟體
|
||||
install.failed.install_online=無法識別要安裝的軟體。如果你要安裝 Mod,你需要在模組管理頁面安裝模組。
|
||||
install.failed.malformed=剛才下載的檔案格式損壞。您可以切換到其他下載來源以解決此問題。
|
||||
install.failed.optifine_conflict=暫不支援 OptiFine 與 Forge 同時安裝在 Minecraft 1.13 上
|
||||
install.failed.version_mismatch=該軟體需要的遊戲版本為 %s,但實際的遊戲版本為 %s。
|
||||
|
@ -346,7 +346,7 @@ install.failed=安装失败
|
||||
install.failed.downloading=安装失败,部分文件未能完成下载
|
||||
install.failed.downloading.detail=未能下载文件:%s
|
||||
install.failed.downloading.timeout=下载超时:%s
|
||||
install.failed.install_online=无法识别要安装的软件
|
||||
install.failed.install_online=无法识别要安装的软件。如果你要安装 Mod,你需要在模组管理页面安装模组。
|
||||
install.failed.malformed=下载的文件格式损坏。您可以切换到其他下载源来解决此问题。
|
||||
install.failed.optifine_conflict=暂不支持 OptiFine, Fabric 与 Forge 同时安装在 Minecraft 1.13 及以上版本
|
||||
install.failed.version_mismatch=该软件需要的游戏版本为 %s,但实际的游戏版本为 %s。
|
||||
|
@ -64,14 +64,14 @@ public final class FabricModMetadata {
|
||||
this.contact = contact;
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
public static ModInfo fromFile(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(FileUtils.readText(mcmod), FabricModMetadata.class);
|
||||
String authors = metadata.authors == null ? "" : metadata.authors.stream().map(author -> author.name).collect(Collectors.joining(", "));
|
||||
return new ModInfo(modManager, modFile, metadata.id, metadata.name, new ModInfo.Description(metadata.description),
|
||||
return new ModInfo(modFile, metadata.id, metadata.name, new ModInfo.Description(metadata.description),
|
||||
authors, metadata.version, "", metadata.contact != null ? metadata.contact.getOrDefault("homepage", "") : "", metadata.icon);
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ public final class ForgeNewModMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||
Path modstoml = fs.getPath("META-INF/mods.toml");
|
||||
if (Files.notExists(modstoml))
|
||||
@ -135,7 +135,7 @@ public final class ForgeNewModMetadata {
|
||||
LOG.log(Level.WARNING, "Failed to parse MANIFEST.MF in file " + modFile.getPath());
|
||||
}
|
||||
}
|
||||
return new ModInfo(modManager, modFile, mod.getModId(), mod.getDisplayName(), new ModInfo.Description(mod.getDescription()),
|
||||
return new ModInfo(modFile, mod.getModId(), mod.getDisplayName(), new ModInfo.Description(mod.getDescription()),
|
||||
mod.getAuthors(), mod.getVersion().replace("${file.jarVersion}", jarVersion), "",
|
||||
mod.getDisplayURL(),
|
||||
metadata.getLogoFile());
|
||||
|
@ -120,7 +120,7 @@ public final class ForgeOldModMetadata {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||
Path mcmod = fs.getPath("mcmod.info");
|
||||
if (Files.notExists(mcmod))
|
||||
@ -138,7 +138,7 @@ public final class ForgeOldModMetadata {
|
||||
authors = String.join(", ", metadata.getAuthorList());
|
||||
if (StringUtils.isBlank(authors))
|
||||
authors = metadata.getCredits();
|
||||
return new ModInfo(modManager, modFile, metadata.getModId(), metadata.getName(), new ModInfo.Description(metadata.getDescription()),
|
||||
return new ModInfo(modFile, metadata.getModId(), metadata.getName(), new ModInfo.Description(metadata.getDescription()),
|
||||
authors, metadata.getVersion(), metadata.getGameVersion(),
|
||||
StringUtils.isBlank(metadata.getUrl()) ? metadata.getUpdateUrl() : metadata.url,
|
||||
metadata.getLogoFile());
|
||||
|
@ -108,7 +108,7 @@ public final class LiteModMetadata {
|
||||
return updateURI;
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
||||
try (ZipFile zipFile = new ZipFile(modFile)) {
|
||||
ZipEntry entry = zipFile.getEntry("litemod.json");
|
||||
if (entry == null)
|
||||
@ -116,7 +116,7 @@ public final class LiteModMetadata {
|
||||
LiteModMetadata metadata = JsonUtils.GSON.fromJson(IOUtils.readFullyAsString(zipFile.getInputStream(entry)), LiteModMetadata.class);
|
||||
if (metadata == null)
|
||||
throw new IOException("Mod " + modFile + " `litemod.json` is malformed.");
|
||||
return new ModInfo(modManager, modFile, null, metadata.getName(), new ModInfo.Description(metadata.getDescription()), metadata.getAuthor(),
|
||||
return new ModInfo(modFile, null, metadata.getName(), new ModInfo.Description(metadata.getDescription()), metadata.getAuthor(),
|
||||
metadata.getVersion(), metadata.getGameVersion(), metadata.getUpdateURI(), "");
|
||||
}
|
||||
}
|
||||
|
@ -49,11 +49,11 @@ public final class ModInfo implements Comparable<ModInfo> {
|
||||
private final String logoPath;
|
||||
private final BooleanProperty activeProperty;
|
||||
|
||||
public ModInfo(ModManager modManager, File file, String id, String name, Description description) {
|
||||
this(modManager, file, id, name, description, "", "", "", "", "");
|
||||
public ModInfo(File file, String id, String name, Description description) {
|
||||
this(file, id, name, description, "", "", "", "", "");
|
||||
}
|
||||
|
||||
public ModInfo(ModManager modManager, File file, String id, String name, Description description, String authors, String version, String gameVersion, String url, String logoPath) {
|
||||
public ModInfo(File file, String id, String name, Description description, String authors, String version, String gameVersion, String url, String logoPath) {
|
||||
this.file = file.toPath();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
@ -64,16 +64,16 @@ public final class ModInfo implements Comparable<ModInfo> {
|
||||
this.url = url;
|
||||
this.logoPath = logoPath;
|
||||
|
||||
activeProperty = new SimpleBooleanProperty(this, "active", !modManager.isDisabled(file)) {
|
||||
activeProperty = new SimpleBooleanProperty(this, "active", !ModManager.isDisabled(file)) {
|
||||
@Override
|
||||
protected void invalidated() {
|
||||
Path path = ModInfo.this.file.toAbsolutePath();
|
||||
|
||||
try {
|
||||
if (get())
|
||||
ModInfo.this.file = modManager.enableMod(path);
|
||||
ModInfo.this.file = ModManager.enableMod(path);
|
||||
else
|
||||
ModInfo.this.file = modManager.disableMod(path);
|
||||
ModInfo.this.file = ModManager.disableMod(path);
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.SEVERE, "Unable to invert state of mod file " + path, e);
|
||||
}
|
||||
|
@ -19,16 +19,15 @@ package org.jackhuang.hmcl.mod;
|
||||
|
||||
import org.jackhuang.hmcl.game.GameRepository;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.Collection;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public final class ModManager {
|
||||
private final GameRepository repository;
|
||||
@ -61,29 +60,29 @@ public final class ModManager {
|
||||
}
|
||||
}
|
||||
|
||||
public ModInfo getModInfo(File modFile) {
|
||||
public static ModInfo getModInfo(File modFile) {
|
||||
File file = isDisabled(modFile) ? new File(modFile.getAbsoluteFile().getParentFile(), FileUtils.getNameWithoutExtension(modFile)) : modFile;
|
||||
String description, extension = FileUtils.getExtension(file);
|
||||
switch (extension) {
|
||||
case "zip":
|
||||
case "jar":
|
||||
try {
|
||||
return ForgeOldModMetadata.fromFile(this, modFile);
|
||||
return ForgeOldModMetadata.fromFile(modFile);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
return ForgeNewModMetadata.fromFile(this, modFile);
|
||||
return ForgeNewModMetadata.fromFile(modFile);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
return FabricModMetadata.fromFile(this, modFile);
|
||||
return FabricModMetadata.fromFile(modFile);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
return PackMcMeta.fromFile(this, modFile);
|
||||
return PackMcMeta.fromFile(modFile);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
@ -91,7 +90,7 @@ public final class ModManager {
|
||||
break;
|
||||
case "litemod":
|
||||
try {
|
||||
return LiteModMetadata.fromFile(this, modFile);
|
||||
return LiteModMetadata.fromFile(modFile);
|
||||
} catch (Exception ignore) {
|
||||
description = "LiteLoader Mod";
|
||||
}
|
||||
@ -99,7 +98,7 @@ public final class ModManager {
|
||||
default:
|
||||
throw new IllegalArgumentException("File " + modFile + " is not a mod file.");
|
||||
}
|
||||
return new ModInfo(this, modFile, null, FileUtils.getNameWithoutExtension(modFile), new ModInfo.Description(description));
|
||||
return new ModInfo(modFile, null, FileUtils.getNameWithoutExtension(modFile), new ModInfo.Description(description));
|
||||
}
|
||||
|
||||
public void refreshMods() throws IOException {
|
||||
@ -130,7 +129,7 @@ public final class ModManager {
|
||||
}
|
||||
|
||||
public void addMod(File file) throws IOException {
|
||||
if (!isFileMod(file))
|
||||
if (!isFileNameMod(file))
|
||||
throw new IllegalArgumentException("File " + file + " is not a valid mod file.");
|
||||
|
||||
if (!loaded)
|
||||
@ -152,31 +151,59 @@ public final class ModManager {
|
||||
}
|
||||
}
|
||||
|
||||
public Path disableMod(Path file) throws IOException {
|
||||
public static Path disableMod(Path file) throws IOException {
|
||||
Path disabled = file.getParent().resolve(StringUtils.addSuffix(FileUtils.getName(file), DISABLED_EXTENSION));
|
||||
if (Files.exists(file))
|
||||
Files.move(file, disabled, StandardCopyOption.REPLACE_EXISTING);
|
||||
return disabled;
|
||||
}
|
||||
|
||||
public Path enableMod(Path file) throws IOException {
|
||||
public static Path enableMod(Path file) throws IOException {
|
||||
Path enabled = file.getParent().resolve(StringUtils.removeSuffix(FileUtils.getName(file), DISABLED_EXTENSION));
|
||||
if (Files.exists(file))
|
||||
Files.move(file, enabled, StandardCopyOption.REPLACE_EXISTING);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public boolean isDisabled(File file) {
|
||||
public static boolean isDisabled(File file) {
|
||||
return file.getPath().endsWith(DISABLED_EXTENSION);
|
||||
}
|
||||
|
||||
public boolean isFileMod(File file) {
|
||||
public static boolean isFileNameMod(File file) {
|
||||
String name = file.getName();
|
||||
if (isDisabled(file))
|
||||
name = FileUtils.getNameWithoutExtension(file);
|
||||
return name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".litemod");
|
||||
}
|
||||
|
||||
public static boolean isFileMod(Path modFile) {
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile)) {
|
||||
if (Files.exists(fs.getPath("mcmod.info")) || Files.exists(fs.getPath("META-INF/mods.toml"))) {
|
||||
// Forge mod
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Files.exists(fs.getPath("fabric.mod.json"))) {
|
||||
// Fabric mod
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Files.exists(fs.getPath("litemod.json"))) {
|
||||
// Liteloader mod
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Files.exists(fs.getPath("pack.mcmeta"))) {
|
||||
// resource pack, data pack
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if "mods" directory has mod file named "fileName" no matter the mod is disabled or not
|
||||
*
|
||||
|
@ -144,13 +144,13 @@ public class PackMcMeta implements Validation {
|
||||
}
|
||||
}
|
||||
|
||||
public static ModInfo fromFile(ModManager modManager, File modFile) throws IOException, JsonParseException {
|
||||
public static ModInfo fromFile(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(FileUtils.readText(mcmod), PackMcMeta.class);
|
||||
return new ModInfo(modManager, modFile, null, FileUtils.getNameWithoutExtension(modFile), metadata.pack.description, "", "", "", "", "");
|
||||
return new ModInfo(modFile, null, FileUtils.getNameWithoutExtension(modFile), metadata.pack.description, "", "", "", "", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user