diff --git a/src/main/java/lv/janhouse/mapsyncer/discovery/DiscoverySeeder.java b/src/main/java/lv/janhouse/mapsyncer/discovery/DiscoverySeeder.java index e893ca3..7cf1975 100644 --- a/src/main/java/lv/janhouse/mapsyncer/discovery/DiscoverySeeder.java +++ b/src/main/java/lv/janhouse/mapsyncer/discovery/DiscoverySeeder.java @@ -45,6 +45,10 @@ public final class DiscoverySeeder { public Result seed(TrackedWorld world, long minInhabitedTicks, Consumer log) { List files = new ArrayList<>(); + if (!Files.isDirectory(world.regionDir())) { + // Brand-new world: nothing has been saved yet. + return new Result(0, 0, 0, false); + } try (DirectoryStream stream = Files.newDirectoryStream(world.regionDir(), "r.*.mca")) { for (Path p : stream) { files.add(p); diff --git a/src/main/java/lv/janhouse/mapsyncer/world/TrackedWorld.java b/src/main/java/lv/janhouse/mapsyncer/world/TrackedWorld.java index 1e36fa8..8cca194 100644 --- a/src/main/java/lv/janhouse/mapsyncer/world/TrackedWorld.java +++ b/src/main/java/lv/janhouse/mapsyncer/world/TrackedWorld.java @@ -63,20 +63,34 @@ public final class TrackedWorld { // ---------------------------------------------------------------- layout /** - * Locates the {@code region/} directory. Paper 26.x keeps every dimension, - * the main overworld included, under {@code
/dimensions///}; - * older layouts are probed after that so a migrated server still works. + * Locates the {@code region/} directory. + * + *

Asks the server for the dimension's storage folder (Paper 26.x keeps + * every dimension, the main overworld and Bukkit's extra worlds included, + * under {@code

/dimensions///}). The directory may not exist + * yet for a brand-new world; that is fine, it simply has no region files. + * Older layouts are probed only if the server's answer does not exist and + * one of them does, so a migrated server keeps working. */ static Path findRegionDir(World world) { + List worlds = Bukkit.getWorlds(); + Path main = worlds.isEmpty() ? world.getWorldFolder().toPath() : worlds.get(0).getWorldFolder().toPath(); + Path nms = null; + try { + var level = ((org.bukkit.craftbukkit.CraftWorld) world).getHandle(); + nms = net.minecraft.world.level.dimension.DimensionType.getStorageFolder(level.dimension(), main) + .resolve("region"); + } catch (RuntimeException | LinkageError e) { + // Fall through to probing. + } + if (nms != null && Files.isDirectory(nms)) { + return nms; + } List candidates = new ArrayList<>(); String ns = world.getKey().getNamespace(); String path = world.getKey().getKey(); - List worlds = Bukkit.getWorlds(); - Path main = worlds.isEmpty() ? null : worlds.get(0).getWorldFolder().toPath(); Path own = world.getWorldFolder().toPath(); - if (main != null) { - candidates.add(main.resolve("dimensions").resolve(ns).resolve(path).resolve("region")); - } + candidates.add(main.resolve("dimensions").resolve(ns).resolve(path).resolve("region")); candidates.add(own.resolve("dimensions").resolve(ns).resolve(path).resolve("region")); switch (world.getEnvironment()) { case NETHER -> candidates.add(own.resolve("DIM-1").resolve("region")); @@ -89,7 +103,7 @@ public final class TrackedWorld { return c; } } - return null; + return nms != null ? nms : candidates.get(0); } // ---------------------------------------------------------------- layers