From 694e31a7fe6f34c1947d1f2d10d37e1d95abcef5 Mon Sep 17 00:00:00 2001 From: Glavo Date: Sun, 23 Oct 2022 23:27:21 +0800 Subject: [PATCH] Cache manifest in JarUtils (#1797) --- .../java/org/jackhuang/hmcl/Metadata.java | 6 +-- .../org/jackhuang/hmcl/game/OAuthServer.java | 4 +- .../curse/CurseForgeRemoteModRepository.java | 7 +-- .../org/jackhuang/hmcl/util/io/JarUtils.java | 53 ++++++++++++------- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java b/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java index e703cfcf7..b5fb2ea73 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java @@ -30,7 +30,7 @@ public final class Metadata { public static final String NAME = "HMCL"; public static final String FULL_NAME = "Hello Minecraft! Launcher"; - public static final String VERSION = System.getProperty("hmcl.version.override", JarUtils.thisJar().flatMap(JarUtils::getImplementationVersion).orElse("@develop@")); + public static final String VERSION = System.getProperty("hmcl.version.override", JarUtils.getManifestAttribute("Implementation-Version", "@develop@")); public static final String TITLE = NAME + " " + VERSION; public static final String FULL_TITLE = FULL_NAME + " v" + VERSION; @@ -39,10 +39,10 @@ public final class Metadata { public static final String CONTACT_URL = "https://github.com/huanghongxun/HMCL/issues"; public static final String HELP_URL = "https://hmcl.huangyuhui.net/help"; public static final String CHANGELOG_URL = "https://hmcl.huangyuhui.net/changelog/"; - public static final String PUBLISH_URL = "http://www.mcbbs.net/thread-142335-1-1.html"; + public static final String PUBLISH_URL = "https://www.mcbbs.net/thread-142335-1-1.html"; public static final String EULA_URL = "https://hmcl.huangyuhui.net/eula"; - public static final String BUILD_CHANNEL = JarUtils.thisJar().flatMap(JarUtils::getManifest).map(manifest -> manifest.getMainAttributes().getValue("Build-Channel")).orElse("nightly"); + public static final String BUILD_CHANNEL = JarUtils.getManifestAttribute("Build-Channel", "nightly"); public static final Path MINECRAFT_DIRECTORY = OperatingSystem.getWorkingDirectory("minecraft"); public static final Path HMCL_DIRECTORY = OperatingSystem.getWorkingDirectory("hmcl"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/OAuthServer.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/OAuthServer.java index 72f6a56f3..0cd9c5af6 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/OAuthServer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/OAuthServer.java @@ -160,13 +160,13 @@ public final class OAuthServer extends NanoHTTPD implements OAuth.Session { @Override public String getClientId() { return System.getProperty("hmcl.microsoft.auth.id", - JarUtils.thisJar().flatMap(JarUtils::getManifest).map(manifest -> manifest.getMainAttributes().getValue("Microsoft-Auth-Id")).orElse("")); + JarUtils.getManifestAttribute("Microsoft-Auth-Id", "")); } @Override public String getClientSecret() { return System.getProperty("hmcl.microsoft.auth.secret", - JarUtils.thisJar().flatMap(JarUtils::getManifest).map(manifest -> manifest.getMainAttributes().getValue("Microsoft-Auth-Secret")).orElse("")); + JarUtils.getManifestAttribute("Microsoft-Auth-Secret", "")); } @Override diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseForgeRemoteModRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseForgeRemoteModRepository.java index 0999806d3..1f5045549 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseForgeRemoteModRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseForgeRemoteModRepository.java @@ -41,12 +41,7 @@ public final class CurseForgeRemoteModRepository implements RemoteModRepository private static final String PREFIX = "https://api.curseforge.com"; - private static String apiKey; - - static { - apiKey = System.getProperty("hmcl.curseforge.apikey", - JarUtils.thisJar().flatMap(JarUtils::getManifest).map(manifest -> manifest.getMainAttributes().getValue("CurseForge-Api-Key")).orElse("")); - } + private static final String apiKey = System.getProperty("hmcl.curseforge.apikey", JarUtils.getManifestAttribute("CurseForge-Api-Key", "")); private final Type type; private final int section; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/JarUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/JarUtils.java index 2d0636e4b..408372df1 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/JarUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/JarUtils.java @@ -18,14 +18,13 @@ package org.jackhuang.hmcl.util.io; import java.io.IOException; +import java.io.InputStream; import java.net.URISyntaxException; import java.nio.file.FileSystemNotFoundException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.CodeSource; import java.util.Optional; -import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -34,22 +33,45 @@ public final class JarUtils { } @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - private static final Optional THIS_JAR = - Optional.ofNullable(JarUtils.class.getProtectionDomain().getCodeSource()) - .map(CodeSource::getLocation) - .map(url -> { - try { - return Paths.get(url.toURI()); - } catch (FileSystemNotFoundException | IllegalArgumentException | URISyntaxException e) { - return null; - } - }) - .filter(Files::isRegularFile); + private static final Optional THIS_JAR; + + private static final Manifest manifest; + + static { + THIS_JAR = Optional.ofNullable(JarUtils.class.getProtectionDomain().getCodeSource()) + .map(codeSource -> { + try { + return Paths.get(codeSource.getLocation().toURI()); + } catch (FileSystemNotFoundException | IllegalArgumentException | URISyntaxException e) { + return null; + } + }) + .filter(Files::isRegularFile); + + Manifest mf = null; + try (InputStream input = JarUtils.class.getResourceAsStream("/META-INF/MANIFEST.MF")) { + if (input != null) + mf = new Manifest(input); + } catch (IOException e) { + // Logger has not started + e.printStackTrace(); + } + + if (mf == null) + mf = THIS_JAR.flatMap(JarUtils::getManifest).orElseGet(Manifest::new); + + manifest = mf; + } public static Optional thisJar() { return THIS_JAR; } + public static String getManifestAttribute(String name, String defaultValue) { + String value = manifest.getMainAttributes().getValue(name); + return value != null ? value : defaultValue; + } + public static Optional getManifest(Path jar) { try (JarFile file = new JarFile(jar.toFile())) { return Optional.ofNullable(file.getManifest()); @@ -57,9 +79,4 @@ public final class JarUtils { return Optional.empty(); } } - - public static Optional getImplementationVersion(Path jar) { - return Optional.of(jar).flatMap(JarUtils::getManifest) - .flatMap(manifest -> Optional.ofNullable(manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION))); - } }