WorldEdit Schematic Entity Serialization

Discussion in 'Spigot Plugin Development' started by Lazertx, Feb 27, 2015.

  1. I have written this code based off of methods in the WorldEdit source.

    Code (Text):
        private void saveCastleSchematic(Castle castle) {
            World world = LocalWorldAdapter.adapt(new BukkitWorld(castle.getLocation().getWorld()));

            Closer closer = Closer.create();
            try {
                Region region = new CuboidRegion(
                        LocationUtil.getMinVector(castle),
                        LocationUtil.getMaxVector(castle)
                );
                Clipboard clipboard = new BlockArrayClipboard(region);
                EditSession editSession = ProjectCW.getInstance().getWorldEdit().getEditSessionFactory().getEditSession(world, 184320);
                ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
                Operations.completeLegacy(forwardExtentCopy);
                File file = new File(FilePaths.CASTLE_DATA_FOLDER, castle.getCastleID() + ".schematic");

                file.delete();

                FileOutputStream fileOutputStream = closer.register(new FileOutputStream(file));
                BufferedOutputStream bufferedOutputStream = closer.register(new BufferedOutputStream(fileOutputStream));
                ClipboardWriter writer = closer.register(ClipboardFormat.SCHEMATIC.getWriter(bufferedOutputStream));
                if (writer != null) {
                    writer.write(clipboard, editSession.getWorld().getWorldData());
                }
            } catch (IOException | MaxChangedBlocksException e) {
                System.out.println("Unable to save castle progress.");
            } finally {
                try {
                    closer.close();
                } catch (IOException e) {
                    System.out.println("Unable to save castle progress.");
                }
            }
        }
    My intention is to save the blocks within the region as well as the entities. Saving the blocks works perfectly, but I can't seem to save the entities like WorldEdit does.

    If anyone could offer some insight as to how I would go about saving the entities it would be greatly appreciated.
     
  2. @Lazertx In my plugin AreaShop I use a similar way of saving/restoring regions, and in response to your question I checked if AreaShop also saves/restores entities in the schematics: It does. So I suggest you check the code I use in AreaShop and adapt your code to use the same WorldEdit methods.

    saveRegionBlocks() method in AreaShop

    restoreRegionBlocks() method in AreaShop

    Thanks to you to let me find out that AreaShop actually supports saving/restoring entities, and also for the 'LocalWorldAdapter.adapt()' method, because I used a crude way to get the correct world before (just changed it). Something I know is that you have to use WorldEdit 6+ to use entities in schematics, but since a couple of the methods you use are for WorldEdit 6+ anyway I suppose that your testing server also uses that.

    If you have any questions about my methods then just ask.
     
  3. I am glad that you found something useful in my code. I also got my plugin working thanks to your code and I decided to make a util class for schematics that anyone could use with a couple of changes.

    Code (Text):
    package com.projectcw.util;

    import com.projectcw.ProjectCW;
    import com.projectcw.castle.Castle;
    import com.sk89q.worldedit.EditSession;
    import com.sk89q.worldedit.MaxChangedBlocksException;
    import com.sk89q.worldedit.bukkit.BukkitWorld;
    import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
    import com.sk89q.worldedit.extent.clipboard.Clipboard;
    import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
    import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
    import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
    import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
    import com.sk89q.worldedit.function.operation.Operations;
    import com.sk89q.worldedit.internal.LocalWorldAdapter;
    import com.sk89q.worldedit.regions.Region;
    import com.sk89q.worldedit.session.ClipboardHolder;
    import com.sk89q.worldedit.util.io.Closer;
    import com.sk89q.worldedit.world.World;
    import com.sk89q.worldedit.world.registry.WorldData;

    import java.io.*;

    /**
    * Created by Derek on 2/28/2015.
    * Time: 5:02 PM
    */
    public class SchematicUtil {

        public static void pasteSchematic(ClipboardHolder clipboardHolder, Castle castle) {
            ProjectCW projectCW = ProjectCW.getInstance();
            World world = LocalWorldAdapter.adapt(new BukkitWorld(projectCW.getConfigOptions().getCastleWorld()));
            Region region = clipboardHolder.getClipboard().getRegion();
            EditSession editSession = projectCW.getWorldEdit().getEditSessionFactory().getEditSession(world, region.getWidth() * region.getHeight() * region.getLength());
            editSession.enableQueue();

            try {
                Operations.completeLegacy(clipboardHolder.createPaste(editSession, editSession.getWorld().getWorldData())
                        .to(LocationUtil.getMinVector(castle))
                        .build());
            } catch (MaxChangedBlocksException e) {
                System.out.println("Too many blocks changed.");
            }

            editSession.flushQueue();
        }

        public static ClipboardHolder loadSchematic(File file, org.bukkit.World bukkitWorld) {
            World world = LocalWorldAdapter.adapt(new BukkitWorld(bukkitWorld));
            WorldData worldData = world.getWorldData();
            Closer closer = Closer.create();

            try {
                FileInputStream fileInputStream = closer.register(new FileInputStream(file));
                BufferedInputStream bufferedInputStream = closer.register(new BufferedInputStream(fileInputStream));
                ClipboardReader clipboardReader = ClipboardFormat.SCHEMATIC.getReader(bufferedInputStream);
                ClipboardHolder clipboardHolder = new ClipboardHolder(clipboardReader.read(worldData), worldData);

                clipboardHolder.getClipboard().setOrigin(clipboardHolder.getClipboard().getMinimumPoint());
                return clipboardHolder;
            } catch (IOException e) {
                System.out.println("Unable to load schematic file " + file.getPath());
                e.printStackTrace();
            } finally {
                try {
                    closer.close();
                } catch (IOException ignored) {
                }
            }
            return null;
        }

        public static void saveSchematic(File file, Region region, World world) {
            Clipboard clipboard = new BlockArrayClipboard(region);
            clipboard.setOrigin(region.getMinimumPoint());
            EditSession editSession = ProjectCW.getInstance().getWorldEdit().getEditSessionFactory().getEditSession(world, region.getWidth() * region.getHeight() * region.getLength());
            ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
            forwardExtentCopy.setRemovingEntities(true);
            Closer closer = Closer.create();

            try {
                Operations.completeLegacy(forwardExtentCopy);

                FileOutputStream fileOutputStream = closer.register(new FileOutputStream(file));
                BufferedOutputStream bufferedOutputStream = closer.register(new BufferedOutputStream(fileOutputStream));
                ClipboardWriter clipboardWriter = closer.register(ClipboardFormat.SCHEMATIC.getWriter(bufferedOutputStream));
                if (clipboardWriter != null) {
                    file.delete();
                    clipboardWriter.write(clipboard, editSession.getWorld().getWorldData());
                }
            } catch (IOException | MaxChangedBlocksException e) {
                System.out.println("Unable to save schematic " + file.getPath() + ".");
            } finally {
                try {
                    closer.close();
                } catch (IOException e) {
                    System.out.println("Unable to save schematic " + file.getPath() + ".");
                }
            }
        }
    }
     
     
    • Like Like x 2