将 org.jackhuang.hmcl.mod 从 java.io.File 迁移至 NIO (#4499)

This commit is contained in:
Glavo
2025-09-17 19:29:59 +08:00
committed by GitHub
parent 94994ffdb6
commit e9d7d0a33c
27 changed files with 154 additions and 164 deletions

View File

@@ -29,7 +29,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -38,7 +37,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public final class HMCLModpackInstallTask extends Task<Void> { public final class HMCLModpackInstallTask extends Task<Void> {
private final File zipFile; private final Path zipFile;
private final String name; private final String name;
private final HMCLGameRepository repository; private final HMCLGameRepository repository;
private final DefaultDependencyManager dependency; private final DefaultDependencyManager dependency;
@@ -46,7 +45,7 @@ public final class HMCLModpackInstallTask extends Task<Void> {
private final List<Task<?>> dependencies = new ArrayList<>(1); private final List<Task<?>> dependencies = new ArrayList<>(1);
private final List<Task<?>> dependents = new ArrayList<>(4); private final List<Task<?>> dependents = new ArrayList<>(4);
public HMCLModpackInstallTask(Profile profile, File zipFile, Modpack modpack, String name) { public HMCLModpackInstallTask(Profile profile, Path zipFile, Modpack modpack, String name) {
dependency = profile.getDependency(); dependency = profile.getDependency();
repository = profile.getRepository(); repository = profile.getRepository();
this.zipFile = zipFile; this.zipFile = zipFile;
@@ -74,8 +73,8 @@ public final class HMCLModpackInstallTask extends Task<Void> {
} }
} catch (JsonParseException | IOException ignore) { } catch (JsonParseException | IOException ignore) {
} }
dependents.add(new ModpackInstallTask<>(zipFile, run.toFile(), modpack.getEncoding(), Collections.singletonList("/minecraft"), it -> !"pack.json".equals(it), config)); dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), Collections.singletonList("/minecraft"), it -> !"pack.json".equals(it), config));
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList("/minecraft"), modpack, HMCLModpackProvider.INSTANCE, modpack.getName(), modpack.getVersion(), repository.getModpackConfiguration(name).toFile()).withStage("hmcl.modpack")); dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList("/minecraft"), modpack, HMCLModpackProvider.INSTANCE, modpack.getName(), modpack.getVersion(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
} }
@Override @Override

View File

@@ -30,7 +30,6 @@ import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
@@ -49,15 +48,14 @@ public final class HMCLModpackProvider implements ModpackProvider {
} }
@Override @Override
public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, File zipFile, Modpack modpack) throws MismatchedModpackTypeException { public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, Path zipFile, Modpack modpack) throws MismatchedModpackTypeException {
if (!(modpack.getManifest() instanceof HMCLModpackManifest)) if (!(modpack.getManifest() instanceof HMCLModpackManifest))
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName()); throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
if (!(dependencyManager.getGameRepository() instanceof HMCLGameRepository)) { if (!(dependencyManager.getGameRepository() instanceof HMCLGameRepository repository)) {
throw new IllegalArgumentException("HMCLModpackProvider requires HMCLGameRepository"); throw new IllegalArgumentException("HMCLModpackProvider requires HMCLGameRepository");
} }
HMCLGameRepository repository = (HMCLGameRepository) dependencyManager.getGameRepository();
Profile profile = repository.getProfile(); Profile profile = repository.getProfile();
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new HMCLModpackInstallTask(profile, zipFile, modpack, name)); return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new HMCLModpackInstallTask(profile, zipFile, modpack, name));
@@ -81,7 +79,7 @@ public final class HMCLModpackProvider implements ModpackProvider {
private static class HMCLModpack extends Modpack { private static class HMCLModpack extends Modpack {
@Override @Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name) { public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
return new HMCLModpackInstallTask(((HMCLGameRepository) dependencyManager.getGameRepository()).getProfile(), zipFile, this, name); return new HMCLModpackInstallTask(((HMCLGameRepository) dependencyManager.getGameRepository()).getProfile(), zipFile, this, name);
} }
} }

View File

@@ -211,17 +211,17 @@ public final class ModpackHelper {
}; };
if (modpack.getManifest() instanceof MultiMCInstanceConfiguration) if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
return modpack.getInstallTask(profile.getDependency(), zipFile, name) return modpack.getInstallTask(profile.getDependency(), zipFile.toPath(), name)
.whenComplete(Schedulers.defaultScheduler(), success, failure) .whenComplete(Schedulers.defaultScheduler(), success, failure)
.thenComposeAsync(createMultiMCPostInstallTask(profile, (MultiMCInstanceConfiguration) modpack.getManifest(), name)) .thenComposeAsync(createMultiMCPostInstallTask(profile, (MultiMCInstanceConfiguration) modpack.getManifest(), name))
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download")); .withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
else if (modpack.getManifest() instanceof McbbsModpackManifest) else if (modpack.getManifest() instanceof McbbsModpackManifest)
return modpack.getInstallTask(profile.getDependency(), zipFile, name) return modpack.getInstallTask(profile.getDependency(), zipFile.toPath(), name)
.whenComplete(Schedulers.defaultScheduler(), success, failure) .whenComplete(Schedulers.defaultScheduler(), success, failure)
.thenComposeAsync(createMcbbsPostInstallTask(profile, (McbbsModpackManifest) modpack.getManifest(), name)) .thenComposeAsync(createMcbbsPostInstallTask(profile, (McbbsModpackManifest) modpack.getManifest(), name))
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download")); .withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
else else
return modpack.getInstallTask(profile.getDependency(), zipFile, name) return modpack.getInstallTask(profile.getDependency(), zipFile.toPath(), name)
.whenComplete(Schedulers.javafx(), success, failure) .whenComplete(Schedulers.javafx(), success, failure)
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download")); .withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
} }
@@ -243,10 +243,10 @@ public final class ModpackHelper {
throw new UnsupportedModpackException(); throw new UnsupportedModpackException();
} }
if (modpack.getManifest() instanceof MultiMCInstanceConfiguration) if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
return provider.createUpdateTask(profile.getDependency(), name, zipFile, modpack) return provider.createUpdateTask(profile.getDependency(), name, zipFile.toPath(), modpack)
.thenComposeAsync(() -> createMultiMCPostUpdateTask(profile, (MultiMCInstanceConfiguration) modpack.getManifest(), name)); .thenComposeAsync(() -> createMultiMCPostUpdateTask(profile, (MultiMCInstanceConfiguration) modpack.getManifest(), name));
else else
return provider.createUpdateTask(profile.getDependency(), name, zipFile, modpack); return provider.createUpdateTask(profile.getDependency(), name, zipFile.toPath(), modpack);
} }
public static void toVersionSetting(MultiMCInstanceConfiguration c, VersionSetting vs) { public static void toVersionSetting(MultiMCInstanceConfiguration c, VersionSetting vs) {

View File

@@ -175,7 +175,7 @@ public final class ExportWizardProvider implements WizardProvider {
@Override @Override
public void execute() { public void execute() {
dependency = new McbbsModpackExportTask(profile.getRepository(), version, exportInfo, modpackFile); dependency = new McbbsModpackExportTask(profile.getRepository(), version, exportInfo, modpackFile.toPath());
} }
@Override @Override
@@ -223,7 +223,7 @@ public final class ExportWizardProvider implements WizardProvider {
/* overrideCommands */ true, /* overrideCommands */ true,
/* overrideWindow */ true, /* overrideWindow */ true,
/* iconKey */ null // TODO /* iconKey */ null // TODO
), modpackFile); ), modpackFile.toPath());
} }
@Override @Override
@@ -243,7 +243,7 @@ public final class ExportWizardProvider implements WizardProvider {
@Override @Override
public void execute() { public void execute() {
dependency = new ServerModpackExportTask(profile.getRepository(), version, exportInfo, modpackFile); dependency = new ServerModpackExportTask(profile.getRepository(), version, exportInfo, modpackFile.toPath());
} }
@Override @Override
@@ -267,7 +267,7 @@ public final class ExportWizardProvider implements WizardProvider {
profile.getRepository(), profile.getRepository(),
version, version,
exportInfo, exportInfo,
modpackFile modpackFile.toPath()
); );
} }

