优化 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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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);
@ -140,4 +139,3 @@ public final class ForgeNewModMetadata {
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.");
@ -144,4 +142,3 @@ public final class ForgeOldModMetadata {
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.");
@ -158,4 +156,3 @@ public class PackMcMeta implements Validation {
"", "", "", "", "");
}
}
}