diff --git a/paper-server/src/main/java/io/papermc/paper/world/migration/LegacyCraftBukkitWorldMigration.java b/paper-server/src/main/java/io/papermc/paper/world/migration/LegacyCraftBukkitWorldMigration.java index ba24fda2395f..d186498e9769 100644 --- a/paper-server/src/main/java/io/papermc/paper/world/migration/LegacyCraftBukkitWorldMigration.java +++ b/paper-server/src/main/java/io/papermc/paper/world/migration/LegacyCraftBukkitWorldMigration.java @@ -96,8 +96,11 @@ private void run() throws IOException { this.migrateLegacyCraftBukkitPaperData(tempStorage, levelDataResult.dataTag()); tempStorage.saveAndJoin(); } - deleteMigratedSeparateRoot(this.sourceRoot); - LOGGER.info("Completed legacy CraftBukkit import for world '{}' ({})", this.context.worldName(), this.context.dimensionKey().identifier()); + + final Path oldSourceRoot = this.sourceRoot.resolveSibling(this.sourceRoot.getFileName() + ".old"); + + Files.move(this.sourceRoot, oldSourceRoot); + LOGGER.info("Completed legacy CraftBukkit import for world '{}' ({}), the old world was moved into '{}'", this.context.worldName(), this.context.dimensionKey().identifier(), oldSourceRoot); } private void migrateSharedSavedData() throws IOException { @@ -187,18 +190,6 @@ private void copySavedDataIfPresent( WorldMigrationSupport.copySavedDataIfPresent(this.sourceDataRoots, this.targetDataRoot, type, true); } - private static void deleteMigratedSeparateRoot(final Path sourceRoot) throws IOException { - if (!Files.exists(sourceRoot)) { - return; - } - - try (final var paths = Files.walk(sourceRoot)) { - for (final Path path : paths.sorted(java.util.Comparator.reverseOrder()).toList()) { - Files.deleteIfExists(path); - } - } - } - private @Nullable Path findExplicitFile( final List dataRoots, final String... relativeCandidates diff --git a/paper-server/src/main/java/io/papermc/paper/world/migration/WorldMigrationSupport.java b/paper-server/src/main/java/io/papermc/paper/world/migration/WorldMigrationSupport.java index f961539a3e38..48d8e58cdcf0 100644 --- a/paper-server/src/main/java/io/papermc/paper/world/migration/WorldMigrationSupport.java +++ b/paper-server/src/main/java/io/papermc/paper/world/migration/WorldMigrationSupport.java @@ -8,7 +8,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.NbtException; @@ -88,6 +90,9 @@ static void migrateDimensionDirectories(final Path sourceDimensionRoot, final Pa return; } + boolean pathsWithConflicts = false; + final HashMap migrationPaths = new HashMap<>(); + for (final String directory : DIMENSION_DIRECTORIES) { final Path source = sourceDimensionRoot.resolve(directory); if (!Files.exists(source)) { @@ -95,38 +100,21 @@ static void migrateDimensionDirectories(final Path sourceDimensionRoot, final Pa } final Path target = targetDimensionPath.resolve(directory); - LOGGER.info("Migrating world directory from {} to {}", source, target); - mergeMove(source, target); - } - } - - private static void mergeMove(final Path source, final Path target) throws IOException { - if (Files.isDirectory(source)) { - Files.createDirectories(target); - try (final var entries = Files.list(source)) { - for (final Path child : entries.toList()) { - mergeMove(child, target.resolve(child.getFileName().toString())); - } + if (Files.exists(target)) { + pathsWithConflicts = true; + LOGGER.error("The folder '{}' already exists for dimension {}", directory, targetDimensionPath); + continue; } - tryDeleteIfEmpty(source); - return; + migrationPaths.put(source, target); } - if (Files.exists(target)) { - throw new IOException("Refusing to overwrite existing migrated file " + target + " while moving " + source); + if (pathsWithConflicts) { + throw new IOException("Refusing to overwrite dimension directories in " + targetDimensionPath + " while migrating from " + sourceDimensionRoot); } - Files.createDirectories(target.getParent()); - Files.move(source, target); - } - - private static void tryDeleteIfEmpty(final Path path) throws IOException { - try (final var entries = Files.list(path)) { - if (entries.findAny().isPresent()) { - return; - } + for (Map.Entry entry : migrationPaths.entrySet()) { + Files.move(entry.getKey(), entry.getValue()); } - Files.deleteIfExists(path); } record LevelDataResult(@Nullable Dynamic dataTag, boolean fatalError) {}