View File

@@ -30,23 +30,22 @@ import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public final class MinecraftInstanceTask<T> extends Task<ModpackConfiguration<T>> { public final class MinecraftInstanceTask<T> extends Task<ModpackConfiguration<T>> {
private final File zipFile; private final Path zipFile;
private final Charset encoding; private final Charset encoding;
private final List<String> subDirectories; private final List<String> subDirectories;
private final File jsonFile; private final Path jsonFile;
private final T manifest; private final T manifest;
private final String type; private final String type;
private final String name; private final String name;
private final String version; private final String version;
public MinecraftInstanceTask(File zipFile, Charset encoding, List<String> subDirectories, T manifest, ModpackProvider modpackProvider, String name, String version, File jsonFile) { public MinecraftInstanceTask(Path zipFile, Charset encoding, List<String> subDirectories, T manifest, ModpackProvider modpackProvider, String name, String version, Path jsonFile) {
this.zipFile = zipFile; this.zipFile = zipFile;
this.encoding = encoding; this.encoding = encoding;
this.subDirectories = subDirectories.stream().map(FileUtils::normalizePath).collect(Collectors.toList()); this.subDirectories = subDirectories.stream().map(FileUtils::normalizePath).toList();
this.manifest = manifest; this.manifest = manifest;
this.jsonFile = jsonFile; this.jsonFile = jsonFile;
this.type = modpackProvider.getName(); this.type = modpackProvider.getName();
@@ -58,12 +57,12 @@ public final class MinecraftInstanceTask<T> extends Task<ModpackConfiguration<T>
public void execute() throws Exception { public void execute() throws Exception {
List<ModpackConfiguration.FileInformation> overrides = new ArrayList<>(); List<ModpackConfiguration.FileInformation> overrides = new ArrayList<>();
try (FileSystem fs = CompressingUtils.readonly(zipFile.toPath()).setEncoding(encoding).build()) { try (FileSystem fs = CompressingUtils.readonly(zipFile).setEncoding(encoding).build()) {
for (String subDirectory : subDirectories) { for (String subDirectory : subDirectories) {
Path root = fs.getPath(subDirectory); Path root = fs.getPath(subDirectory);
if (Files.exists(root)) if (Files.exists(root))
Files.walkFileTree(root, new SimpleFileVisitor<Path>() { Files.walkFileTree(root, new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String relativePath = root.relativize(file).normalize().toString().replace(File.separatorChar, '/'); String relativePath = root.relativize(file).normalize().toString().replace(File.separatorChar, '/');
@@ -75,9 +74,8 @@ public final class MinecraftInstanceTask<T> extends Task<ModpackConfiguration<T>
} }
ModpackConfiguration<T> configuration = new ModpackConfiguration<>(manifest, type, name, version, overrides); ModpackConfiguration<T> configuration = new ModpackConfiguration<>(manifest, type, name, version, overrides);
Path jsonPath = jsonFile.toPath(); Files.createDirectories(jsonFile.getParent());
Files.createDirectories(jsonPath.getParent()); JsonUtils.writeToJsonFile(jsonFile, configuration);
JsonUtils.writeToJsonFile(jsonPath, configuration);
setResult(configuration); setResult(configuration);
} }
} }

View File

@@ -20,8 +20,8 @@ package org.jackhuang.hmcl.mod;
import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import java.io.File;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.List; import java.util.List;
/** /**
@@ -114,7 +114,7 @@ public abstract class Modpack {
return this; return this;
} }
public abstract Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name); public abstract Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name);
public static boolean acceptFile(String path, List<String> blackList, List<String> whiteList) { public static boolean acceptFile(String path, List<String> blackList, List<String> whiteList) {
if (path.isEmpty()) if (path.isEmpty())

View File

@@ -21,31 +21,30 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.DigestUtils; import org.jackhuang.hmcl.util.DigestUtils;
import org.jackhuang.hmcl.util.io.Unzipper; import org.jackhuang.hmcl.util.io.Unzipper;
import java.io.File;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.function.Predicate; import java.util.function.Predicate;
public class ModpackInstallTask<T> extends Task<Void> { public class ModpackInstallTask<T> extends Task<Void> {
private final File modpackFile; private final Path modpackFile;
private final File dest; private final Path dest;
private final Charset charset; private final Charset charset;
private final List<String> subDirectories; private final List<String> subDirectories;
private final List<ModpackConfiguration.FileInformation> overrides; private final List<ModpackConfiguration.FileInformation> overrides;
private final Predicate<String> callback; private final Predicate<String> callback;
/** /// Constructor
* Constructor ///
* @param modpackFile a zip file /// @param modpackFile a zip file
* @param dest destination to store unpacked files /// @param dest destination to store unpacked files
* @param charset charset of the zip file /// @param charset charset of the zip file
* @param subDirectories the subdirectory of zip file to unpack /// @param subDirectories the subdirectory of zip file to unpack
* @param callback test whether the file (given full path) in zip file should be unpacked or not /// @param callback test whether the file (given full path) in zip file should be unpacked or not
* @param oldConfiguration old modpack information if upgrade /// @param oldConfiguration old modpack information if upgrade
*/ public ModpackInstallTask(Path modpackFile, Path dest, Charset charset, List<String> subDirectories, Predicate<String> callback, ModpackConfiguration<T> oldConfiguration) {
public ModpackInstallTask(File modpackFile, File dest, Charset charset, List<String> subDirectories, Predicate<String> callback, ModpackConfiguration<T> oldConfiguration) {
this.modpackFile = modpackFile; this.modpackFile = modpackFile;
this.dest = dest; this.dest = dest;
this.charset = charset; this.charset = charset;
@@ -61,7 +60,7 @@ public class ModpackInstallTask<T> extends Task<Void> {
@Override @Override
public void execute() throws Exception { public void execute() throws Exception {
Set<String> entries = new HashSet<>(); Set<String> entries = new HashSet<>();
Files.createDirectories(dest.toPath()); Files.createDirectories(dest);
HashMap<String, ModpackConfiguration.FileInformation> files = new HashMap<>(); HashMap<String, ModpackConfiguration.FileInformation> files = new HashMap<>();
for (ModpackConfiguration.FileInformation file : overrides) for (ModpackConfiguration.FileInformation file : overrides)
@@ -97,9 +96,9 @@ public class ModpackInstallTask<T> extends Task<Void> {
// If old modpack have this entry, and new modpack deleted it. Delete this file. // If old modpack have this entry, and new modpack deleted it. Delete this file.
for (ModpackConfiguration.FileInformation file : overrides) { for (ModpackConfiguration.FileInformation file : overrides) {
File original = new File(dest, file.getPath()); Path original = dest.resolve(file.getPath());
if (original.exists() && !entries.contains(file.getPath())) if (Files.exists(original) && !entries.contains(file.getPath()))
original.delete(); Files.deleteIfExists(original);
} }
} }
} }

View File

@@ -23,7 +23,6 @@ import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.game.LaunchOptions; import org.jackhuang.hmcl.game.LaunchOptions;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
@@ -34,7 +33,7 @@ public interface ModpackProvider {
Task<?> createCompletionTask(DefaultDependencyManager dependencyManager, String version); Task<?> createCompletionTask(DefaultDependencyManager dependencyManager, String version);
Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, File zipFile, Modpack modpack) throws MismatchedModpackTypeException; Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, Path zipFile, Modpack modpack) throws MismatchedModpackTypeException;
/** /**
* @param zipFile the opened modpack zip file. * @param zipFile the opened modpack zip file.

View File

@@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@@ -148,12 +147,12 @@ public final class CurseCompletionTask extends Task<Void> {
.filter(f -> f.getFileName() != null) .filter(f -> f.getFileName() != null)
.flatMap(f -> { .flatMap(f -> {
try { try {
File path = guessFilePath(f, resourcePacksRoot.toFile(), shaderPacksRoot.toFile()); Path path = guessFilePath(f, resourcePacksRoot, shaderPacksRoot);
if (path == null) { if (path == null) {
return Stream.empty(); return Stream.empty();
} }
var task = new FileDownloadTask(f.getUrl(), path.toPath()); var task = new FileDownloadTask(f.getUrl(), path);
task.setCacheRepository(dependency.getCacheRepository()); task.setCacheRepository(dependency.getCacheRepository());
task.setCaching(true); task.setCaching(true);
return Stream.of(task.withCounter("hmcl.modpack.download")); return Stream.of(task.withCounter("hmcl.modpack.download"));
@@ -181,23 +180,23 @@ public final class CurseCompletionTask extends Task<Void> {
* @return ./resourcepacks/$filename or ./shaderpacks/$filename or ./mods/$filename if the file doesn't exist. null if the file existed. * @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. * @throws IOException If IOException was encountered during getting data from CurseForge.
*/ */
private File guessFilePath(CurseManifestFile file, File resourcePacksRoot, File shaderPacksRoot) throws IOException { private Path guessFilePath(CurseManifestFile file, Path resourcePacksRoot, Path shaderPacksRoot) throws IOException {
RemoteMod mod = CurseForgeRemoteModRepository.MODS.getModById(Integer.toString(file.getProjectID())); RemoteMod mod = CurseForgeRemoteModRepository.MODS.getModById(Integer.toString(file.getProjectID()));
int classID = ((CurseAddon) mod.getData()).getClassId(); int classID = ((CurseAddon) mod.getData()).getClassId();
String fileName = file.getFileName(); String fileName = file.getFileName();
switch (classID) { return switch (classID) {
case 12: // Resource pack case 12, // Resource pack
case 6552: { // Shader pack 6552 -> { // Shader pack
File res = new File(classID == 12 ? resourcePacksRoot : shaderPacksRoot, fileName); Path res = (classID == 12 ? resourcePacksRoot : shaderPacksRoot).resolve(fileName);
return res.exists() ? null : res; yield Files.exists(res) ? null : res;
} }
default: { default -> {
if (modManager.hasSimpleMod(fileName)) { if (modManager.hasSimpleMod(fileName)) {
return null; yield null;
} }
return modManager.getSimpleModPath(fileName).toFile(); yield modManager.getSimpleModPath(fileName);
} }
} };
} }
@Override @Override

View File

@@ -26,7 +26,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -44,11 +43,11 @@ public final class CurseInstallTask extends Task<Void> {
private final DefaultDependencyManager dependencyManager; private final DefaultDependencyManager dependencyManager;
private final DefaultGameRepository repository; private final DefaultGameRepository repository;
private final File zipFile; private final Path zipFile;
private final Modpack modpack; private final Modpack modpack;
private final CurseManifest manifest; private final CurseManifest manifest;
private final String name; private final String name;
private final File run; private final Path run;
private final ModpackConfiguration<CurseManifest> config; private final ModpackConfiguration<CurseManifest> config;
private final List<Task<?>> dependents = new ArrayList<>(4); private final List<Task<?>> dependents = new ArrayList<>(4);
private final List<Task<?>> dependencies = new ArrayList<>(1); private final List<Task<?>> dependencies = new ArrayList<>(1);
@@ -61,14 +60,14 @@ public final class CurseInstallTask extends Task<Void> {
* @param manifest The manifest content of given CurseForge modpack. * @param manifest The manifest content of given CurseForge modpack.
* @param name the new version name * @param name the new version name
*/ */
public CurseInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, CurseManifest manifest, String name) { public CurseInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, CurseManifest manifest, String name) {
this.dependencyManager = dependencyManager; this.dependencyManager = dependencyManager;
this.zipFile = zipFile; this.zipFile = zipFile;
this.modpack = modpack; this.modpack = modpack;
this.manifest = manifest; this.manifest = manifest;
this.name = name; this.name = name;
this.repository = dependencyManager.getGameRepository(); this.repository = dependencyManager.getGameRepository();
this.run = repository.getRunDirectory(name).toFile(); this.run = repository.getRunDirectory(name);
Path json = repository.getModpackConfiguration(name); Path json = repository.getModpackConfiguration(name);
if (repository.hasVersion(name) && Files.notExists(json)) if (repository.hasVersion(name) && Files.notExists(json))
@@ -107,7 +106,7 @@ public final class CurseInstallTask extends Task<Void> {
} }
this.config = config; this.config = config;
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), Collections.singletonList(manifest.getOverrides()), any -> true, config).withStage("hmcl.modpack")); dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), Collections.singletonList(manifest.getOverrides()), any -> true, config).withStage("hmcl.modpack"));
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList(manifest.getOverrides()), manifest, CurseModpackProvider.INSTANCE, manifest.getName(), manifest.getVersion(), repository.getModpackConfiguration(name).toFile()).withStage("hmcl.modpack")); dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList(manifest.getOverrides()), manifest, CurseModpackProvider.INSTANCE, manifest.getName(), manifest.getVersion(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
dependencies.add(new CurseCompletionTask(dependencyManager, name, manifest)); dependencies.add(new CurseCompletionTask(dependencyManager, name, manifest));
} }
@@ -128,11 +127,10 @@ public final class CurseInstallTask extends Task<Void> {
// For update, remove mods not listed in new manifest // For update, remove mods not listed in new manifest
for (CurseManifestFile oldCurseManifestFile : config.getManifest().getFiles()) { for (CurseManifestFile oldCurseManifestFile : config.getManifest().getFiles()) {
if (StringUtils.isBlank(oldCurseManifestFile.getFileName())) continue; if (StringUtils.isBlank(oldCurseManifestFile.getFileName())) continue;
File oldFile = new File(run, "mods/" + oldCurseManifestFile.getFileName()); Path oldFile = run.resolve("mods/" + oldCurseManifestFile.getFileName());
if (!oldFile.exists()) continue; if (Files.notExists(oldFile)) continue;
if (manifest.getFiles().stream().noneMatch(oldCurseManifestFile::equals)) if (manifest.getFiles().stream().noneMatch(oldCurseManifestFile::equals))
if (!oldFile.delete()) Files.deleteIfExists(oldFile);
throw new IOException("Unable to delete mod file " + oldFile);
} }
} }

