Skip to content
Merged
Show file tree
Hide file tree
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
19 changes: 10 additions & 9 deletions src/main/java/me/itzg/helpers/curseforge/CurseForgeApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,19 @@ public Mono<CurseForgeFile> getModFileInfo(
}
return e;
})
.map(GetModFileResponse::getData);
.map(GetModFileResponse::getData)
.checkpoint();
}

public Mono<Path> download(CurseForgeFile cfFile, Path outputFile, FileDownloadStatusHandler handler) {
return preparedFetch.fetch(
cfFile.getDownloadUrl() != null ?
normalizeDownloadUrl(cfFile.getDownloadUrl())
: downloadFallbackUriBuilder.resolve(
"/v1/mods/{modId}/files/{fileId}/download",
cfFile.getModId(), cfFile.getId()
)
)
final URI uriToDownload = cfFile.getDownloadUrl() != null ?
normalizeDownloadUrl(cfFile.getDownloadUrl())
: downloadFallbackUriBuilder.resolve(
"/v1/mods/{modId}/files/{fileId}/download",
cfFile.getModId(), cfFile.getId()
);
log.trace("Downloading cfFile={} from normalizedUrl={}", cfFile, uriToDownload);
return preparedFetch.fetch(uriToDownload)
.toFile(outputFile)
.skipExisting(true)
.handleStatus(handler)
Expand Down
28 changes: 18 additions & 10 deletions src/main/java/me/itzg/helpers/curseforge/CurseForgeInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import me.itzg.helpers.json.ObjectMappers;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.jetbrains.annotations.Nullable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
Expand Down Expand Up @@ -435,17 +436,19 @@ private Path locateWorldZipInRepo(String fileName) {
return locateFileIn(fileName, downloadsRepo, downloadsRepo.resolve(REPO_SUBDIR_WORLDS));
}

private static Path locateFileIn(String fileName, Path... dirs) {
private static Path locateFileIn(String fileName, @Nullable Path... dirs) {
for (Path dir : dirs) {
final Path resolved = dir.resolve(fileName);
if (Files.exists(resolved)) {
return resolved;
}
if (dir != null) {
final Path resolved = dir.resolve(fileName);
if (Files.exists(resolved)) {
return resolved;
}

// When downloading, the browser may replace spaces with +'s
final Path altResolved = dir.resolve(fileName.replace(' ', '+'));
if (Files.exists(altResolved)) {
return altResolved;
// When downloading, the browser may replace spaces with +'s
final Path altResolved = dir.resolve(fileName.replace(' ', '+'));
if (Files.exists(altResolved)) {
return altResolved;
}
}
}
return null;
Expand Down Expand Up @@ -581,6 +584,7 @@ private ModPackResults processModpack(InstallContext context,
excludeIncludeIds.getForceIncludeIds(),
context.categoryInfo
)
.checkpoint()
)
.collectList()
.block();
Expand Down Expand Up @@ -741,6 +745,7 @@ else if (category.getSlug().equals("worlds")) {
final Mono<ResolveResult> resolvedFileMono =
Mono.defer(() ->
downloadOrResolveFile(context, modInfo, isWorld, outputDir, cfFile)
.checkpoint()
)
// retry the deferred part above if one of the expected failure cases
.retryWhen(
Expand Down Expand Up @@ -795,7 +800,10 @@ private Mono<ResolveResult> downloadOrResolveFile(InstallContext context, CurseF

// Will try to locate an existing file by alternate names that browser might create,
// but only for non-world files of the modpack
final Path locatedFile = !isWorld ? locateFileIn(cfFile.getFileName(), outputDir) : null;
final Path locatedFile = !isWorld ? locateFileIn(cfFile.getFileName(),
outputDir,
downloadsRepo
) : null;

if (locatedFile != null) {
log.info("Mod file {} already exists", locatedFile);
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/me/itzg/helpers/curseforge/FileHashVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import me.itzg.helpers.curseforge.model.FileHash;
import me.itzg.helpers.curseforge.model.HashAlgo;
Expand All @@ -24,6 +25,10 @@ public class FileHashVerifier {
}

public static Mono<Path> verify(Path file, List<FileHash> hashes) {
if (hashes.isEmpty()) {
return Mono.just(file);
}

for (final FileHash hash : hashes) {
final ChecksumAlgo checksumAlgo = algos.get(hash.getAlgo());
if (checksumAlgo != null) {
Expand All @@ -42,6 +47,10 @@ public static Mono<Path> verify(Path file, List<FileHash> hashes) {
}
}

return Mono.error(new IllegalArgumentException("Unable to find compatible checksum algorithm"));
return Mono.error(new IllegalArgumentException("Unable to find compatible checksum algorithm from " +
hashes.stream()
.map(FileHash::getAlgo)
.collect(Collectors.toList())
));
}
}