mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-10 04:16:02 -04:00
Allow specifying authlib-injector path
This commit is contained in:
parent
bb0c11fa12
commit
ea5b31d537
@ -29,8 +29,10 @@ import org.jackhuang.hmcl.auth.AccountFactory;
|
|||||||
import org.jackhuang.hmcl.auth.AuthenticationException;
|
import org.jackhuang.hmcl.auth.AuthenticationException;
|
||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccountFactory;
|
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.AuthlibInjectorDownloader;
|
||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
|
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.OfflineAccount;
|
||||||
import org.jackhuang.hmcl.auth.offline.OfflineAccountFactory;
|
import org.jackhuang.hmcl.auth.offline.OfflineAccountFactory;
|
||||||
import org.jackhuang.hmcl.auth.yggdrasil.MojangYggdrasilProvider;
|
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 org.jackhuang.hmcl.task.Schedulers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -61,9 +64,7 @@ public final class Accounts {
|
|||||||
|
|
||||||
public static final OfflineAccountFactory FACTORY_OFFLINE = OfflineAccountFactory.INSTANCE;
|
public static final OfflineAccountFactory FACTORY_OFFLINE = OfflineAccountFactory.INSTANCE;
|
||||||
public static final YggdrasilAccountFactory FACTORY_YGGDRASIL = new YggdrasilAccountFactory(MojangYggdrasilProvider.INSTANCE);
|
public static final YggdrasilAccountFactory FACTORY_YGGDRASIL = new YggdrasilAccountFactory(MojangYggdrasilProvider.INSTANCE);
|
||||||
public static final AuthlibInjectorAccountFactory FACTORY_AUTHLIB_INJECTOR = new AuthlibInjectorAccountFactory(
|
public static final AuthlibInjectorAccountFactory FACTORY_AUTHLIB_INJECTOR = new AuthlibInjectorAccountFactory(createAuthlibInjectorArtifactProvider(), Accounts::getOrCreateAuthlibInjectorServer);
|
||||||
new AuthlibInjectorDownloader(Metadata.HMCL_DIRECTORY, DownloadProviders::getDownloadProvider),
|
|
||||||
Accounts::getOrCreateAuthlibInjectorServer);
|
|
||||||
|
|
||||||
// ==== login type / account factory mapping ====
|
// ==== login type / account factory mapping ====
|
||||||
private static final Map<String, AccountFactory<?>> type2factory = new HashMap<>();
|
private static final Map<String, AccountFactory<?>> type2factory = new HashMap<>();
|
||||||
@ -240,6 +241,16 @@ public final class Accounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ==== authlib-injector ====
|
// ==== 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) {
|
private static AuthlibInjectorServer getOrCreateAuthlibInjectorServer(String url) {
|
||||||
return config().getAuthlibInjectorServers().stream()
|
return config().getAuthlibInjectorServers().stream()
|
||||||
.filter(server -> url.equals(server.getUrl()))
|
.filter(server -> url.equals(server.getUrl()))
|
||||||
|
@ -36,9 +36,9 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
|||||||
|
|
||||||
public class AuthlibInjectorAccount extends YggdrasilAccount {
|
public class AuthlibInjectorAccount extends YggdrasilAccount {
|
||||||
private AuthlibInjectorServer server;
|
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);
|
super(service, username, characterUUID, session);
|
||||||
|
|
||||||
this.downloader = downloader;
|
this.downloader = downloader;
|
||||||
|
@ -29,13 +29,13 @@ import java.util.function.Function;
|
|||||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||||
|
|
||||||
public class AuthlibInjectorAccountFactory extends AccountFactory<AuthlibInjectorAccount> {
|
public class AuthlibInjectorAccountFactory extends AccountFactory<AuthlibInjectorAccount> {
|
||||||
private AuthlibInjectorDownloader downloader;
|
private AuthlibInjectorArtifactProvider downloader;
|
||||||
private Function<String, AuthlibInjectorServer> serverLookup;
|
private Function<String, AuthlibInjectorServer> serverLookup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param serverLookup a function that looks up {@link AuthlibInjectorServer} by url
|
* @param serverLookup a function that looks up {@link AuthlibInjectorServer} by url
|
||||||
*/
|
*/
|
||||||
public AuthlibInjectorAccountFactory(AuthlibInjectorDownloader downloader, Function<String, AuthlibInjectorServer> serverLookup) {
|
public AuthlibInjectorAccountFactory(AuthlibInjectorArtifactProvider downloader, Function<String, AuthlibInjectorServer> serverLookup) {
|
||||||
this.downloader = downloader;
|
this.downloader = downloader;
|
||||||
this.serverLookup = serverLookup;
|
this.serverLookup = serverLookup;
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,39 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.auth.authlibinjector;
|
package org.jackhuang.hmcl.auth.authlibinjector;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.jar.Attributes;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
public class AuthlibInjectorArtifactInfo {
|
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 int buildNumber;
|
||||||
private String version;
|
private String version;
|
||||||
private Path location;
|
private Path location;
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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<AuthlibInjectorArtifactInfo> getArtifactInfoImmediately();
|
||||||
|
|
||||||
|
}
|
@ -32,13 +32,11 @@ import java.nio.file.Path;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.jar.Attributes;
|
|
||||||
import java.util.jar.JarFile;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
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";
|
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;
|
this.downloadProvider = downloadProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public AuthlibInjectorArtifactInfo getArtifactInfo() throws IOException {
|
public AuthlibInjectorArtifactInfo getArtifactInfo() throws IOException {
|
||||||
synchronized (artifactLocation) {
|
synchronized (artifactLocation) {
|
||||||
Optional<AuthlibInjectorArtifactInfo> local = getLocalArtifact();
|
Optional<AuthlibInjectorArtifactInfo> local = getLocalArtifact();
|
||||||
@ -79,6 +78,7 @@ public class AuthlibInjectorDownloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Optional<AuthlibInjectorArtifactInfo> getArtifactInfoImmediately() {
|
public Optional<AuthlibInjectorArtifactInfo> getArtifactInfoImmediately() {
|
||||||
return getLocalArtifact();
|
return getLocalArtifact();
|
||||||
}
|
}
|
||||||
@ -120,38 +120,13 @@ public class AuthlibInjectorDownloader {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return Optional.of(readArtifactInfo(artifactLocation));
|
return Optional.of(AuthlibInjectorArtifactInfo.from(artifactLocation));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
|
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
|
||||||
return Optional.empty();
|
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 {
|
private class AuthlibInjectorVersionInfo {
|
||||||
@SerializedName("build_number")
|
@SerializedName("build_number")
|
||||||
public int buildNumber;
|
public int buildNumber;
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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<AuthlibInjectorArtifactInfo> getArtifactInfoImmediately() {
|
||||||
|
try {
|
||||||
|
return Optional.of(getArtifactInfo());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -118,3 +118,4 @@ No plugin API.
|
|||||||
|`-Dhmcl.self_integrity_check.disable=true`|Bypass the self integrity check when checking for update.|
|
|`-Dhmcl.self_integrity_check.disable=true`|Bypass the self integrity check when checking for update.|
|
||||||
|`-Dhmcl.version.override=<version>`|Override the version number.|
|
|`-Dhmcl.version.override=<version>`|Override the version number.|
|
||||||
|`-Dhmcl.update_source.override=<url>`|Override the update source.|
|
|`-Dhmcl.update_source.override=<url>`|Override the update source.|
|
||||||
|
|`-Dhmcl.authlibinjector.location=<path>`|Use specified authlib-injector (instead of downloading one).|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user