[Bugfix] 使用 tomlj 代替 toml4j 以适配 TOML 标准 (#5863)

Resolves #5544
This commit is contained in:
Calboot authored and GitHub committed 2026-04-20 21:35:47 +08:00
1 parent 312a285792
commit 8969f55a1f
4 files changed
+38 -16

No files matched your search

@@ -93,5 +93,10 @@
"title": "LWJGL Unsafe Agent",
"subtitle": "Copyright © 2026 Glavo.\nLicensed under the Apache 2.0 License.",
"externalLink": "https://github.com/HMCL-dev/lwjgl-unsafe-agent"
},
{
"title": "TomlJ",
"subtitle": "Licensed under the Apache 2.0 License.",
"externalLink": "https://github.com/tomlj/tomlj"
}
]
+1 -1
View File
@@ -16,7 +16,7 @@ dependencies {
api(libs.kala.compress.tar)
api(libs.simple.png.javafx)
api(libs.gson)
api(libs.toml)
api(libs.tomlj)
api(libs.xz)
api(libs.lz4)
api(libs.fx.gson)
@@ -24,7 +24,6 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.annotations.JsonAdapter;
import com.moandjiezana.toml.Toml;
import kala.compress.archivers.zip.ZipArchiveEntry;
import org.jackhuang.hmcl.mod.LocalModFile;
import org.jackhuang.hmcl.mod.ModLoaderType;
@@ -35,6 +34,10 @@ 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.tree.ZipFileTree;
import org.tomlj.Toml;
import org.tomlj.TomlArray;
import org.tomlj.TomlParseResult;
import org.tomlj.TomlTable;
import java.io.IOException;
import java.io.InputStream;
@@ -42,8 +45,8 @@ import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
@@ -208,10 +211,15 @@ public final class ForgeNewModMetadata {
ZipArchiveEntry modToml = tree.getEntry(tomlPath);
if (modToml == null)
throw new IOException("File " + modFile + " is not a Forge 1.13+ or NeoForge mod.");
Toml toml = new Toml().read(tree.readTextEntry(modToml));
ForgeNewModMetadata metadata = toml.to(ForgeNewModMetadata.class);
TomlParseResult tomlParseResult = Toml.parse(tree.readTextEntry(modToml));
if (tomlParseResult.hasErrors()) {
var ioException = new IOException("Mod " + modFile + " `%s` is malformed..".formatted(modToml.getName()));
tomlParseResult.errors().forEach(ioException::addSuppressed);
throw ioException;
}
ForgeNewModMetadata metadata = JsonUtils.GSON.fromJson(tomlParseResult.toJson(), ForgeNewModMetadata.class);
if (metadata == null || metadata.getMods().isEmpty())
throw new IOException("Mod " + modFile + " `mods.toml` is malformed..");
throw new IOException("Mod " + modFile + " `%s` is malformed..".formatted(modToml.getName()));
Mod mod = metadata.getMods().get(0);
ZipArchiveEntry manifestMF = tree.getEntry("META-INF/MANIFEST.MF");
String jarVersion = "";
@@ -224,7 +232,7 @@ public final class ForgeNewModMetadata {
}
}
ModLoaderType type = analyzeLoader(toml, mod.getModId(), modLoaderType);
ModLoaderType type = analyzeLoader(tomlParseResult, mod.getModId(), modLoaderType);
return new LocalModFile(modManager, modManager.getLocalMod(mod.getModId(), type), modFile, mod.getDisplayName(), new LocalModFile.Description(mod.getDescription()),
mod.getAuthors(), jarVersion == null ? mod.getVersion() : mod.getVersion().replace("${file.jarVersion}", jarVersion), "",
@@ -293,23 +301,32 @@ public final class ForgeNewModMetadata {
throw new IOException();
}
private static ModLoaderType analyzeLoader(Toml toml, String modID, ModLoaderType loader) {
List<HashMap<String, Object>> dependencies = null;
private static ModLoaderType analyzeLoader(TomlParseResult toml, String modID, ModLoaderType loader) {
List<Map<String, Object>> dependencies = null;
try {
dependencies = toml.getList("dependencies." + modID);
TomlArray tomlArray = toml.getArray("dependencies." + modID);
if (tomlArray != null) {
dependencies = tomlArray.toList().stream().map( o -> ((TomlTable) o).toMap()).toList();
}
} catch (ClassCastException ignored) { // https://github.com/HMCL-dev/HMCL/issues/5068
}
if (dependencies == null) {
try {
dependencies = toml.getList("dependencies"); // ??? I have no idea why some of the Forge mods use [[dependencies]]
TomlArray tomlArray = toml.getArray("dependencies"); // ??? I have no idea why some of the Forge mods use [[dependencies]]
if (tomlArray != null) {
dependencies = tomlArray.toList().stream().map( o -> ((TomlTable) o).toMap()).toList();
}
} catch (ClassCastException e) {
try {
Toml table = toml.getTable("dependencies");
TomlTable table = toml.getTable("dependencies");
if (table == null)
return loader;
dependencies = table.getList(modID);
TomlArray tomlArray = table.getArray(modID);
if (tomlArray != null) {
dependencies = tomlArray.toList().stream().map( o -> ((TomlTable) o).toMap()).toList();
}
} catch (Throwable ignored) {
}
}
@@ -321,7 +338,7 @@ public final class ForgeNewModMetadata {
ModLoaderType result = null;
loop:
for (HashMap<String, Object> dependency : dependencies) {
for (Map<String, Object> dependency : dependencies) {
switch ((String) dependency.get("modId")) {
case "forge":
result = ModLoaderType.FORGE;
+2 -2
View File
@@ -4,7 +4,7 @@ jetbrains-annotations = "26.1.0"
kala-compress = "1.27.1-3"
simple-png-javafx = "0.3.0"
gson = "2.13.2"
toml4j = "0.7.2"
tomlj = "1.1.1"
xz = "1.12"
lz4 = "1.10.4.1"
fx-gson = "5.0.0"
@@ -38,7 +38,7 @@ kala-compress-zip = { module = "org.glavo.kala:kala-compress-archivers-zip", ver
kala-compress-tar = { module = "org.glavo.kala:kala-compress-archivers-tar", version.ref = "kala-compress" }
simple-png-javafx = { module = "org.glavo:simple-png-javafx", version.ref = "simple-png-javafx" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
toml = { module = "com.moandjiezana.toml:toml4j", version.ref = "toml4j" }
tomlj = { module = "org.tomlj:tomlj", version.ref = "tomlj" }
xz = { module = "org.tukaani:xz", version.ref = "xz" }
lz4 = { module = "org.glavo:lz4-java", version.ref = "lz4" }
fx-gson = { module = "org.hildan.fxgson:fx-gson", version.ref = "fx-gson" }