Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import javafx.collections.ObservableList;
import javafx.scene.control.Skin;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.game.World;
import org.jackhuang.hmcl.mod.Datapack;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
Expand All @@ -44,13 +45,13 @@
import static org.jackhuang.hmcl.util.logging.Logger.LOG;

public final class DatapackListPage extends ListPageBase<DatapackListPageSkin.DatapackInfoObject> implements WorldManagePage.WorldRefreshable {
private final Path worldDir;
private final World world;
private final Datapack datapack;
final BooleanProperty readOnly;

public DatapackListPage(WorldManagePage worldManagePage) {
this.worldDir = worldManagePage.getWorld().getFile();
datapack = new Datapack(worldDir.resolve("datapacks"));
world = worldManagePage.getWorld();
datapack = new Datapack(world.getFile().resolve("datapacks"));
setItems(MappedObservableList.create(datapack.getPacks(), DatapackListPageSkin.DatapackInfoObject::new));
readOnly = worldManagePage.readOnlyProperty();
FXUtils.applyDragListener(this, it -> Objects.equals("zip", FileUtils.getExtension(it)),
Expand All @@ -68,7 +69,7 @@ private void installMultiDatapack(List<Path> datapackPath) {

private void installSingleDatapack(Path datapack) {
try {
this.datapack.installPack(datapack);
this.datapack.installPack(datapack, world.getGameVersion());
} catch (IOException | IllegalArgumentException e) {
LOG.warning("Unable to parse datapack file " + datapack, e);
}
Expand Down
21 changes: 17 additions & 4 deletions HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Datapack.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.Unzipper;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;

import java.io.IOException;
import java.nio.file.*;
Expand Down Expand Up @@ -57,7 +58,7 @@ public ObservableList<Pack> getPacks() {
return packs;
}

public static void installPack(Path sourceDatapackPath, Path targetDatapackDirectory) throws IOException {
public static void installPack(Path sourceDatapackPath, Path targetDatapackDirectory, GameVersionNumber gameVersionNumber) throws IOException {
boolean containsMultiplePacks;
Set<String> packs = new HashSet<>();
try (FileSystem fs = CompressingUtils.readonly(sourceDatapackPath).setAutoDetectEncoding(true).build()) {
Expand Down Expand Up @@ -106,7 +107,19 @@ public static void installPack(Path sourceDatapackPath, Path targetDatapackDirec
.setSubDirectory("/datapacks/")
.unzip();

try (FileSystem outputResourcesZipFS = CompressingUtils.createWritableZipFileSystem(targetDatapackDirectory.getParent().resolve("resources.zip"));
Path targetResourceZipPath;
// When the version cannot be obtained, the old version logic is used by default.
boolean useNewResourcePath = gameVersionNumber != null
&& gameVersionNumber.compareTo("26.1-snapshot-6") >= 0;

if (useNewResourcePath) {
Files.createDirectories(targetDatapackDirectory.getParent().resolve("resourcepacks"));
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The directory name 'resourcepacks' is hardcoded in multiple places (lines 115-116, 118). Consider extracting this as a named constant to improve maintainability and reduce the risk of typos.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还行,两处挨一块的应该不需要单独写

targetResourceZipPath = targetDatapackDirectory.getParent().resolve("resourcepacks/resources.zip");
} else {
targetResourceZipPath = targetDatapackDirectory.getParent().resolve("resources.zip");
}

try (FileSystem outputResourcesZipFS = CompressingUtils.createWritableZipFileSystem(targetResourceZipPath);
FileSystem inputPackZipFS = CompressingUtils.createReadOnlyZipFileSystem(sourceDatapackPath)) {
Path resourcesZip = inputPackZipFS.getPath("resources.zip");
if (Files.isRegularFile(resourcesZip)) {
Expand Down Expand Up @@ -138,8 +151,8 @@ public static void installPack(Path sourceDatapackPath, Path targetDatapackDirec
}
}

public void installPack(Path sourcePackPath) throws IOException {
installPack(sourcePackPath, path);
public void installPack(Path sourcePackPath, GameVersionNumber gameVersionNumber) throws IOException {
installPack(sourcePackPath, path, gameVersionNumber);
loadFromDir();
}

Expand Down