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) {
|
public Result seed(TrackedWorld world, long minInhabitedTicks, Consumer<String> log) {
|
||||||
List<Path> files = new ArrayList<>();
|
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")) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(world.regionDir(), "r.*.mca")) {
|
||||||
for (Path p : stream) {
|
for (Path p : stream) {
|
||||||
files.add(p);
|
files.add(p);
|
||||||
|
|||||||
@@ -63,20 +63,34 @@ public final class TrackedWorld {
|
|||||||
// ---------------------------------------------------------------- layout
|
// ---------------------------------------------------------------- layout
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locates the {@code region/} directory. Paper 26.x keeps every dimension,
|
* Locates the {@code region/} directory.
|
||||||
* the main overworld included, under {@code <main>/dimensions/<ns>/<path>/};
|
*
|
||||||
* older layouts are probed after that so a migrated server still works.
|
* <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) {
|
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<>();
|
List<Path> candidates = new ArrayList<>();
|
||||||
String ns = world.getKey().getNamespace();
|
String ns = world.getKey().getNamespace();
|
||||||
String path = world.getKey().getKey();
|
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();
|
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"));
|
candidates.add(own.resolve("dimensions").resolve(ns).resolve(path).resolve("region"));
|
||||||
switch (world.getEnvironment()) {
|
switch (world.getEnvironment()) {
|
||||||
case NETHER -> candidates.add(own.resolve("DIM-1").resolve("region"));
|
case NETHER -> candidates.add(own.resolve("DIM-1").resolve("region"));
|
||||||
@@ -89,7 +103,7 @@ public final class TrackedWorld {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return nms != null ? nms : candidates.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------- layers
|
// ---------------------------------------------------------------- layers
|
||||||
|
|||||||
Reference in New Issue
Block a user