diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java index 775f0fa93..8ae3ded4c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java @@ -65,15 +65,7 @@ public final class GameAssetDownloadTask extends Task { this.assetIndexFile = dependencyManager.getGameRepository().getIndexFile(version.getId(), assetIndexInfo.getId()); this.integrityCheck = integrityCheck; - if (!assetIndexFile.exists() || forceDownloadingIndex) { - dependents.add(new GameAssetIndexDownloadTask(dependencyManager, this.version)); - } else { - try { - JsonUtils.fromNonNullJson(FileUtils.readText(assetIndexFile), AssetIndex.class); - } catch (IOException | JsonParseException e) { - dependents.add(new GameAssetIndexDownloadTask(dependencyManager, this.version)); - } - } + dependents.add(new GameAssetIndexDownloadTask(dependencyManager, this.version, forceDownloadingIndex)); } @Override diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java index a3731b87c..05b6b0402 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java @@ -17,16 +17,26 @@ */ package org.jackhuang.hmcl.download.game; +import com.google.gson.JsonParseException; import org.jackhuang.hmcl.download.AbstractDependencyManager; +import org.jackhuang.hmcl.game.AssetIndex; import org.jackhuang.hmcl.game.AssetIndexInfo; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.util.DigestUtils; +import org.jackhuang.hmcl.util.Hex; +import org.jackhuang.hmcl.util.StringUtils; +import org.jackhuang.hmcl.util.gson.JsonUtils; +import org.jackhuang.hmcl.util.io.FileUtils; import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.List; +import java.util.logging.Level; + +import static org.jackhuang.hmcl.util.Logging.LOG; /** * This task is to download asset index file provided in minecraft.json. @@ -37,6 +47,7 @@ public final class GameAssetIndexDownloadTask extends Task { private final AbstractDependencyManager dependencyManager; private final Version version; + private final boolean forceDownloading; private final List> dependencies = new LinkedList<>(); /** @@ -45,9 +56,10 @@ public final class GameAssetIndexDownloadTask extends Task { * @param dependencyManager the dependency manager that can provides {@link org.jackhuang.hmcl.game.GameRepository} * @param version the resolved version */ - public GameAssetIndexDownloadTask(AbstractDependencyManager dependencyManager, Version version) { + public GameAssetIndexDownloadTask(AbstractDependencyManager dependencyManager, Version version, boolean forceDownloading) { this.dependencyManager = dependencyManager; this.version = version; + this.forceDownloading = forceDownloading; setSignificance(TaskSignificance.MODERATE); } @@ -60,12 +72,34 @@ public final class GameAssetIndexDownloadTask extends Task { public void execute() { AssetIndexInfo assetIndexInfo = version.getAssetIndex(); File assetIndexFile = dependencyManager.getGameRepository().getIndexFile(version.getId(), assetIndexInfo.getId()); + boolean verifyHashCode = StringUtils.isNotBlank(assetIndexInfo.getSha1()) && assetIndexInfo.getUrl().contains(assetIndexInfo.getSha1()); + + if (assetIndexFile.exists() && !forceDownloading) { + // verify correctness of file content + if (verifyHashCode) { + try { + String actualSum = Hex.encodeHex(DigestUtils.digest("SHA-1", assetIndexFile.toPath())); + if (actualSum.equalsIgnoreCase(assetIndexInfo.getSha1())) + return; + } catch (IOException e) { + LOG.log(Level.WARNING, "Failed to calculate sha1sum of file " + assetIndexInfo, e); + // continue downloading + } + } else { + try { + JsonUtils.fromNonNullJson(FileUtils.readText(assetIndexFile), AssetIndex.class); + return; + } catch (IOException | JsonParseException ignore) { + } + } + } // We should not check the hash code of asset index file since this file is not consistent // And Mojang will modify this file anytime. So assetIndex.hash might be outdated. FileDownloadTask task = new FileDownloadTask( dependencyManager.getDownloadProvider().injectURLWithCandidates(assetIndexInfo.getUrl()), - assetIndexFile + assetIndexFile, + verifyHashCode ? new FileDownloadTask.IntegrityCheck("SHA-1", assetIndexInfo.getSha1()) : null ); task.setCacheRepository(dependencyManager.getCacheRepository()); dependencies.add(task);