Search in sources :

Example 1 with FaweOutputStream

use of com.fastasyncworldedit.core.internal.io.FaweOutputStream in project FastAsyncWorldEdit by IntellectualSites.

the class ChunkPacket method apply.

@Override
public byte[] apply(byte[] buffer) {
    try {
        byte[] sectionBytes = getSectionBytes();
        FastByteArrayOutputStream baos = new FastByteArrayOutputStream(buffer);
        FaweOutputStream fos = new FaweOutputStream(baos);
        fos.writeInt(this.chunkX);
        fos.writeInt(this.chunkZ);
        fos.writeBoolean(this.full);
        fos.writeVarInt(getChunk().getBitMask());
        fos.writeNBT("", getHeightMap());
        fos.writeVarInt(sectionBytes.length);
        fos.write(sectionBytes);
        // TODO entities / NBT
        // Set<CompoundTag> entities = chunk.getEntities();
        // Map<BlockVector3, CompoundTag> tiles = chunk.getTiles();
        // (Entities / NBT)
        fos.writeVarInt(0);
        return baos.toByteArray();
    } catch (Throwable e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}
Also used : FastByteArrayOutputStream(com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream) FaweOutputStream(com.fastasyncworldedit.core.internal.io.FaweOutputStream)

Example 2 with FaweOutputStream

use of com.fastasyncworldedit.core.internal.io.FaweOutputStream in project FastAsyncWorldEdit by IntellectualSites.

the class FastSchematicWriter method write2.

/**
 * Writes a version 2 schematic file.
 *
 * @param clipboard The clipboard
 */
private void write2(Clipboard clipboard) throws IOException {
    Region region = clipboard.getRegion();
    BlockVector3 origin = clipboard.getOrigin();
    BlockVector3 min = region.getMinimumPoint();
    BlockVector3 offset = min.subtract(origin);
    int width = region.getWidth();
    int height = region.getHeight();
    int length = region.getLength();
    if (width > MAX_SIZE) {
        throw new IllegalArgumentException("Width of region too large for a .schematic");
    }
    if (height > MAX_SIZE) {
        throw new IllegalArgumentException("Height of region too large for a .schematic");
    }
    if (length > MAX_SIZE) {
        throw new IllegalArgumentException("Length of region too large for a .schematic");
    }
    final DataOutput rawStream = outputStream.getOutputStream();
    outputStream.writeLazyCompoundTag("Schematic", out -> {
        out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion());
        out.writeNamedTag("Version", CURRENT_VERSION);
        out.writeNamedTag("Width", (short) width);
        out.writeNamedTag("Height", (short) height);
        out.writeNamedTag("Length", (short) length);
        // The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
        out.writeNamedTag("Offset", new int[] { min.getBlockX(), min.getBlockY(), min.getBlockZ() });
        out.writeLazyCompoundTag("Metadata", out1 -> {
            out1.writeNamedTag("WEOffsetX", offset.getBlockX());
            out1.writeNamedTag("WEOffsetY", offset.getBlockY());
            out1.writeNamedTag("WEOffsetZ", offset.getBlockZ());
            out1.writeNamedTag("FAWEVersion", Fawe.instance().getVersion().build);
        });
        ByteArrayOutputStream blocksCompressed = new ByteArrayOutputStream();
        FaweOutputStream blocksOut = new FaweOutputStream(new DataOutputStream(new LZ4BlockOutputStream(blocksCompressed)));
        ByteArrayOutputStream tilesCompressed = new ByteArrayOutputStream();
        NBTOutputStream tilesOut = new NBTOutputStream(new LZ4BlockOutputStream(tilesCompressed));
        List<Integer> paletteList = new ArrayList<>();
        char[] palette = new char[BlockTypesCache.states.length];
        Arrays.fill(palette, Character.MAX_VALUE);
        int paletteMax = 0;
        int numTiles = 0;
        Clipboard finalClipboard;
        if (clipboard instanceof BlockArrayClipboard) {
            finalClipboard = ((BlockArrayClipboard) clipboard).getParent();
        } else {
            finalClipboard = clipboard;
        }
        Iterator<BlockVector3> iterator = finalClipboard.iterator(Order.YZX);
        while (iterator.hasNext()) {
            BlockVector3 pos = iterator.next();
            BaseBlock block = pos.getFullBlock(finalClipboard);
            CompoundTag nbt = block.getNbtData();
            if (nbt != null) {
                Map<String, Tag> values = new HashMap<>(nbt.getValue());
                // Positions are kept in NBT, we don't want that.
                values.remove("x");
                values.remove("y");
                values.remove("z");
                values.put("Id", new StringTag(block.getNbtId()));
                // Remove 'id' if it exists. We want 'Id'.
                // Do this after we get "getNbtId" cos otherwise "getNbtId" doesn't work.
                // Dum.
                values.remove("id");
                values.put("Pos", new IntArrayTag(new int[] { pos.getX(), pos.getY(), pos.getZ() }));
                numTiles++;
                tilesOut.writeTagPayload(new CompoundTag(values));
            }
            int ordinal = block.getOrdinal();
            if (ordinal == 0) {
                ordinal = 1;
            }
            char value = palette[ordinal];
            if (value == Character.MAX_VALUE) {
                int size = paletteMax++;
                palette[ordinal] = value = (char) size;
                paletteList.add(ordinal);
            }
            blocksOut.writeVarInt(value);
        }
        // close
        tilesOut.close();
        blocksOut.close();
        out.writeNamedTag("PaletteMax", paletteMax);
        out.writeLazyCompoundTag("Palette", out12 -> {
            for (int i = 0; i < paletteList.size(); i++) {
                int stateOrdinal = paletteList.get(i);
                BlockState state = BlockTypesCache.states[stateOrdinal];
                out12.writeNamedTag(state.getAsString(), i);
            }
        });
        out.writeNamedTagName("BlockData", NBTConstants.TYPE_BYTE_ARRAY);
        rawStream.writeInt(blocksOut.size());
        try (LZ4BlockInputStream in = new LZ4BlockInputStream(new ByteArrayInputStream(blocksCompressed.toByteArray()))) {
            IOUtil.copy(in, rawStream);
        }
        if (numTiles != 0) {
            out.writeNamedTagName("BlockEntities", NBTConstants.TYPE_LIST);
            rawStream.write(NBTConstants.TYPE_COMPOUND);
            rawStream.writeInt(numTiles);
            try (LZ4BlockInputStream in = new LZ4BlockInputStream(new ByteArrayInputStream(tilesCompressed.toByteArray()))) {
                IOUtil.copy(in, rawStream);
            }
        } else {
            out.writeNamedEmptyList("BlockEntities");
        }
        if (finalClipboard.hasBiomes()) {
            writeBiomes(finalClipboard, out);
        }
        List<Tag> entities = new ArrayList<>();
        for (Entity entity : finalClipboard.getEntities()) {
            BaseEntity state = entity.getState();
            if (state != null) {
                Map<String, Tag> values = new HashMap<>();
                // Put NBT provided data
                CompoundTag rawTag = state.getNbtData();
                if (rawTag != null) {
                    values.putAll(rawTag.getValue());
                }
                // Store our location data, overwriting any
                values.remove("id");
                Location loc = entity.getLocation();
                if (!brokenEntities) {
                    loc = loc.setPosition(loc.add(min.toVector3()));
                }
                values.put("Id", new StringTag(state.getType().getId()));
                values.put("Pos", writeVector(loc));
                values.put("Rotation", writeRotation(entity.getLocation()));
                CompoundTag entityTag = new CompoundTag(values);
                entities.add(entityTag);
            }
        }
        if (entities.isEmpty()) {
            out.writeNamedEmptyList("Entities");
        } else {
            out.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities));
        }
    });
}
Also used : StringTag(com.sk89q.jnbt.StringTag) DataOutput(java.io.DataOutput) BaseEntity(com.sk89q.worldedit.entity.BaseEntity) Entity(com.sk89q.worldedit.entity.Entity) HashMap(java.util.HashMap) DataOutputStream(java.io.DataOutputStream) ArrayList(java.util.ArrayList) BaseBlock(com.sk89q.worldedit.world.block.BaseBlock) LZ4BlockOutputStream(net.jpountz.lz4.LZ4BlockOutputStream) CompoundTag(com.sk89q.jnbt.CompoundTag) IntArrayTag(com.sk89q.jnbt.IntArrayTag) BlockArrayClipboard(com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard) BaseEntity(com.sk89q.worldedit.entity.BaseEntity) ByteArrayOutputStream(java.io.ByteArrayOutputStream) BlockVector3(com.sk89q.worldedit.math.BlockVector3) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) NBTOutputStream(com.sk89q.jnbt.NBTOutputStream) LZ4BlockInputStream(net.jpountz.lz4.LZ4BlockInputStream) ListTag(com.sk89q.jnbt.ListTag) BlockState(com.sk89q.worldedit.world.block.BlockState) ByteArrayInputStream(java.io.ByteArrayInputStream) Region(com.sk89q.worldedit.regions.Region) Clipboard(com.sk89q.worldedit.extent.clipboard.Clipboard) BlockArrayClipboard(com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard) StringTag(com.sk89q.jnbt.StringTag) IntArrayTag(com.sk89q.jnbt.IntArrayTag) ListTag(com.sk89q.jnbt.ListTag) CompoundTag(com.sk89q.jnbt.CompoundTag) Tag(com.sk89q.jnbt.Tag) FaweOutputStream(com.fastasyncworldedit.core.internal.io.FaweOutputStream) Location(com.sk89q.worldedit.util.Location)

