From 412a3ee3448add6b8e128419cdfb1dfe3d235ca9 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 24 Mar 2020 08:08:56 +0000 Subject: [PATCH] Support v2 schematics properly. No 3D biomes are supported by it as yet. (#2716) --- .../bukkit/util/BukkitSchematicHandler.java | 60 ++++++++++++++----- .../bukkit/util/block/BukkitLocalQueue.java | 31 ++++++---- .../plotsquared/plot/generator/HybridGen.java | 5 ++ .../plot/generator/HybridPlotManager.java | 6 ++ .../plot/generator/HybridPlotWorld.java | 22 +++++++ .../plot/generator/HybridUtils.java | 9 +++ .../plot/util/SchematicHandler.java | 10 +++- .../plot/util/block/BasicLocalBlockQueue.java | 6 ++ .../util/block/DelegateLocalBlockQueue.java | 4 ++ .../plot/util/block/LocalBlockQueue.java | 2 + 10 files changed, 124 insertions(+), 31 deletions(-) diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java index 4139d2191..e8fce64b4 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java @@ -7,26 +7,17 @@ import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; -import com.sk89q.jnbt.ByteArrayTag; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.IntArrayTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.ShortTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; +import com.sk89q.jnbt.*; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import java.io.ByteArrayOutputStream; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.IntStream; /** @@ -52,7 +43,9 @@ public class BukkitSchematicHandler extends SchematicHandler { int height = cuboidRegion.getHeight(); final int length = cuboidRegion.getLength(); Map schematic = new HashMap<>(); - schematic.put("Version", new IntTag(1)); + schematic.put("Version", new IntTag(2)); + schematic.put("DataVersion", new IntTag(WorldEdit.getInstance().getPlatformManager() + .queryCapability(Capability.WORLD_EDITING).getDataVersion())); Map metadata = new HashMap<>(); metadata.put("WEOffsetX", new IntTag(0)); @@ -69,9 +62,11 @@ public class BukkitSchematicHandler extends SchematicHandler { schematic.put("Offset", new IntArrayTag(new int[] {0, 0, 0,})); Map palette = new HashMap<>(); + Map biomePalette = new HashMap<>(); List tileEntities = new ArrayList<>(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length); + ByteArrayOutputStream biomeBuffer = new ByteArrayOutputStream(width * length); // Queue final ArrayDeque queue = new ArrayDeque<>(regions); TaskManager.runTask(new Runnable() { @@ -88,6 +83,14 @@ public class BukkitSchematicHandler extends SchematicHandler { schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray())); schematic.put("TileEntities", new ListTag(CompoundTag.class, tileEntities)); + + schematic.put("BiomePaletteMax", new IntTag(biomePalette.size())); + + Map biomePaletteTag = new HashMap<>(); + biomePalette.forEach((key, value) -> biomePaletteTag.put(key, new IntTag(value))); + + schematic.put("BiomePalette", new CompoundTag(biomePaletteTag)); + schematic.put("BiomeData", new ByteArrayTag(biomeBuffer.toByteArray())); whenDone.value = new CompoundTag(schematic); TaskManager.runTask(whenDone); }); @@ -177,6 +180,31 @@ public class BukkitSchematicHandler extends SchematicHandler { blockId >>>= 7; } buffer.write(blockId); + + if (ry == sy) { + BlockVector2 pt = + BlockVector2.at(x, z); + BiomeType biome = + cuboidRegion.getWorld() + .getBiome(pt); + String biomeStr = biome.getId(); + int biomeId; + if (biomePalette + .containsKey(biomeStr)) { + biomeId = + biomePalette.get(biomeStr); + } else { + biomeId = biomePalette.size(); + biomePalette + .put(biomeStr, biomeId); + } + while ((biomeId & -128) != 0) { + biomeBuffer + .write(biomeId & 127 | 128); + biomeId >>>= 7; + } + biomeBuffer.write(biomeId); + } } if (xiter.hasNext()) { this.run(); diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java index 2af0bf69b..663d6144b 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java @@ -9,9 +9,7 @@ import com.github.intellectualsites.plotsquared.plot.util.world.BlockUtil; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.biome.BiomeType; @@ -90,6 +88,9 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue { @Override public final void setComponents(LocalChunk lc) throws ExecutionException, InterruptedException { setBaseBlocks(lc); + if (setBiome()) { + setBiomes(lc); + } } public void setBaseBlocks(LocalChunk localChunk) { @@ -143,22 +144,26 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue { } public void setBiomes(LocalChunk lc) { - if (lc.biomes != null) { - World worldObj = Bukkit.getWorld(getWorld()); - int bx = lc.getX() << 4; - int bz = lc.getX() << 4; + World worldObj = Bukkit.getWorld(getWorld()); + if (worldObj == null) { + throw new NullPointerException("World cannot be null."); + } + PaperLib.getChunkAtAsync(worldObj, lc.getX(), lc.getZ(), true).thenAccept(chunk -> { for (int x = 0; x < lc.biomes.length; x++) { - BiomeType[] biomes2 = lc.biomes[x]; - if (biomes2 != null) { - for (BiomeType biomeStr : biomes2) { - if (biomeStr != null) { - Biome biome = BukkitAdapter.adapt(biomeStr); - worldObj.setBiome(bx, bz, biome); + BiomeType[] biomeZ = lc.biomes[x]; + if (biomeZ != null) { + for (int z = 0; z < biomeZ.length; z++) { + if (biomeZ[z] != null) { + BiomeType biomeType = biomeZ[z]; + + Biome biome = BukkitAdapter.adapt(biomeType); + worldObj + .setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, biome); } } } } - } + }); } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridGen.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridGen.java index 5efd5b6d4..9ee97a3ca 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridGen.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridGen.java @@ -8,6 +8,7 @@ import com.github.intellectualsites.plotsquared.plot.object.PlotId; import com.github.intellectualsites.plotsquared.plot.util.MathMan; import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue; import com.google.common.base.Preconditions; +import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; import org.jetbrains.annotations.NotNull; @@ -34,6 +35,10 @@ public class HybridGen extends IndependentPlotGenerator { } } } + BiomeType biome = world.G_SCH_B.get(MathMan.pair(relativeX, relativeZ)); + if (biome != null) { + result.setBiome(x, z, biome); + } } @Override public void generateChunk(@NotNull ScopedLocalBlockQueue result, @NotNull PlotArea settings) { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotManager.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotManager.java index d3e4fbe46..93ff23f90 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotManager.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotManager.java @@ -118,6 +118,12 @@ public class HybridPlotManager extends ClassicPlotManager { } } } + BiomeType biome = hybridPlotWorld.G_SCH_B.get(MathMan.pair(absX, absZ)); + if (biome != null) { + queue.setBiome(x, z, biome); + } else { + queue.setBiome(x, z, hybridPlotWorld.PLOT_BIOME); + } } } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotWorld.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotWorld.java index 38896d044..61c658013 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotWorld.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridPlotWorld.java @@ -17,10 +17,12 @@ import com.sk89q.jnbt.CompoundTagBuilder; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.transform.BlockTransformExtent; import com.sk89q.worldedit.internal.helper.MCDirections; +import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import org.jetbrains.annotations.NotNull; @@ -36,6 +38,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { public short PATH_WIDTH_LOWER; public short PATH_WIDTH_UPPER; public HashMap G_SCH; + public HashMap G_SCH_B; public int SCHEM_Y; private Location SIGN_LOCATION; @@ -211,6 +214,10 @@ public class HybridPlotWorld extends ClassicPlotWorld { id, false, h3); } } + BiomeType biome = blockArrayClipboard3 + .getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); + addOverlayBiome((short) (x + shift + oddshift + centerShiftX), + (short) (z + shift + oddshift + centerShiftZ), biome); } } /* HashMap items = schematic3.getTiles(); @@ -319,4 +326,19 @@ public class HybridPlotWorld extends ClassicPlotWorld { } existing[y] = id; } + + public void addOverlayBiome(short x, short z, BiomeType id) { + if (z < 0) { + z += this.SIZE; + } else if (z >= this.SIZE) { + z -= this.SIZE; + } + if (x < 0) { + x += this.SIZE; + } else if (x >= this.SIZE) { + x -= this.SIZE; + } + int pair = MathMan.pair(x, z); + this.G_SCH_B.put(pair, id); + } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java index 754bd6f24..f5ce01b69 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java @@ -29,6 +29,7 @@ import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; @@ -613,6 +614,14 @@ public abstract class HybridUtils { } } } + BiomeType biome = plotWorld.G_SCH_B.get(MathMan.pair(absX, absZ)); + if (biome != null) { + queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X, + finalZ + Z + plotWorld.ROAD_OFFSET_Z, biome); + } else { + queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X, + finalZ + Z + plotWorld.ROAD_OFFSET_Z, plotWorld.PLOT_BIOME); + } } } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java index 6975023c8..3883192c2 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java @@ -23,6 +23,7 @@ import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import org.jetbrains.annotations.NotNull; @@ -234,6 +235,11 @@ public abstract class SchematicHandler { BaseBlock id = blockArrayClipboard .getFullBlock(BlockVector3.at(rx, ry, rz)); queue.setBlock(xx, yy, zz, id); + if (ry == 0) { + BiomeType biome = + blockArrayClipboard.getBiome(BlockVector2.at(rx, rz)); + queue.setBiome(xx, zz, biome); + } } } } @@ -392,7 +398,7 @@ public abstract class SchematicHandler { TaskManager.runTask(whenDone); return; } - MainUtil.upload(uuid, file, "schematic", new RunnableVal() { + MainUtil.upload(uuid, file, "schem", new RunnableVal() { @Override public void run(OutputStream output) { try (NBTOutputStream nos = new NBTOutputStream( new GZIPOutputStream(output, true))) { @@ -444,7 +450,7 @@ public abstract class SchematicHandler { } - public class UnsupportedFormatException extends Exception { + public static class UnsupportedFormatException extends Exception { /** * Throw with a message. * diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java index 1c166850c..0f3bc38a5 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java @@ -24,6 +24,7 @@ public abstract class BasicLocalBlockQueue extends LocalBlockQueue { private LocalChunk lastWrappedChunk; private int lastX = Integer.MIN_VALUE; private int lastZ = Integer.MIN_VALUE; + private boolean setbiome = false; public BasicLocalBlockQueue(String world) { super(world); @@ -139,9 +140,14 @@ public abstract class BasicLocalBlockQueue extends LocalBlockQueue { } } result.setBiome(x & 15, z & 15, biomeType); + setbiome = true; return true; } + @Override public final boolean setBiome() { + return setbiome; + } + public final void setChunk(LocalChunk chunk) { LocalChunk previous = this.blockChunks.put(chunk.longHash(), chunk); if (previous != null) { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/DelegateLocalBlockQueue.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/DelegateLocalBlockQueue.java index 78e706b6b..4aa308a95 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/DelegateLocalBlockQueue.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/DelegateLocalBlockQueue.java @@ -80,6 +80,10 @@ public class DelegateLocalBlockQueue extends LocalBlockQueue { return parent.setBiome(x, z, biome); } + @Override public boolean setBiome() { + return parent.setBiome(); + } + @Override public String getWorld() { return parent.getWorld(); } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java index 35935e8ff..9072dd42b 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java @@ -73,6 +73,8 @@ public abstract class LocalBlockQueue { public abstract boolean setBiome(int x, int z, BiomeType biome); + public abstract boolean setBiome(); + public abstract String getWorld(); public abstract void flush();