Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 41 additions & 32 deletions src/main/java/me/itzg/helpers/fabric/FabricMetaClient.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package me.itzg.helpers.fabric;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
Expand All @@ -16,6 +17,7 @@
import me.itzg.helpers.http.FileDownloadStatusHandler;
import me.itzg.helpers.http.SharedFetch;
import me.itzg.helpers.http.UriBuilder;
import org.apache.commons.codec.binary.Hex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import reactor.core.publisher.Mono;
Expand Down Expand Up @@ -155,52 +157,59 @@ public Mono<Path> downloadLauncher(
.handleStatus(statusHandler)
.assemble()
.retryWhen(Retry.backoff(downloadRetryMaxAttempts, downloadRetryMinBackoff).filter(IOException.class::isInstance))
.flatMap(path -> skipValidation ? Mono.just(path) : validateLauncherJar(path))
.doOnError(InvalidContentException.class, e -> log.warn("Invalid launcher jar, will try again", e))
.flatMap(path -> skipValidation ?
Mono.just(path)
: validateLauncherJar(path).subscribeOn(Schedulers.boundedElastic())
)
.doOnError(InvalidContentException.class, e ->
log.warn("Invalid launcher jar, will try again: {}", e.getMessage())
)
.retryWhen(Retry.backoff(downloadRetryMaxAttempts, downloadRetryMinBackoff).filter(InvalidContentException.class::isInstance))
.checkpoint("downloadLauncher");
}

private Mono<Path> validateLauncherJar(Path path) {
return Mono.fromCallable(() -> {
log.debug("Validating Fabric launcher file {}", path);
return Mono.create(sink -> {
log.debug("Validating Fabric launcher file {}", path);

if (!path.toFile().isFile()) {
throw new InvalidContentException("Downloaded launcher jar is not a file");
}
try {
final Properties installProperties = IoStreams.readFileFromZip(path, "install.properties", in -> {
Properties p = new Properties();
p.load(in);
return p;
}
);
if (installProperties == null) {
debugDownloadedContent(path);
throw new InvalidContentException("Downloaded launcher jar does not contain an install.properties");
}
if (!installProperties.containsKey("game-version")) {
debugDownloadedContent(path);
throw new InvalidContentException("Downloaded launcher jar does not contain a valid install.properties");
if (!path.toFile().isFile()) {
sink.error(new InvalidContentException("Downloaded launcher jar is not a file"));
}
try {
final Properties installProperties = IoStreams.readFileFromZip(path, "install.properties", in -> {
Properties p = new Properties();
p.load(in);
return p;
}
} catch (IOException e) {
);
if (installProperties == null) {
debugDownloadedContent(path);
throw new InvalidContentException("Downloaded launcher jar could not be read as a jar/zip", e);
sink.error(new InvalidContentException("Does not contain an install.properties"));
}
else if (!installProperties.containsKey("game-version")) {
debugDownloadedContent(path);
sink.error(new InvalidContentException("Does not contain a valid install.properties"));
}
} catch (IOException e) {
debugDownloadedContent(path);
sink.error(new InvalidContentException("Could not be read as a jar/zip", e));
}

return path;
})
.subscribeOn(Schedulers.boundedElastic());
sink.success(path);
});
}

private static void debugDownloadedContent(Path path) {
if (log.isDebugEnabled()) {
try (BufferedReader reader = Files.newBufferedReader(path)) {
final char[] buf = new char[100];
final int amount = reader.read(buf);
log.debug("Downloaded launcher jar content starts with: {}", new String(buf, 0, amount));
try (InputStream in = Files.newInputStream(path)) {
final byte[] buf = new byte[100];
final int amount = in.read(buf);

log.debug("Downloaded launcher jar content starts with: {}",
Hex.encodeHexString(ByteBuffer.wrap(buf, 0, amount))
);
} catch (IOException e) {
throw new GenericException("Failed to read downloaded launcher jar for debugging", e);
log.warn("Failed to debug content of launcher jar", e);
}
}
}
Expand Down