View File

@@ -30,7 +30,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.IOUtils; import org.jackhuang.hmcl.util.io.IOUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
@@ -49,11 +48,11 @@ public final class CurseModpackProvider implements ModpackProvider {
} }
@Override @Override
public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, File zipFile, Modpack modpack) throws MismatchedModpackTypeException { public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, Path zipFile, Modpack modpack) throws MismatchedModpackTypeException {
if (!(modpack.getManifest() instanceof CurseManifest)) if (!(modpack.getManifest() instanceof CurseManifest curseManifest))
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName()); throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new CurseInstallTask(dependencyManager, zipFile, modpack, (CurseManifest) modpack.getManifest(), name)); return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new CurseInstallTask(dependencyManager, zipFile, modpack, curseManifest, name));
} }
@Override @Override
@@ -69,7 +68,7 @@ public final class CurseModpackProvider implements ModpackProvider {
return new Modpack(manifest.getName(), manifest.getAuthor(), manifest.getVersion(), manifest.getMinecraft().getGameVersion(), description, encoding, manifest) { return new Modpack(manifest.getName(), manifest.getAuthor(), manifest.getVersion(), manifest.getMinecraft().getGameVersion(), description, encoding, manifest) {
@Override @Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name) { public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
return new CurseInstallTask(dependencyManager, zipFile, this, manifest, name); return new CurseInstallTask(dependencyManager, zipFile, this, manifest, name);
} }
}; };