Example 3 with FaweOutputStream

use of com.fastasyncworldedit.core.internal.io.FaweOutputStream in project FastAsyncWorldEdit by IntellectualSites.

the class FaweStreamChangeSet method addBiomeChange.

@Override
public void addBiomeChange(int bx, int by, int bz, BiomeType from, BiomeType to) {
    blockSize++;
    try {
        int x = bx >> 2;
        int y = by >> 2;
        int z = bz >> 2;
        FaweOutputStream os = getBiomeOS();
        os.write((byte) (x >> 24));
        os.write((byte) (x >> 16));
        os.write((byte) (x >> 8));
        os.write((byte) (x));
        os.write((byte) (z >> 24));
        os.write((byte) (z >> 16));
        os.write((byte) (z >> 8));
        os.write((byte) (z));
        // only need to store biomes in the 4x4x4 chunks so only need one byte for y still (signed byte -128 -> 127)
        // means -512 -> 508. Add 128 to avoid negative value casting.
        os.write((byte) (y + 128));
        os.writeVarInt(from.getInternalId());
        os.writeVarInt(to.getInternalId());
    } catch (Throwable e) {
        e.printStackTrace();
    }
}
Also used : FaweOutputStream(com.fastasyncworldedit.core.internal.io.FaweOutputStream)

