Development Assistance How to regenerate a map?

Discussion in 'Plugin Help/Development/Requests' started by quinster08, Jun 27, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    quinster08

    Helo,

    I'm creating a minigame and I want to regenerate a entire built map. How to do so? Please help me! :D
     
  2. Offline

    terturl890

    You could use WorldEdit and just have the map be a Schematic. And when the game is done, get the selection and repaste it at the spot you set the map as. The great thing is the Schematic will paste over the old one so you wont have to delete/check if there is something there.

    A more harder way would to iterate through every block in the map and reset the block.... but that might be a bit server intensive.
     
  3. Offline

    xTrollxDudex

    0.0

    @quinster08
    Use the seed and remove, then create the world again
     
  4. Offline

    terturl890

    Schematics would be good for a built map. What if the map is not a whole world? Just a little section. Most mini-games have little arenas built.
     
  5. If the map contains buildings that you want to keep, if they're small, just use a schematic. If not or you just want an alternative, what I do is (even though it's fairly intensive and I'm sure this isn't the best way, just a suggestion if no other alternatives):
    1. Put the map folder in /plugins/PluginName/Map
    2. In the plugin, when wanting to regenerate the map, I first disable the mini-game arena (prevent players from joining the world).
    3. Then I unload the arena world using Bukkit.getServer().unloadWorld(world, false);
    4. Then I delete the world folder, obtained through world.getWorldFolder(). I delete it using a custom method, as File#delete doesn't work on folders, only files.
    5. Then I copy the folder from the /plugin/PluginName/ folder (Map) to the world folder using the code, making sure that 'uid.dat', 'session.lock' and player data isn't copied. In the first place, to make it easier, you could just delete 'uid.dat', 'session.lock', 'playerdata' and 'stats' from the Map folder.
    6. Then I load the world using Bukkit.getServer().createWorld(WorldCreator.name(worldName));

    Here's my FileUtilities class, containing the methods to copy a directory and delete a directory.
    Credit for FileUtilities#copyDirectory(final Path source, final Path target) goes to someone from StackOverflow.
    Code:
    import java.io.*;
    import java.nio.ByteBuffer;
    import java.nio.file.*;
    import java.nio.file.attribute.*;
    import java.util.EnumSet;
    
    public class FileUtilities {
    
        public static void copyFolder(File sourceDir, File destinationDir, String... ignoredFiles) throws IOException {
            if (sourceDir != null && destinationDir != null && sourceDir.exists()) {
                copyDirectory(sourceDir.toPath(), destinationDir.toPath());
                if (ignoredFiles != null) {
                    for (String ignoredFilePath : ignoredFiles) {
                        File ignoredFile = new File(destinationDir, ignoredFilePath);
                        if (ignoredFile.exists()) delete(ignoredFile);
                    }
                }
            }
        }
    
        private static void copyDirectory(final Path source, final Path target) throws IOException {
            Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new FileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes sourceBasic) throws IOException {
                    Path targetDir = Files.createDirectories(target.resolve(source.relativize(dir)));
                    AclFileAttributeView acl = Files.getFileAttributeView(dir, AclFileAttributeView.class);
                    if (acl != null) Files.getFileAttributeView(targetDir, AclFileAttributeView.class).setAcl(acl.getAcl());
                    DosFileAttributeView dosAttrs = Files.getFileAttributeView(dir, DosFileAttributeView.class);
                    if (dosAttrs != null) {
                        DosFileAttributes sourceDosAttrs = dosAttrs.readAttributes();
                        DosFileAttributeView targetDosAttrs = Files.getFileAttributeView(targetDir, DosFileAttributeView.class);
                        targetDosAttrs.setArchive(sourceDosAttrs.isArchive());
                        targetDosAttrs.setHidden(sourceDosAttrs.isHidden());
                        targetDosAttrs.setReadOnly(sourceDosAttrs.isReadOnly());
                        targetDosAttrs.setSystem(sourceDosAttrs.isSystem());
                    }
                    FileOwnerAttributeView ownerAttrs = Files.getFileAttributeView(dir, FileOwnerAttributeView.class);
                    if (ownerAttrs != null) {
                        FileOwnerAttributeView targetOwner = Files.getFileAttributeView(targetDir, FileOwnerAttributeView.class);
                        targetOwner.setOwner(ownerAttrs.getOwner());
                    }
                    PosixFileAttributeView posixAttrs = Files.getFileAttributeView(dir, PosixFileAttributeView.class);
                    if (posixAttrs != null) {
                        PosixFileAttributes sourcePosix = posixAttrs.readAttributes();
                        PosixFileAttributeView targetPosix = Files.getFileAttributeView(targetDir, PosixFileAttributeView.class);
                        targetPosix.setPermissions(sourcePosix.permissions());
                        targetPosix.setGroup(sourcePosix.group());
                    }
                    UserDefinedFileAttributeView userAttrs = Files.getFileAttributeView(dir, UserDefinedFileAttributeView.class);
                    if (userAttrs != null) {
                        UserDefinedFileAttributeView targetUser = Files.getFileAttributeView(targetDir, UserDefinedFileAttributeView.class);
                        for (String key : userAttrs.list()) {
                            ByteBuffer buffer = ByteBuffer.allocate(userAttrs.size(key));
                            userAttrs.read(key, buffer);
                            buffer.flip();
                            targetUser.write(key, buffer);
                        }
                    }
                    BasicFileAttributeView targetBasic = Files.getFileAttributeView(targetDir, BasicFileAttributeView.class);
                    targetBasic.setTimes(sourceBasic.lastModifiedTime(), sourceBasic.lastAccessTime(), sourceBasic.creationTime());
                    return FileVisitResult.CONTINUE;
                }
    
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.copy(file, target.resolve(source.relativize(file)), StandardCopyOption.COPY_ATTRIBUTES);
                    return FileVisitResult.CONTINUE;
                }
    
                @Override
                public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {
                    throw e;
                }
    
                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
                    if (e != null) throw e;
                    return FileVisitResult.CONTINUE;
                }
            });
        }
    
        public static void delete(File source) {
            if (source.isDirectory()) {
                File[] dirFiles = source.listFiles();
                if (dirFiles != null) {
                    for (File subFile : dirFiles) delete(subFile);
                }
            }
            source.delete();
        }
    
    }
    
    Then, an example usage:
    Code:
    String arenaWorldName = "Arena1";
    World arenaWorld = Bukkit.getServer().getWorld(arenaWorldName);
    if (arenaWorld != null) {
        File arenaFolder = arenaWorld.getWorldFolder();
        Bukkit.getServer().unloadWorld(arenaWorld, false);
        FileUtilities.delete(arenaFolder);
    } else {
        arenaWorld = new File(Bukkit.getServer().getWorldContainer(), arenaWorldName);
    }
    
    File mapFolder = new File(plugin.getDataFolder(), "Map");
    if (mapFolder.exists()) {
        FileUtilities.copyFolder(mapFolder, arenaFolder,  "uid.dat", "session.lock", "playerdata", "stats");
    }
    Bukkit.getServer().createWorld(WorldCreator.name(arenaWorldName));
    
     
    Last edited: Jun 30, 2015
    quinster08 likes this.
Thread Status:
Not open for further replies.

Share This Page