Solved Cloning Worlds (1.8.8)

Discussion in 'Plugin Development' started by Lightcaster5, Jun 28, 2020.

  1. Offline

    Lightcaster5

    I have been trying for some time to clone a world, specifically to be used in a minigame. The map is too big for a schematic so I am trying to just clone an untouched, original world to a world that players actually join and play in. For those who will suggest it, I have tried this which gives me LOTS of chunk errors, I have also tried using Multiverse's API, the cloneWorld(String oldName, String newName, String generator) returns errors because something is null in the API. If anyone has working methods of cloning a world, or any suggestions to fix any errors discussed above, I would be thankful to know.
     
  2. Offline

    caderapee

    @Lightcaster5 Since copying file need to play with outputstream and it's not easy to figure , here u go
    https://pastebin.com/SxMxsLij
    Get the folder of the map into a file, create a new folder in the same repertory with the name of your world, then use the method copyFolder()
     
  3. Offline

    Lightcaster5

    Thanks but will I still have to remove the uid.dat file from the newly created world?

    EDIT: Just as I suspected... chunk errors galore!
    Code:
    Code:
        public static void resetWorld(Integer gameID) {
            String resetMapName = Main.plugin.getConfig().getString("maps." + gameID + ".reset-map-name");
            World source = Bukkit.getWorld(resetMapName);
            File sourceFolder = source.getWorldFolder();
    
            File target = new File(gameID.toString());
    
            copyFolder(sourceFolder, target);
        }
    This chunk that the console is spammed with is repeated when joining and leaving the new world:
    Code:
    Couldn't save chunk; already in use by another instance of Minecraft?
    net.minecraft.server.v1_8_R3.ExceptionWorldConflict: The save for world located at .\1 is being accessed from another location, aborting
            at net.minecraft.server.v1_8_R3.WorldNBTStorage.checkSession(WorldNBTStorage.java:72) ~[Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.World.checkSession(World.java:2824) ~[Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.ChunkRegionLoader.a(ChunkRegionLoader.java:120) ~[Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.ChunkProviderServer.saveChunk(ChunkProviderServer.java:251) [Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.ChunkProviderServer.unloadChunks(ChunkProviderServer.java:357) [Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.WorldServer.doTick(WorldServer.java:234) [Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:770) [Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [Spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_251]
    After a lot of struggle and finally finding and piecing together parts that work, I have found a solution. After running and testing the final code several times, I am very happy to say there are no chunk errors!

    Here is the code:
    Code:
        private static void copyFileStructure(File source, File target) {
            try {
                ArrayList<String> ignore = new ArrayList<>(Arrays.asList("uid.dat", "session.lock"));
                if (!ignore.contains(source.getName())) {
                    if (source.isDirectory()) {
                        if (!target.exists())
                            if (!target.mkdirs())
                                throw new IOException("Couldn't create world directory!");
                        String files[] = source.list();
                        for (String file : files) {
                            File srcFile = new File(source, file);
                            File destFile = new File(target, file);
                            copyFileStructure(srcFile, destFile);
                        }
                    } else {
                        InputStream in = new FileInputStream(source);
                        OutputStream out = new FileOutputStream(target);
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = in.read(buffer)) > 0)
                            out.write(buffer, 0, length);
                        in.close();
                        out.close();
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        public static void copyWorld(World originalWorld, String newWorldName) {
            File copiedFile = new File(Bukkit.getWorldContainer(), newWorldName);
            copyFileStructure(originalWorld.getWorldFolder(), copiedFile);
            new WorldCreator(newWorldName).createWorld();
        }
    Usage:

    Code:
    copyWorld(Bukkit.getWorld("OriginalMap"), "CopiedMap");
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 30, 2020

Share This Page