diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java index 4039d37a8..beb058876 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java @@ -10,9 +10,7 @@ import javafx.collections.ObservableList; import org.jackhuang.hmcl.util.*; import java.io.IOException; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.nio.file.Path; +import java.nio.file.*; import java.util.*; import java.util.logging.Level; @@ -48,7 +46,40 @@ public class Datapack { } if (isMultiple) { - new Unzipper(path, worldPath).setReplaceExistentFile(true).unzip(); + new Unzipper(path, worldPath) + .setReplaceExistentFile(true) + .setFilter(new Unzipper.FileFilter() { + @Override + public boolean accept(Path destPath, boolean isDirectory, Path zipEntry, String entryPath) { + // We will merge resources.zip instead of replacement. + return !entryPath.equals("resources.zip"); + } + }) + .unzip(); + + try (FileSystem dest = CompressingUtils.createWritableZipFileSystem(worldPath.resolve("resources.zip")); + FileSystem zip = CompressingUtils.createReadOnlyZipFileSystem(path)) { + Path resourcesZip = zip.getPath("resources.zip"); + if (Files.isRegularFile(resourcesZip)) { + Path temp = Files.createTempFile("hmcl", ".zip"); + Files.copy(resourcesZip, temp, StandardCopyOption.REPLACE_EXISTING); + try (FileSystem resources = CompressingUtils.createReadOnlyZipFileSystem(temp)) { + FileUtils.copyDirectory(resources.getPath("/"), dest.getPath("/")); + } + } + Path packMcMeta = dest.getPath("pack.mcmeta"); + Files.write(packMcMeta, Arrays.asList("{", + "\t\"pack\": {", + "\t\t\"pack_format\": 4,", + "\t\t\"description\": \"Modified by HMCL.\"", + "\t}", + "}"), StandardOpenOption.CREATE); + + + Path packPng = dest.getPath("pack.png"); + if (Files.isRegularFile(packPng)) + Files.delete(packPng); + } } else { FileUtils.copyFile(path.toFile(), datapacks.resolve(FileUtils.getName(path)).toFile()); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CompressingUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CompressingUtils.java index 4997a73d3..85f2ace76 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CompressingUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CompressingUtils.java @@ -74,7 +74,7 @@ public final class CompressingUtils { // Since Java 8 throws ZipError stupidly throw new ZipException(error.getMessage()); } catch (UnsupportedOperationException ex) { - throw new IOException("Not a zip file"); + throw new IOException("Not a zip file", ex); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java index 91c3e5d32..2b2274c6f 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java @@ -118,7 +118,7 @@ public final class FileUtils { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Path destFile = dest.resolve(src.relativize(file)); - Files.copy(file, destFile); + Files.copy(file, destFile, StandardCopyOption.REPLACE_EXISTING); return FileVisitResult.CONTINUE; } @@ -126,7 +126,7 @@ public final class FileUtils { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { Path destDir = dest.resolve(src.relativize(dir)); - Files.createDirectory(destDir); + Files.createDirectories(destDir); return FileVisitResult.CONTINUE; }