From ea5b31d537913feb2244b4536ba89a9e67ab8bfc Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 24 Nov 2018 20:32:22 +0800 Subject: [PATCH] Allow specifying authlib-injector path --- .../org/jackhuang/hmcl/setting/Accounts.java | 17 +++++-- .../AuthlibInjectorAccount.java | 4 +- .../AuthlibInjectorAccountFactory.java | 4 +- .../AuthlibInjectorArtifactInfo.java | 29 +++++++++++ .../AuthlibInjectorArtifactProvider.java | 29 +++++++++++ .../AuthlibInjectorDownloader.java | 33 ++----------- ...SimpleAuthlibInjectorArtifactProvider.java | 49 +++++++++++++++++++ README.md | 1 + 8 files changed, 130 insertions(+), 36 deletions(-) create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactProvider.java create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/SimpleAuthlibInjectorArtifactProvider.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java index a3d2f8ee6..75fa01fc5 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java @@ -29,8 +29,10 @@ import org.jackhuang.hmcl.auth.AccountFactory; import org.jackhuang.hmcl.auth.AuthenticationException; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccountFactory; +import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorArtifactProvider; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDownloader; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; +import org.jackhuang.hmcl.auth.authlibinjector.SimpleAuthlibInjectorArtifactProvider; import org.jackhuang.hmcl.auth.offline.OfflineAccount; import org.jackhuang.hmcl.auth.offline.OfflineAccountFactory; import org.jackhuang.hmcl.auth.yggdrasil.MojangYggdrasilProvider; @@ -39,6 +41,7 @@ import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory; import org.jackhuang.hmcl.task.Schedulers; import java.io.IOException; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -61,9 +64,7 @@ public final class Accounts { public static final OfflineAccountFactory FACTORY_OFFLINE = OfflineAccountFactory.INSTANCE; public static final YggdrasilAccountFactory FACTORY_YGGDRASIL = new YggdrasilAccountFactory(MojangYggdrasilProvider.INSTANCE); - public static final AuthlibInjectorAccountFactory FACTORY_AUTHLIB_INJECTOR = new AuthlibInjectorAccountFactory( - new AuthlibInjectorDownloader(Metadata.HMCL_DIRECTORY, DownloadProviders::getDownloadProvider), - Accounts::getOrCreateAuthlibInjectorServer); + public static final AuthlibInjectorAccountFactory FACTORY_AUTHLIB_INJECTOR = new AuthlibInjectorAccountFactory(createAuthlibInjectorArtifactProvider(), Accounts::getOrCreateAuthlibInjectorServer); // ==== login type / account factory mapping ==== private static final Map> type2factory = new HashMap<>(); @@ -240,6 +241,16 @@ public final class Accounts { } // ==== authlib-injector ==== + private static AuthlibInjectorArtifactProvider createAuthlibInjectorArtifactProvider() { + String authlibinjectorLocation = System.getProperty("hmcl.authlibinjector.location"); + if (authlibinjectorLocation == null) { + return new AuthlibInjectorDownloader(Metadata.HMCL_DIRECTORY, DownloadProviders::getDownloadProvider); + } else { + LOG.info("Using specified authlib-injector: " + authlibinjectorLocation); + return new SimpleAuthlibInjectorArtifactProvider(Paths.get(authlibinjectorLocation)); + } + } + private static AuthlibInjectorServer getOrCreateAuthlibInjectorServer(String url) { return config().getAuthlibInjectorServers().stream() .filter(server -> url.equals(server.getUrl())) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java index c8c15e281..9b81f9503 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java @@ -36,9 +36,9 @@ import static java.nio.charset.StandardCharsets.UTF_8; public class AuthlibInjectorAccount extends YggdrasilAccount { private AuthlibInjectorServer server; - private AuthlibInjectorDownloader downloader; + private AuthlibInjectorArtifactProvider downloader; - protected AuthlibInjectorAccount(YggdrasilService service, AuthlibInjectorServer server, AuthlibInjectorDownloader downloader, String username, UUID characterUUID, YggdrasilSession session) { + protected AuthlibInjectorAccount(YggdrasilService service, AuthlibInjectorServer server, AuthlibInjectorArtifactProvider downloader, String username, UUID characterUUID, YggdrasilSession session) { super(service, username, characterUUID, session); this.downloader = downloader; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java index 16b9c7fd2..30b41e0f0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java @@ -29,13 +29,13 @@ import java.util.function.Function; import static org.jackhuang.hmcl.util.Lang.tryCast; public class AuthlibInjectorAccountFactory extends AccountFactory { - private AuthlibInjectorDownloader downloader; + private AuthlibInjectorArtifactProvider downloader; private Function serverLookup; /** * @param serverLookup a function that looks up {@link AuthlibInjectorServer} by url */ - public AuthlibInjectorAccountFactory(AuthlibInjectorDownloader downloader, Function serverLookup) { + public AuthlibInjectorAccountFactory(AuthlibInjectorArtifactProvider downloader, Function serverLookup) { this.downloader = downloader; this.serverLookup = serverLookup; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactInfo.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactInfo.java index f313a89a8..95418990b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactInfo.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactInfo.java @@ -17,10 +17,39 @@ */ package org.jackhuang.hmcl.auth.authlibinjector; +import java.io.IOException; import java.nio.file.Path; +import java.util.Optional; +import java.util.jar.Attributes; +import java.util.jar.JarFile; public class AuthlibInjectorArtifactInfo { + public static AuthlibInjectorArtifactInfo from(Path location) throws IOException { + try (JarFile jarFile = new JarFile(location.toFile())) { + Attributes attributes = jarFile.getManifest().getMainAttributes(); + + String title = Optional.ofNullable(attributes.getValue("Implementation-Title")) + .orElseThrow(() -> new IOException("Missing Implementation-Title")); + if (!"authlib-injector".equals(title)) { + throw new IOException("Bad Implementation-Title"); + } + + String version = Optional.ofNullable(attributes.getValue("Implementation-Version")) + .orElseThrow(() -> new IOException("Missing Implementation-Version")); + + int buildNumber; + try { + buildNumber = Optional.ofNullable(attributes.getValue("Build-Number")) + .map(Integer::parseInt) + .orElseThrow(() -> new IOException("Missing Build-Number")); + } catch (NumberFormatException e) { + throw new IOException("Bad Build-Number", e); + } + return new AuthlibInjectorArtifactInfo(buildNumber, version, location.toAbsolutePath()); + } + } + private int buildNumber; private String version; private Path location; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactProvider.java new file mode 100644 index 000000000..94b8ed33f --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorArtifactProvider.java @@ -0,0 +1,29 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2018 huangyuhui + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see {http://www.gnu.org/licenses/}. + */ +package org.jackhuang.hmcl.auth.authlibinjector; + +import java.io.IOException; +import java.util.Optional; + +public interface AuthlibInjectorArtifactProvider { + + AuthlibInjectorArtifactInfo getArtifactInfo() throws IOException; + + Optional getArtifactInfoImmediately(); + +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorDownloader.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorDownloader.java index 68a75b1e3..35e99c34c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorDownloader.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorDownloader.java @@ -32,13 +32,11 @@ import java.nio.file.Path; import java.util.Map; import java.util.Optional; import java.util.function.Supplier; -import java.util.jar.Attributes; -import java.util.jar.JarFile; import java.util.logging.Level; import static org.jackhuang.hmcl.util.Logging.LOG; -public class AuthlibInjectorDownloader { +public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvider { private static final String LATEST_BUILD_URL = "https://authlib-injector.yushi.moe/artifact/latest.json"; @@ -58,6 +56,7 @@ public class AuthlibInjectorDownloader { this.downloadProvider = downloadProvider; } + @Override public AuthlibInjectorArtifactInfo getArtifactInfo() throws IOException { synchronized (artifactLocation) { Optional local = getLocalArtifact(); @@ -79,6 +78,7 @@ public class AuthlibInjectorDownloader { } } + @Override public Optional getArtifactInfoImmediately() { return getLocalArtifact(); } @@ -120,38 +120,13 @@ public class AuthlibInjectorDownloader { return Optional.empty(); } try { - return Optional.of(readArtifactInfo(artifactLocation)); + return Optional.of(AuthlibInjectorArtifactInfo.from(artifactLocation)); } catch (IOException e) { LOG.log(Level.WARNING, "Bad authlib-injector artifact", e); return Optional.empty(); } } - private static AuthlibInjectorArtifactInfo readArtifactInfo(Path location) throws IOException { - try (JarFile jarFile = new JarFile(location.toFile())) { - Attributes attributes = jarFile.getManifest().getMainAttributes(); - - String title = Optional.ofNullable(attributes.getValue("Implementation-Title")) - .orElseThrow(() -> new IOException("Missing Implementation-Title")); - if (!"authlib-injector".equals(title)) { - throw new IOException("Bad Implementation-Title"); - } - - String version = Optional.ofNullable(attributes.getValue("Implementation-Version")) - .orElseThrow(() -> new IOException("Missing Implementation-Version")); - - int buildNumber; - try { - buildNumber = Optional.ofNullable(attributes.getValue("Build-Number")) - .map(Integer::parseInt) - .orElseThrow(() -> new IOException("Missing Build-Number")); - } catch (NumberFormatException e) { - throw new IOException("Bad Build-Number", e); - } - return new AuthlibInjectorArtifactInfo(buildNumber, version, location.toAbsolutePath()); - } - } - private class AuthlibInjectorVersionInfo { @SerializedName("build_number") public int buildNumber; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/SimpleAuthlibInjectorArtifactProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/SimpleAuthlibInjectorArtifactProvider.java new file mode 100644 index 000000000..9084cac8f --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/SimpleAuthlibInjectorArtifactProvider.java @@ -0,0 +1,49 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2018 huangyuhui + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see {http://www.gnu.org/licenses/}. + */ +package org.jackhuang.hmcl.auth.authlibinjector; + +import static org.jackhuang.hmcl.util.Logging.LOG; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Optional; +import java.util.logging.Level; + +public class SimpleAuthlibInjectorArtifactProvider implements AuthlibInjectorArtifactProvider { + + private Path location; + + public SimpleAuthlibInjectorArtifactProvider(Path location) { + this.location = location; + } + + @Override + public AuthlibInjectorArtifactInfo getArtifactInfo() throws IOException { + return AuthlibInjectorArtifactInfo.from(location); + } + + @Override + public Optional getArtifactInfoImmediately() { + try { + return Optional.of(getArtifactInfo()); + } catch (IOException e) { + LOG.log(Level.WARNING, "Bad authlib-injector artifact", e); + return Optional.empty(); + } + } +} diff --git a/README.md b/README.md index abac9ebc3..8ec7e8c1a 100644 --- a/README.md +++ b/README.md @@ -118,3 +118,4 @@ No plugin API. |`-Dhmcl.self_integrity_check.disable=true`|Bypass the self integrity check when checking for update.| |`-Dhmcl.version.override=`|Override the version number.| |`-Dhmcl.update_source.override=`|Override the update source.| +|`-Dhmcl.authlibinjector.location=`|Use specified authlib-injector (instead of downloading one).|