View File

@@ -32,7 +32,6 @@ import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@@ -55,7 +54,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
private final DefaultGameRepository repository; private final DefaultGameRepository repository;
private final ModManager modManager; private final ModManager modManager;
private final String version; private final String version;
private final File configurationFile; private final Path configurationFile;
private ModpackConfiguration<McbbsModpackManifest> configuration; private ModpackConfiguration<McbbsModpackManifest> configuration;
private McbbsModpackManifest manifest; private McbbsModpackManifest manifest;
private final List<Task<?>> dependencies = new ArrayList<>(); private final List<Task<?>> dependencies = new ArrayList<>();
@@ -73,7 +72,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
this.repository = dependencyManager.getGameRepository(); this.repository = dependencyManager.getGameRepository();
this.modManager = repository.getModManager(version); this.modManager = repository.getModManager(version);
this.version = version; this.version = version;
this.configurationFile = repository.getModpackConfiguration(version).toFile(); this.configurationFile = repository.getModpackConfiguration(version);
this.configuration = configuration; this.configuration = configuration;
setStage("hmcl.modpack.download"); setStage("hmcl.modpack.download");
@@ -85,7 +84,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
if (configuration == null) { if (configuration == null) {
// Load configuration from disk // Load configuration from disk
try { try {
configuration = JsonUtils.fromNonNullJson(Files.readString(configurationFile.toPath()), ModpackConfiguration.typeOf(McbbsModpackManifest.class)); configuration = JsonUtils.fromNonNullJson(Files.readString(configurationFile), ModpackConfiguration.typeOf(McbbsModpackManifest.class));
} catch (IOException | JsonParseException e) { } catch (IOException | JsonParseException e) {
throw new IOException("Malformed modpack configuration"); throw new IOException("Malformed modpack configuration");
} }
@@ -239,7 +238,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
manifest = newManifest; manifest = newManifest;
configuration = configuration.setManifest(newManifest); configuration = configuration.setManifest(newManifest);
JsonUtils.writeToJsonFile(configurationFile.toPath(), configuration); JsonUtils.writeToJsonFile(configurationFile, configuration);
for (McbbsModpackManifest.File file : newManifest.getFiles()) for (McbbsModpackManifest.File file : newManifest.getFiles())
if (file instanceof McbbsModpackManifest.CurseFile) { if (file instanceof McbbsModpackManifest.CurseFile) {

View File

@@ -47,16 +47,22 @@ public class McbbsModpackExportTask extends Task<Void> {
private final DefaultGameRepository repository; private final DefaultGameRepository repository;
private final String version; private final String version;
private final ModpackExportInfo info; private final ModpackExportInfo info;
private final File modpackFile; private final Path modpackFile;
public McbbsModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo info, File modpackFile) { public McbbsModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo info, Path modpackFile) {
this.repository = repository; this.repository = repository;
this.version = version; this.version = version;
this.info = info.validate(); this.info = info.validate();
this.modpackFile = modpackFile; this.modpackFile = modpackFile;
onDone().register(event -> { onDone().register(event -> {
if (event.isFailed()) modpackFile.delete(); if (event.isFailed()) {
try {
Files.deleteIfExists(modpackFile);
} catch (IOException e) {
LOG.warning("Failed to delete modpack file: " + modpackFile, e);
}
}
}); });
} }
@@ -66,7 +72,7 @@ public class McbbsModpackExportTask extends Task<Void> {
blackList.add(version + ".jar"); blackList.add(version + ".jar");
blackList.add(version + ".json"); blackList.add(version + ".json");
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker"); LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
try (Zipper zip = new Zipper(modpackFile.toPath())) { try (var zip = new Zipper(modpackFile)) {
Path runDirectory = repository.getRunDirectory(version); Path runDirectory = repository.getRunDirectory(version);
List<McbbsModpackManifest.File> files = new ArrayList<>(); List<McbbsModpackManifest.File> files = new ArrayList<>();
zip.putDirectory(runDirectory, "overrides", path -> { zip.putDirectory(runDirectory, "overrides", path -> {

View File

@@ -29,7 +29,6 @@ import org.jackhuang.hmcl.mod.ModpackInstallTask;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -38,10 +37,10 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
public class McbbsModpackLocalInstallTask extends Task<Void> { public final class McbbsModpackLocalInstallTask extends Task<Void> {
private final DefaultDependencyManager dependencyManager; private final DefaultDependencyManager dependencyManager;
private final File zipFile; private final Path zipFile;
private final Modpack modpack; private final Modpack modpack;
private final McbbsModpackManifest manifest; private final McbbsModpackManifest manifest;
private final String name; private final String name;
@@ -51,7 +50,7 @@ public class McbbsModpackLocalInstallTask extends Task<Void> {
private final List<Task<?>> dependencies = new ArrayList<>(2); private final List<Task<?>> dependencies = new ArrayList<>(2);
private final List<Task<?>> dependents = new ArrayList<>(4); private final List<Task<?>> dependents = new ArrayList<>(4);
public McbbsModpackLocalInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, McbbsModpackManifest manifest, String name) { public McbbsModpackLocalInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, McbbsModpackManifest manifest, String name) {
this.dependencyManager = dependencyManager; this.dependencyManager = dependencyManager;
this.zipFile = zipFile; this.zipFile = zipFile;
this.modpack = modpack; this.modpack = modpack;
@@ -87,8 +86,8 @@ public class McbbsModpackLocalInstallTask extends Task<Void> {
} }
} catch (JsonParseException | IOException ignore) { } catch (JsonParseException | IOException ignore) {
} }
dependents.add(new ModpackInstallTask<>(zipFile, run.toFile(), modpack.getEncoding(), Collections.singletonList("/overrides"), any -> true, config).withStage("hmcl.modpack")); dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), Collections.singletonList("/overrides"), any -> true, config).withStage("hmcl.modpack"));
instanceTask = new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList("/overrides"), manifest, McbbsModpackProvider.INSTANCE, modpack.getName(), modpack.getVersion(), repository.getModpackConfiguration(name).toFile()); instanceTask = new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList("/overrides"), manifest, McbbsModpackProvider.INSTANCE, modpack.getName(), modpack.getVersion(), repository.getModpackConfiguration(name));
dependents.add(instanceTask.withStage("hmcl.modpack")); dependents.add(instanceTask.withStage("hmcl.modpack"));
} }

View File

@@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -423,7 +424,7 @@ public class McbbsModpackManifest implements ModpackManifest, Validation {
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion(); .orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
return new Modpack(name, author, version, gameVersion, description, encoding, this) { return new Modpack(name, author, version, gameVersion, description, encoding, this) {
@Override @Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, java.io.File zipFile, String name) { public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
return new McbbsModpackLocalInstallTask(dependencyManager, zipFile, this, McbbsModpackManifest.this, name); return new McbbsModpackLocalInstallTask(dependencyManager, zipFile, this, McbbsModpackManifest.this, name);
} }
}; };

View File

@@ -26,7 +26,6 @@ import org.jackhuang.hmcl.mod.*;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@@ -46,11 +45,11 @@ public final class McbbsModpackProvider implements ModpackProvider {
} }
@Override @Override
public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, File zipFile, Modpack modpack) throws MismatchedModpackTypeException { public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, Path zipFile, Modpack modpack) throws MismatchedModpackTypeException {
if (!(modpack.getManifest() instanceof McbbsModpackManifest)) if (!(modpack.getManifest() instanceof McbbsModpackManifest mcbbsModpackManifest))
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName()); throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new McbbsModpackLocalInstallTask(dependencyManager, zipFile, modpack, (McbbsModpackManifest) modpack.getManifest(), name)); return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new McbbsModpackLocalInstallTask(dependencyManager, zipFile, modpack, mcbbsModpackManifest, name));
} }
@Override @Override

