diff --git a/FCLCore/src/main/java/com/tungsten/fclcore/mod/curse/CurseCompletionTask.java b/FCLCore/src/main/java/com/tungsten/fclcore/mod/curse/CurseCompletionTask.java index e6bc4441..cfe97efe 100644 --- a/FCLCore/src/main/java/com/tungsten/fclcore/mod/curse/CurseCompletionTask.java +++ b/FCLCore/src/main/java/com/tungsten/fclcore/mod/curse/CurseCompletionTask.java @@ -33,13 +33,13 @@ import com.tungsten.fclcore.util.io.FileUtils; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Complete the CurseForge version. @@ -51,7 +51,7 @@ public final class CurseCompletionTask extends Task { private final ModManager modManager; private final String version; private CurseManifest manifest; - private final List> dependencies = new ArrayList<>(); + private List> dependencies; private final AtomicBoolean allNameKnown = new AtomicBoolean(true); private final AtomicInteger finished = new AtomicInteger(0); @@ -136,28 +136,31 @@ public final class CurseCompletionTask extends Task { .collect(Collectors.toList())); FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(newManifest)); - File resourcePacks = new File(repository.getVersionRoot(modManager.getVersion()), "resourcepacks"); - for (CurseManifestFile file : newManifest.getFiles()) - if (StringUtils.isNotBlank(file.getFileName())) { - RemoteMod mod = CurseForgeRemoteModRepository.MODS.getModById(Integer.toString(file.getProjectID())); - File target; - if (((CurseAddon) mod.getData()).getClassId() == 12) { - target = new File(resourcePacks, file.getFileName()); - if (target.exists()) { - continue; - } - } else { - if (modManager.hasSimpleMod(file.getFileName())) { - continue; - } - target = modManager.getSimpleModPath(file.getFileName()).toFile(); - } + File versionRoot = repository.getVersionRoot(modManager.getVersion()); + File resourcePacksRoot = new File(versionRoot, "resourcepacks"), shaderPacksRoot = new File(versionRoot, "shaderpacks"); + finished.set(0); + dependencies = newManifest.getFiles() + .stream().parallel() + .filter(f -> f.getFileName() != null) + .flatMap(f -> { + try { + File path = guessFilePath(f, resourcePacksRoot, shaderPacksRoot); + if (path == null) { + return Stream.empty(); + } - FileDownloadTask task = new FileDownloadTask(file.getUrl(), target); - task.setCacheRepository(dependency.getCacheRepository()); - task.setCaching(true); - dependencies.add(task.withCounter("fcl.modpack.download")); - } + FileDownloadTask task = new FileDownloadTask(f.getUrl(), path); + task.setCacheRepository(dependency.getCacheRepository()); + task.setCaching(true); + return Stream.of(task.withCounter("fcl.modpack.download")); + } catch (IOException e) { + Logging.LOG.log(Level.WARNING, "Could not query api.curseforge.com for mod: " + f.getProjectID() + ", " + f.getFileID(), e); + return Stream.empty(); // Ignore this file. + } finally { + updateProgress(finished.incrementAndGet(), newManifest.getFiles().size()); + } + }) + .collect(Collectors.toList()); if (!dependencies.isEmpty()) { getProperties().put("total", dependencies.size()); @@ -165,6 +168,33 @@ public final class CurseCompletionTask extends Task { } } + /** + * Guess where to store the file. + * @param file The file. + * @param resourcePacksRoot ./resourcepacks. + * @param shaderPacksRoot ./shaderpacks. + * @return ./resourcepacks/$filename or ./shaderpacks/$filename or ./mods/$filename if the file doesn't exist. null if the file existed. + * @throws IOException If IOException was encountered during getting data from CurseForge. + */ + private File guessFilePath(CurseManifestFile file, File resourcePacksRoot, File shaderPacksRoot) throws IOException { + RemoteMod mod = CurseForgeRemoteModRepository.MODS.getModById(Integer.toString(file.getProjectID())); + int classID = ((CurseAddon) mod.getData()).getClassId(); + String fileName = file.getFileName(); + switch (classID) { + case 12: // Resource pack + case 6552: { // Shader pack + File res = new File(classID == 12 ? resourcePacksRoot : shaderPacksRoot, fileName); + return res.exists() ? null : res; + } + default: { + if (modManager.hasSimpleMod(fileName)) { + return null; + } + return modManager.getSimpleModPath(fileName).toFile(); + } + } + } + @Override public boolean doPostExecute() { return true;