[Code Snippets] Copy Worlds

Discussion in 'Spigot Plugin Development' started by DotRar, May 17, 2015.

  1. Hey, I wanted to share something cool I created earlier today, it copies your worlds from a template, very useful for minigames where you can build.

    First of all, you want to get your world files and put them in your server directory, under a directory names "backup" (You can change this if you want). Here's an example:
    http://imgur.com/OrhZZLQ (The images are big, so I won't be pasting the image into the thread.)

    Now open up your IDE and create a new project. Once you've done that, create we'll start working on our methods. Your code should currently look a little like this:
    Code (Text):
    package net.ultimamc.copy;

    import org.bukkit.plugin.java.JavaPlugin;

    public class Main extends JavaPlugin {
     
        public void onEnable() {
         
        }
     
        public void onDisable() {
         
        }
     
        public void copy() {
         
        }
    }
     

    We'll start with the copy() method:

    First, let's get the plugins data folder.
    Code (Text):
    File dataFolder = new File(this.getDataFolder().getPath());
    And turn it into a string:
    Code (Text):
    String strData = dataFolder.toString();
    Now let's split the string up using File.pathSeperator instead of "/", as some operating systems do not use "/". File.seperator works for all operating systems.
    Code (Text):
    String[] split = strData.toString().split(File.pathSeparator);
    Now get the server directory, we do this by finding a bit of the string array we made.
    Code (Text):
    String rootFolder = split[split.length - 3];
    Finally turn it into a file.
    Code (Text):
    File root = new File(rootFolder);
    Your code should now look like this:
    Code (Text):
    package net.ultimamc.copy;

    import java.io.File;
    import java.io.IOException;

    import org.apache.commons.io.FileUtils;
    import org.bukkit.Bukkit;
    import org.bukkit.WorldCreator;
    import org.bukkit.plugin.java.JavaPlugin;

    public class Main extends JavaPlugin {
     
        public void onEnable() {
         
        }
     
        public void onDisable() {
         
        }
     
        public void copy() {
            File dataFolder = new File(this.getDataFolder().getPath());
            String strData = dataFolder.toString();
            String[] split = strData.toString().split(File.pathSeparator);
            String rootFolder = split[split.length - 3];
            File root = new File(rootFolder);

    We'll now continue with the copy method, we'll add the copying part now:

    We'll locate the backup folder location.
    Code (Text):
    File srcDir = new File(root+File.pathSeparator+"backup");
    And obviously check if it exists.
    Code (Text):
    if (!srcDir.exists()) {
        Bukkit.getLogger().warning("Backup does not exist!");
        return;
    }
    Now, let's define the new directory, which is the server world directory, probably "world"
    Code (Text):
    File destDir = new File(root+File.pathSeparator+"world");
    Apache commons has a nice FileUtils class that we can use, but it can throw an IOException.
    Code (Text):
    try {
        FileUtils.copyDirectory(srcDir, destDir);
    } catch (IOException ex) {
         ex.printStackTrace();
    }
    And finally, set up the world.
    Code (Text):
    Bukkit.getServer().createWorld(new WorldCreator("world"));
    You'll want to call this, in your onEnable method, so add that. Your code should now look like this:
    Code (Text):
    package net.ultimamc.copy;

    import java.io.File;
    import java.io.IOException;

    import org.apache.commons.io.FileUtils;
    import org.bukkit.Bukkit;
    import org.bukkit.WorldCreator;
    import org.bukkit.plugin.java.JavaPlugin;

    public class Main extends JavaPlugin {
     
        public void onEnable() {
            copy();
        }
     
        public void onDisable() {
         
        }
     
        public void copy() {
            File dataFolder = new File(this.getDataFolder().getPath());
            String strData = dataFolder.toString();
            String[] split = strData.toString().split(File.pathSeparator);
            String rootFolder = split[split.length - 3];
            File root = new File(rootFolder);
         
            File srcDir = new File(root+File.pathSeparator+"backup");
            if (!srcDir.exists()) {
                Bukkit.getLogger().warning("Backup does not exist!");
                return;
            }
            File destDir = new File(root+File.pathSeparator+"world");
            try {
                FileUtils.copyDirectory(srcDir, destDir);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            Bukkit.getServer().createWorld(new WorldCreator("world"));
        }
    }
     

    We'll now get to work on the deleting code, so create a new void named "delete":
    Code (Text):
    public void delete() {
    }
    First, unload the world.
    Code (Text):
    Bukkit.getServer().unloadWorld("world", true);
    Getting an existing world's folder is very easy, so let's define it now.
    Code (Text):
    File dir = new File(Bukkit.getServer().getWorld("world").getWorldFolder().getPath());
    We can now delete it using Apache Common's FileUtils, but we must check for exceptions.
    Code (Text):
    try {
        FileUtils.deleteDirectory(dir);
    }
    catch (IOException ex) {
        ex.printStackTrace();
    }
    Finally, call it in your onDisable() method. Your code should like this:
    Code (Text):
    package net.ultimamc.copy;

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;

    import org.apache.commons.io.FileUtils;
    import org.bukkit.Bukkit;
    import org.bukkit.WorldCreator;
    import org.bukkit.plugin.java.JavaPlugin;

    public class Main extends JavaPlugin {
     
        public void onEnable() {
            copy();
        }
     
        public void onDisable() {
            delete();
        }
     
        public void copy() {
            File dataFolder = new File(this.getDataFolder().getPath());
            String strData = dataFolder.toString();
            String[] split = strData.toString().split(File.pathSeparator);
            String rootFolder = split[split.length - 3];
            File root = new File(rootFolder);
         
            File srcDir = new File(root+File.pathSeparator+"backup");
            if (!srcDir.exists()) {
                Bukkit.getLogger().warning("Backup does not exist!");
                return;
            }
            File destDir = new File(root+File.pathSeparator+"world");
            try {
                FileUtils.copyDirectory(srcDir, destDir);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            Bukkit.getServer().createWorld(new WorldCreator("world"));
        }
     
        public void delete() {
            Bukkit.getServer().unloadWorld("world", true);
            File dir = new File(Bukkit.getServer().getWorld("world").getWorldFolder().getPath());
            try {
                FileUtils.deleteDirectory(dir);
            }
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    Anndddd... you're done! You can now run this and it will work if you have everything correctly set up. If it doesn't work, be sure to reply to the thread.
     
  2. Found a bug, working on it.
     
  3. deleting/coping folder for minigame?? are you sure you want to do this?? wouldn't it be much smaller/faster to save schematics of the minigame arena and reload them??
     
    • Agree Agree x 2
  4. For huge maps it can cause a lot of lag, I use stuff like this too ;p, but I dont delete them I just unload without saving and load.
    @RW_Craft you can get the server's folder by calling Bukkit.getWorldContainer() :p
     
  5. well, he specifically mentioned minigames, that's why I made my post.
     
  6. A face-ground is appropriate here for me.
    [​IMG]
     
  7. Some minigames have large maps, take war lords on hypixel for example.
     
  8. then you should just copy over the original map file...not entire folder..
     
  9. Clear out player files, save space ;)
     
  10. @lapsile11 did you really have to necropost to post that smiley face?