View File

@@ -25,7 +25,6 @@ import org.jackhuang.hmcl.mod.*;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -35,23 +34,23 @@ public class ModrinthInstallTask extends Task<Void> {
private final DefaultDependencyManager dependencyManager; private final DefaultDependencyManager dependencyManager;
private final DefaultGameRepository repository; private final DefaultGameRepository repository;
private final File zipFile; private final Path zipFile;
private final Modpack modpack; private final Modpack modpack;
private final ModrinthManifest manifest; private final ModrinthManifest manifest;
private final String name; private final String name;
private final File run; private final Path run;
private final ModpackConfiguration<ModrinthManifest> config; private final ModpackConfiguration<ModrinthManifest> config;
private final List<Task<?>> dependents = new ArrayList<>(4); private final List<Task<?>> dependents = new ArrayList<>(4);
private final List<Task<?>> dependencies = new ArrayList<>(1); private final List<Task<?>> dependencies = new ArrayList<>(1);
public ModrinthInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, ModrinthManifest manifest, String name) { public ModrinthInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, ModrinthManifest manifest, String name) {
this.dependencyManager = dependencyManager; this.dependencyManager = dependencyManager;
this.zipFile = zipFile; this.zipFile = zipFile;
this.modpack = modpack; this.modpack = modpack;
this.manifest = manifest; this.manifest = manifest;
this.name = name; this.name = name;
this.repository = dependencyManager.getGameRepository(); this.repository = dependencyManager.getGameRepository();
this.run = repository.getRunDirectory(name).toFile(); this.run = repository.getRunDirectory(name);
Path json = repository.getModpackConfiguration(name); Path json = repository.getModpackConfiguration(name);
if (repository.hasVersion(name) && Files.notExists(json)) if (repository.hasVersion(name) && Files.notExists(json))
@@ -103,7 +102,7 @@ public class ModrinthInstallTask extends Task<Void> {
this.config = config; this.config = config;
List<String> subDirectories = Arrays.asList("/client-overrides", "/overrides"); List<String> subDirectories = Arrays.asList("/client-overrides", "/overrides");
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), subDirectories, any -> true, config).withStage("hmcl.modpack")); dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), subDirectories, any -> true, config).withStage("hmcl.modpack"));
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), subDirectories, manifest, ModrinthModpackProvider.INSTANCE, manifest.getName(), manifest.getVersionId(), repository.getModpackConfiguration(name).toFile()).withStage("hmcl.modpack")); dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), subDirectories, manifest, ModrinthModpackProvider.INSTANCE, manifest.getName(), manifest.getVersionId(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
dependencies.add(new ModrinthCompletionTask(dependencyManager, name, manifest)); dependencies.add(new ModrinthCompletionTask(dependencyManager, name, manifest));
} }
@@ -123,7 +122,7 @@ public class ModrinthInstallTask extends Task<Void> {
if (config != null) { if (config != null) {
// For update, remove mods not listed in new manifest // For update, remove mods not listed in new manifest
for (ModrinthManifest.File oldManifestFile : config.getManifest().getFiles()) { for (ModrinthManifest.File oldManifestFile : config.getManifest().getFiles()) {
Path oldFile = run.toPath().resolve(oldManifestFile.getPath()); Path oldFile = run.resolve(oldManifestFile.getPath());
if (!Files.exists(oldFile)) continue; if (!Files.exists(oldFile)) continue;
if (manifest.getFiles().stream().noneMatch(oldManifestFile::equals)) { if (manifest.getFiles().stream().noneMatch(oldManifestFile::equals)) {
Files.deleteIfExists(oldFile); Files.deleteIfExists(oldFile);

View File

@@ -27,16 +27,22 @@ public class ModrinthModpackExportTask extends Task<Void> {
private final DefaultGameRepository repository; private final DefaultGameRepository repository;
private final String version; private final String version;
private final ModpackExportInfo info; private final ModpackExportInfo info;
private final File modpackFile; private final Path modpackFile;
public ModrinthModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo info, File modpackFile) { public ModrinthModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo info, Path modpackFile) {
this.repository = repository; this.repository = repository;
this.version = version; this.version = version;
this.info = info.validate(); this.info = info.validate();
this.modpackFile = modpackFile; this.modpackFile = modpackFile;
onDone().register(event -> { onDone().register(event -> {
if (event.isFailed()) modpackFile.delete(); if (event.isFailed()) {
try {
Files.deleteIfExists(modpackFile);
} catch (IOException e) {
LOG.warning("Failed to delete modpack file: " + modpackFile, e);
}
}
}); });
} }
@@ -107,7 +113,7 @@ public class ModrinthModpackExportTask extends Task<Void> {
blackList.add(version + ".jar"); blackList.add(version + ".jar");
blackList.add(version + ".json"); blackList.add(version + ".json");
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker"); LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
try (Zipper zip = new Zipper(modpackFile.toPath())) { try (var zip = new Zipper(modpackFile)) {
Path runDirectory = repository.getRunDirectory(version); Path runDirectory = repository.getRunDirectory(version);
List<ModrinthManifest.File> files = new ArrayList<>(); List<ModrinthManifest.File> files = new ArrayList<>();
Set<String> filesInManifest = new HashSet<>(); Set<String> filesInManifest = new HashSet<>();
@@ -139,7 +145,7 @@ public class ModrinthModpackExportTask extends Task<Void> {
} }
zip.putDirectory(runDirectory, "client-overrides", path -> { zip.putDirectory(runDirectory, "client-overrides", path -> {
String relativePath = path.toString().replace(File.separatorChar, '/'); String relativePath = path.replace(File.separatorChar, '/');
if (filesInManifest.contains(relativePath)) { if (filesInManifest.contains(relativePath)) {
return false; return false;
} }

View File

@@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
@@ -47,11 +46,11 @@ public final class ModrinthModpackProvider implements ModpackProvider {
} }
@Override @Override
public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, File zipFile, Modpack modpack) throws MismatchedModpackTypeException { public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, Path zipFile, Modpack modpack) throws MismatchedModpackTypeException {
if (!(modpack.getManifest() instanceof ModrinthManifest)) if (!(modpack.getManifest() instanceof ModrinthManifest modrinthManifest))
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName()); throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new ModrinthInstallTask(dependencyManager, zipFile, modpack, (ModrinthManifest) modpack.getManifest(), name)); return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new ModrinthInstallTask(dependencyManager, zipFile, modpack, modrinthManifest, name));
} }
@Override @Override
@@ -59,7 +58,7 @@ public final class ModrinthModpackProvider implements ModpackProvider {
ModrinthManifest manifest = JsonUtils.fromNonNullJson(CompressingUtils.readTextZipEntry(zip, "modrinth.index.json"), ModrinthManifest.class); ModrinthManifest manifest = JsonUtils.fromNonNullJson(CompressingUtils.readTextZipEntry(zip, "modrinth.index.json"), ModrinthManifest.class);
return new Modpack(manifest.getName(), "", manifest.getVersionId(), manifest.getGameVersion(), manifest.getSummary(), encoding, manifest) { return new Modpack(manifest.getName(), "", manifest.getVersionId(), manifest.getGameVersion(), manifest.getSummary(), encoding, manifest) {
@Override @Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, java.io.File zipFile, String name) { public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
return new ModrinthInstallTask(dependencyManager, zipFile, this, manifest, name); return new ModrinthInstallTask(dependencyManager, zipFile, this, manifest, name);
} }
}; };

View File

@@ -26,9 +26,10 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.Zipper; import org.jackhuang.hmcl.util.io.Zipper;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -44,13 +45,13 @@ public class MultiMCModpackExportTask extends Task<Void> {
private final String versionId; private final String versionId;
private final List<String> whitelist; private final List<String> whitelist;
private final MultiMCInstanceConfiguration configuration; private final MultiMCInstanceConfiguration configuration;
private final File output; private final Path output;
/** /**
* @param output mod pack file. * @param output mod pack file.
* @param versionId to locate version.json * @param versionId to locate version.json
*/ */
public MultiMCModpackExportTask(DefaultGameRepository repository, String versionId, List<String> whitelist, MultiMCInstanceConfiguration configuration, File output) { public MultiMCModpackExportTask(DefaultGameRepository repository, String versionId, List<String> whitelist, MultiMCInstanceConfiguration configuration, Path output) {
this.repository = repository; this.repository = repository;
this.versionId = versionId; this.versionId = versionId;
this.whitelist = whitelist; this.whitelist = whitelist;
@@ -58,7 +59,13 @@ public class MultiMCModpackExportTask extends Task<Void> {
this.output = output; this.output = output;
onDone().register(event -> { onDone().register(event -> {
if (event.isFailed()) output.delete(); if (event.isFailed()) {
try {
Files.deleteIfExists(output);
} catch (IOException e) {
LOG.warning("Failed to delete modpack file: " + output, e);
}
}
}); });
} }
@@ -68,7 +75,7 @@ public class MultiMCModpackExportTask extends Task<Void> {
blackList.add(versionId + ".jar"); blackList.add(versionId + ".jar");
blackList.add(versionId + ".json"); blackList.add(versionId + ".json");
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker"); LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
try (Zipper zip = new Zipper(output.toPath())) { try (Zipper zip = new Zipper(output)) {
zip.putDirectory(repository.getRunDirectory(versionId), ".minecraft", path -> Modpack.acceptFile(path, blackList, whitelist)); zip.putDirectory(repository.getRunDirectory(versionId), ".minecraft", path -> Modpack.acceptFile(path, blackList, whitelist));
String gameVersion = repository.getGameVersion(versionId) String gameVersion = repository.getGameVersion(versionId)

View File

@@ -39,7 +39,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream;
@@ -77,7 +76,7 @@ import java.util.Objects;
*/ */
public final class MultiMCModpackInstallTask extends Task<MultiMCInstancePatch.ResolvedInstance> { public final class MultiMCModpackInstallTask extends Task<MultiMCInstancePatch.ResolvedInstance> {
private final File zipFile; private final Path zipFile;
private final Modpack modpack; private final Modpack modpack;
private final MultiMCInstanceConfiguration manifest; private final MultiMCInstanceConfiguration manifest;
private final String name; private final String name;
@@ -86,7 +85,7 @@ public final class MultiMCModpackInstallTask extends Task<MultiMCInstancePatch.R
private final List<Task<?>> dependencies = new ArrayList<>(); private final List<Task<?>> dependencies = new ArrayList<>();
private final DefaultDependencyManager dependencyManager; private final DefaultDependencyManager dependencyManager;
public MultiMCModpackInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, MultiMCInstanceConfiguration manifest, String name) { public MultiMCModpackInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, MultiMCInstanceConfiguration manifest, String name) {
this.zipFile = zipFile; this.zipFile = zipFile;
this.modpack = modpack; this.modpack = modpack;
this.manifest = manifest; this.manifest = manifest;
@@ -133,8 +132,8 @@ public final class MultiMCModpackInstallTask extends Task<MultiMCInstancePatch.R
} }
// TODO: Optimize unbearably slow ModpackInstallTask // TODO: Optimize unbearably slow ModpackInstallTask
dependents.add(new ModpackInstallTask<>(zipFile, run.toFile(), modpack.getEncoding(), Collections.singletonList(mcDirectory), any -> true, config).withStage("hmcl.modpack")); dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), Collections.singletonList(mcDirectory), any -> true, config).withStage("hmcl.modpack"));
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList(mcDirectory), manifest, MultiMCModpackProvider.INSTANCE, manifest.getName(), null, repository.getModpackConfiguration(name).toFile()).withStage("hmcl.modpack")); dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList(mcDirectory), manifest, MultiMCModpackProvider.INSTANCE, manifest.getName(), null, repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
} }
// Stage #1: Load all related Json-Patch from meta maven or local mod pack. // Stage #1: Load all related Json-Patch from meta maven or local mod pack.
@@ -351,7 +350,7 @@ public final class MultiMCModpackInstallTask extends Task<MultiMCInstancePatch.R
} }
private FileSystem openModpack() throws IOException { private FileSystem openModpack() throws IOException {
return CompressingUtils.readonly(zipFile.toPath()).setAutoDetectEncoding(true).setEncoding(modpack.getEncoding()).build(); return CompressingUtils.readonly(zipFile).setAutoDetectEncoding(true).setEncoding(modpack.getEncoding()).build();
} }
private static boolean testPath(Path root) { private static boolean testPath(Path root) {

View File

@@ -27,7 +27,6 @@ import org.jackhuang.hmcl.mod.ModpackUpdateTask;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@@ -47,11 +46,11 @@ public final class MultiMCModpackProvider implements ModpackProvider {
} }
@Override @Override
public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, File zipFile, Modpack modpack) throws MismatchedModpackTypeException { public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, Path zipFile, Modpack modpack) throws MismatchedModpackTypeException {
if (!(modpack.getManifest() instanceof MultiMCInstanceConfiguration)) if (!(modpack.getManifest() instanceof MultiMCInstanceConfiguration multiMCInstanceConfiguration))
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName()); throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new MultiMCModpackInstallTask(dependencyManager, zipFile, modpack, (MultiMCInstanceConfiguration) modpack.getManifest(), name)); return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new MultiMCModpackInstallTask(dependencyManager, zipFile, modpack, multiMCInstanceConfiguration, name));
} }
private static String getRootEntryName(ZipArchiveReader file) throws IOException { private static String getRootEntryName(ZipArchiveReader file) throws IOException {
@@ -86,7 +85,7 @@ public final class MultiMCModpackProvider implements ModpackProvider {
MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, instanceStream, manifest); MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, instanceStream, manifest);
return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), encoding, cfg) { return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), encoding, cfg) {
@Override @Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name) { public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
return new MultiMCModpackInstallTask(dependencyManager, zipFile, this, cfg, name); return new MultiMCModpackInstallTask(dependencyManager, zipFile, this, cfg, name);
} }
}; };

