From 84c18c86933deeeadffac7c99cf7246247ee82c3 Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Fri, 7 Sep 2018 11:27:14 +0800 Subject: [PATCH] Move cache repository to HMCLCore --- .../hmcl/game/HMCLCacheRepository.java | 30 +++++++ .../hmcl/game/HMCLDependencyManager.java | 48 ------------ .../hmcl/game/HMCLGameLibrariesTask.java | 61 --------------- .../hmcl/game/HMCLLibraryDownloadTask.java | 78 ------------------- .../org/jackhuang/hmcl/setting/Profile.java | 7 +- .../org/jackhuang/hmcl/setting/Settings.java | 8 +- .../download/AbstractDependencyManager.java | 5 ++ .../hmcl/download/DefaultCacheRepository.java | 41 +++------- .../download/DefaultDependencyManager.java | 9 ++- .../hmcl/download/DependencyManager.java | 6 ++ .../download/game/GameAssetDownloadTask.java | 7 +- .../game/GameAssetIndexDownloadTask.java | 5 +- .../hmcl/download/game/GameDownloadTask.java | 7 +- .../hmcl/download/game/GameLibrariesTask.java | 2 + .../download/game/LibraryDownloadTask.java | 30 ++++++- .../jackhuang/hmcl/task/FileDownloadTask.java | 13 +++- ...alRepository.java => CacheRepository.java} | 12 +-- 17 files changed, 124 insertions(+), 245 deletions(-) create mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLCacheRepository.java delete mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLDependencyManager.java delete mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLibrariesTask.java delete mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLibraryDownloadTask.java rename HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLocalRepository.java => HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java (89%) rename HMCLCore/src/main/java/org/jackhuang/hmcl/util/{LocalRepository.java => CacheRepository.java} (91%) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLCacheRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLCacheRepository.java new file mode 100644 index 000000000..0022609bd --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLCacheRepository.java @@ -0,0 +1,30 @@ +package org.jackhuang.hmcl.game; + +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import org.jackhuang.hmcl.download.DefaultCacheRepository; + +import java.nio.file.Paths; + +public class HMCLCacheRepository extends DefaultCacheRepository { + + private final StringProperty directory = new SimpleStringProperty(); + + public HMCLCacheRepository() { + directory.addListener((a, b, t) -> changeDirectory(Paths.get(t))); + } + + public String getDirectory() { + return directory.get(); + } + + public StringProperty directoryProperty() { + return directory; + } + + public void setDirectory(String directory) { + this.directory.set(directory); + } + + public static final HMCLCacheRepository REPOSITORY = new HMCLCacheRepository(); +} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLDependencyManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLDependencyManager.java deleted file mode 100644 index 033de21c1..000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLDependencyManager.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Hello Minecraft! Launcher. - * Copyright (C) 2018 huangyuhui - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see {http://www.gnu.org/licenses/}. - */ -package org.jackhuang.hmcl.game; - -import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.download.game.GameAssetDownloadTask; -import org.jackhuang.hmcl.setting.Profile; -import org.jackhuang.hmcl.task.ParallelTask; -import org.jackhuang.hmcl.task.Task; - -/** - * @author huangyuhui - */ -public class HMCLDependencyManager extends DefaultDependencyManager { - - public HMCLDependencyManager(Profile profile, DownloadProvider downloadProvider) { - super(profile.getRepository(), downloadProvider); - } - - @Override - public Task checkGameCompletionAsync(Version version) { - return new ParallelTask( - new GameAssetDownloadTask(this, version), - new HMCLGameLibrariesTask(this, version) - ); - } - - @Override - public Task checkLibraryCompletionAsync(Version version) { - return new HMCLGameLibrariesTask(this, version); - } -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLibrariesTask.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLibrariesTask.java deleted file mode 100644 index 72651d774..000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLibrariesTask.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Hello Minecraft! Launcher. - * Copyright (C) 2017 huangyuhui - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see {http://www.gnu.org/licenses/}. - */ -package org.jackhuang.hmcl.game; - -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.Lang; - -import java.io.File; -import java.util.LinkedList; -import java.util.List; - -public class HMCLGameLibrariesTask extends Task { - - private final HMCLDependencyManager dependencyManager; - private final Version version; - private final List dependencies = new LinkedList<>(); - - /** - * Constructor. - * - * @param dependencyManager the dependency manager that can provides {@link org.jackhuang.hmcl.game.GameRepository} - * @param version the resolved version - */ - public HMCLGameLibrariesTask(HMCLDependencyManager dependencyManager, Version version) { - this.dependencyManager = dependencyManager; - this.version = version; - setSignificance(TaskSignificance.MODERATE); - } - - @Override - public List getDependencies() { - return dependencies; - } - - @Override - public void execute() { - version.getLibraries().stream().filter(Library::appliesToCurrentEnvironment).forEach(library -> { - File file = dependencyManager.getGameRepository().getLibraryFile(version, library); - if (!file.exists()) - dependencies.add(new HMCLLibraryDownloadTask(dependencyManager, file, library)); - else - HMCLLocalRepository.REPOSITORY.tryCacheLibrary(library, file.toPath()); - }); - } - -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLibraryDownloadTask.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLibraryDownloadTask.java deleted file mode 100644 index 8c21f336f..000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLibraryDownloadTask.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Hello Minecraft! Launcher. - * Copyright (C) 2017 huangyuhui - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see {http://www.gnu.org/licenses/}. - */ -package org.jackhuang.hmcl.game; - -import org.jackhuang.hmcl.download.game.LibraryDownloadTask; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.FileUtils; -import org.jackhuang.hmcl.util.Logging; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; -import java.util.logging.Level; - -public final class HMCLLibraryDownloadTask extends LibraryDownloadTask { - - private boolean cached = false; - - public HMCLLibraryDownloadTask(HMCLDependencyManager dependencyManager, File file, Library library) { - super(dependencyManager, file, library); - } - - @Override - public void preExecute() throws Exception { - Optional libPath = HMCLLocalRepository.REPOSITORY.getLibrary(library); - if (libPath.isPresent()) { - try { - FileUtils.copyFile(libPath.get().toFile(), jar); - cached = true; - return; - } catch (IOException e) { - Logging.LOG.log(Level.WARNING, "Failed to copy file from cache", e); - // We cannot copy cached file to current location - // so we try to download a new one. - } - } - - super.preExecute(); - } - - @Override - public Collection getDependents() { - if (cached) return Collections.emptyList(); - else return super.getDependents(); - } - - @Override - public void execute() throws Exception { - if (cached) return; - super.execute(); - } - - @Override - public void postExecute() throws Exception { - super.postExecute(); - - if (!cached) - HMCLLocalRepository.REPOSITORY.cacheLibrary(library, jar.toPath(), xz); - } -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java index af17a2d0c..bfd694a1f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java @@ -21,9 +21,10 @@ import com.google.gson.*; import javafx.beans.InvalidationListener; import javafx.beans.Observable; import javafx.beans.property.*; +import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.event.EventBus; import org.jackhuang.hmcl.event.RefreshedVersionsEvent; -import org.jackhuang.hmcl.game.HMCLDependencyManager; +import org.jackhuang.hmcl.game.HMCLCacheRepository; import org.jackhuang.hmcl.game.HMCLGameRepository; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.mod.ModManager; @@ -159,8 +160,8 @@ public final class Profile implements Observable { return modManager; } - public HMCLDependencyManager getDependency() { - return new HMCLDependencyManager(this, Settings.instance().getDownloadProvider()); + public DefaultDependencyManager getDependency() { + return new DefaultDependencyManager(repository, Settings.instance().getDownloadProvider(), HMCLCacheRepository.REPOSITORY); } public VersionSetting getVersionSetting(String id) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java index b3a18f7c6..a262a8e38 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -20,8 +20,8 @@ package org.jackhuang.hmcl.setting; import javafx.scene.text.Font; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.game.HMCLLocalRepository; -import org.jackhuang.hmcl.util.LocalRepository; +import org.jackhuang.hmcl.game.HMCLCacheRepository; +import org.jackhuang.hmcl.util.CacheRepository; import static org.jackhuang.hmcl.setting.ConfigHolder.config; @@ -48,8 +48,8 @@ public class Settings { Accounts.init(); Profiles.init(); - LocalRepository.setInstance(HMCLLocalRepository.REPOSITORY); - HMCLLocalRepository.REPOSITORY.directoryProperty().bind(config().commonDirectoryProperty()); + CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY); + HMCLCacheRepository.REPOSITORY.directoryProperty().bind(config().commonDirectoryProperty()); } public Font getFont() { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/AbstractDependencyManager.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/AbstractDependencyManager.java index f30c269ba..f7d6595de 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/AbstractDependencyManager.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/AbstractDependencyManager.java @@ -17,6 +17,8 @@ */ package org.jackhuang.hmcl.download; +import org.jackhuang.hmcl.util.CacheRepository; + /** * * @author huangyuhui @@ -25,6 +27,9 @@ public abstract class AbstractDependencyManager implements DependencyManager { public abstract DownloadProvider getDownloadProvider(); + @Override + public abstract DefaultCacheRepository getCacheRepository(); + @Override public VersionList getVersionList(String id) { return getDownloadProvider().getVersionListById(id); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLocalRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java similarity index 89% rename from HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLocalRepository.java rename to HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java index dfb2eb740..2f7bc6a52 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLLocalRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java @@ -15,18 +15,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see {http://www.gnu.org/licenses/}. */ -package org.jackhuang.hmcl.game; +package org.jackhuang.hmcl.download; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; import org.jackhuang.hmcl.download.game.LibraryDownloadTask; -import org.jackhuang.hmcl.ui.FXUtils; +import org.jackhuang.hmcl.game.Library; +import org.jackhuang.hmcl.game.LibraryDownloadInfo; import org.jackhuang.hmcl.util.*; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -34,32 +32,22 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.stream.Collectors; -public class HMCLLocalRepository extends LocalRepository { - private final StringProperty directory = new SimpleStringProperty(); - +public class DefaultCacheRepository extends CacheRepository { private Path librariesDir; private Path indexFile; private final ReadWriteLock lock = new ReentrantReadWriteLock(); private Index index = null; - public HMCLLocalRepository() { - FXUtils.onChange(directory, t -> changeDirectory(Paths.get(t))); + public DefaultCacheRepository() { + this(OperatingSystem.getWorkingDirectory("minecraft").toPath()); } - public String getDirectory() { - return directory.get(); - } - - public StringProperty directoryProperty() { - return directory; - } - - public void setDirectory(String directory) { - this.directory.set(directory); + public DefaultCacheRepository(Path commonDirectory) { + changeDirectory(commonDirectory); } @Override - protected void changeDirectory(Path commonDir) { + public void changeDirectory(Path commonDir) { super.changeDirectory(commonDir); librariesDir = commonDir.resolve("libraries"); @@ -206,9 +194,6 @@ public class HMCLLocalRepository extends LocalRepository { } } - private static final String SHA1 = "SHA-1"; - public static final HMCLLocalRepository REPOSITORY = new HMCLLocalRepository(); - /** * { * "libraries": { @@ -218,13 +203,7 @@ public class HMCLLocalRepository extends LocalRepository { * "hash": "blablabla", * "type": "forge" * ] - * }, - * "indexes": [ - * { - * "name": "1.7.10", - * "hash": "..." - * } - * ] + * } * // assets and versions will not be included in index. * } */ diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java index e72ef378a..21af2e93c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java @@ -43,10 +43,12 @@ public class DefaultDependencyManager extends AbstractDependencyManager { private final DefaultGameRepository repository; private final DownloadProvider downloadProvider; + private final DefaultCacheRepository cacheRepository; - public DefaultDependencyManager(DefaultGameRepository repository, DownloadProvider downloadProvider) { + public DefaultDependencyManager(DefaultGameRepository repository, DownloadProvider downloadProvider, DefaultCacheRepository cacheRepository) { this.repository = repository; this.downloadProvider = downloadProvider; + this.cacheRepository = cacheRepository; } @Override @@ -59,6 +61,11 @@ public class DefaultDependencyManager extends AbstractDependencyManager { return downloadProvider; } + @Override + public DefaultCacheRepository getCacheRepository() { + return cacheRepository; + } + @Override public GameBuilder gameBuilder() { return new DefaultGameBuilder(this); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DependencyManager.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DependencyManager.java index 65add1341..0d619db8b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DependencyManager.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DependencyManager.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.download; import org.jackhuang.hmcl.game.GameRepository; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.util.CacheRepository; /** * Do everything that will connect to Internet. @@ -34,6 +35,11 @@ public interface DependencyManager { */ GameRepository getGameRepository(); + /** + * The cache repository + */ + CacheRepository getCacheRepository(); + /** * Check if the game is complete. * Check libraries, assets files and so on. 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 e9b1de62f..3be70de6b 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 @@ -26,7 +26,7 @@ import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.Constants; import org.jackhuang.hmcl.util.FileUtils; -import org.jackhuang.hmcl.util.LocalRepository; +import org.jackhuang.hmcl.util.CacheRepository; import org.jackhuang.hmcl.util.NetworkUtils; import java.io.File; @@ -84,14 +84,15 @@ public final class GameAssetDownloadTask extends Task { File file = dependencyManager.getGameRepository().getAssetObject(version.getId(), assetIndexInfo.getId(), assetObject); if (file.isFile()) - LocalRepository.getInstance().tryCacheFile(file.toPath(), LocalRepository.SHA1, assetObject.getHash()); + dependencyManager.getCacheRepository().tryCacheFile(file.toPath(), CacheRepository.SHA1, assetObject.getHash()); else { String url = dependencyManager.getDownloadProvider().getAssetBaseURL() + assetObject.getLocation(); FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(url), file, new FileDownloadTask.IntegrityCheck("SHA-1", assetObject.getHash())); task.setName(assetObject.getHash()); dependencies.add(task + .setCacheRepository(dependencyManager.getCacheRepository()) .setCaching(true) - .setCandidate(LocalRepository.getInstance().getCommonDirectory() + .setCandidate(dependencyManager.getCacheRepository().getCommonDirectory() .resolve("assets").resolve("objects").resolve(assetObject.getLocation()))); } 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 854e927a7..d6f7e00dc 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 @@ -22,7 +22,7 @@ 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.LocalRepository; +import org.jackhuang.hmcl.util.CacheRepository; import org.jackhuang.hmcl.util.NetworkUtils; import java.io.File; @@ -68,7 +68,8 @@ public final class GameAssetIndexDownloadTask extends Task { NetworkUtils.toURL(dependencyManager.getDownloadProvider().injectURL(assetIndexInfo.getUrl())), assetIndexFile ).setCaching(true) - .setCandidate(LocalRepository.getInstance().getCommonDirectory() + .setCacheRepository(dependencyManager.getCacheRepository()) + .setCandidate(dependencyManager.getCacheRepository().getCommonDirectory() .resolve("assets").resolve("indexes").resolve(assetIndexInfo.getId() + ".json"))); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameDownloadTask.java index df6b1e2ce..458c32bfc 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameDownloadTask.java @@ -22,7 +22,7 @@ import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck; import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.LocalRepository; +import org.jackhuang.hmcl.util.CacheRepository; import org.jackhuang.hmcl.util.NetworkUtils; import java.io.File; @@ -59,9 +59,10 @@ public final class GameDownloadTask extends Task { dependencies.add(new FileDownloadTask( NetworkUtils.toURL(dependencyManager.getDownloadProvider().injectURL(version.getDownloadInfo().getUrl())), jar, - IntegrityCheck.of(LocalRepository.SHA1, version.getDownloadInfo().getSha1())) + IntegrityCheck.of(CacheRepository.SHA1, version.getDownloadInfo().getSha1())) .setCaching(true) - .setCandidate(LocalRepository.getInstance().getCommonDirectory().resolve("jars").resolve(gameVersion + ".jar"))); + .setCacheRepository(dependencyManager.getCacheRepository()) + .setCandidate(dependencyManager.getCacheRepository().getCommonDirectory().resolve("jars").resolve(gameVersion + ".jar"))); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java index b667a8e73..f1eab5640 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java @@ -61,6 +61,8 @@ public final class GameLibrariesTask extends Task { File file = dependencyManager.getGameRepository().getLibraryFile(version, library); if (!file.exists()) dependencies.add(new LibraryDownloadTask(dependencyManager, file, library)); + else + dependencyManager.getCacheRepository().tryCacheLibrary(library, file.toPath()); }); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibraryDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibraryDownloadTask.java index b1e3b5486..4d2ec9b5e 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibraryDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibraryDownloadTask.java @@ -1,6 +1,7 @@ package org.jackhuang.hmcl.download.game; import org.jackhuang.hmcl.download.AbstractDependencyManager; +import org.jackhuang.hmcl.download.DefaultCacheRepository; import org.jackhuang.hmcl.game.Library; import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck; @@ -14,11 +15,13 @@ import org.tukaani.xz.XZInputStream; import java.io.*; import java.net.URL; import java.nio.charset.Charset; +import java.nio.file.Path; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Pack200; +import java.util.logging.Level; import static org.jackhuang.hmcl.util.DigestUtils.digest; import static org.jackhuang.hmcl.util.Hex.encodeHex; @@ -26,10 +29,12 @@ import static org.jackhuang.hmcl.util.Hex.encodeHex; public class LibraryDownloadTask extends Task { private FileDownloadTask task; protected final File jar; + protected final DefaultCacheRepository cacheRepository; private final File xzFile; protected final Library library; protected final String url; protected boolean xz; + private boolean cached = false; public LibraryDownloadTask(AbstractDependencyManager dependencyManager, File file, Library library) { setSignificance(TaskSignificance.MODERATE); @@ -38,6 +43,7 @@ public class LibraryDownloadTask extends Task { library = library.setClassifier("universal"); this.library = library; + this.cacheRepository = dependencyManager.getCacheRepository(); url = dependencyManager.getDownloadProvider().injectURL(library.getDownload().getUrl()); jar = file; @@ -47,7 +53,8 @@ public class LibraryDownloadTask extends Task { @Override public Collection getDependents() { - return Collections.singleton(task); + if (cached) return Collections.emptyList(); + else return Collections.singleton(task); } @Override @@ -57,6 +64,8 @@ public class LibraryDownloadTask extends Task { @Override public void execute() throws Exception { + if (cached) return; + if (!isDependentsSucceeded()) { // Since FileDownloadTask wraps the actual exception with another IOException. // We should extract it letting the error message clearer. @@ -76,6 +85,19 @@ public class LibraryDownloadTask extends Task { @Override public void preExecute() throws Exception { + Optional libPath = cacheRepository.getLibrary(library); + if (libPath.isPresent()) { + try { + FileUtils.copyFile(libPath.get().toFile(), jar); + cached = true; + return; + } catch (IOException e) { + Logging.LOG.log(Level.WARNING, "Failed to copy file from cache", e); + // We cannot copy cached file to current location + // so we try to download a new one. + } + } + try { URL packXz = NetworkUtils.toURL(url + ".pack.xz"); if (NetworkUtils.URLExists(packXz)) { @@ -92,6 +114,12 @@ public class LibraryDownloadTask extends Task { } } + @Override + public void postExecute() throws Exception { + if (!cached) + cacheRepository.cacheLibrary(library, jar.toPath(), xz); + } + public static boolean checksumValid(File libPath, List checksums) { try { if (checksums == null || checksums.isEmpty()) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FileDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FileDownloadTask.java index 99e13ddb1..43b9c0d8a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FileDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FileDownloadTask.java @@ -84,6 +84,7 @@ public class FileDownloadTask extends Task { private final EventManager> onFailed = new EventManager<>(); private Path candidate; private boolean caching; + private CacheRepository repository = CacheRepository.getInstance(); private RandomAccessFile rFile; private InputStream stream; @@ -165,14 +166,18 @@ public class FileDownloadTask extends Task { return this; } + public FileDownloadTask setCacheRepository(CacheRepository repository) { + this.repository = repository; + return this; + } + @Override public void execute() throws Exception { URL currentURL = url; // Check cache if (integrityCheck != null && caching) { - Optional cache = LocalRepository.getInstance() - .checkExistentFile(candidate, integrityCheck.getAlgorithm(), integrityCheck.getChecksum()); + Optional cache = repository.checkExistentFile(candidate, integrityCheck.getAlgorithm(), integrityCheck.getChecksum()); if (cache.isPresent()) { try { FileUtils.copyFile(cache.get().toFile(), file); @@ -296,9 +301,9 @@ public class FileDownloadTask extends Task { if (caching) { try { if (integrityCheck == null) - LocalRepository.getInstance().cacheFile(file.toPath(), LocalRepository.SHA1, Hex.encodeHex(DigestUtils.digest(LocalRepository.SHA1, file.toPath()))); + repository.cacheFile(file.toPath(), CacheRepository.SHA1, Hex.encodeHex(DigestUtils.digest(CacheRepository.SHA1, file.toPath()))); else - LocalRepository.getInstance().cacheFile(file.toPath(), integrityCheck.getAlgorithm(), integrityCheck.getChecksum()); + repository.cacheFile(file.toPath(), integrityCheck.getAlgorithm(), integrityCheck.getChecksum()); } catch (IOException e) { Logging.LOG.log(Level.WARNING, "Failed to cache file", e); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/LocalRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java similarity index 91% rename from HMCLCore/src/main/java/org/jackhuang/hmcl/util/LocalRepository.java rename to HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java index 4b4cab384..d4aa492c3 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/LocalRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java @@ -22,11 +22,11 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; -public class LocalRepository { +public class CacheRepository { private Path commonDirectory; private Path cacheDirectory; - protected void changeDirectory(Path commonDir) { + public void changeDirectory(Path commonDir) { commonDirectory = commonDir; cacheDirectory = commonDir.resolve("cache"); } @@ -97,14 +97,14 @@ public class LocalRepository { return cache; } - private static LocalRepository instance = new LocalRepository(); + private static CacheRepository instance = new CacheRepository(); - public static LocalRepository getInstance() { + public static CacheRepository getInstance() { return instance; } - public static void setInstance(LocalRepository instance) { - LocalRepository.instance = instance; + public static void setInstance(CacheRepository instance) { + CacheRepository.instance = instance; } public static final String SHA1 = "SHA-1";