Redesign authlib-injector updater

The process of searching for authlib-injector.jar has been changed to:
1. use ~/.hmcl/authlib-injector.jar if present
2. use ./authlib-injector.jar if present
3. download if none of above is present

Instead of checking for updates when logging in, we now do it at startup.
We only check for updates if there is at least one authlib-injector
server configured.

This changed is expected to imporve launching speed.
This commit is contained in:
yushijinhun
2020-08-09 17:02:42 +08:00
committed by Yuhui Huang
parent ae63b9712e
commit 94b6d7596e
2 changed files with 68 additions and 28 deletions

View File

@@ -31,6 +31,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.logging.Level;
@@ -43,38 +44,31 @@ public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvide
private final Path artifactLocation;
private final Supplier<DownloadProvider> downloadProvider;
/**
* The flag will be reset after application restart.
*/
private boolean updateChecked = false;
/**
* @param artifactsDirectory where to save authlib-injector artifacts
*/
public AuthlibInjectorDownloader(Path artifactsDirectory, Supplier<DownloadProvider> downloadProvider) {
this.artifactLocation = artifactsDirectory.resolve("authlib-injector.jar");
public AuthlibInjectorDownloader(Path artifactLocation, Supplier<DownloadProvider> downloadProvider) {
this.artifactLocation = artifactLocation;
this.downloadProvider = downloadProvider;
}
@Override
public AuthlibInjectorArtifactInfo getArtifactInfo() throws IOException {
synchronized (artifactLocation) {
Optional<AuthlibInjectorArtifactInfo> cached = getArtifactInfoImmediately();
if (cached.isPresent()) {
return cached.get();
}
synchronized (this) {
Optional<AuthlibInjectorArtifactInfo> local = getLocalArtifact();
if (!local.isPresent() || !updateChecked) {
try {
update(local);
updateChecked = true;
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to download authlib-injector", e);
if (!local.isPresent()) {
throw e;
}
LOG.warning("Fallback to use cached artifact: " + local.get());
}
if (local.isPresent()) {
return local.get();
}
return getLocalArtifact().orElseThrow(() -> new IOException("The updated authlib-inejector cannot be recognized"));
LOG.info("No local authlib-injector found, downloading");
updateChecked.set(true);
update();
local = getLocalArtifact();
return local.orElseThrow(() -> new IOException("The downloaded authlib-inejector cannot be recognized"));
}
}
@@ -83,10 +77,22 @@ public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvide
return getLocalArtifact();
}
private void update(Optional<AuthlibInjectorArtifactInfo> local) throws IOException {
LOG.info("Checking update of authlib-injector");
private final AtomicBoolean updateChecked = new AtomicBoolean(false);
public void checkUpdate() throws IOException {
// this method runs only once
if (updateChecked.compareAndSet(false, true)) {
synchronized (this) {
LOG.info("Checking update of authlib-injector");
update();
}
}
}
private void update() throws IOException {
AuthlibInjectorVersionInfo latest = getLatestArtifactInfo();
Optional<AuthlibInjectorArtifactInfo> local = getLocalArtifact();
if (local.isPresent() && local.get().getBuildNumber() >= latest.buildNumber) {
return;
}
@@ -116,11 +122,15 @@ public class AuthlibInjectorDownloader implements AuthlibInjectorArtifactProvide
}
private Optional<AuthlibInjectorArtifactInfo> getLocalArtifact() {
if (!Files.isRegularFile(artifactLocation)) {
return parseArtifact(artifactLocation);
}
protected static Optional<AuthlibInjectorArtifactInfo> parseArtifact(Path path) {
if (!Files.isRegularFile(path)) {
return Optional.empty();
}
try {
return Optional.of(AuthlibInjectorArtifactInfo.from(artifactLocation));
return Optional.of(AuthlibInjectorArtifactInfo.from(path));
} catch (IOException e) {
LOG.log(Level.WARNING, "Bad authlib-injector artifact", e);
return Optional.empty();