diff --git a/src/main/java/com/github/franckyi/cmpdl/CMPDL.java b/src/main/java/com/github/franckyi/cmpdl/CMPDL.java index cb46f67..938678e 100644 --- a/src/main/java/com/github/franckyi/cmpdl/CMPDL.java +++ b/src/main/java/com/github/franckyi/cmpdl/CMPDL.java @@ -50,6 +50,7 @@ public void start(Stage primaryStage) throws Exception { scene = new Scene(mainWindow.getView()); stage.setScene(scene); stage.setTitle(TITLE); + stage.setOnCloseRequest(e -> currentContent.getController().handleClose()); stage.show(); } diff --git a/src/main/java/com/github/franckyi/cmpdl/controller/DestinationPaneController.java b/src/main/java/com/github/franckyi/cmpdl/controller/DestinationPaneController.java index ab6f78c..1e06f19 100644 --- a/src/main/java/com/github/franckyi/cmpdl/controller/DestinationPaneController.java +++ b/src/main/java/com/github/franckyi/cmpdl/controller/DestinationPaneController.java @@ -92,7 +92,9 @@ public void handlePrevious() { public void handleStart() { File dst = new File(destinationField.getText()); if (dst.isDirectory()) { - if (!dst.exists()) dst.mkdirs(); + if (!dst.exists()) { + dst.mkdirs(); + } if (!dst.canWrite()) { new Alert(Alert.AlertType.ERROR, "Permission denied. Please choose another destination folder.", ButtonType.OK).show(); } else { @@ -100,7 +102,7 @@ public void handleStart() { CMPDL.mainWindow.getController().setContent(CMPDL.progressPane); CMPDL.mainWindow.getController().getStartButton().setDisable(true); CMPDL.mainWindow.getController().getPreviousButton().setDisable(true); - CMPDL.progressPane.getController().downloadModpack(); + CMPDL.progressPane.getController().start(); } } else { new Alert(Alert.AlertType.ERROR, "The destination must be a folder.", ButtonType.OK).show(); diff --git a/src/main/java/com/github/franckyi/cmpdl/controller/ProgressPaneController.java b/src/main/java/com/github/franckyi/cmpdl/controller/ProgressPaneController.java index 6d30b4b..cadd6a6 100644 --- a/src/main/java/com/github/franckyi/cmpdl/controller/ProgressPaneController.java +++ b/src/main/java/com/github/franckyi/cmpdl/controller/ProgressPaneController.java @@ -23,7 +23,7 @@ public class ProgressPaneController implements Initializable, IContentController private Project project; private ProjectFile projectFile; - private File destination, zipFile, unzipFolder, minecraft, modsFolder, temp; + private File destination, zipFile, unzipFolder, minecraft, modsFolder, temp, progressFile; private ModpackManifest manifest; @FXML @@ -80,7 +80,6 @@ public void handleClose() { if (buttonType.orElse(null) == ButtonType.YES) { if (task2 != null) task2.cancel(); if (task1 != null) task1.cancel(); - new CleanTask(temp).run(); Platform.exit(); } } else { @@ -98,6 +97,7 @@ public void setData(Project project, ProjectFile projectFile, File destination) modsFolder.mkdirs(); temp = new File(destination, ".cmpdl_temp"); temp.mkdirs(); + progressFile = new File(temp, ".progress"); zipFile = new File(temp, projectFile.getFileNameOnDisk()); unzipFolder = new File(temp, projectFile.getFileNameOnDisk().replace(".zip", "")); unzipFolder.mkdirs(); @@ -134,28 +134,41 @@ public void log(String s, Object... args) { Platform.runLater(() -> console.appendText(s0 + "\n")); } + public void start() { + if (progressFile.exists()) { + readManifest(); + } else { + downloadModpack(); + } + } + public void downloadModpack() { log("Downloading modpack"); DownloadFileTask task = new DownloadFileTask(projectFile.getDownloadUrl(), new File(temp, projectFile.getFileNameOnDisk())); - task.setOnSucceeded(e -> unzipModpack()); + task.setOnSucceeded(e -> { + log("Modpack downloaded successfully"); + unzipModpack(); + }); setTask1(task); CMPDL.EXECUTOR_SERVICE.execute(task); } private void unzipModpack() { - log("Modpack downloaded successfully"); log("Unzipping modpack"); UnzipFileTask task = new UnzipFileTask(zipFile, unzipFolder); - task.setOnSucceeded(e -> readManifest()); + task.setOnSucceeded(e -> { + log("Modpack unzipped successfully"); + readManifest(); + }); setTask1(task); CMPDL.EXECUTOR_SERVICE.execute(task); } private void readManifest() { - log("Modpack unzipped successfully"); log("Reading manifest"); ReadManifestTask task = new ReadManifestTask(new File(unzipFolder, "manifest.json")); task.setOnSucceeded(e -> task.getValue().ifPresent(manifest -> { + log("Manifest read successfully"); this.manifest = manifest; log("### Manifest content :"); log(manifest.toString()); @@ -166,10 +179,12 @@ private void readManifest() { } private void downloadMods() { - log("Manifest read successfully"); log("Downloading mods"); - DownloadModsTask task = new DownloadModsTask(modsFolder, manifest.getMods()); - task.setOnSucceeded(e -> copyOverrides()); + DownloadModsTask task = new DownloadModsTask(modsFolder, progressFile, manifest.getMods()); + task.setOnSucceeded(e -> { + log("Downloaded mods successfully"); + copyOverrides(); + }); setTask1(task); task.taskProperty().addListener((observable, oldValue, newValue) -> { if (newValue != null) setTask2(newValue); @@ -179,16 +194,17 @@ private void downloadMods() { private void copyOverrides() { setTask2(null); - log("Downloaded mods successfully"); log("Copying overrides"); CopyOverridesTask task = new CopyOverridesTask(new File(unzipFolder, manifest.getOverrides()), minecraft); - task.setOnSucceeded(e -> clean()); + task.setOnSucceeded(e -> { + log("Copied overrides successfully"); + clean(); + }); setTask1(task); CMPDL.EXECUTOR_SERVICE.execute(task); } private void clean() { - log("Copied overrides successfully"); log("Cleaning"); CleanTask task = new CleanTask(temp); task.setOnSucceeded(e -> finish()); diff --git a/src/main/java/com/github/franckyi/cmpdl/model/ModpackManifest.java b/src/main/java/com/github/franckyi/cmpdl/model/ModpackManifest.java index 3e0cba4..b0a64ac 100644 --- a/src/main/java/com/github/franckyi/cmpdl/model/ModpackManifest.java +++ b/src/main/java/com/github/franckyi/cmpdl/model/ModpackManifest.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class ModpackManifest { @@ -64,15 +65,21 @@ public String toString() { name.replaceAll("%", ""), version.replaceAll("%", ""), author.replaceAll("%", ""), mcVersion, mods.size(), forge); } - public class ModpackManifestMod { + public static class ModpackManifestMod { private final int projectId, fileId; - private ModpackManifestMod(JSONObject json) { + public ModpackManifestMod(JSONObject json) { projectId = json.getInt("projectID"); fileId = json.getInt("fileID"); } + public ModpackManifestMod(String line) { + String[] split = line.split(":"); + projectId = Integer.parseInt(split[0]); + fileId = Integer.parseInt(split[1]); + } + public int getProjectId() { return projectId; } @@ -80,5 +87,19 @@ public int getProjectId() { public int getFileId() { return fileId; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ModpackManifestMod that = (ModpackManifestMod) o; + return projectId == that.projectId && + fileId == that.fileId; + } + + @Override + public int hashCode() { + return Objects.hash(projectId, fileId); + } } } diff --git a/src/main/java/com/github/franckyi/cmpdl/task/mpimport/DownloadModsTask.java b/src/main/java/com/github/franckyi/cmpdl/task/mpimport/DownloadModsTask.java index 33ce73b..59d8d2d 100644 --- a/src/main/java/com/github/franckyi/cmpdl/task/mpimport/DownloadModsTask.java +++ b/src/main/java/com/github/franckyi/cmpdl/task/mpimport/DownloadModsTask.java @@ -11,43 +11,65 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.concurrent.Task; -import java.io.File; +import java.io.*; import java.util.List; public class DownloadModsTask extends TaskBase { - private final File modsFolder; + private final File modsFolder, progressFile; private final List mods; private ObjectProperty> task = new SimpleObjectProperty<>(); - public DownloadModsTask(File modsFolder, List mods) { + public DownloadModsTask(File modsFolder, File progressFile, List mods) { this.modsFolder = modsFolder; + this.progressFile = progressFile; this.mods = mods; } @Override - protected Void call0() { - updateProgress(0, 1); - for (int i = 0; i < mods.size(); i++) { - if (isCancelled()) return null; - updateTitle(String.format("Downloading mods (%d/%d)", i + 1, mods.size())); - ModpackManifest.ModpackManifestMod mod = mods.get(i); - CMPDL.progressPane.getController().log("Resolving file %d:%d", mod.getProjectId(), mod.getFileId()); - ProjectFile file = CurseMetaAPI.getProjectFile(mod.getProjectId(), mod.getFileId()); - if (file != null) { - DownloadFileTask task = new DownloadFileTask(file.getDownloadUrl(), new File(modsFolder, file.getFileNameOnDisk())); - setTask(task); - CMPDL.progressPane.getController().log("Downloading file %s", file.getFileName().replaceAll("%", "")); - task.run(); - } else { - CMPDL.progressPane.getController().log("Unknown file %d:%d - skipping", mod.getProjectId(), mod.getFileId()); + protected Void call0() throws IOException { + int max = mods.size(); + int start = 0; + if (progressFile != null && progressFile.exists() && progressFile.isFile()) { + BufferedReader reader = new BufferedReader(new FileReader(progressFile)); + String line; + while ((line = reader.readLine()) != null && !isCancelled()) { + ModpackManifest.ModpackManifestMod mod = new ModpackManifest.ModpackManifestMod(line); + mods.remove(mod); + CMPDL.progressPane.getController().log("File %d:%d already downloaded - skipping", mod.getProjectId(), mod.getFileId()); + start++; + } + reader.close(); + } else { + progressFile.createNewFile(); + } + try (BufferedWriter writer = new BufferedWriter(new FileWriter(progressFile, true))) { + for (int i = start; i < max; i++) { + updateProgress(start, max); + if (isCancelled()) { + writer.close(); + return null; + } + updateTitle(String.format("Downloading mods (%d/%d)", i + 1, max)); + ModpackManifest.ModpackManifestMod mod = mods.get(i - start); + CMPDL.progressPane.getController().log("Resolving file %d:%d", mod.getProjectId(), mod.getFileId()); + ProjectFile file = CurseMetaAPI.getProjectFile(mod.getProjectId(), mod.getFileId()); + if (file != null) { + DownloadFileTask task = new DownloadFileTask(file.getDownloadUrl(), new File(modsFolder, file.getFileNameOnDisk())); + setTask(task); + CMPDL.progressPane.getController().log("Downloading file %s", file.getFileName().replaceAll("%", "")); + task.run(); + } else { + CMPDL.progressPane.getController().log("!!! Unknown file %d:%d - skipping !!!", mod.getProjectId(), mod.getFileId()); + } + writer.write(String.format("%d:%d\n", mod.getProjectId(), mod.getFileId())); } - updateProgress(i, mods.size()); } return null; } + private void setTask(Task task) { Platform.runLater(() -> this.task.setValue(task)); }