Example 4 with FaweOutputStream

use of com.fastasyncworldedit.core.internal.io.FaweOutputStream in project FastAsyncWorldEdit by IntellectualSites.

the class FaweStreamChangeSet method add.

@Override
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
    blockSize++;
    try {
        FaweOutputStream stream = getBlockOS(x, y, z);
        // x
        posDel.write(stream, x - originX, y, z - originZ);
        idDel.writeChange(stream, combinedFrom, combinedTo);
    } catch (Throwable e) {
        e.printStackTrace();
    }
}
Also used : FaweOutputStream(com.fastasyncworldedit.core.internal.io.FaweOutputStream)

Aggregations

FaweOutputStream (com.fastasyncworldedit.core.internal.io.FaweOutputStream)4 FastByteArrayOutputStream (com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream)1 MutableBlockVector3 (com.fastasyncworldedit.core.math.MutableBlockVector3)1 CompoundTag (com.sk89q.jnbt.CompoundTag)1 IntArrayTag (com.sk89q.jnbt.IntArrayTag)1 ListTag (com.sk89q.jnbt.ListTag)1 NBTOutputStream (com.sk89q.jnbt.NBTOutputStream)1 StringTag (com.sk89q.jnbt.StringTag)1 Tag (com.sk89q.jnbt.Tag)1 BaseEntity (com.sk89q.worldedit.entity.BaseEntity)1 Entity (com.sk89q.worldedit.entity.Entity)1 BlockArrayClipboard (com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard)1 Clipboard (com.sk89q.worldedit.extent.clipboard.Clipboard)1 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)1 Region (com.sk89q.worldedit.regions.Region)1 Location (com.sk89q.worldedit.util.Location)1 BaseBlock (com.sk89q.worldedit.world.block.BaseBlock)1 BlockState (com.sk89q.worldedit.world.block.BlockState)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1