View File

@@ -43,16 +43,22 @@ public class ServerModpackExportTask extends Task<Void> {
private final DefaultGameRepository repository; private final DefaultGameRepository repository;
private final String versionId; private final String versionId;
private final ModpackExportInfo exportInfo; private final ModpackExportInfo exportInfo;
private final File modpackFile; private final Path modpackFile;
public ServerModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo exportInfo, File modpackFile) { public ServerModpackExportTask(DefaultGameRepository repository, String version, ModpackExportInfo exportInfo, Path modpackFile) {
this.repository = repository; this.repository = repository;
this.versionId = version; this.versionId = version;
this.exportInfo = exportInfo.validate(); this.exportInfo = exportInfo.validate();
this.modpackFile = modpackFile; this.modpackFile = modpackFile;
onDone().register(event -> { onDone().register(event -> {
if (event.isFailed()) modpackFile.delete(); if (event.isFailed()) {
try {
Files.deleteIfExists(modpackFile);
} catch (IOException e) {
LOG.warning("Failed to delete modpack file: " + modpackFile, e);
}
}
}); });
} }
@@ -62,7 +68,7 @@ public class ServerModpackExportTask extends Task<Void> {
blackList.add(versionId + ".jar"); blackList.add(versionId + ".jar");
blackList.add(versionId + ".json"); blackList.add(versionId + ".json");
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker"); LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
try (Zipper zip = new Zipper(modpackFile.toPath())) { try (Zipper zip = new Zipper(modpackFile)) {
Path runDirectory = repository.getRunDirectory(versionId); Path runDirectory = repository.getRunDirectory(versionId);
List<ModpackConfiguration.FileInformation> files = new ArrayList<>(); List<ModpackConfiguration.FileInformation> files = new ArrayList<>();
zip.putDirectory(runDirectory, "overrides", path -> { zip.putDirectory(runDirectory, "overrides", path -> {

View File

@@ -28,7 +28,6 @@ import org.jackhuang.hmcl.mod.ModpackInstallTask;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -38,7 +37,7 @@ import java.util.List;
public class ServerModpackLocalInstallTask extends Task<Void> { public class ServerModpackLocalInstallTask extends Task<Void> {
private final File zipFile; private final Path zipFile;
private final Modpack modpack; private final Modpack modpack;
private final ServerModpackManifest manifest; private final ServerModpackManifest manifest;
private final String name; private final String name;
@@ -46,7 +45,7 @@ public class ServerModpackLocalInstallTask extends Task<Void> {
private final List<Task<?>> dependencies = new ArrayList<>(); private final List<Task<?>> dependencies = new ArrayList<>();
private final List<Task<?>> dependents = new ArrayList<>(4); private final List<Task<?>> dependents = new ArrayList<>(4);
public ServerModpackLocalInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, ServerModpackManifest manifest, String name) { public ServerModpackLocalInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, ServerModpackManifest manifest, String name) {
this.zipFile = zipFile; this.zipFile = zipFile;
this.modpack = modpack; this.modpack = modpack;
this.manifest = manifest; this.manifest = manifest;
@@ -79,8 +78,8 @@ public class ServerModpackLocalInstallTask extends Task<Void> {
} }
} catch (JsonParseException | IOException ignore) { } catch (JsonParseException | IOException ignore) {
} }
dependents.add(new ModpackInstallTask<>(zipFile, run.toFile(), modpack.getEncoding(), Collections.singletonList("/overrides"), any -> true, config).withStage("hmcl.modpack")); dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), Collections.singletonList("/overrides"), any -> true, config).withStage("hmcl.modpack"));
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList("/overrides"), manifest, ServerModpackProvider.INSTANCE, modpack.getName(), modpack.getVersion(), repository.getModpackConfiguration(name).toFile()).withStage("hmcl.modpack")); dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList("/overrides"), manifest, ServerModpackProvider.INSTANCE, modpack.getName(), modpack.getVersion(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
} }
@Override @Override

View File

@@ -27,9 +27,9 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.TolerableValidationException; import org.jackhuang.hmcl.util.gson.TolerableValidationException;
import org.jackhuang.hmcl.util.gson.Validation; import org.jackhuang.hmcl.util.gson.Validation;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -126,7 +126,7 @@ public class ServerModpackManifest implements ModpackManifest, Validation {
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion(); .orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
return new Modpack(name, author, version, gameVersion, description, encoding, this) { return new Modpack(name, author, version, gameVersion, description, encoding, this) {
@Override @Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, File zipFile, String name) { public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
return new ServerModpackLocalInstallTask(dependencyManager, zipFile, this, ServerModpackManifest.this, name); return new ServerModpackLocalInstallTask(dependencyManager, zipFile, this, ServerModpackManifest.this, name);
} }
}; };

