优化 mod 列表加载速度 (#1985)

* Share ZipFileSystem

* fix memory leak
This commit is contained in:
Glavo
2023-01-08 18:15:55 +08:00
committed by GitHub
parent bf822d7cf7
commit 1cc429c7ca
5 changed files with 80 additions and 88 deletions

View File

@@ -21,7 +21,6 @@ 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.FileUtils;
import java.io.IOException;
@@ -58,8 +57,7 @@ public final class FabricModMetadata {
this.contact = contact;
}
public static LocalModFile fromFile(ModManager modManager, Path modFile) throws IOException, JsonParseException {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile)) {
public static LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException, JsonParseException {
Path mcmod = fs.getPath("fabric.mod.json");
if (Files.notExists(mcmod))
throw new IOException("File " + modFile + " is not a Fabric mod.");
@@ -68,7 +66,6 @@ public final class FabricModMetadata {
return new LocalModFile(modManager, modManager.getLocalMod(metadata.id, ModLoaderType.FABRIC), modFile, metadata.name, new LocalModFile.Description(metadata.description),
authors, metadata.version, "", metadata.contact != null ? metadata.contact.getOrDefault("homepage", "") : "", metadata.icon);
}
}
@JsonAdapter(FabricModAuthorSerializer.class)
public static final class FabricModAuthor {

View File

@@ -3,10 +3,10 @@ package org.jackhuang.hmcl.mod;
import com.google.gson.JsonParseException;
import com.moandjiezana.toml.Toml;
import org.jackhuang.hmcl.util.Immutable;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -115,8 +115,7 @@ public final class ForgeNewModMetadata {
}
}
public static LocalModFile fromFile(ModManager modManager, Path modFile) throws IOException, JsonParseException {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile)) {
public static LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException, JsonParseException {
Path modstoml = fs.getPath("META-INF/mods.toml");
if (Files.notExists(modstoml))
throw new IOException("File " + modFile + " is not a Forge 1.13+ mod.");
@@ -127,8 +126,8 @@ public final class ForgeNewModMetadata {
Path manifestMF = fs.getPath("META-INF/MANIFEST.MF");
String jarVersion = "";
if (Files.exists(manifestMF)) {
try {
Manifest manifest = new Manifest(Files.newInputStream(manifestMF));
try (InputStream is = Files.newInputStream(manifestMF)) {
Manifest manifest = new Manifest(is);
jarVersion = manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to parse MANIFEST.MF in file " + modFile);
@@ -139,5 +138,4 @@ public final class ForgeNewModMetadata {
mod.getDisplayURL(),
metadata.getLogoFile());
}
}
}

View File

@@ -23,7 +23,6 @@ import com.google.gson.reflect.TypeToken;
import org.jackhuang.hmcl.util.Immutable;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.IOException;
@@ -120,8 +119,7 @@ public final class ForgeOldModMetadata {
return authors;
}
public static LocalModFile fromFile(ModManager modManager, Path modFile) throws IOException, JsonParseException {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile)) {
public static LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException, JsonParseException {
Path mcmod = fs.getPath("mcmod.info");
if (Files.notExists(mcmod))
throw new IOException("File " + modFile + " is not a Forge mod.");
@@ -143,5 +141,4 @@ public final class ForgeOldModMetadata {
StringUtils.isBlank(metadata.getUrl()) ? metadata.getUpdateUrl() : metadata.url,
metadata.getLogoFile());
}
}
}

View File

@@ -73,25 +73,28 @@ public final class ModManager {
String fileName = StringUtils.removeSuffix(FileUtils.getName(modFile), DISABLED_EXTENSION, OLD_EXTENSION);
String description;
if (fileName.endsWith(".zip") || fileName.endsWith(".jar")) {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile)) {
try {
return ForgeOldModMetadata.fromFile(this, modFile);
return ForgeOldModMetadata.fromFile(this, modFile, fs);
} catch (Exception ignore) {
}
try {
return ForgeNewModMetadata.fromFile(this, modFile);
return ForgeNewModMetadata.fromFile(this, modFile, fs);
} catch (Exception ignore) {
}
try {
return FabricModMetadata.fromFile(this, modFile);
return FabricModMetadata.fromFile(this, modFile, fs);
} catch (Exception ignore) {
}
try {
return PackMcMeta.fromFile(this, modFile);
return PackMcMeta.fromFile(this, modFile, fs);
} catch (Exception ignore) {
}
} catch (Exception ignored) {
}
description = "";
} else if (fileName.endsWith(".litemod")) {

View File

@@ -23,7 +23,6 @@ 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.FileUtils;
import java.io.IOException;
@@ -143,8 +142,7 @@ public class PackMcMeta implements Validation {
}
}
public static LocalModFile fromFile(ModManager modManager, Path modFile) throws IOException, JsonParseException {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile)) {
public static LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException, JsonParseException {
Path mcmod = fs.getPath("pack.mcmeta");
if (Files.notExists(mcmod))
throw new IOException("File " + modFile + " is not a resource pack.");
@@ -157,5 +155,4 @@ public class PackMcMeta implements Validation {
metadata.pack.description,
"", "", "", "", "");
}
}
}