diff --git a/src/main/java/link/infra/packwiz/installer/UpdateManager.java b/src/main/java/link/infra/packwiz/installer/UpdateManager.java index dd0ccb5..2b9e002 100644 --- a/src/main/java/link/infra/packwiz/installer/UpdateManager.java +++ b/src/main/java/link/infra/packwiz/installer/UpdateManager.java @@ -9,6 +9,7 @@ import java.net.URI; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.HashMap; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; @@ -197,9 +198,18 @@ public class UpdateManager { // TODO: throw exception } + if (manifest.cachedFiles == null) { + manifest.cachedFiles = new HashMap(); + } + // TODO: progress bar ConcurrentLinkedQueue exceptionQueue = new ConcurrentLinkedQueue(); - List newFiles = indexFile.files.stream().filter(f -> { + List newFiles = indexFile.files.stream().map(f -> { + if (f.hashFormat == null || f.hashFormat.length() == 0) { + f.hashFormat = indexFile.hashFormat; + } + return f; + }).filter(f -> { ManifestFile.File cachedFile = manifest.cachedFiles.get(f.file); Object newHash; try { @@ -208,7 +218,7 @@ public class UpdateManager { exceptionQueue.add(e); return false; } - return cachedFile == null || newHash.equals(cachedFile.hash); + return cachedFile == null || !newHash.equals(cachedFile.hash); }).parallel().map(f -> { try { f.downloadMeta(indexFile, indexUri); @@ -244,7 +254,7 @@ public class UpdateManager { DownloadCompletion dc = new DownloadCompletion(); dc.file = f; - if (cachedFile.linkedFileHash != null && f.linkedFile != null) { + if (cachedFile != null && cachedFile.linkedFileHash != null && f.linkedFile != null) { try { if (cachedFile.linkedFileHash.equals(f.linkedFile.getHash())) { // Do nothing, the file didn't change @@ -268,8 +278,12 @@ public class UpdateManager { hash = f.getHash(); } if (fileSource.hashIsEqual(hash)) { + Files.createDirectories(Paths.get(opts.packFolder, f.getDestURI().toString()).getParent()); Files.copy(data.inputStream(), Paths.get(opts.packFolder, f.getDestURI().toString()), StandardCopyOption.REPLACE_EXISTING); } else { + System.out.println("Invalid hash for " + f.getDestURI().toString()); + System.out.println("Calculated: " + fileSource.getHash()); + System.out.println("Expected: " + hash); dc.err = new Exception("Hash invalid!"); } @@ -313,13 +327,22 @@ public class UpdateManager { ret.err = e; } } + manifest.cachedFiles.put(ret.file.file, newCachedFile); } // TODO: show errors properly? String progress; - if (ret != null && ret.file != null) { - progress = "Downloaded " + ret.file.getName(); - } else if (ret.err != null) { - progress = "Failed to download: " + ret.err.getMessage(); + if (ret != null) { + if (ret.err != null) { + if (ret.file != null) { + progress = "Failed to download " + ret.file.getName() + ": " + ret.err.getMessage(); + } else { + progress = "Failed to download: " + ret.err.getMessage(); + } + } else if (ret.file != null) { + progress = "Downloaded " + ret.file.getName(); + } else { + progress = "Failed to download, unknown reason"; + } } else { progress = "Failed to download, unknown reason"; } diff --git a/src/main/java/link/infra/packwiz/installer/metadata/IndexFile.java b/src/main/java/link/infra/packwiz/installer/metadata/IndexFile.java index c7ac666..873ccc3 100644 --- a/src/main/java/link/infra/packwiz/installer/metadata/IndexFile.java +++ b/src/main/java/link/infra/packwiz/installer/metadata/IndexFile.java @@ -4,6 +4,7 @@ import java.net.URI; import java.nio.file.Paths; import java.util.List; +import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import com.moandjiezana.toml.Toml; @@ -19,6 +20,7 @@ public class IndexFile { public List files; public static class File { + @JsonAdapter(SpaceSafeURIParser.class) public URI file; @SerializedName("hash-format") public String hashFormat; diff --git a/src/main/java/link/infra/packwiz/installer/metadata/ModFile.java b/src/main/java/link/infra/packwiz/installer/metadata/ModFile.java index 6b5c10c..118f5e7 100644 --- a/src/main/java/link/infra/packwiz/installer/metadata/ModFile.java +++ b/src/main/java/link/infra/packwiz/installer/metadata/ModFile.java @@ -3,6 +3,7 @@ package link.infra.packwiz.installer.metadata; import java.net.URI; import java.util.Map; +import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import link.infra.packwiz.installer.UpdateManager.Options.Side; @@ -17,6 +18,7 @@ public class ModFile { public Download download; public static class Download { + @JsonAdapter(SpaceSafeURIParser.class) public URI url; @SerializedName("hash-format") public String hashFormat; diff --git a/src/main/java/link/infra/packwiz/installer/metadata/PackFile.java b/src/main/java/link/infra/packwiz/installer/metadata/PackFile.java index 0924cd2..97df666 100644 --- a/src/main/java/link/infra/packwiz/installer/metadata/PackFile.java +++ b/src/main/java/link/infra/packwiz/installer/metadata/PackFile.java @@ -3,6 +3,7 @@ package link.infra.packwiz.installer.metadata; import java.net.URI; import java.util.Map; +import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; public class PackFile { @@ -10,6 +11,7 @@ public class PackFile { public IndexFileLoc index; public static class IndexFileLoc { + @JsonAdapter(SpaceSafeURIParser.class) public URI file; @SerializedName("hash-format") public String hashFormat; diff --git a/src/main/java/link/infra/packwiz/installer/metadata/SpaceSafeURIParser.java b/src/main/java/link/infra/packwiz/installer/metadata/SpaceSafeURIParser.java new file mode 100644 index 0000000..670ce50 --- /dev/null +++ b/src/main/java/link/infra/packwiz/installer/metadata/SpaceSafeURIParser.java @@ -0,0 +1,31 @@ +package link.infra.packwiz.installer.metadata; + +import java.lang.reflect.Type; +import java.net.URI; +import java.net.URISyntaxException; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +/** + * This class encodes spaces before parsing the URI, so the URI can actually be + * parsed. + */ +class SpaceSafeURIParser implements JsonDeserializer { + + @Override + public URI deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + String uriString = json.getAsString().replace(" ", "%20"); + try { + return new URI(uriString); + } catch (URISyntaxException e) { + throw new JsonParseException("Failed to parse URI", e); + } + } + + // TODO: replace this with a better solution? + +} \ No newline at end of file