View File

@@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
@@ -47,11 +46,11 @@ public final class ServerModpackProvider implements ModpackProvider {
} }
@Override @Override
public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, File zipFile, Modpack modpack) throws MismatchedModpackTypeException { public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, String name, Path zipFile, Modpack modpack) throws MismatchedModpackTypeException {
if (!(modpack.getManifest() instanceof ServerModpackManifest)) if (!(modpack.getManifest() instanceof ServerModpackManifest serverModpackManifest))
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName()); throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new ServerModpackLocalInstallTask(dependencyManager, zipFile, modpack, (ServerModpackManifest) modpack.getManifest(), name)); return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new ServerModpackLocalInstallTask(dependencyManager, zipFile, modpack, serverModpackManifest, name));
} }
@Override @Override

View File

@@ -22,7 +22,6 @@ import kala.compress.archivers.zip.ZipArchiveReader;
import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.platform.OperatingSystem; import org.jackhuang.hmcl.util.platform.OperatingSystem;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
@@ -237,8 +236,8 @@ public final class CompressingUtils {
* @return the plain text content of given file. * @return the plain text content of given file.
* @throws IOException if the file is not a valid zip file. * @throws IOException if the file is not a valid zip file.
*/ */
public static String readTextZipEntry(File zipFile, String name) throws IOException { public static String readTextZipEntry(Path zipFile, String name) throws IOException {
try (ZipArchiveReader s = new ZipArchiveReader(zipFile.toPath())) { try (ZipArchiveReader s = new ZipArchiveReader(zipFile)) {
return readTextZipEntry(s, name); return readTextZipEntry(s, name);
} }
} }
@@ -269,21 +268,6 @@ public final class CompressingUtils {
} }
} }
/**
* Read the text content of a file in zip.
*
* @param file the zip file
* @param name the location of the text in zip file, something like A/B/C/D.txt
* @return the plain text content of given file.
*/
public static Optional<String> readTextZipEntryQuietly(File file, String name) {
try {
return Optional.of(readTextZipEntry(file, name));
} catch (IOException | NullPointerException e) {
return Optional.empty();
}
}
/** /**
* Read the text content of a file in zip. * Read the text content of a file in zip.
* *