Worldedit - Save/Load Schematics with entities

Discussion in 'Programming Help' started by Shadow3097, Feb 11, 2016.

  1. Shadow3097

    Shadow3097 New Member

    So i read this post here (http://forum.enginehub.org/threads/worldedit-schematic-entity-serialization.16039/) and tried to implement the saving and loading of a schematic file including the entities. However, the entities wont get moved according to the paste location and stay at their original location. Is there something i messed up with or is this the default behaviour? Here is my code (mostly taken from the example above):

    Code (Text):
    package pd;

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;

    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.entity.Player;

    import com.sk89q.worldedit.EditSession;
    import com.sk89q.worldedit.MaxChangedBlocksException;
    import com.sk89q.worldedit.Vector;
    import com.sk89q.worldedit.bukkit.BukkitWorld;
    import com.sk89q.worldedit.bukkit.selections.Selection;
    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.CuboidRegion;
    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;

    public class SchematicUtils
    {
        public static void saveSchematic(File file, Player player)
        {
            file.delete();
            Selection selection = Pixeldungeon.instance.worldEdit.getSelection(player);

            if(selection == null)
            {
                player.sendMessage(ChatColor.RED + "You didnt select anything with worledit!");
            }
           
            CuboidRegion selectedRegion = new CuboidRegion(
                    selection.getNativeMinimumPoint(),
                    selection.getNativeMaximumPoint());

            Clipboard clipboard = new BlockArrayClipboard(selectedRegion);
            clipboard.setOrigin(selectedRegion.getMinimumPoint());

            World world = LocalWorldAdapter.adapt(new BukkitWorld(player.getWorld()));
            EditSession editSession = Pixeldungeon.instance.worldEdit.getWorldEdit().getEditSessionFactory().getEditSession(world, selectedRegion.getWidth() * selectedRegion.getLength() * selectedRegion.getHeight());
            ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(editSession, selectedRegion, clipboard, selectedRegion.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));
                clipboardWriter.write(clipboard, editSession.getWorld().getWorldData());
            }
            catch (IOException | MaxChangedBlocksException e)
            {
                Pixeldungeon.instance.getLogger().severe("Unable to save schematic " + file.getPath() + ".");

            }
            finally
            {

                try
                {
                    closer.close();
                }
                catch (IOException e)
                {
                    Pixeldungeon.instance.getLogger().severe("Unable to save schematic " + file.getPath() + ".");
                }
            }
        }
       
        public static void loadSchematic(File file, Location location)
        {
            World world = LocalWorldAdapter.adapt(new BukkitWorld(location.getWorld()));
            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());
                pasteSchematic(clipboardHolder, location);
            }
            catch (IOException e)
            {
                Pixeldungeon.instance.getLogger().severe("Unable to load schematic file " + file.getPath());
                e.printStackTrace();
            }
            finally
            {
                try
                {
                    closer.close();
                }
                catch (IOException ignored) {}
            }
        }
       
        private static void pasteSchematic(ClipboardHolder clipboardHolder, Location location)
        {
            World world = LocalWorldAdapter.adapt(new BukkitWorld(location.getWorld()));
            Region region = clipboardHolder.getClipboard().getRegion();
            EditSession editSession = Pixeldungeon.instance.worldEdit.getWorldEdit().getEditSessionFactory().getEditSession(world, region.getWidth() * region.getHeight() * region.getLength());
            editSession.enableQueue();
           
            try
            {
                Operations.completeLegacy(clipboardHolder.createPaste(editSession, editSession.getWorld().getWorldData())
                        .to(new Vector(location.getBlockX(), location.getBlockY(), location.getBlockZ()))
                        .build());
            }
            catch (MaxChangedBlocksException e)
            {
                Pixeldungeon.instance.getLogger().severe("Too many blocks changed.");
            }

            editSession.flushQueue();
        }
    }
     
  2. sk89q

    sk89q Administrator Developer

    1. Does copy and paste with the commands seem to move entities correctly?
    2. After saving to and loading from a schematic as well?
    3. Do you happen to have your IDE setup for debugging a running MC server?
  3. Shadow3097

    Shadow3097 New Member

    1. Nope, i tried to copy paste and it seems that it doesnt move entities too.
    2. The pasting with schematics doesnt seem to move it too.
    3. I am testing everything on my own server, but i can set it up to work with my local server.

    From my testing, it seems that this generally happens with worldedit copy/paste.
    //Edit: I found this bug report, which is pretty much the same i am experiencing. Rotating the clipboard before pasting seems to solve the issue:
    http://dev.enginehub.org/youtrack/issue/WORLDEDIT-3275
    Last edited: Feb 13, 2016