Fix #2762: 光影应当被下载至 ./shaderpacks 下 (#2770)

* Fix #2762: Shader packs should be downloaded in to the ./shaderpacks directory.

* Make the network requests parallely in order to make CurseCompletionTask faster.

* Support displaying the process.

* Fix: checkstyle

* update

* update

* update

* update

---------

Co-authored-by: Glavo <zjx001202@gmail.com>
This commit is contained in:
Burning_TNT 2024-02-19 17:28:07 +08:00 committed by GitHub
parent e9ae43b1f1
commit a81462425d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -33,13 +33,13 @@ import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* Complete the CurseForge version. * Complete the CurseForge version.
@ -53,7 +53,7 @@ public final class CurseCompletionTask extends Task<Void> {
private final ModManager modManager; private final ModManager modManager;
private final String version; private final String version;
private CurseManifest manifest; private CurseManifest manifest;
private final List<Task<?>> dependencies = new ArrayList<>(); private List<Task<?>> dependencies;
private final AtomicBoolean allNameKnown = new AtomicBoolean(true); private final AtomicBoolean allNameKnown = new AtomicBoolean(true);
private final AtomicInteger finished = new AtomicInteger(0); private final AtomicInteger finished = new AtomicInteger(0);
@ -138,28 +138,31 @@ public final class CurseCompletionTask extends Task<Void> {
.collect(Collectors.toList())); .collect(Collectors.toList()));
FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(newManifest)); FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(newManifest));
File resourcePacks = new File(repository.getVersionRoot(modManager.getVersion()), "resourcepacks"); File versionRoot = repository.getVersionRoot(modManager.getVersion());
for (CurseManifestFile file : newManifest.getFiles()) File resourcePacksRoot = new File(versionRoot, "resourcepacks"), shaderPacksRoot = new File(versionRoot, "shaderpacks");
if (StringUtils.isNotBlank(file.getFileName())) { finished.set(0);
RemoteMod mod = CurseForgeRemoteModRepository.MODS.getModById(Integer.toString(file.getProjectID())); dependencies = newManifest.getFiles()
File target; .stream().parallel()
if (((CurseAddon) mod.getData()).getClassId() == 12) { .filter(f -> f.getFileName() != null)
target = new File(resourcePacks, file.getFileName()); .flatMap(f -> {
if (target.exists()) { try {
continue; File path = guessFilePath(f, resourcePacksRoot, shaderPacksRoot);
} if (path == null) {
} else { return Stream.empty();
if (modManager.hasSimpleMod(file.getFileName())) { }
continue;
}
target = modManager.getSimpleModPath(file.getFileName()).toFile();
}
FileDownloadTask task = new FileDownloadTask(file.getUrl(), target); FileDownloadTask task = new FileDownloadTask(f.getUrl(), path);
task.setCacheRepository(dependency.getCacheRepository()); task.setCacheRepository(dependency.getCacheRepository());
task.setCaching(true); task.setCaching(true);
dependencies.add(task.withCounter("hmcl.modpack.download")); return Stream.of(task.withCounter("hmcl.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()) { if (!dependencies.isEmpty()) {
getProperties().put("total", dependencies.size()); getProperties().put("total", dependencies.size());
@ -167,6 +170,33 @@ public final class CurseCompletionTask extends Task<Void> {
} }
} }
/**
* 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 @Override
public boolean doPostExecute() { public boolean doPostExecute() {
return true; return true;