diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java index 599ce7cb9..ee2c149f0 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java @@ -7,6 +7,7 @@ package com.onarandombox.MultiverseCore.api; +import com.onarandombox.MultiverseCore.enums.WorldDeleteMode; import com.onarandombox.MultiverseCore.utils.PurgeWorlds; import com.onarandombox.MultiverseCore.utils.SimpleWorldPurger; import org.bukkit.World; @@ -108,12 +109,24 @@ boolean addWorld(String name, Environment env, String seedString, WorldType type * @param name The name of the world to remove * @param removeFromConfig If true(default), we'll remove the entries from the * config. If false, they'll stay and the world may come back. - * @param deleteWorldFolder If true the world folder will be completely deleted. If false + * @param deleteWorldFolder If true, the world folder will be completely deleted. If false, * only the contents of the world folder will be deleted * @return True if success, false if failure. + * @deprecated Use {@link MVWorldManager#deleteWorld(String, boolean, WorldDeleteMode)} */ + @Deprecated boolean deleteWorld(String name, boolean removeFromConfig, boolean deleteWorldFolder); + /** + * + * @param name The world name + * @param removeFromConfig If true(default), we'll remove the entires from the + * config. If false, they'll stay and the world may come back. + * @param whatToDelete What files or folders should be deleted. + * @return True if success, false if failure. + */ + boolean deleteWorld(String name, boolean removeFromConfig, WorldDeleteMode whatToDelete); + /** * Unload a world from Multiverse. * diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java index 4efe7ad51..8361ed517 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java @@ -41,7 +41,8 @@ public RegenCommand(MultiverseCore plugin) { public void runCommand(CommandSender sender, List args) { String worldName = args.get(0); boolean useseed = (!(args.size() == 1)); - boolean randomseed = (args.size() == 2 && args.get(1).equalsIgnoreCase("-s")); + boolean randomseed = (args.size() == 2 && args.get(1).equalsIgnoreCase("-s")) || + (args.size() == 3 && args.get(2).equalsIgnoreCase("--keep-gamerules")); String seed = (args.size() == 3) ? args.get(2) : ""; boolean keepGamerules = CommandHandler.hasFlag("--keep-gamerules", args); this.plugin.getCommandQueueManager().addToQueue(new QueuedCommand( diff --git a/src/main/java/com/onarandombox/MultiverseCore/enums/WorldDeleteMode.java b/src/main/java/com/onarandombox/MultiverseCore/enums/WorldDeleteMode.java new file mode 100644 index 000000000..7f1f5ce97 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/enums/WorldDeleteMode.java @@ -0,0 +1,19 @@ +package com.onarandombox.MultiverseCore.enums; + +/** + * Custom enum for method argument in deciding what to delete when deleting a world + */ +public enum WorldDeleteMode { + /** + * Delete all contents in the directory except for Paper's configuration file. + */ + WORLD, + /** + * Delete all contents in the directory. + */ + CONFIG_AND_WORLD, + /** + * Delete everything, including the directory. + */ + ALL +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/FileUtils.java b/src/main/java/com/onarandombox/MultiverseCore/utils/FileUtils.java index 571143bb8..a13a610eb 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/FileUtils.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/FileUtils.java @@ -68,6 +68,19 @@ public static boolean deleteFolderContents(File file) { } } + public static boolean deleteWorldContents(File file) { + try (Stream files = Files.walk(file.toPath())){ + files.sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .filter(f -> !f.equals(file) && !f.getName().equals("paper-world.yml")) + .forEach(File::delete); + return true; + } catch (IOException e) { + Logging.warning(e.getMessage()); + return false; + } + } + /** * Helper method to copy the world-folder. * @param source Source-File diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java index 0b2ab0701..0560aeb2b 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java @@ -16,6 +16,7 @@ import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.SafeTTeleporter; import com.onarandombox.MultiverseCore.api.WorldPurger; +import com.onarandombox.MultiverseCore.enums.WorldDeleteMode; import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent; import org.bukkit.Bukkit; import org.bukkit.GameRule; @@ -48,7 +49,6 @@ import java.util.Stack; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -505,7 +505,7 @@ private boolean doLoad(WorldCreator creator, boolean ignoreExists) { * {@inheritDoc} */ @Override - public boolean deleteWorld(String name, boolean removeFromConfig, boolean deleteWorldFolder) { + public boolean deleteWorld(String name, boolean removeFromConfig, WorldDeleteMode whatToDelete) { if (this.hasUnloadedWorld(name, false)) { // Attempt to load if unloaded so we can actually delete the world if (!this.doLoad(name)) { @@ -540,7 +540,17 @@ public boolean deleteWorld(String name, boolean removeFromConfig, boolean delete try { File worldFile = world.getWorldFolder(); Logging.finer("deleteWorld(): worldFile: " + worldFile.getAbsolutePath()); - if (deleteWorldFolder ? FileUtils.deleteFolder(worldFile) : FileUtils.deleteFolderContents(worldFile)) { + boolean success; + + if (whatToDelete.equals(WorldDeleteMode.CONFIG_AND_WORLD)) { + success = FileUtils.deleteFolderContents(worldFile); + } else if (whatToDelete.equals(WorldDeleteMode.WORLD)) { + success = FileUtils.deleteWorldContents(worldFile); + } else { + success = FileUtils.deleteFolder(worldFile); + } + + if (success) { Logging.info("World '%s' was DELETED.", name); return true; } else { @@ -559,6 +569,14 @@ public boolean deleteWorld(String name, boolean removeFromConfig, boolean delete } } + /** + * {@inheritDoc} + */ + @Override + public boolean deleteWorld(String name, boolean removeFromConfig, boolean deleteWorldFolder) { + return this.deleteWorld(name, removeFromConfig, deleteWorldFolder ? WorldDeleteMode.ALL : WorldDeleteMode.CONFIG_AND_WORLD); + } + /** * {@inheritDoc} */ @@ -947,7 +965,7 @@ public boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, S } // Do the regen. - if (!this.deleteWorld(name, false, false)) { + if (!this.deleteWorld(name, false, WorldDeleteMode.WORLD)) { Logging.severe("Unable to regen world as world cannot be deleted."); return false; } @@ -971,6 +989,11 @@ public boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, S } } + // If using a new seed, you will most definitely want the same spawn the world uses. + if (useNewSeed && !world.getSpawnLocation().equals(world.getCBWorld().getSpawnLocation())) { + world.setSpawnLocation(world.getCBWorld().getSpawnLocation()); + } + // Send all players that were in the old world, BACK to it! SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter(); Location newSpawn = world.getSpawnLocation();