world: resolve the region directory through the server, not by probing
Build / build (push) Successful in 1m20s
Build / build (push) Successful in 1m20s
Paper 26.x stores every dimension under <main>/dimensions/<ns>/<path>/, and the directory does not exist until the first save, so a brand-new world was reported as "no region directory found" and never tracked. Ask DimensionType.getStorageFolder for the exact path and accept that it may not exist yet; the legacy layouts are still probed for migrated servers. The seeder now treats a missing directory as an empty world. Claude-Session: https://claude.ai/code/session_011FePLXwBsCGLTzaSkk1Z6V
This commit is contained in:
@@ -45,6 +45,10 @@ public final class DiscoverySeeder {
|
||||
|
||||
public Result seed(TrackedWorld world, long minInhabitedTicks, Consumer<String> log) {
|
||||
List<Path> 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<Path> stream = Files.newDirectoryStream(world.regionDir(), "r.*.mca")) {
|
||||
for (Path p : stream) {
|
||||
files.add(p);
|
||||
|
||||
@@ -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 <main>/dimensions/<ns>/<path>/};
|
||||
* older layouts are probed after that so a migrated server still works.
|
||||
* Locates the {@code region/} directory.
|
||||
*
|
||||
* <p>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 <main>/dimensions/<ns>/<path>/}). 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<World> 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<Path> candidates = new ArrayList<>();
|
||||
String ns = world.getKey().getNamespace();
|
||||
String path = world.getKey().getKey();
|
||||
List<World> 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
|
||||
|
||||
Reference in New Issue
Block a user