From b57c472b86f1cac4d5e9aba92503251390e3521e Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 17 Dec 2020 14:09:54 +0000 Subject: [PATCH 01/55] Save the get blocks to the set chunk after history is written when post-processing --- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 11 +++++++--- .../mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java | 13 +++++++++++- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 11 +++++++--- .../mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java | 13 +++++++++++- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 11 +++++++--- .../mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java | 13 +++++++++++- .../mc1_16_4/BukkitGetBlocks_1_16_4.java | 11 +++++++--- .../mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java | 13 +++++++++++- .../com/boydti/fawe/beta/IChunkGetCopy.java | 6 ++++++ .../object/changeset/AbstractChangeSet.java | 20 ++++++++++++++----- 10 files changed, 101 insertions(+), 21 deletions(-) create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index 0cb058215..40d082be9 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -357,13 +357,18 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { if (!set.hasSection(layer)) { continue; } - if (createCopy) { - copy.storeSection(layer); - } bitMask |= 1 << layer; char[] setArr = set.load(layer); + // If we're creating a copy, it's because we're delaying history so we do not want to write to + // the chunkSet yet. + if (createCopy) { + setArr = setArr.clone(); + copy.storeSection(layer); + copy.storeSetBlocks(layer, setArr); + } + ChunkSection newSection; ChunkSection existingSection = sections[layer]; if (existingSection == null) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java index a9aef70f4..19fb70d5d 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java @@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_15_2; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.beta.IChunkGetCopy; import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -28,12 +29,13 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 { +public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 implements IChunkGetCopy { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; private final char[][] blocks = new char[16][4096]; + private final char[][] newSetBlocks = new char[16][]; protected BukkitGetBlocks_1_15_2_Copy(WorldServer world, int X, int Z) { super(world, X, Z); @@ -126,4 +128,13 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 { final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } + + protected void storeSetBlocks(int layer, char[] blocks) { + newSetBlocks[layer] = blocks; + } + + @Override + public char[] getNewSetArr(int layer) { + return newSetBlocks[layer]; + } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index a2538a143..9ab5ff383 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -357,13 +357,18 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { if (!set.hasSection(layer)) { continue; } - if (createCopy) { - copy.storeSection(layer); - } bitMask |= 1 << layer; char[] setArr = set.load(layer); + // If we're creating a copy, it's because we're delaying history so we do not want to write to + // the chunkSet yet. + if (createCopy) { + setArr = setArr.clone(); + copy.storeSection(layer); + copy.storeSetBlocks(layer, setArr); + } + ChunkSection newSection; ChunkSection existingSection = sections[layer]; if (existingSection == null) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java index 9b9dc3697..5deaaa901 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java @@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_1; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.beta.IChunkGetCopy; import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -29,12 +30,13 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 { +public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 implements IChunkGetCopy { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; private final char[][] blocks = new char[16][4096]; + private final char[][] newSetBlocks = new char[16][]; protected BukkitGetBlocks_1_16_1_Copy(WorldServer world, int X, int Z) { super(world, X, Z); @@ -127,4 +129,13 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 { final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } + + protected void storeSetBlocks(int layer, char[] blocks) { + newSetBlocks[layer] = blocks; + } + + @Override + public char[] getNewSetArr(int layer) { + return newSetBlocks[layer]; + } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index e19038d48..e63973c68 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -360,13 +360,18 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { if (!set.hasSection(layer)) { continue; } - if (createCopy) { - copy.storeSection(layer); - } bitMask |= 1 << layer; char[] setArr = set.load(layer); + // If we're creating a copy, it's because we're delaying history so we do not want to write to + // the chunkSet yet. + if (createCopy) { + setArr = setArr.clone(); + copy.storeSection(layer); + copy.storeSetBlocks(layer, setArr); + } + ChunkSection newSection; ChunkSection existingSection = sections[layer]; if (existingSection == null) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java index ac80fe3f1..dccf17358 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java @@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_2; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.beta.IChunkGetCopy; import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -29,12 +30,13 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 { +public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 implements IChunkGetCopy { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; private final char[][] blocks = new char[16][4096]; + private final char[][] newSetBlocks = new char[16][]; protected BukkitGetBlocks_1_16_2_Copy(WorldServer world, int X, int Z) { super(world, X, Z); @@ -127,4 +129,13 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 { final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } + + protected void storeSetBlocks(int layer, char[] blocks) { + newSetBlocks[layer] = blocks; + } + + @Override + public char[] getNewSetArr(int layer) { + return newSetBlocks[layer]; + } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index 962fd3a7b..061ba338e 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -360,13 +360,18 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { if (!set.hasSection(layer)) { continue; } - if (createCopy) { - copy.storeSection(layer); - } bitMask |= 1 << layer; char[] setArr = set.load(layer); + // If we're creating a copy, it's because we're delaying history so we do not want to write to + // the chunkSet yet. + if (createCopy) { + setArr = setArr.clone(); + copy.storeSection(layer); + copy.storeSetBlocks(layer, setArr); + } + ChunkSection newSection; ChunkSection existingSection = sections[layer]; if (existingSection == null) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java index 2eec240cb..3a2ebe25f 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java @@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_4; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.beta.IChunkGetCopy; import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -29,12 +30,13 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 { +public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 implements IChunkGetCopy { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; private final char[][] blocks = new char[16][4096]; + private final char[][] newSetBlocks = new char[16][]; protected BukkitGetBlocks_1_16_4_Copy(WorldServer world, int X, int Z) { super(world, X, Z); @@ -127,4 +129,13 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 { final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } + + protected void storeSetBlocks(int layer, char[] blocks) { + newSetBlocks[layer] = blocks; + } + + @Override + public char[] getNewSetArr(int layer) { + return newSetBlocks[layer]; + } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java new file mode 100644 index 000000000..87b3b4396 --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java @@ -0,0 +1,6 @@ +package com.boydti.fawe.beta; + +public interface IChunkGetCopy { + + char[] getNewSetArr(int layer); +} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java index dad021ee1..29dbef3e3 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java @@ -5,6 +5,7 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunkGet; +import com.boydti.fawe.beta.IChunkGetCopy; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.object.HistoryExtent; import com.boydti.fawe.util.EditSessionBuilder; @@ -158,6 +159,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { addEntityCreate(tag); } } + boolean updateSet = get instanceof IChunkGetCopy; for (int layer = 0; layer < 16; layer++) { if (!set.hasSection(layer)) { continue; @@ -168,7 +170,11 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { blocksGet = FaweCache.IMP.EMPTY_CHAR_4096; } char[] blocksSet = set.load(layer); - + char[] newBlocksSet = null; + if (updateSet) { + newBlocksSet = ((IChunkGetCopy) get).getNewSetArr(layer); + } +; int by = layer << 4; for (int y = 0, index = 0; y < 16; y++) { int yy = y + by; @@ -176,14 +182,18 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { int zz = z + bz; for (int x = 0; x < 16; x++, index++) { int xx = bx + x; - int combinedFrom = blocksGet[index]; - if (combinedFrom == 0) { - combinedFrom = BlockID.AIR; + int from = blocksGet[index]; + if (from == 0) { + from = BlockID.AIR; } - int combinedTo = blocksSet[index]; + final int combinedFrom = from; + final int combinedTo = blocksSet[index]; if (combinedTo != 0) { add(xx, yy, zz, combinedFrom, combinedTo); } + if (updateSet) { + blocksSet[index] = newBlocksSet[index]; + } } } } From 236e3c3f6f08fc2f1c4a111f7a9c4d3748d46b6a Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 17 Dec 2020 15:02:49 +0000 Subject: [PATCH 02/55] correctly set changes to editsession for line/spline fixes #696 --- .../src/main/java/com/sk89q/worldedit/EditSession.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index e6051f754..fc822a7bb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2767,7 +2767,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { newVset = this.getHollowed(newVset); } } - return setBlocks(newVset, pattern); + return this.changes += setBlocks(newVset, pattern); } /** @@ -2840,7 +2840,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { if (!filled) { vset = getHollowed(vset); } - return setBlocks(vset, pattern); + return this.changes += setBlocks(vset, pattern); } /** @@ -2892,7 +2892,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { if (!filled) { newVset = this.getHollowed(newVset); } - return setBlocks(newVset, pattern); + return this.changes += setBlocks(newVset, pattern); } return changes; } From 94a14b03b6c7b8c05ad801be83ce209e7e12bd86 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 17 Dec 2020 15:26:17 +0000 Subject: [PATCH 03/55] fix brush size 0/1 --- .../src/main/java/com/sk89q/worldedit/EditSession.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index fc822a7bb..9a02e26cd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2046,18 +2046,18 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int yy; - double nextXn = invRadiusX; + double nextXn = 0; forX: for (int x = 0; x <= ceilRadiusX; ++x) { final double xn = nextXn; double dx = xn * xn; nextXn = (x + 1) * invRadiusX; - double nextZn = invRadiusZ; + double nextZn = 0; forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { final double zn = nextZn; double dz = zn * zn; double dxz = dx + dz; nextZn = (z + 1) * invRadiusZ; - double nextYn = invRadiusY; + double nextYn = 0; forY: for (int y = 0; y <= ceilRadiusY; ++y) { final double yn = nextYn; @@ -2076,7 +2076,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } if (!filled) { - if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1) { + if (nextXn * nextXn + dy * dy + dz * dz <= 1 && nextYn * nextYn + dx * dx + dz * dz <= 1 && nextZn * nextZn + dx * dx + dy * dy <= 1) { continue; } } From d379b0af9b06d7e591e9105e467925ee4359a38e Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 17 Dec 2020 20:19:54 +0000 Subject: [PATCH 04/55] fix //image ane image brush fixes #208 and fixes #698 --- .../boydti/fawe/util/RandomTextureUtil.java | 3 ++ .../com/boydti/fawe/util/TextureUtil.java | 10 +++--- .../worldedit/command/BrushCommands.java | 33 ++++++++++--------- .../worldedit/command/GenerationCommands.java | 20 +++++++---- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/RandomTextureUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/RandomTextureUtil.java index bb2b23076..e47621944 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/RandomTextureUtil.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/RandomTextureUtil.java @@ -1,5 +1,6 @@ package com.boydti.fawe.util; +import com.plotsquared.core.util.PseudoRandom; import com.sk89q.worldedit.world.block.BlockType; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -34,6 +35,8 @@ public class RandomTextureUtil extends CachedTextureUtil { if (i < 0) { int i1 = -i; return -ThreadLocalRandom.current().nextInt(i1); + } else if( i == 0) { + return 0; } else { return ThreadLocalRandom.current().nextInt(i); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java index 6c112c83f..ab52685f5 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java @@ -629,7 +629,6 @@ public class TextureUtil implements TextureHolder { mods.add(modId); } } - continue; } String modelsDir = "assets/%1$s/models/block/%2$s.json"; String texturesDir = "assets/%1$s/textures/%2$s.png"; @@ -638,14 +637,14 @@ public class TextureUtil implements TextureHolder { }.getType(); for (BlockType blockType : BlockTypesCache.values) { - if (!blockType.getMaterial().isFullCube()) { + if (!blockType.getMaterial().isFullCube() || blockType.getId().toLowerCase().contains("shulker")) { continue; } int combined = blockType.getInternalId(); String id = blockType.getId(); String[] split = id.split(":", 2); String name = split.length == 1 ? id : split[1]; - String nameSpace = split.length == 1 ? "minecraft" : split[0]; + String nameSpace = split.length == 1 ? "" : split[0]; Map texturesMap = new ConcurrentHashMap<>(); // Read models @@ -684,8 +683,11 @@ public class TextureUtil implements TextureHolder { continue; } + String[] texSplit = models.iterator().next().split(":"); + String texture = texSplit[texSplit.length - 1]; + textureFileName = - String.format(texturesDir, nameSpace, models.iterator().next()); + String.format(texturesDir, nameSpace, texture); } BufferedImage image = readImage(zipFile, textureFileName); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 916a93ae5..0e173d269 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -85,7 +85,6 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.CreatureButcher; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; -import com.sk89q.worldedit.extension.platform.binding.ProvideBindings; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.function.Contextual; @@ -130,6 +129,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.net.URL; import java.nio.file.FileSystems; import java.util.List; @@ -498,22 +498,23 @@ public class BrushCommands { set(context, brush).setSize(radius).setFill(fill); } - @Command( - name = "image", + @Command(name = "image", desc = "Use a height map to paint a surface", - descFooter = "Use a height map to paint any surface.\n" - ) - @CommandPermissions("worldedit.brush.stencil") - public void imageBrush(LocalSession session, InjectedValueAccess context, - @Arg(desc = "The size of the brush", def = "5") - Expression radius, ProvideBindings.ImageUri imageUri, - @Arg(def = "1", desc = "scale height") - double yscale, - @Switch(name = 'a', desc = "Use image Alpha") - boolean alpha, - @Switch(name = 'f', desc = "Blend the image with existing terrain") - boolean fadeOut) throws WorldEditException, IOException { - BufferedImage image = imageUri.load(); + descFooter = "Use a height map to paint any surface.\n") + @CommandPermissions("worldedit.brush.image") + public void imageBrush(LocalSession session, + InjectedValueAccess context, + @Arg(desc = "Image URL (imgur only)") String imageURL, + @Arg(desc = "The size of the brush", def = "5") Expression radius, + @Arg(def = "1", desc = "scale height") double yscale, + @Switch(name = 'a', desc = "Use image Alpha") boolean alpha, + @Switch(name = 'f', desc = "Blend the image with existing terrain") boolean fadeOut) + throws WorldEditException, IOException { + URL url = new URL(imageURL); + if (!url.getHost().equalsIgnoreCase("i.imgur.com")) { + throw new IOException("Only i.imgur.com links are allowed!"); + } + BufferedImage image = MainUtil.readImage(url); worldEdit.checkMaxBrushRadius(radius); if (yscale != 1) { ImageUtil.scaleAlpha(image, yscale); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index a7d65b216..4ceeef74e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -58,7 +58,7 @@ import org.enginehub.piston.annotation.param.Arg; import org.enginehub.piston.annotation.param.Switch; import org.jetbrains.annotations.Range; -import java.awt.RenderingHints; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; @@ -131,20 +131,26 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.image") @Logging(PLACEMENT) - public void image(Actor actor, LocalSession session, EditSession editSession, String argStr, @Arg(desc = "boolean", def = "true") boolean randomize, - @Arg(desc = "TODO", def = "100") int threshold, @Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions) throws WorldEditException, IOException { + public void image(Actor actor, + LocalSession session, + EditSession editSession, + @Arg(desc = "Image URL (imgur only)") String imageURL, + @Arg(desc = "boolean", def = "true") boolean randomize, + @Arg(desc = "TODO", def = "100") int threshold, + @Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions) throws WorldEditException, IOException { TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold); - URL url = new URL(argStr); + URL url = new URL(imageURL); if (!url.getHost().equalsIgnoreCase("i.imgur.com")) { throw new IOException("Only i.imgur.com links are allowed!"); } BufferedImage image = MainUtil.readImage(url); if (dimensions != null) { - image = ImageUtil.getScaledInstance(image, dimensions.getBlockX(), dimensions.getBlockZ(), RenderingHints.VALUE_INTERPOLATION_BILINEAR, false); + image = ImageUtil.getScaledInstance(image, dimensions.getBlockX(), dimensions.getBlockZ(), + RenderingHints.VALUE_INTERPOLATION_BILINEAR, false); } - BlockVector3 pos1 = session.getPlacementPosition(actor); - BlockVector3 pos2 = pos1.add(image.getWidth() - 1, 0, image.getHeight() - 1); + BlockVector3 pos1 = session.getPlacementPosition(actor); + BlockVector3 pos2 = pos1.add(image.getWidth() - 1, 0, image.getHeight() - 1); CuboidRegion region = new CuboidRegion(pos1, pos2); int[] count = new int[1]; final BufferedImage finalImage = image; From 884ec322b818ac3423c3b5043c141e5a9c08a98f Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 17 Dec 2020 22:04:49 +0000 Subject: [PATCH 05/55] Ensure chunk sections are reloaded for every edit/chunk read Add an option for force-reloading the cached chunk sections when a layer is updated --- .../adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java | 13 ++++++++----- .../adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java | 13 ++++++++----- .../adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java | 13 ++++++++----- .../adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java | 16 +++++++++++----- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index 40d082be9..549526f9f 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -397,7 +397,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); - } else if (existingSection != getSections()[layer]) { + } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { @@ -642,7 +642,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { @Override public synchronized char[] update(int layer, char[] data) { - ChunkSection section = getSections()[layer]; + ChunkSection section = getSections(true)[layer]; // Section is null, return empty array if (section == null) { data = new char[4096]; @@ -757,7 +757,10 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { } } - public ChunkSection[] getSections() { + public ChunkSection[] getSections(boolean force) { + if (force) { + return sections = getChunk().getSections().clone(); + } ChunkSection[] tmp = sections; if (tmp == null) { synchronized (this) { @@ -809,7 +812,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { @Override public boolean hasSection(int layer) { - return getSections()[layer] != null; + return getSections(false)[layer] != null; } @Override @@ -825,7 +828,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections()[i]; + ChunkSection existing = getSections(false)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 9ab5ff383..458ae27a5 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -397,7 +397,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); - } else if (existingSection != getSections()[layer]) { + } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { @@ -644,7 +644,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { @Override public synchronized char[] update(int layer, char[] data) { - ChunkSection section = getSections()[layer]; + ChunkSection section = getSections(true)[layer]; // Section is null, return empty array if (section == null) { data = new char[4096]; @@ -759,7 +759,10 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { } } - public ChunkSection[] getSections() { + public ChunkSection[] getSections(boolean force) { + if (force) { + return sections = getChunk().getSections().clone(); + } ChunkSection[] tmp = sections; if (tmp == null) { synchronized (this) { @@ -811,7 +814,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { @Override public boolean hasSection(int layer) { - return getSections()[layer] != null; + return getSections(false)[layer] != null; } @Override @@ -827,7 +830,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections()[i]; + ChunkSection existing = getSections(false)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index e63973c68..44c885305 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -400,7 +400,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); - } else if (existingSection != getSections()[layer]) { + } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { @@ -647,7 +647,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { @Override public synchronized char[] update(int layer, char[] data) { - ChunkSection section = getSections()[layer]; + ChunkSection section = getSections(true)[layer]; // Section is null, return empty array if (section == null) { data = new char[4096]; @@ -762,7 +762,10 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { } } - public ChunkSection[] getSections() { + public ChunkSection[] getSections(boolean force) { + if (force) { + return sections = getChunk().getSections().clone(); + } ChunkSection[] tmp = sections; if (tmp == null) { synchronized (this) { @@ -814,7 +817,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { @Override public boolean hasSection(int layer) { - return getSections()[layer] != null; + return getSections(false)[layer] != null; } @Override @@ -830,7 +833,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections()[i]; + ChunkSection existing = getSections(false)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index 061ba338e..e43987767 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -1,6 +1,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_4; import com.boydti.fawe.Fawe; +import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; @@ -27,8 +28,10 @@ import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.block.BlockTypesCache; import net.minecraft.server.v1_16_R3.BiomeBase; import net.minecraft.server.v1_16_R3.BiomeStorage; +import net.minecraft.server.v1_16_R3.Block; import net.minecraft.server.v1_16_R3.BlockPosition; import net.minecraft.server.v1_16_R3.Chunk; import net.minecraft.server.v1_16_R3.ChunkSection; @@ -400,7 +403,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); - } else if (existingSection != getSections()[layer]) { + } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { @@ -647,7 +650,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { @Override public synchronized char[] update(int layer, char[] data) { - ChunkSection section = getSections()[layer]; + ChunkSection section = getSections(true)[layer]; // Section is null, return empty array if (section == null) { data = new char[4096]; @@ -762,7 +765,10 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { } } - public ChunkSection[] getSections() { + public ChunkSection[] getSections(boolean force) { + if (force) { + return sections = getChunk().getSections().clone(); + } ChunkSection[] tmp = sections; if (tmp == null) { synchronized (this) { @@ -814,7 +820,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { @Override public boolean hasSection(int layer) { - return getSections()[layer] != null; + return getSections(false)[layer] != null; } @Override @@ -830,7 +836,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections()[i]; + ChunkSection existing = getSections(false)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); From e8f0c0e6ea2d30d4632d4b41878df6fdb097ef3b Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 17 Dec 2020 22:05:32 +0000 Subject: [PATCH 06/55] allow count to access "full" chunks if counting air --- .../fawe/beta/implementation/queue/ParallelQueueExtent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java index 0314c1b6e..1e8bd2301 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java @@ -140,7 +140,7 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap return // Apply a filter over a region apply(region, searchMask - .toFilter(new CountFilter()), false) // Adapt the mask to a filter which counts + .toFilter(new CountFilter()), searchMask.replacesAir()) // Adapt the mask to a filter which counts .getParent() // Get the counter of this mask .getTotal(); // Get the total from the counter } From e08fda0ac2719c11a60965ee38c44d1382aad8b5 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 17 Dec 2020 22:06:32 +0000 Subject: [PATCH 07/55] cache the correct number of blocks for FAWE fixes #747 --- .../worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java | 2 +- .../worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java | 2 +- .../worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java | 2 +- .../worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java index 58e86eb92..aa63a5b2d 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java @@ -124,7 +124,7 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { return false; } - ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size + ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java index cd3625917..1ab34aabf 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java @@ -123,7 +123,7 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { return false; } - ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size + ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java index 966831373..3c9d4b680 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java @@ -124,7 +124,7 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { return false; } - ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size + ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_16_2 material = (BlockMaterial_1_16_2) state.getMaterial(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java index 79fc3499b..9abe6a038 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java @@ -125,7 +125,7 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { return false; } - ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size + ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial(); From 7444c643a1142f4bd95cfe12f851b2e8b536563c Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sat, 19 Dec 2020 16:18:57 +0000 Subject: [PATCH 08/55] Switch to IncendoPaster "library" --- worldedit-bukkit/build.gradle.kts | 4 + worldedit-core/build.gradle.kts | 1 + .../com/boydti/fawe/util/IncendoPaster.java | 298 ------------------ .../worldedit/command/WorldEditCommands.java | 8 +- 4 files changed, 11 insertions(+), 300 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/boydti/fawe/util/IncendoPaster.java diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index eb767c152..0a49fb6b9 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -69,6 +69,7 @@ dependencies { exclude("com.sk89q.worldedit.worldedit-libs", "core") } "compile"("org.bstats:bstats-bukkit:1.7") + "compile"("com.intellectualsites.paster:Paster:1.0-SNAPSHOT") // Third party "implementation"("com.github.InventivetalentDev:MapManager:1.7.+") { isTransitive = false } "implementation"("com.github.TechFortress:GriefPrevention:16.+") { isTransitive = false } @@ -119,6 +120,9 @@ tasks.named("shadowJar") { relocate("org.bstats", "com.boydti.metrics") { include(dependency("org.bstats:bstats-bukkit:1.7")) } + relocate("com.intellectualsites.paster", "com.boydti.fawe.paster") { + include(dependency("com.intellectualsites.paster:Paster:1.0-SNAPSHOT")) + } } } diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index d9f5e8215..5093b00b7 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -59,6 +59,7 @@ dependencies { "compile"("com.plotsquared:PlotSquared-Core:5.12.2") { isTransitive = false } + "api"("com.intellectualsites.paster:Paster:1.0-SNAPSHOT") } tasks.named("test") { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/IncendoPaster.java b/worldedit-core/src/main/java/com/boydti/fawe/util/IncendoPaster.java deleted file mode 100644 index f1b1a739f..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/IncendoPaster.java +++ /dev/null @@ -1,298 +0,0 @@ -package com.boydti.fawe.util; - -import com.boydti.fawe.Fawe; -import com.google.common.base.Charsets; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.sk89q.worldedit.util.paste.Paster; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; - -/** - * Single class paster for the Incendo paste service - * - * @author Sauilitired - */ -@SuppressWarnings({"unused", "WeakerAccess"}) -public final class IncendoPaster implements Paster { - - /** - * Upload service URL - */ - public static final String UPLOAD_PATH = "https://athion.net/ISPaster/paste/upload"; - /** - * Valid paste applications - */ - public static final Collection - VALID_APPLICATIONS = Arrays - .asList("plotsquared", "fastasyncworldedit", "incendopermissions", "kvantum"); - - private final Collection files = new ArrayList<>(); - private final String pasteApplication; - - /** - * Construct a new paster - * - * @param pasteApplication The application that is sending the paste - */ - public IncendoPaster(final String pasteApplication) { - if (pasteApplication == null || pasteApplication.isEmpty()) { - throw new IllegalArgumentException("paste application cannot be null, nor empty"); - } - if (!VALID_APPLICATIONS.contains(pasteApplication.toLowerCase(Locale.ROOT))) { - throw new IllegalArgumentException( - String.format("Unknown application name: %s", pasteApplication)); - } - this.pasteApplication = pasteApplication; - } - - @Override - public Callable paste(String content) { - return new PasteTask(content); - } - - private final class PasteTask implements Callable { - - private PasteTask(String content) {} - - @Override - public URL call() throws Exception { - return new URL(debugPaste()); - } - - } - - /** - * Get an immutable collection containing all the files that have been added to this paster - * - * @return Unmodifiable collection - */ - public final Collection getFiles() { - return Collections.unmodifiableCollection(this.files); - } - - /** - * Add a file to the paster - * - * @param file File to paste - */ - public void addFile(final PasteFile file) { - if (file == null) { - throw new IllegalArgumentException("File cannot be null"); - } - // Check to see that no duplicate files are submitted - for (final PasteFile pasteFile : this.files) { - if (pasteFile.fileName.equalsIgnoreCase(file.getFileName())) { - throw new IllegalArgumentException(String.format("Found duplicate file with name %s", - file.getFileName())); - } - } - this.files.add(file); - } - - /** - * Create a JSON string from the submitted information - * - * @return compiled JSON string - */ - private String toJsonString() { - final StringBuilder builder = new StringBuilder("{\n"); - builder.append("\"paste_application\": \"").append(this.pasteApplication).append("\",\n\"files\": \""); - Iterator fileIterator = this.files.iterator(); - while (fileIterator.hasNext()) { - final PasteFile file = fileIterator.next(); - builder.append(file.getFileName()); - if (fileIterator.hasNext()) { - builder.append(","); - } - } - builder.append("\",\n"); - fileIterator = this.files.iterator(); - while (fileIterator.hasNext()) { - final PasteFile file = fileIterator.next(); - builder.append("\"file-").append(file.getFileName()).append("\": \"") - .append(file.getContent().replaceAll("\"", "\\\\\"")).append("\""); - if (fileIterator.hasNext()) { - builder.append(",\n"); - } - } - builder.append("\n}"); - return builder.toString(); - } - - /** - * Upload the paste and return the status message - * - * @return Status message - * @throws Throwable any and all exceptions - */ - public final String upload() throws Throwable { - final URL url = new URL(UPLOAD_PATH); - final URLConnection connection = url.openConnection(); - final HttpURLConnection httpURLConnection = (HttpURLConnection) connection; - httpURLConnection.setRequestMethod("POST"); - httpURLConnection.setDoOutput(true); - final byte[] content = toJsonString().getBytes(Charsets.UTF_8); - httpURLConnection.setFixedLengthStreamingMode(content.length); - httpURLConnection.setRequestProperty("Content-Type", "application/json"); - httpURLConnection.setRequestProperty("Accept", "*/*"); - httpURLConnection.connect(); - try (final OutputStream stream = httpURLConnection.getOutputStream()) { - stream.write(content); - } - if (!httpURLConnection.getResponseMessage().contains("OK")) { - throw new IllegalStateException(String.format("Server returned status: %d %s", - httpURLConnection.getResponseCode(), httpURLConnection.getResponseMessage())); - } - final StringBuilder input = new StringBuilder(); - try (final BufferedReader inputStream = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()))) { - String line; - while ((line = inputStream.readLine()) != null) { - input.append(line).append("\n"); - } - } - return input.toString(); - } - - /** - * Simple class that represents a paste file - */ - public static class PasteFile { - - private final String fileName; - private final String content; - - /** - * Construct a new paste file - * - * @param fileName File name, cannot be empty, nor null - * @param content File content, cannot be empty, nor null - */ - public PasteFile(final String fileName, final String content) { - if (fileName == null || fileName.isEmpty()) { - throw new IllegalArgumentException("file name cannot be null, nor empty"); - } - if (content == null || content.isEmpty()) { - throw new IllegalArgumentException("content cannot be null, nor empty"); - } - this.fileName = fileName; - this.content = content; - } - - /** - * Get the file name - * - * @return File name - */ - public String getFileName() { - return this.fileName; - } - - /** - * Get the file content as a single string - * - * @return File content - */ - public String getContent() { - return this.content; - } - } - - public static String debugPaste() throws IOException { - final IncendoPaster incendoPaster = new IncendoPaster("fastasyncworldedit"); - - StringBuilder b = new StringBuilder(); - b.append( - "# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your " - + "problem\n"); - b.append("\n# Server Information\n"); - b.append(Fawe.imp().getDebugInfo()); - b.append("\n# YAY! Now, let's see what we can find in your JVM\n"); - Runtime runtime = Runtime.getRuntime(); - RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean(); - b.append("Uptime: ").append(TimeUnit.MINUTES.convert(rb.getUptime(), TimeUnit.MILLISECONDS)) - .append(" minutes").append('\n'); - b.append("JVM Flags: ").append(rb.getInputArguments()).append('\n'); - b.append("Free Memory: ").append(runtime.freeMemory() / 1024 / 1024).append(" MB").append('\n'); - b.append("Max Memory: ").append(runtime.maxMemory() / 1024 / 1024).append(" MB").append('\n'); - b.append("Total Memory: ").append(runtime.totalMemory() / 1024 / 1024).append(" MB").append('\n'); - b.append("Available Processors: ").append(runtime.availableProcessors()).append('\n'); - b.append("Java Name: ").append(rb.getVmName()).append('\n'); - b.append("Java Version: '").append(System.getProperty("java.version")).append("'\n"); - b.append("Java Vendor: '").append(System.getProperty("java.vendor")).append("'\n"); - b.append("Operating System: '").append(System.getProperty("os.name")).append("'\n"); - b.append("OS Version: ").append(System.getProperty("os.version")).append('\n'); - b.append("OS Arch: ").append(System.getProperty("os.arch")).append('\n'); - b.append("# Okay :D Great. You are now ready to create your bug report!"); - b.append("\n# You can do so at https://github.com/IntellectualSites/FastAsyncWorldEdit/issues"); - b.append("\n# or via our Discord at https://discord.gg/KxkjDVg"); - incendoPaster.addFile(new IncendoPaster.PasteFile("information", b.toString())); - - try { - final File logFile = new File(Fawe.imp().getDirectory(), "../../logs/latest.log"); - final String file; - if (Files.size(logFile.toPath()) > 14_000_000) { - file = "too big :("; - } else { - file = readFile(logFile); - } - incendoPaster.addFile(new IncendoPaster.PasteFile("latest.log", file)); - } catch (IOException ignored) { - } - - incendoPaster.addFile(new PasteFile("config.yml", readFile(new File(Fawe.imp().getDirectory(), "config.yml")))); - incendoPaster.addFile(new PasteFile("config-legacy.yml", readFile(new File(Fawe.imp().getDirectory(), "config-legacy.yml")))); - - final String rawResponse; - try { - rawResponse = incendoPaster.upload(); - } catch (Throwable throwable) { - throw new IOException(String.format("Failed to upload files: %s", throwable.getMessage()), throwable); - } - final JsonObject jsonObject = new JsonParser().parse(rawResponse).getAsJsonObject(); - - if (jsonObject.has("created")) { - final String pasteId = jsonObject.get("paste_id").getAsString(); - return String.format("https://athion.net/ISPaster/paste/view/%s", pasteId); - } else { - throw new IOException(String.format("Failed to upload files: %s", - jsonObject.get("response").getAsString())); - } - } - - private static String readFile(final File file) throws IOException { - final StringBuilder content = new StringBuilder(); - final List lines = new ArrayList<>(); - try (final BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line; - while ((line = reader.readLine()) != null) { - lines.add(line); - } - } - for (int i = Math.max(0, lines.size() - 1000); i < lines.size(); i++) { - content.append(lines.get(i)).append("\n"); - } - return content.toString(); - } - -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java index 76afac4b8..b84c814a6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java @@ -22,7 +22,7 @@ package com.sk89q.worldedit.command; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweVersion; import com.boydti.fawe.config.Settings; -import com.boydti.fawe.util.IncendoPaster; +import com.intellectualsites.paster.IncendoPaster; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; @@ -47,6 +47,7 @@ import org.enginehub.piston.annotation.param.Arg; import org.enginehub.piston.annotation.param.ArgFlag; import org.enginehub.piston.annotation.param.Switch; +import java.io.File; import java.io.IOException; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -139,7 +140,10 @@ public class WorldEditCommands { public void report(Actor actor) throws WorldEditException { String dest; try { - dest = IncendoPaster.debugPaste(); + final File logFile = new File(Fawe.imp().getDirectory(), "../../logs/latest.log"); + final File config = new File(Fawe.imp().getDirectory(), "config.yml"); + final File legacyConfig = new File(Fawe.imp().getDirectory(), "config-legacy.yml"); + dest = IncendoPaster.debugPaste(logFile, Fawe.imp().getDebugInfo(), config, legacyConfig); } catch (IOException e) { actor.printInfo(TextComponent.of(e.getMessage())); return; From c5a74cde729f969f05ca48ddb943e0c75491e2ff Mon Sep 17 00:00:00 2001 From: NotMyFault Date: Sun, 20 Dec 2020 22:11:19 +0100 Subject: [PATCH 09/55] Create dependabot.yml --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..e07581508 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" From 5964ac83035a536b2e719bee3ccb7d24174edb88 Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Sun, 20 Dec 2020 22:24:55 +0100 Subject: [PATCH 10/55] renovate > dependabot --- .github/dependabot.yml | 6 ------ renovate.json | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 .github/dependabot.yml create mode 100644 renovate.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index e07581508..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "gradle" - directory: "/" - schedule: - interval: "weekly" diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..c5820bb43 --- /dev/null +++ b/renovate.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "config:base" + ] +} \ No newline at end of file From acec8a8749ada029829cf42b426a2b0de1b5c535 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 20 Dec 2020 21:29:54 +0000 Subject: [PATCH 11/55] Add renovate.json --- renovate.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..f45d8f110 --- /dev/null +++ b/renovate.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "config:base" + ] +} From aca45e4ab07f3bc17b16e4ba05a8c85ed779ec60 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 20 Dec 2020 23:15:24 +0100 Subject: [PATCH 12/55] Update dependency com.comphenix.protocol:ProtocolLib to v4.5.1 (#789) Co-authored-by: Renovate Bot --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 0a49fb6b9..6822937f9 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -77,7 +77,7 @@ dependencies { "implementation"("com.bekvon.bukkit.residence:Residence:4.5._13.1") { isTransitive = false } "implementation"("com.palmergames.bukkit:towny:0.84.0.9") { isTransitive = false } "implementation"("com.thevoxelbox.voxelsniper:voxelsniper:5.171.0") { isTransitive = false } - "implementation"("com.comphenix.protocol:ProtocolLib:4.5.0") { isTransitive = false } + "implementation"("com.comphenix.protocol:ProtocolLib:4.5.1") { isTransitive = false } } tasks.named("processResources") { From 2eb4f1472415407708fa8b30373eb10d6227fdfd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 20 Dec 2020 23:35:57 +0100 Subject: [PATCH 13/55] Update dependency com.plotsquared:PlotSquared-Core to v5.13.3 (#791) Co-authored-by: Renovate Bot --- worldedit-core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 5093b00b7..817318608 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -56,7 +56,7 @@ dependencies { "compile"("com.github.intellectualsites.plotsquared:PlotSquared-API:latest") { isTransitive = false } - "compile"("com.plotsquared:PlotSquared-Core:5.12.2") { + "compile"("com.plotsquared:PlotSquared-Core:5.13.3") { isTransitive = false } "api"("com.intellectualsites.paster:Paster:1.0-SNAPSHOT") From 79f825d21a7e05dc0581d7a3179269abfd43c469 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 21 Dec 2020 00:37:05 +0000 Subject: [PATCH 14/55] Update dependency io.papermc:paperlib to v1.0.6 --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 6822937f9..56adb3d67 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -56,7 +56,7 @@ dependencies { "compileOnly"("org.jetbrains:annotations:20.1.0") "testCompileOnly"("org.jetbrains:annotations:20.1.0") "compileOnly"("org.spigotmc:spigot:1.16.4-R0.1-SNAPSHOT") - "implementation"("io.papermc:paperlib:1.0.4") + "implementation"("io.papermc:paperlib:1.0.6") "compileOnly"("com.sk89q:dummypermscompat:1.10") { exclude("com.github.MilkBowl", "VaultAPI") } From d77e16c66fceb3600a492fddffac5b47178dc364 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 21 Dec 2020 02:36:35 +0000 Subject: [PATCH 15/55] Update dependency org.bstats:bstats-bukkit to v1.8 --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 6822937f9..d995ca20a 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -68,7 +68,7 @@ dependencies { exclude("com.sk89q.worldedit.worldedit-libs", "bukkit") exclude("com.sk89q.worldedit.worldedit-libs", "core") } - "compile"("org.bstats:bstats-bukkit:1.7") + "compile"("org.bstats:bstats-bukkit:1.8") "compile"("com.intellectualsites.paster:Paster:1.0-SNAPSHOT") // Third party "implementation"("com.github.InventivetalentDev:MapManager:1.7.+") { isTransitive = false } From f6cbde6386a96a9a6f7393d0ee11d8db430f70fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 10:44:31 +0100 Subject: [PATCH 16/55] Update dependency org.yaml:snakeyaml to v1.27 (#804) Co-authored-by: Renovate Bot --- worldedit-core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 817318608..9ef42d38e 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -31,7 +31,7 @@ dependencies { "implementation"("de.schlichtherle:truezip:6.8.3") "implementation"("net.java.truevfs:truevfs-profile-default_2.13:0.12.1") "implementation"("org.mozilla:rhino-runtime:1.7.12") - "implementation"("org.yaml:snakeyaml:1.23") + "implementation"("org.yaml:snakeyaml:1.27") "implementation"("com.google.guava:guava:${Versions.GUAVA}") "implementation"("com.google.code.findbugs:jsr305:3.0.2") "implementation"("com.google.code.gson:gson:${Versions.GSON}") From 2f23643635b8c22c9b52328620c9c4d3d3c75c05 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 10:47:07 +0100 Subject: [PATCH 17/55] Update dependency org.slf4j:slf4j-api to v1.7.30 (#803) Co-authored-by: Renovate Bot --- worldedit-core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 9ef42d38e..196b33f3c 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -35,7 +35,7 @@ dependencies { "implementation"("com.google.guava:guava:${Versions.GUAVA}") "implementation"("com.google.code.findbugs:jsr305:3.0.2") "implementation"("com.google.code.gson:gson:${Versions.GSON}") - "implementation"("org.slf4j:slf4j-api:1.7.27") + "implementation"("org.slf4j:slf4j-api:1.7.30") "implementation"("it.unimi.dsi:fastutil:${Versions.FAST_UTIL}") val antlrVersion = "4.7.2" From b3ecbe8c9537ab2a700f20618d208908d6d4bbfc Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Mon, 21 Dec 2020 10:50:12 +0100 Subject: [PATCH 18/55] bStats 1.8 --- worldedit-bukkit/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index d995ca20a..2483315e0 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -109,7 +109,7 @@ tasks.named("shadowJar") { include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) include(dependency("org.antlr:antlr4-runtime")) relocate("org.bstats", "com.sk89q.worldedit.bukkit.bstats") { - include(dependency("org.bstats:bstats-bukkit:1.7")) + include(dependency("org.bstats:bstats-bukkit:1.8")) } relocate("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") { include(dependency("io.papermc:paperlib:1.0.4")) @@ -118,7 +118,7 @@ tasks.named("shadowJar") { include(dependency("it.unimi.dsi:fastutil")) } relocate("org.bstats", "com.boydti.metrics") { - include(dependency("org.bstats:bstats-bukkit:1.7")) + include(dependency("org.bstats:bstats-bukkit:1.8")) } relocate("com.intellectualsites.paster", "com.boydti.fawe.paster") { include(dependency("com.intellectualsites.paster:Paster:1.0-SNAPSHOT")) From f36afe1907151a773b6b97031d24a5f4ca0e9a17 Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Mon, 21 Dec 2020 10:52:15 +0100 Subject: [PATCH 19/55] Paperlib 1.6 --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 417561059..421ff7fb3 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -112,7 +112,7 @@ tasks.named("shadowJar") { include(dependency("org.bstats:bstats-bukkit:1.8")) } relocate("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") { - include(dependency("io.papermc:paperlib:1.0.4")) + include(dependency("io.papermc:paperlib:1.0.6")) } relocate("it.unimi.dsi.fastutil", "com.sk89q.worldedit.bukkit.fastutil") { include(dependency("it.unimi.dsi:fastutil")) From 7928479046415ef2883d64b2775b7521e41c585a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 10:55:46 +0100 Subject: [PATCH 20/55] Update dependency de.schlichtherle:truezip to v6.8.4 (#793) Co-authored-by: Renovate Bot --- worldedit-core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 196b33f3c..490599d7f 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -28,7 +28,7 @@ configurations.all { dependencies { "api"(project(":worldedit-libs:core")) - "implementation"("de.schlichtherle:truezip:6.8.3") + "implementation"("de.schlichtherle:truezip:6.8.4") "implementation"("net.java.truevfs:truevfs-profile-default_2.13:0.12.1") "implementation"("org.mozilla:rhino-runtime:1.7.12") "implementation"("org.yaml:snakeyaml:1.27") From 73406b2e15d8974feccade40c60f3bd15ac9bc27 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 10:57:19 +0100 Subject: [PATCH 21/55] Update dependency gradle to v6.7.1 (#794) Co-authored-by: Renovate Bot --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 12d38de6a..4d9ca1649 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From a32f3b0e8ca556f86748d9f02ea0ac9b6ed6f4ef Mon Sep 17 00:00:00 2001 From: NotMyFault Date: Mon, 21 Dec 2020 11:17:46 +0100 Subject: [PATCH 22/55] Exclude dependencies from renovate --- renovate.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index f45d8f110..7620d71b8 100644 --- a/renovate.json +++ b/renovate.json @@ -1,5 +1,6 @@ { "extends": [ "config:base" - ] + ], + "ignoreDeps": ["guava", "rhino-runtime", "mockito-core", "antlr4", "antlr4-runtime", "paranamer"] } From be05ae923052818d16a47bb884ec0ec09beb1086 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 11:40:00 +0100 Subject: [PATCH 23/55] Update dependency net.java.truevfs:truevfs-profile-default_2.13 to v0.12.2 (#796) Co-authored-by: Renovate Bot --- worldedit-core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 490599d7f..3cb349f00 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -29,7 +29,7 @@ configurations.all { dependencies { "api"(project(":worldedit-libs:core")) "implementation"("de.schlichtherle:truezip:6.8.4") - "implementation"("net.java.truevfs:truevfs-profile-default_2.13:0.12.1") + "implementation"("net.java.truevfs:truevfs-profile-default_2.13:0.12.2") "implementation"("org.mozilla:rhino-runtime:1.7.12") "implementation"("org.yaml:snakeyaml:1.27") "implementation"("com.google.guava:guava:${Versions.GUAVA}") From 44f15da5a37971bc21196e32748ce04a1c368a68 Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Mon, 21 Dec 2020 15:57:57 +0100 Subject: [PATCH 24/55] Update Paster --- worldedit-bukkit/build.gradle.kts | 4 ++-- worldedit-core/build.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 421ff7fb3..0e3f6a7d8 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -69,7 +69,7 @@ dependencies { exclude("com.sk89q.worldedit.worldedit-libs", "core") } "compile"("org.bstats:bstats-bukkit:1.8") - "compile"("com.intellectualsites.paster:Paster:1.0-SNAPSHOT") + "compile"("com.intellectualsites.paster:Paster:1.0.1-SNAPSHOT") // Third party "implementation"("com.github.InventivetalentDev:MapManager:1.7.+") { isTransitive = false } "implementation"("com.github.TechFortress:GriefPrevention:16.+") { isTransitive = false } @@ -121,7 +121,7 @@ tasks.named("shadowJar") { include(dependency("org.bstats:bstats-bukkit:1.8")) } relocate("com.intellectualsites.paster", "com.boydti.fawe.paster") { - include(dependency("com.intellectualsites.paster:Paster:1.0-SNAPSHOT")) + include(dependency("com.intellectualsites.paster:Paster:1.0.1-SNAPSHOT")) } } } diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 3cb349f00..431ca76ec 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -59,7 +59,7 @@ dependencies { "compile"("com.plotsquared:PlotSquared-Core:5.13.3") { isTransitive = false } - "api"("com.intellectualsites.paster:Paster:1.0-SNAPSHOT") + "api"("com.intellectualsites.paster:Paster:1.0.1-SNAPSHOT") } tasks.named("test") { From 27512ceab3d468b73a316690526fb40f58d6fd82 Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Mon, 21 Dec 2020 19:40:06 +0100 Subject: [PATCH 25/55] Don't shade metrics twice --- worldedit-bukkit/build.gradle.kts | 3 --- 1 file changed, 3 deletions(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 0e3f6a7d8..ccb2be692 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -108,9 +108,6 @@ tasks.named("shadowJar") { include(dependency("org.slf4j:slf4j-api")) include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) include(dependency("org.antlr:antlr4-runtime")) - relocate("org.bstats", "com.sk89q.worldedit.bukkit.bstats") { - include(dependency("org.bstats:bstats-bukkit:1.8")) - } relocate("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") { include(dependency("io.papermc:paperlib:1.0.6")) } From 9f2baf71f71f688bdc80d85d29bb6b8c7f63003e Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Mon, 21 Dec 2020 19:43:23 +0100 Subject: [PATCH 26/55] Remove unnecessary version check Due the provided scope and api-version it won't load on older versions anyway --- .../sk89q/worldedit/bukkit/WorldEditPlugin.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index f2d2e1347..500d3796e 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.bukkit; - import com.boydti.fawe.Fawe; import com.boydti.fawe.bukkit.FaweBukkit; import com.google.common.base.Joiner; @@ -93,19 +92,6 @@ import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAM */ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter - // This must be before the Logger is initialized, which fails in 1.8 - private static final String FAILED_VERSION_CHECK = - "\n**********************************************\n" - + "** This Minecraft version (%s) is not supported by this version of WorldEdit.\n" - + "** Please download an OLDER version of WorldEdit which does.\n" - + "**********************************************\n"; - - static { - if (PaperLib.getMinecraftVersion() < 13) { - throw new IllegalStateException(String.format(FAILED_VERSION_CHECK, Bukkit.getVersion())); - } - } - private static final Logger log = LoggerFactory.getLogger(WorldEditPlugin.class); public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui"; private static WorldEditPlugin INSTANCE; From bbc0ea0f35909938a2fafe6f969b0627c1d06481 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 21 Dec 2020 20:06:43 +0000 Subject: [PATCH 27/55] Update dependency com.github.luben:zstd-jni to v1.4.8-1 --- worldedit-core/build.gradle.kts | 2 +- worldedit-libs/core/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 431ca76ec..08ff0092c 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -51,7 +51,7 @@ dependencies { "annotationProcessor"("com.google.auto.value:auto-value:${Versions.AUTO_VALUE}") "testImplementation"("ch.qos.logback:logback-core:${Versions.LOGBACK}") "testImplementation"("ch.qos.logback:logback-classic:${Versions.LOGBACK}") - "compile"("com.github.luben:zstd-jni:1.4.3-1") + "compile"("com.github.luben:zstd-jni:1.4.8-1") "compileOnly"("net.fabiozumbi12:redprotect:1.9.6") "compile"("com.github.intellectualsites.plotsquared:PlotSquared-API:latest") { isTransitive = false diff --git a/worldedit-libs/core/build.gradle.kts b/worldedit-libs/core/build.gradle.kts index 915c530b5..8a025d445 100644 --- a/worldedit-libs/core/build.gradle.kts +++ b/worldedit-libs/core/build.gradle.kts @@ -9,7 +9,7 @@ dependencies { exclude(group = "junit", module = "junit") } "shade"("com.thoughtworks.paranamer:paranamer:2.6") - "shade"("com.github.luben:zstd-jni:1.4.3-1") + "shade"("com.github.luben:zstd-jni:1.4.8-1") "shade"("com.sk89q.lib:jlibnoise:1.0.0") "shade"("org.enginehub.piston:core:${Versions.PISTON}") "shade"("org.enginehub.piston.core-ap:runtime:${Versions.PISTON}") From 7236f1d6fae8c5f635a4ca5dc84d49081168e107 Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Tue, 22 Dec 2020 11:57:12 +0100 Subject: [PATCH 28/55] Update zStandard jni --- worldedit-core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 08ff0092c..24da6be85 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -110,7 +110,7 @@ tasks.named("processResources") { } tasks.named("shadowJar") { dependencies { - include(dependency("com.github.luben:zstd-jni:1.4.3-1")) + include(dependency("com.github.luben:zstd-jni:1.4.8-1")) } } From b60d9ef6d55291a7004de2daf8b6df1a937e1b07 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 23 Dec 2020 17:26:26 +0000 Subject: [PATCH 29/55] Fix #787 --- .../src/main/java/com/sk89q/worldedit/EditSession.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 9a02e26cd..c627bdf99 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2076,7 +2076,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } if (!filled) { - if (nextXn * nextXn + dy * dy + dz * dz <= 1 && nextYn * nextYn + dx * dx + dz * dz <= 1 && nextZn * nextZn + dx * dx + dy * dy <= 1) { + if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1) { continue; } } From 3c5041ddb75752cb99772a02fb7b25d3b15e126e Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 24 Dec 2020 15:47:02 +0000 Subject: [PATCH 30/55] Fix uploading/download P2 schematics with /plot save|load --- .../plotsquared/FaweSchematicHandler.java | 60 ++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java index 5704bb9e9..6b92b4163 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java @@ -9,6 +9,7 @@ import com.boydti.fawe.util.IOUtil; import com.boydti.fawe.util.TaskManager; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.location.Location; +import com.plotsquared.core.plot.schematic.Schematic; import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.SchematicHandler; @@ -16,6 +17,7 @@ import com.plotsquared.core.util.task.RunnableVal; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompressedCompoundTag; import com.sk89q.jnbt.CompressedSchematicTag; +import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; @@ -23,22 +25,30 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.FastSchematicReader; import com.sk89q.worldedit.extent.clipboard.io.FastSchematicWriter; +import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader; +import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.World; import net.jpountz.lz4.LZ4BlockInputStream; +import org.jetbrains.annotations.NotNull; +import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.EOFException; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.zip.GZIPInputStream; import static org.bukkit.Bukkit.getWorld; @@ -114,16 +124,14 @@ public class FaweSchematicHandler extends SchematicHandler { com.plotsquared.core.util.task.TaskManager.runTask(whenDone); return; } - CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag); - if (weTag instanceof CompressedSchematicTag) { - Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource(); - URL url = FaweAPI.upload(clipboard, BuiltInClipboardFormat.SPONGE_SCHEMATIC); - whenDone.run(url); - return; - } + final CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag); MainUtil.upload(uuid, file, "schem", new RunnableVal() { @Override public void run(OutputStream output) { + if (weTag instanceof CompressedSchematicTag) { + Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource(); + BuiltInClipboardFormat.SPONGE_SCHEMATIC.write(output, clipboard); + } try { try (PGZIPOutputStream gzip = new PGZIPOutputStream(output)) { try (NBTOutputStream nos = new NBTOutputStream(gzip)) { @@ -137,4 +145,42 @@ public class FaweSchematicHandler extends SchematicHandler { } }, whenDone); } + + @Override + public Schematic getSchematic(@NotNull InputStream is) { + try { + FastSchematicReader schematicReader = new FastSchematicReader( + new NBTInputStream(new BufferedInputStream(new GZIPInputStream(new BufferedInputStream(is))))); + Clipboard clip = schematicReader.read(); + return new Schematic(clip); + } catch (IOException e) { + if (e instanceof EOFException) { + e.printStackTrace(); + return null; + } + try { + SpongeSchematicReader schematicReader = + new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is))); + Clipboard clip = schematicReader.read(); + return new Schematic(clip); + } catch (IOException e2) { + if (e2 instanceof EOFException) { + e.printStackTrace(); + return null; + } + try { + MCEditSchematicReader schematicReader = + new MCEditSchematicReader(new NBTInputStream(new GZIPInputStream(is))); + Clipboard clip = schematicReader.read(); + return new Schematic(clip); + } catch (IOException e3) { + e.printStackTrace(); + PlotSquared.debug( + is.toString() + " | " + is.getClass().getCanonicalName() + " is not in GZIP format : " + e + .getMessage()); + } + } + } + return null; + } } From 6e49427b2602c1e6f4621f2628b74ee70c708806 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 27 Dec 2020 21:03:09 +0000 Subject: [PATCH 31/55] fix WNA --- .../mc1_15_2/FAWEWorldNativeAccess_1_15_2.java | 10 +++------- .../mc1_16_1/FAWEWorldNativeAccess_1_16.java | 10 +++------- .../mc1_16_2/FAWEWorldNativeAccess_1_16.java | 10 +++------- .../mc1_16_4/FAWEWorldNativeAccess_1_16.java | 10 +++------- .../adapter/impl/FAWE_Spigot_v1_15_R2.java | 17 ++++++++++++++++- .../adapter/impl/FAWE_Spigot_v1_16_R1.java | 17 ++++++++++++++++- .../adapter/impl/FAWE_Spigot_v1_16_R2.java | 17 ++++++++++++++++- .../adapter/impl/FAWE_Spigot_v1_16_R3.java | 17 ++++++++++++++++- 8 files changed, 76 insertions(+), 32 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java index bd3767b9a..32359e353 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java @@ -58,7 +58,7 @@ public class FAWEWorldNativeAccess_1_15_2 implements WorldNativeAccess> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { - return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING)); - } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java index d3a3072e8..a4cb0030b 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java @@ -59,7 +59,7 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { - return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING)); - } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/FAWEWorldNativeAccess_1_16.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/FAWEWorldNativeAccess_1_16.java index 664fd0609..4c00de05e 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/FAWEWorldNativeAccess_1_16.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/FAWEWorldNativeAccess_1_16.java @@ -59,7 +59,7 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { - return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING)); - } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/FAWEWorldNativeAccess_1_16.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/FAWEWorldNativeAccess_1_16.java index b86902067..3116a75d0 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/FAWEWorldNativeAccess_1_16.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/FAWEWorldNativeAccess_1_16.java @@ -60,7 +60,7 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { - return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING)); - } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java index aa63a5b2d..ee7fe2e58 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java @@ -107,6 +107,7 @@ import static org.slf4j.LoggerFactory.getLogger; public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { private final Spigot_v1_15_R2 parent; private char[] ibdToStateOrdinal; + private int[] ordinalToIbdID; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft // ------------------------------------------------------------------------ @@ -125,11 +126,14 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I return false; } ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size + ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); - ibdToStateOrdinal[id] = state.getOrdinalChar(); + char ordinal = state.getOrdinalChar(); + ibdToStateOrdinal[id] = ordinal; + ordinalToIbdID[ordinal] = id; } return true; } @@ -348,6 +352,17 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I } } + public int ordinalToIbdID(char ordinal) { + synchronized (this) { + try { + return ordinalToIbdID[ordinal]; + } catch (NullPointerException e) { + init(); + return ordinalToIbdID(ordinal); + } + } + } + @Override public > BlockData adapt(B state) { BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java index 1ab34aabf..688bf8c11 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java @@ -106,6 +106,7 @@ import static org.slf4j.LoggerFactory.getLogger; public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { private final Spigot_v1_16_R1 parent; private char[] ibdToStateOrdinal; + private int[] ordinalToIbdID; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft // ------------------------------------------------------------------------ @@ -124,11 +125,14 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I return false; } ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size + ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); - ibdToStateOrdinal[id] = state.getOrdinalChar(); + char ordinal = state.getOrdinalChar(); + ibdToStateOrdinal[id] = ordinal; + ordinalToIbdID[ordinal] = id; } return true; } @@ -347,6 +351,17 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I } } + public int ordinalToIbdID(char ordinal) { + synchronized (this) { + try { + return ordinalToIbdID[ordinal]; + } catch (NullPointerException e) { + init(); + return ordinalToIbdID(ordinal); + } + } + } + @Override public > BlockData adapt(B state) { BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java index 3c9d4b680..1121093ea 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java @@ -106,6 +106,7 @@ import static org.slf4j.LoggerFactory.getLogger; public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { private final Spigot_v1_16_R2 parent; private char[] ibdToStateOrdinal; + private int[] ordinalToIbdID; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft @@ -125,11 +126,14 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I return false; } ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size + ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_16_2 material = (BlockMaterial_1_16_2) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); - ibdToStateOrdinal[id] = state.getOrdinalChar(); + char ordinal = state.getOrdinalChar(); + ibdToStateOrdinal[id] = ordinal; + ordinalToIbdID[ordinal] = id; } return true; } @@ -348,6 +352,17 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I } } + public int ordinalToIbdID(char ordinal) { + synchronized (this) { + try { + return ordinalToIbdID[ordinal]; + } catch (NullPointerException e) { + init(); + return ordinalToIbdID(ordinal); + } + } + } + @Override public > BlockData adapt(B state) { BlockMaterial_1_16_2 material = (BlockMaterial_1_16_2) state.getMaterial(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java index 9abe6a038..a49b342bd 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java @@ -107,6 +107,7 @@ import static org.slf4j.LoggerFactory.getLogger; public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { private final Spigot_v1_16_R3 parent; private char[] ibdToStateOrdinal; + private int[] ordinalToIbdID; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft @@ -126,11 +127,14 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I return false; } ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size + ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); - ibdToStateOrdinal[id] = state.getOrdinalChar(); + char ordinal = state.getOrdinalChar(); + ibdToStateOrdinal[id] = ordinal; + ordinalToIbdID[ordinal] = id; } return true; } @@ -349,6 +353,17 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I } } + public int ordinalToIbdID(char ordinal) { + synchronized (this) { + try { + return ordinalToIbdID[ordinal]; + } catch (NullPointerException e) { + init(); + return ordinalToIbdID(ordinal); + } + } + } + @Override public > BlockData adapt(B state) { BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial(); From 71059505d19436529c6d8608f07e1dfe600c2a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 26 Dec 2020 21:00:45 +0100 Subject: [PATCH 32/55] Implement missing AsyncChunk#getTileEntities --- .../com/boydti/fawe/bukkit/wrapper/AsyncChunk.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncChunk.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncChunk.java index 590668be6..030e86c78 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncChunk.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncChunk.java @@ -6,6 +6,7 @@ import com.boydti.fawe.util.TaskManager; import org.bukkit.Chunk; import org.bukkit.ChunkSnapshot; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; @@ -14,6 +15,8 @@ import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.Collections; +import java.util.function.Predicate; import java.util.function.Supplier; public class AsyncChunk implements Chunk { @@ -120,6 +123,16 @@ public class AsyncChunk implements Chunk { return TaskManager.IMP.sync(() -> world.getChunkAt(x, z).getTileEntities(useSnapshot)); } + @NotNull @Override + public Collection getTileEntities(@NotNull Predicate blockPredicate, + boolean useSnapshot) { + if (!isLoaded()) { + return Collections.emptyList(); + } + return TaskManager.IMP.sync(() -> world.getChunkAt(x, z) + .getTileEntities(blockPredicate, useSnapshot)); + } + @Override public boolean isLoaded() { return world.isChunkLoaded(x, z); From df48b7e81d0aab836e4d5c604867c787ad2b284b Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 31 Dec 2020 15:01:54 +0000 Subject: [PATCH 33/55] stop bottling clipboard sizes for no reason --- .../com/boydti/fawe/object/clipboard/LinearClipboard.java | 4 ---- .../com/boydti/fawe/object/clipboard/SimpleClipboard.java | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java index 962a73695..0be9cffcc 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java @@ -21,10 +21,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.UUID; -/** - * Best used when clipboard selections are small, or using legacy formats - * (Small being < Integer.MAX_VALUE/BLOCK_SIZE_BYTES blocks) - */ public abstract class LinearClipboard extends SimpleClipboard { protected final HashSet entities = new HashSet<>(); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/SimpleClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/SimpleClipboard.java index 06b250567..8317860b9 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/SimpleClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/SimpleClipboard.java @@ -14,7 +14,7 @@ public abstract class SimpleClipboard implements Clipboard { SimpleClipboard(BlockVector3 dimensions) { this.size = dimensions; long longVolume = (long) getWidth() * (long) getHeight() * (long) getLength(); - if (longVolume >= Integer.MAX_VALUE >> 2) { + if (longVolume >= Integer.MAX_VALUE) { throw new IllegalArgumentException("Dimensions are too large for this clipboard format."); } this.area = getWidth() * getLength(); From 935130aa0ef2ffacca8ef6066bf5be503acb6e9d Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 31 Dec 2020 15:22:29 +0000 Subject: [PATCH 34/55] Fix AsyncBlock --- .../fawe/bukkit/wrapper/AsyncBlock.java | 84 ++++++++++--------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java index 59c2dc706..d9663e2f3 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java @@ -26,8 +26,8 @@ import org.bukkit.plugin.Plugin; import org.bukkit.util.BoundingBox; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -70,32 +70,32 @@ public class AsyncBlock implements Block { return world.getBlock(x, y, z).getBlockType().getInternalId(); } - @NotNull + @Nonnull @Override public AsyncBlock getRelative(int modX, int modY, int modZ) { return new AsyncBlock(world, x + modX, y + modY, z + modZ); } - @NotNull + @Nonnull @Override public AsyncBlock getRelative(BlockFace face) { return this.getRelative(face.getModX(), face.getModY(), face.getModZ()); } - @NotNull + @Nonnull @Override public AsyncBlock getRelative(BlockFace face, int distance) { return this.getRelative(face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance); } - @NotNull + @Nonnull @Override public Material getType() { return getBlockData().getMaterial(); } - @NotNull + @Nonnull @Override public BlockData getBlockData() { return BukkitAdapter.adapt(world.getBlock(x, y, z)); @@ -141,7 +141,7 @@ public class AsyncBlock implements Block { return (byte) 15; } - @NotNull + @Nonnull @Override public AsyncWorld getWorld() { return world; @@ -162,7 +162,7 @@ public class AsyncBlock implements Block { return z; } - @NotNull + @Nonnull @Override public Location getLocation() { return new Location(world, x, y, z); @@ -179,14 +179,14 @@ public class AsyncBlock implements Block { return loc; } - @NotNull + @Nonnull @Override public AsyncChunk getChunk() { return world.getChunkAt(x >> 4, z >> 4); } @Override - public void setBlockData(@NotNull BlockData blockData) { + public void setBlockData(@Nonnull BlockData blockData) { try { world.setBlock(x, y, z, BukkitAdapter.adapt(blockData)); } catch (WorldEditException e) { @@ -195,12 +195,12 @@ public class AsyncBlock implements Block { } @Override - public void setBlockData(@NotNull BlockData blockData, boolean b) { + public void setBlockData(@Nonnull BlockData blockData, boolean b) { setBlockData(blockData); } @Override - public void setType(@NotNull Material type) { + public void setType(@Nonnull Material type) { try { world.setBlock(x, y, z, BukkitAdapter.asBlockType(type).getDefaultState()); } catch (WorldEditException e) { @@ -209,12 +209,12 @@ public class AsyncBlock implements Block { } @Override - public void setType(@NotNull Material type, boolean applyPhysics) { + public void setType(@Nonnull Material type, boolean applyPhysics) { setType(type); } @Override - public BlockFace getFace(@NotNull Block block) { + public BlockFace getFace(@Nonnull Block block) { BlockFace[] directions = BlockFace.values(); for (BlockFace face : directions) { if (this.getX() + face.getModX() == block.getX() @@ -226,7 +226,7 @@ public class AsyncBlock implements Block { return null; } - @NotNull + @Nonnull @Override public AsyncBlockState getState() { BaseBlock state = world.getFullBlock(x, y, z); @@ -250,19 +250,19 @@ public class AsyncBlock implements Block { } @Override - @NotNull + @Nonnull public AsyncBlockState getState(boolean useSnapshot) { return getState(); } - @NotNull + @Nonnull @Override public Biome getBiome() { return world.getAdapter().adapt(world.getBiomeType(x, y, z)); } @Override - public void setBiome(@NotNull Biome bio) { + public void setBiome(@Nonnull Biome bio) { BiomeType biome = world.getAdapter().adapt(bio); world.setBiome(x, 0, z, biome); } @@ -278,17 +278,17 @@ public class AsyncBlock implements Block { } @Override - public boolean isBlockFacePowered(@NotNull BlockFace face) { + public boolean isBlockFacePowered(@Nonnull BlockFace face) { return false; } @Override - public boolean isBlockFaceIndirectlyPowered(@NotNull BlockFace face) { + public boolean isBlockFaceIndirectlyPowered(@Nonnull BlockFace face) { return false; } @Override - public int getBlockPower(@NotNull BlockFace face) { + public int getBlockPower(@Nonnull BlockFace face) { return 0; } @@ -324,7 +324,7 @@ public class AsyncBlock implements Block { return this.getWorld().getHumidity(this.getX(), this.getZ()); } - @NotNull + @Nonnull @Override public PistonMoveReaction getPistonMoveReaction() { return PistonMoveReaction.IGNORE; @@ -341,23 +341,23 @@ public class AsyncBlock implements Block { } @Override - public boolean breakNaturally(@NotNull ItemStack tool) { + public boolean breakNaturally(@Nonnull ItemStack tool) { return TaskManager.IMP.sync(() -> getUnsafeBlock().breakNaturally(tool)); } - public boolean breakNaturally(@NotNull ItemStack tool, boolean value) { + public boolean breakNaturally(@Nonnull ItemStack tool, boolean value) { return TaskManager.IMP.sync(() -> getUnsafeBlock().breakNaturally(tool)); } - @NotNull + @Nonnull @Override public Collection getDrops() { return TaskManager.IMP.sync(() -> getUnsafeBlock().getDrops()); } - @NotNull + @Nonnull @Override - public Collection getDrops(@NotNull ItemStack tool) { + public Collection getDrops(@Nonnull ItemStack tool) { return TaskManager.IMP.sync(() -> getUnsafeBlock().getDrops(tool)); } @@ -366,23 +366,23 @@ public class AsyncBlock implements Block { } @Override - public void setMetadata(@NotNull String metadataKey, @NotNull MetadataValue newMetadataValue) { + public void setMetadata(@Nonnull String metadataKey, @Nonnull MetadataValue newMetadataValue) { this.getUnsafeBlock().setMetadata(metadataKey, newMetadataValue); } - @NotNull + @Nonnull @Override - public List getMetadata(@NotNull String metadataKey) { + public List getMetadata(@Nonnull String metadataKey) { return this.getUnsafeBlock().getMetadata(metadataKey); } @Override - public boolean hasMetadata(@NotNull String metadataKey) { + public boolean hasMetadata(@Nonnull String metadataKey) { return this.getUnsafeBlock().hasMetadata(metadataKey); } @Override - public void removeMetadata(@NotNull String metadataKey, @NotNull Plugin owningPlugin) { + public void removeMetadata(@Nonnull String metadataKey, @Nonnull Plugin owningPlugin) { this.getUnsafeBlock().removeMetadata(metadataKey, owningPlugin); } @@ -392,12 +392,12 @@ public class AsyncBlock implements Block { } @Override - public RayTraceResult rayTrace(@NotNull Location arg0, @NotNull Vector arg1, double arg2, - @NotNull FluidCollisionMode arg3) { + public RayTraceResult rayTrace(@Nonnull Location arg0, @Nonnull Vector arg1, double arg2, + @Nonnull FluidCollisionMode arg3) { return this.getUnsafeBlock().rayTrace(arg0, arg1, arg2, arg3); } - public boolean applyBoneMeal(@NotNull BlockFace face) { + public boolean applyBoneMeal(@Nonnull BlockFace face) { throw new UnsupportedOperationException("FAWE does not support this yet"); } @@ -405,22 +405,28 @@ public class AsyncBlock implements Block { throw new UnsupportedOperationException("FAWE does not support this yet"); } - @NotNull + @Nonnull @Override - public float getDestroySpeed(@NotNull ItemStack itemStack) { + public float getDestroySpeed(@Nonnull ItemStack itemStack) { throw new UnsupportedOperationException("FAWE does not support this yet"); } - @NotNull + @Nonnull @Override public BoundingBox getBoundingBox() { return this.getUnsafeBlock().getBoundingBox(); } @Override - @NotNull + @Nonnull public BlockSoundGroup getSoundGroup() { return TaskManager.IMP.sync(() -> getUnsafeBlock().getSoundGroup()); } + + @Override + @Nonnull + public boolean isSolid() { + return this.getType().isSolid(); + } } From 59c227b49a824b5b9ff0604827da46c4faed3fa5 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 31 Dec 2020 15:32:00 +0000 Subject: [PATCH 35/55] actually fix AsyncBlock --- .../boydti/fawe/bukkit/wrapper/AsyncBlock.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java index d9663e2f3..ad4b44712 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlock.java @@ -314,6 +314,21 @@ public class AsyncBlock implements Block { return world.getBlock(x, y, z).getMaterial().isLiquid(); } + @Override + public boolean isBuildable() { + return this.getUnsafeBlock().isBuildable(); + } + + @Override + public boolean isBurnable() { + return this.getType().isBurnable(); + } + + @Override + public boolean isReplaceable() { + return this.getUnsafeBlock().isReplaceable(); + } + @Override public double getTemperature() { return this.getWorld().getTemperature(this.getX(), this.getZ()); From 82f640d13286bfa02d335cfb2b2774e050374101 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 31 Dec 2020 17:45:07 +0000 Subject: [PATCH 36/55] fix loading Fawe.properties --- worldedit-core/src/main/java/com/boydti/fawe/Fawe.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java b/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java index dab5fc305..41104b552 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java @@ -235,8 +235,8 @@ public class Fawe { // Setting up config.yml File file = new File(this.implementation.getDirectory(), "config.yml"); Settings.IMP.PLATFORM = implementation.getPlatform().replace("\"", ""); - try (InputStream stream = getClass().getResourceAsStream(File.separator + "fawe.properties"); - BufferedReader br = new BufferedReader(new InputStreamReader(stream))) { + try (InputStream stream = getClass().getResourceAsStream("/fawe.properties"); + BufferedReader br = new BufferedReader(new InputStreamReader(stream))) { String versionString = br.readLine(); String commitString = br.readLine(); String dateString = br.readLine(); From fbfe3221d7d22c51bfceabf21c657fbc98f54946 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 1 Jan 2021 15:01:35 +0000 Subject: [PATCH 37/55] Fix fast schematic reader/writer - Have both sponge and fast r/w available but default to "fast" - Correctly "offset" entities in the schematic, and add a legacy mode for loading old FAWE schematics with entities required. - Lazily reading means it's read in order of appearance in the inputstream so we need to read schematic version first (skip past everything) and then reset the stream. Fixes #740 - Add an FAWEVersion to the metadata - Correctly actually return a BlockArrayClipboard when required. Fixes #454 --- .../fawe/jnbt/streamer/StreamDelegate.java | 2 +- .../java/com/sk89q/jnbt/NBTInputStream.java | 26 +++-- .../worldedit/command/SchematicCommands.java | 6 +- .../clipboard/io/BuiltInClipboardFormat.java | 94 ++++++++++++++++++- .../clipboard/io/FastSchematicReader.java | 65 ++++++++++--- .../clipboard/io/FastSchematicWriter.java | 41 +++----- .../extent/clipboard/io/SchematicReader.java | 2 +- .../clipboard/io/SpongeSchematicWriter.java | 2 + 8 files changed, 181 insertions(+), 57 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/streamer/StreamDelegate.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/streamer/StreamDelegate.java index a404c8956..eea8b8545 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/streamer/StreamDelegate.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/streamer/StreamDelegate.java @@ -200,7 +200,7 @@ public class StreamDelegate { Object raw = is.readTagPayloadRaw(type, depth); valueReader.apply(0, raw); } else { - is.readTagPaylodLazy(type, depth + 1, this); + is.readTagPayloadLazy(type, depth + 1, this); } } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java index c2282e9fc..c86179b4b 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java @@ -61,6 +61,14 @@ public final class NBTInputStream implements Closeable { this.is = dis; } + public void mark(int mark) { + is.mark(mark); + } + + public void reset() throws IOException { + is.reset(); + } + /** * Reads an NBT tag from the stream. * @@ -99,7 +107,7 @@ public final class NBTInputStream implements Closeable { if (child != null) { child.acceptRoot(this, type, 0); } else { - readTagPaylodLazy(type, 0); + readTagPayloadLazy(type, 0); } } catch (Throwable e) { e.printStackTrace(); @@ -119,7 +127,7 @@ public final class NBTInputStream implements Closeable { private byte[] buf; - public void readTagPaylodLazy(int type, int depth) throws IOException { + public void readTagPayloadLazy(int type, int depth) throws IOException { switch (type) { case NBTConstants.TYPE_END: return; @@ -152,7 +160,7 @@ public final class NBTInputStream implements Closeable { int childType = is.readByte(); length = is.readInt(); for (int i = 0; i < length; ++i) { - readTagPaylodLazy(childType, depth + 1); + readTagPayloadLazy(childType, depth + 1); } return; } @@ -165,7 +173,7 @@ public final class NBTInputStream implements Closeable { return; } is.skipBytes(is.readShort() & 0xFFFF); - readTagPaylodLazy(childType, depth + 1); + readTagPayloadLazy(childType, depth + 1); } } case NBTConstants.TYPE_INT_ARRAY: { @@ -181,7 +189,7 @@ public final class NBTInputStream implements Closeable { } } - public void readTagPaylodLazy(int type, int depth, StreamDelegate scope) throws IOException { + public void readTagPayloadLazy(int type, int depth, StreamDelegate scope) throws IOException { switch (type) { case NBTConstants.TYPE_END: return; @@ -293,11 +301,11 @@ public final class NBTInputStream implements Closeable { child = scope.get0(); if (child == null) { for (int i = 0; i < length; ++i) { - readTagPaylodLazy(childType, depth + 1); + readTagPayloadLazy(childType, depth + 1); } } else { for (int i = 0; i < length; ++i) { - readTagPaylodLazy(childType, depth + 1, child); + readTagPayloadLazy(childType, depth + 1, child); } } return; @@ -330,9 +338,9 @@ public final class NBTInputStream implements Closeable { } StreamDelegate child = scope.get(is); if (child == null) { - readTagPaylodLazy(childType, depth + 1); + readTagPayloadLazy(childType, depth + 1); } else { - readTagPaylodLazy(childType, depth + 1, child); + readTagPayloadLazy(childType, depth + 1, child); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 037cae63c..cf3488921 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -147,7 +147,7 @@ public class SchematicCommands { @Deprecated @CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.web", "worldedit.schematic.load.asset"}) public void loadall(Player player, LocalSession session, - @Arg(desc = "Format name.", def = "schematic") + @Arg(desc = "Format name.", def = "fast") String formatName, @Arg(desc = "File name.") String filename, @@ -223,7 +223,7 @@ public class SchematicCommands { public void load(Actor actor, LocalSession session, @Arg(desc = "File name.") String filename, - @Arg(desc = "Format name.", def = "sponge") + @Arg(desc = "Format name.", def = "fast") String formatName) throws FilenameException { LocalConfiguration config = worldEdit.getConfiguration(); @@ -323,7 +323,7 @@ public class SchematicCommands { public void save(Actor actor, LocalSession session, @Arg(desc = "File name.") String filename, - @Arg(desc = "Format name.", def = "sponge") + @Arg(desc = "Format name.", def = "fast") String formatName, @Switch(name = 'f', desc = "Overwrite an existing file.") boolean allowOverwrite, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index d01db5dbb..cde698903 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -24,8 +24,11 @@ import com.boydti.fawe.object.io.ResettableFileInputStream; import com.boydti.fawe.object.schematic.MinecraftStructure; import com.boydti.fawe.object.schematic.PNGWriter; import com.google.common.collect.ImmutableSet; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; +import com.sk89q.jnbt.NamedTag; +import com.sk89q.jnbt.Tag; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -35,6 +38,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Locale; +import java.util.Map; import java.util.Set; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -44,6 +48,44 @@ import java.util.zip.GZIPOutputStream; */ public enum BuiltInClipboardFormat implements ClipboardFormat { + FAST("fast", "fawe") { + + @Override + public String getPrimaryFileExtension() { + return "schem"; + } + + @Override + public ClipboardReader getReader(InputStream inputStream) throws IOException { + if (inputStream instanceof FileInputStream) { + inputStream = new ResettableFileInputStream((FileInputStream) inputStream); + } + BufferedInputStream buffered = new BufferedInputStream(inputStream); + NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered))); + return new FastSchematicReader(nbtStream); + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + OutputStream gzip; + if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) { + gzip = outputStream; + } else { + outputStream = new BufferedOutputStream(outputStream); + gzip = new PGZIPOutputStream(outputStream); + } + NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip)); + return new FastSchematicWriter(nbtStream); + } + + @Override + public boolean isFormat(File file) { + String name = file.getName().toLowerCase(Locale.ROOT); + return name.endsWith(".schem") || name.endsWith(".sponge"); + } + + }, + /** * The Schematic format used by MCEdit. */ @@ -77,8 +119,49 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { return name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce"); } }, + SPONGE_SCHEMATIC("sponge", "schem") { + @Override + public String getPrimaryFileExtension() { + return "schem"; + } + @Override + public ClipboardReader getReader(InputStream inputStream) throws IOException { + NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(inputStream)); + return new SpongeSchematicReader(nbtStream); + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream)); + return new SpongeSchematicWriter(nbtStream); + } + + @Override + public boolean isFormat(File file) { + try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) { + NamedTag rootTag = str.readNamedTag(); + if (!rootTag.getName().equals("Schematic")) { + return false; + } + CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); + + // Check + Map schematic = schematicTag.getValue(); + if (!schematic.containsKey("Version")) { + return false; + } + } catch (Exception e) { + return false; + } + + return true; + } + }, + + BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") { + @Override public String getPrimaryFileExtension() { return "schem"; @@ -91,7 +174,9 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } BufferedInputStream buffered = new BufferedInputStream(inputStream); NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered))); - return new FastSchematicReader(nbtStream); + FastSchematicReader reader = new FastSchematicReader(nbtStream); + reader.setBrokenEntities(true); + return reader; } @Override @@ -104,13 +189,14 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { gzip = new PGZIPOutputStream(outputStream); } NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip)); - return new FastSchematicWriter(nbtStream); + FastSchematicWriter writer = new FastSchematicWriter(nbtStream); + writer.setBrokenEntities(true); + return writer; } @Override public boolean isFormat(File file) { - String name = file.getName().toLowerCase(Locale.ROOT); - return name.endsWith(".schem") || name.endsWith(".sponge"); + return false; } }, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java index c0c413689..e4674b85f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java @@ -30,10 +30,12 @@ import com.boydti.fawe.object.io.FastByteArraysInputStream; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.NBTInputStream; +import com.sk89q.jnbt.NamedTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; @@ -45,6 +47,7 @@ import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityTypes; @@ -58,6 +61,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.OptionalInt; import java.util.UUID; import java.util.function.Function; @@ -70,9 +74,10 @@ public class FastSchematicReader extends NBTSchematicReader { private static final Logger log = LoggerFactory.getLogger(FastSchematicReader.class); private final NBTInputStream inputStream; - private DataFixer fixer = null; + private DataFixer fixer; private int dataVersion = -1; private int version = -1; + private int faweWritten = -1; private FastByteArrayOutputStream blocksOut; private FaweOutputStream blocks; @@ -92,6 +97,7 @@ public class FastSchematicReader extends NBTSchematicReader { private char[] palette; private char[] biomePalette; private BlockVector3 min = BlockVector3.ZERO; + private boolean brokenEntities = false; /** @@ -105,6 +111,10 @@ public class FastSchematicReader extends NBTSchematicReader { this.fixer = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataFixer(); } + public void setBrokenEntities(boolean brokenEntities) { + this.brokenEntities = brokenEntities; + } + private String fix(String palettePart) { if (fixer == null || dataVersion == -1) { return palettePart; @@ -133,7 +143,7 @@ public class FastSchematicReader extends NBTSchematicReader { return fixer.fixUp(DataFixer.FixTypes.BIOME, biomePalettePart, dataVersion); } - public StreamDelegate createDelegate() { + public StreamDelegate createVersionDelegate() { StreamDelegate root = new StreamDelegate(); StreamDelegate schematic = root.add("Schematic"); schematic.add("DataVersion").withInt((i, v) -> dataVersion = v); @@ -143,6 +153,12 @@ public class FastSchematicReader extends NBTSchematicReader { dataVersion = Constants.DATA_VERSION_MC_1_13_2; } }); + return root; + } + + public StreamDelegate createDelegate() { + StreamDelegate root = new StreamDelegate(); + StreamDelegate schematic = root.add("Schematic"); schematic.add("Width").withInt((i, v) -> width = v); schematic.add("Height").withInt((i, v) -> height = v); schematic.add("Length").withInt((i, v) -> length = v); @@ -152,17 +168,19 @@ public class FastSchematicReader extends NBTSchematicReader { metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v); metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v); metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v); + metadata.add("FAWEVersion").withInt((i, v) -> faweWritten = v); StreamDelegate paletteDelegate = schematic.add("Palette"); paletteDelegate.withValue((ValueReader>) (ignore, v) -> { palette = new char[v.size()]; for (Entry entry : v.entrySet()) { - BlockState state = null; + BlockState state; + String palettePart = fix(entry.getKey()); try { - String palettePart = fix(entry.getKey()); state = BlockState.get(palettePart); - } catch (InputParseException e) { - e.printStackTrace(); + } catch (InputParseException ignored) { + log.warn("Invalid BlockState in palette: " + palettePart + ". Block will be replaced with air."); + state = BlockTypes.AIR.getDefaultState(); } int index = (int) entry.getValue(); palette[index] = (char) state.getOrdinal(); @@ -224,10 +242,14 @@ public class FastSchematicReader extends NBTSchematicReader { @Override public Clipboard read(UUID uuid, Function createOutput) throws IOException { StreamDelegate root = createDelegate(); + StreamDelegate versions = createVersionDelegate(); + inputStream.mark(Integer.MAX_VALUE); + inputStream.readNamedTagLazy(versions); + inputStream.reset(); inputStream.readNamedTagLazy(root); if (version != 1 && version != 2) { - throw new IOException("This schematic version is currently not supported"); + throw new IOException("This schematic version is currently not supported (" + version + ")"); } if (blocks != null) { @@ -240,9 +262,11 @@ public class FastSchematicReader extends NBTSchematicReader { biomes = null; BlockVector3 dimensions = BlockVector3.at(width, height, length); - BlockVector3 origin = BlockVector3.ZERO; + BlockVector3 origin; if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) { origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ); + } else { + origin = BlockVector3.ZERO; } Clipboard clipboard = createOutput.apply(dimensions); @@ -352,7 +376,7 @@ public class FastSchematicReader extends NBTSchematicReader { if (id == null) { id = (StringTag) value.get("id"); if (id == null) { - return null; + continue; } } value.put("id", id); @@ -363,7 +387,26 @@ public class FastSchematicReader extends NBTSchematicReader { ent = fixEntity(ent); BaseEntity state = new BaseEntity(type, ent); Location loc = ent.getEntityLocation(clipboard); - clipboard.createEntity(loc, state); + if (brokenEntities) { + clipboard.createEntity(loc, state); + continue; + } + if (faweWritten == -1) { + int locX = loc.getBlockX(); + int locY = loc.getBlockY(); + int locZ = loc.getBlockZ(); + BlockVector3 max = min.add(dimensions).subtract(BlockVector3.ONE); + if (locX < min.getX() || locY < min.getY() || locZ < min.getZ() + || locX > max.getX() || locY > max.getY() || locZ > max.getZ()) { + for (Entity e : clipboard.getEntities()) { + clipboard.removeEntity(e); + } + log.error("Detected schematic entity outside clipboard region. FAWE will not load entities. " + + "Please try loading the schematic with the format \"legacyentity\""); + break; + } + } + clipboard.createEntity(loc.setPosition(loc.subtract(min.toVector3())), state); } else { log.debug("Invalid entity: " + id); } @@ -372,7 +415,7 @@ public class FastSchematicReader extends NBTSchematicReader { clipboard.setOrigin(origin); if (!min.equals(BlockVector3.ZERO)) { - new BlockArrayClipboard(clipboard, min); + clipboard = new BlockArrayClipboard(clipboard, min); } return clipboard; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java index 092bc94d0..6351c7f80 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java @@ -19,10 +19,10 @@ package com.sk89q.worldedit.extent.clipboard.io; +import com.boydti.fawe.Fawe; import com.boydti.fawe.jnbt.streamer.IntValueReader; import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.util.IOUtil; -import com.google.common.collect.Maps; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntArrayTag; import com.sk89q.jnbt.ListTag; @@ -39,6 +39,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.visitor.Order; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -58,8 +59,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; @@ -72,6 +71,7 @@ public class FastSchematicWriter implements ClipboardWriter { private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE; private final NBTOutputStream outputStream; + private boolean brokenEntities = false; /** * Create a new schematic writer. @@ -83,6 +83,10 @@ public class FastSchematicWriter implements ClipboardWriter { this.outputStream = outputStream; } + public void setBrokenEntities(boolean brokenEntities) { + this.brokenEntities = brokenEntities; + } + @Override public void write(Clipboard clipboard) throws IOException { // For now always write the latest version. Maybe provide support for earlier if more appear. @@ -132,6 +136,7 @@ public class FastSchematicWriter implements ClipboardWriter { out1.writeNamedTag("WEOffsetX", offset.getBlockX()); out1.writeNamedTag("WEOffsetY", offset.getBlockY()); out1.writeNamedTag("WEOffsetZ", offset.getBlockZ()); + out1.writeNamedTag("FAWEVersion", Fawe.get().getVersion().build); }); ByteArrayOutputStream blocksCompressed = new ByteArrayOutputStream(); @@ -240,8 +245,12 @@ public class FastSchematicWriter implements ClipboardWriter { // 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(entity.getLocation())); + values.put("Pos", writeVector(loc)); values.put("Rotation", writeRotation(entity.getLocation())); CompoundTag entityTag = new CompoundTag(values); @@ -311,30 +320,6 @@ public class FastSchematicWriter implements ClipboardWriter { } } - private void writeEntities(Clipboard clipboard, NBTOutputStream schematic) throws IOException { - List entities = clipboard.getEntities().stream().map(e -> { - BaseEntity state = e.getState(); - if (state == null) { - return null; - } - Map values = Maps.newHashMap(); - CompoundTag rawData = state.getNbtData(); - if (rawData != null) { - values.putAll(rawData.getValue()); - } - values.remove("id"); - values.put("Id", new StringTag(state.getType().getId())); - values.put("Pos", writeVector(e.getLocation().toVector())); - values.put("Rotation", writeRotation(e.getLocation())); - - return new CompoundTag(values); - }).filter(Objects::nonNull).collect(Collectors.toList()); - if (entities.isEmpty()) { - return; - } - schematic.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities)); - } - @Override public void close() throws IOException { outputStream.close(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java index 14f363009..e64bb3a97 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java @@ -378,7 +378,7 @@ public class SchematicReader implements ClipboardReader { BlockVector3 min = BlockVector3.at(originX, originY, originZ); if (!min.equals(BlockVector3.ZERO)) { - new BlockArrayClipboard(clipboard, min); + clipboard = new BlockArrayClipboard(clipboard, min); } return clipboard; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index c556febf9..00e7e8868 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.extent.clipboard.io; +import com.boydti.fawe.Fawe; import com.google.common.collect.Maps; import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.CompoundTag; @@ -114,6 +115,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { metadata.put("WEOffsetX", new IntTag(offset.getBlockX())); metadata.put("WEOffsetY", new IntTag(offset.getBlockY())); metadata.put("WEOffsetZ", new IntTag(offset.getBlockZ())); + metadata.put("FAWEVersion", new IntTag(Fawe.get().getVersion().build)); schematic.put("Metadata", new CompoundTag(metadata)); From 606cfa5cbc0fc09205e67204c3e1583d1bbe41ec Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 1 Jan 2021 16:07:57 +0000 Subject: [PATCH 38/55] we don't need to "update" when copying sections --- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 14 +++++++------- .../mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java | 4 ++-- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 14 +++++++------- .../mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java | 4 ++-- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 14 +++++++------- .../mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java | 4 ++-- .../mc1_16_4/BukkitGetBlocks_1_16_4.java | 17 +++++++---------- .../mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java | 4 ++-- 8 files changed, 36 insertions(+), 39 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index 549526f9f..f078eb9a0 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -90,6 +90,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { public NibbleArray[] skyLight = new NibbleArray[16]; private boolean createCopy = false; private BukkitGetBlocks_1_15_2_Copy copy = null; + private boolean forceLoadSections = true; public BukkitGetBlocks_1_15_2(World world, int chunkX, int chunkZ) { this(((CraftWorld) world).getHandle(), chunkX, chunkZ); @@ -316,6 +317,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { + forceLoadSections = false; copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world, getChunkX(), getChunkZ()) : null; try { WorldServer nmsWorld = world; @@ -364,7 +366,6 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { // If we're creating a copy, it's because we're delaying history so we do not want to write to // the chunkSet yet. if (createCopy) { - setArr = setArr.clone(); copy.storeSection(layer); copy.storeSetBlocks(layer, setArr); } @@ -408,7 +409,6 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode); if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); - continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); } @@ -475,9 +475,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { Set entityRemoves = set.getEntityRemoves(); if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } + syncTasks = new Runnable[3]; syncTasks[2] = () -> { final List[] entities = nmsChunk.getEntitySlices(); @@ -637,6 +635,8 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { } catch (Throwable e) { e.printStackTrace(); return null; + } finally { + forceLoadSections = true; } } @@ -758,7 +758,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { } public ChunkSection[] getSections(boolean force) { - if (force) { + if (force && forceLoadSections) { return sections = getChunk().getSections().clone(); } ChunkSection[] tmp = sections; @@ -828,7 +828,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections(false)[i]; + ChunkSection existing = getSections(true)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java index 19fb70d5d..837676daa 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java @@ -108,7 +108,7 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 implemen } protected void storeSection(int layer) { - blocks[layer] = update(layer, null).clone(); + blocks[layer] = load(layer).clone(); } @Override @@ -130,7 +130,7 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 implemen } protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks; + newSetBlocks[layer] = blocks.clone(); } @Override diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 458ae27a5..63ad1dada 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -90,6 +90,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { public NibbleArray[] skyLight = new NibbleArray[16]; private boolean createCopy = false; private BukkitGetBlocks_1_16_1_Copy copy = null; + private boolean forceLoadSections = true; public BukkitGetBlocks_1_16_1(World world, int chunkX, int chunkZ) { this(((CraftWorld) world).getHandle(), chunkX, chunkZ); @@ -316,6 +317,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { + forceLoadSections = false; copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world, getChunkX(), getChunkZ()) : null; try { WorldServer nmsWorld = world; @@ -364,7 +366,6 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { // If we're creating a copy, it's because we're delaying history so we do not want to write to // the chunkSet yet. if (createCopy) { - setArr = setArr.clone(); copy.storeSection(layer); copy.storeSetBlocks(layer, setArr); } @@ -410,7 +411,6 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { if (!BukkitAdapter_1_16_1 .setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); - continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); } @@ -477,9 +477,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { Set entityRemoves = set.getEntityRemoves(); if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } + syncTasks = new Runnable[3]; syncTasks[2] = () -> { final List[] entities = nmsChunk.getEntitySlices(); @@ -639,6 +637,8 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { } catch (Throwable e) { e.printStackTrace(); return null; + } finally { + forceLoadSections = true; } } @@ -760,7 +760,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { } public ChunkSection[] getSections(boolean force) { - if (force) { + if (force && forceLoadSections) { return sections = getChunk().getSections().clone(); } ChunkSection[] tmp = sections; @@ -830,7 +830,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections(false)[i]; + ChunkSection existing = getSections(true)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java index 5deaaa901..2cd174af9 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java @@ -109,7 +109,7 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 implemen } protected void storeSection(int layer) { - blocks[layer] = update(layer, null).clone(); + blocks[layer] = load(layer).clone(); } @Override @@ -131,7 +131,7 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 implemen } protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks; + newSetBlocks[layer] = blocks.clone(); } @Override diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index 44c885305..f22000616 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -91,6 +91,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { public NibbleArray[] skyLight = new NibbleArray[16]; private boolean createCopy = false; private BukkitGetBlocks_1_16_2_Copy copy = null; + private boolean forceLoadSections = true; public BukkitGetBlocks_1_16_2(World world, int chunkX, int chunkZ) { this(((CraftWorld) world).getHandle(), chunkX, chunkZ); @@ -319,6 +320,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { + forceLoadSections = false; copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world, getChunkX(), getChunkZ()) : null; try { WorldServer nmsWorld = world; @@ -367,7 +369,6 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { // If we're creating a copy, it's because we're delaying history so we do not want to write to // the chunkSet yet. if (createCopy) { - setArr = setArr.clone(); copy.storeSection(layer); copy.storeSetBlocks(layer, setArr); } @@ -413,7 +414,6 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { if (!BukkitAdapter_1_16_2 .setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); - continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); } @@ -480,9 +480,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { Set entityRemoves = set.getEntityRemoves(); if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } + syncTasks = new Runnable[3]; syncTasks[2] = () -> { final List[] entities = nmsChunk.getEntitySlices(); @@ -642,6 +640,8 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { } catch (Throwable e) { e.printStackTrace(); return null; + } finally { + forceLoadSections = true; } } @@ -763,7 +763,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { } public ChunkSection[] getSections(boolean force) { - if (force) { + if (force && forceLoadSections) { return sections = getChunk().getSections().clone(); } ChunkSection[] tmp = sections; @@ -833,7 +833,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections(false)[i]; + ChunkSection existing = getSections(true)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java index dccf17358..c0086e180 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java @@ -109,7 +109,7 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 implemen } protected void storeSection(int layer) { - blocks[layer] = update(layer, null).clone(); + blocks[layer] = load(layer).clone(); } @Override @@ -131,7 +131,7 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 implemen } protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks; + newSetBlocks[layer] = blocks.clone(); } @Override diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index e43987767..1282a8d45 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -1,7 +1,6 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_4; import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; @@ -28,10 +27,8 @@ import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; import net.minecraft.server.v1_16_R3.BiomeBase; import net.minecraft.server.v1_16_R3.BiomeStorage; -import net.minecraft.server.v1_16_R3.Block; import net.minecraft.server.v1_16_R3.BlockPosition; import net.minecraft.server.v1_16_R3.Chunk; import net.minecraft.server.v1_16_R3.ChunkSection; @@ -94,6 +91,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { public NibbleArray[] skyLight = new NibbleArray[16]; private boolean createCopy = false; private BukkitGetBlocks_1_16_4_Copy copy = null; + private boolean forceLoadSections = true; public BukkitGetBlocks_1_16_4(World world, int chunkX, int chunkZ) { this(((CraftWorld) world).getHandle(), chunkX, chunkZ); @@ -322,6 +320,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { + forceLoadSections = false; copy = createCopy ? new BukkitGetBlocks_1_16_4_Copy(world, getChunkX(), getChunkZ()) : null; try { WorldServer nmsWorld = world; @@ -370,7 +369,6 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { // If we're creating a copy, it's because we're delaying history so we do not want to write to // the chunkSet yet. if (createCopy) { - setArr = setArr.clone(); copy.storeSection(layer); copy.storeSetBlocks(layer, setArr); } @@ -416,7 +414,6 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { if (!BukkitAdapter_1_16_4 .setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); - continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); } @@ -483,9 +480,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { Set entityRemoves = set.getEntityRemoves(); if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } + syncTasks = new Runnable[3]; syncTasks[2] = () -> { final List[] entities = nmsChunk.getEntitySlices(); @@ -645,6 +640,8 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { } catch (Throwable e) { e.printStackTrace(); return null; + } finally { + forceLoadSections = true; } } @@ -766,7 +763,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { } public ChunkSection[] getSections(boolean force) { - if (force) { + if (force && forceLoadSections) { return sections = getChunk().getSections().clone(); } ChunkSection[] tmp = sections; @@ -836,7 +833,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { continue; } - ChunkSection existing = getSections(false)[i]; + ChunkSection existing = getSections(true)[i]; try { final DataPaletteBlock blocksExisting = existing.getBlocks(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java index 3a2ebe25f..da2980d1e 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java @@ -109,7 +109,7 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 implemen } protected void storeSection(int layer) { - blocks[layer] = update(layer, null).clone(); + blocks[layer] = load(layer).clone(); } @Override @@ -131,7 +131,7 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 implemen } protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks; + newSetBlocks[layer] = blocks.clone(); } @Override From 42346b429b7365aaf0c670286a3c40f8a20bd0dd Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 1 Jan 2021 16:48:17 +0000 Subject: [PATCH 39/55] Don't synchronise across the entire edit for a single ChunkSection load (speed boost) --- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 2 +- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 2 +- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 2 +- .../mc1_16_4/BukkitGetBlocks_1_16_4.java | 2 +- .../implementation/blocks/CharBlocks.java | 34 +++++++++++++++---- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index f078eb9a0..b6b2380a2 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -825,7 +825,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 63ad1dada..3a5a68338 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -827,7 +827,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index f22000616..5a8873114 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -830,7 +830,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index 1282a8d45..8fb195641 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -830,7 +830,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index 52ddbb1e7..d17613e18 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -9,17 +9,24 @@ import org.jetbrains.annotations.Range; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; + public abstract class CharBlocks implements IBlocks { public static final Logger logger = LoggerFactory.getLogger(CharBlocks.class); - public static final Section FULL = new Section() { + protected final Section FULL = new Section() { @Override public final char[] get(CharBlocks blocks, int layer) { return blocks.blocks[layer]; } + + @Override + public final boolean isFull() { + return true; + } }; - public static final Section EMPTY = new Section() { + protected final Section EMPTY = new Section() { @Override public final synchronized char[] get(CharBlocks blocks, int layer) { char[] arr = blocks.blocks[layer]; @@ -39,15 +46,22 @@ public abstract class CharBlocks implements IBlocks { } return arr; } + + @Override + public final boolean isFull() { + return false; + } }; public final char[][] blocks; public final Section[] sections; + private final Object[] loadLock = new Object[16]; public CharBlocks() { blocks = new char[16][]; sections = new Section[16]; for (int i = 0; i < 16; i++) { sections[i] = EMPTY; + loadLock[i] = new Object(); } } @@ -55,7 +69,7 @@ public abstract class CharBlocks implements IBlocks { public boolean trim(boolean aggressive) { boolean result = true; for (int i = 0; i < 16; i++) { - if (sections[i] == EMPTY && blocks[i] != null) { + if (!sections[i].isFull() && blocks[i] != null) { blocks[i] = null; } else { result = false; @@ -67,7 +81,7 @@ public abstract class CharBlocks implements IBlocks { @Override public boolean trim(boolean aggressive, int layer) { boolean result = true; - if (sections[layer] == EMPTY && blocks[layer] != null) { + if (!sections[layer].isFull() && blocks[layer] != null) { blocks[layer] = null; } else { result = false; @@ -99,12 +113,18 @@ public abstract class CharBlocks implements IBlocks { @Override public boolean hasSection(@Range(from = 0, to = 15) int layer) { - return sections[layer] == FULL; + return sections[layer].isFull(); } @Override public char[] load(@Range(from = 0, to = 15) int layer) { - return sections[layer].get(this, layer); + Section section = sections[layer]; + if (section.isFull()) { + return section.get(this, layer); + } + synchronized (loadLock[layer]) { + return sections[layer].get(this, layer); + } } @Override @@ -149,6 +169,8 @@ public abstract class CharBlocks implements IBlocks { public abstract char[] get(CharBlocks blocks, @Range(from = 0, to = 15) int layer); + public abstract boolean isFull(); + public final char get(CharBlocks blocks, @Range(from = 0, to = 15) int layer, int index) { return get(blocks, layer)[index]; } From 39b0da2b99e4ec4c8e342ab0c748f0b102108bf2 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 1 Jan 2021 17:19:14 +0000 Subject: [PATCH 40/55] we do want to synchronise across the chunk when loading sections --- .../boydti/fawe/beta/implementation/blocks/CharBlocks.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index d17613e18..cce611d28 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -54,14 +54,13 @@ public abstract class CharBlocks implements IBlocks { }; public final char[][] blocks; public final Section[] sections; - private final Object[] loadLock = new Object[16]; + private final Object loadLock = new Object(); public CharBlocks() { blocks = new char[16][]; sections = new Section[16]; for (int i = 0; i < 16; i++) { sections[i] = EMPTY; - loadLock[i] = new Object(); } } @@ -122,7 +121,7 @@ public abstract class CharBlocks implements IBlocks { if (section.isFull()) { return section.get(this, layer); } - synchronized (loadLock[layer]) { + synchronized (loadLock) { return sections[layer].get(this, layer); } } From 580cb4a91ec576ce041068d4b4916d8aadc4ed6d Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 1 Jan 2021 18:04:30 +0000 Subject: [PATCH 41/55] add chunk tickets and don't force sync sending chunk packets --- .../mc1_15_2/BukkitAdapter_1_15_2.java | 70 +++++++------- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 1 + .../mc1_16_1/BukkitAdapter_1_16_1.java | 70 +++++++------- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 1 + .../mc1_16_2/BukkitAdapter_1_16_2.java | 91 ++++++++++-------- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 1 + .../mc1_16_4/BukkitAdapter_1_16_4.java | 95 +++++++++++-------- .../mc1_16_4/BukkitGetBlocks_1_16_4.java | 1 + 8 files changed, 181 insertions(+), 149 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java index 8098145a1..12a25e0fc 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java @@ -9,6 +9,7 @@ import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -154,25 +155,33 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - Chunk nmsChunk = nmsWorld.getChunkIfLoaded(chunkX, chunkZ); + final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); if (nmsChunk != null) { + TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - return nmsWorld.getChunkAt(chunkX, chunkZ); + final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); + TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + return nmsChunkMain; } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - CraftChunk chunk = (CraftChunk) future.get(); + final CraftChunk chunk = (CraftChunk) future.get(); + TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); + return TaskManager.IMP.sync(() -> { + Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); + chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); + return chunk; + }); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int cx, final int cz) { @@ -190,37 +199,32 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter { return; } if (playerChunk.hasBeenLoaded()) { - TaskManager.IMP.sync(() -> { - try { - int dirtyBits = fieldDirtyBits.getInt(playerChunk); - if (dirtyBits == 0) { - nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); - } - if (mask == 0) { - dirtyBits = 65535; - } else { - dirtyBits |= mask; - } - - fieldDirtyBits.set(playerChunk, dirtyBits); - fieldDirtyCount.set(playerChunk, 64); - - if (lighting) { - ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); - PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine()); - playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { - p.playerConnection.sendPacket(packet); - }); - } - - } catch (IllegalAccessException e) { - e.printStackTrace(); + try { + int dirtyBits = fieldDirtyBits.getInt(playerChunk); + if (dirtyBits == 0) { + nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); } - return null; - }); - return; + if (mask == 0) { + dirtyBits = 65535; + } else { + dirtyBits |= mask; + } + + fieldDirtyBits.set(playerChunk, dirtyBits); + fieldDirtyCount.set(playerChunk, 64); + + if (lighting) { + ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); + PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine()); + playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { + p.playerConnection.sendPacket(packet); + }); + } + + } catch (IllegalAccessException e) { + e.printStackTrace(); + } } - return; } /* diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index b6b2380a2..daae13a16 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -607,6 +607,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { task.run(); } } + nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java index d148d8e81..559d1a6b1 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java @@ -9,6 +9,7 @@ import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -151,25 +152,33 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); + final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); if (nmsChunk != null) { + TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - return nmsWorld.getChunkAt(chunkX, chunkZ); + final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); + TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + return nmsChunkMain; } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - CraftChunk chunk = (CraftChunk) future.get(); + final CraftChunk chunk = (CraftChunk) future.get(); + TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); + return TaskManager.IMP.sync(() -> { + Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); + chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); + return chunk; + }); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int cx, final int cz) { @@ -187,35 +196,32 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { return; } if (playerChunk.hasBeenLoaded()) { - TaskManager.IMP.sync(() -> { - try { - int dirtyBits = fieldDirtyBits.getInt(playerChunk); - if (dirtyBits == 0) { - nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); - } - if (mask == 0) { - dirtyBits = 65535; - } else { - dirtyBits |= mask; - } - - fieldDirtyBits.set(playerChunk, dirtyBits); - fieldDirtyCount.set(playerChunk, 64); - - if (lighting) { - ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); - boolean trustEdges = false; //Added in 1.16.1 Not sure what it does. - PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); - playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { - p.playerConnection.sendPacket(packet); - }); - } - - } catch (IllegalAccessException e) { - e.printStackTrace(); + try { + int dirtyBits = fieldDirtyBits.getInt(playerChunk); + if (dirtyBits == 0) { + nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); } - return null; - }); + if (mask == 0) { + dirtyBits = 65535; + } else { + dirtyBits |= mask; + } + + fieldDirtyBits.set(playerChunk, dirtyBits); + fieldDirtyCount.set(playerChunk, 64); + + if (lighting) { + ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); + boolean trustEdges = false; //Added in 1.16.1 Not sure what it does. + PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); + playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { + p.playerConnection.sendPacket(packet); + }); + } + + } catch (IllegalAccessException e) { + e.printStackTrace(); + } } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 3a5a68338..39f1e9681 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -609,6 +609,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { task.run(); } } + nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java index f75477317..76fdbdece 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java @@ -11,6 +11,7 @@ import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; import com.destroystokyo.paper.util.misc.PooledLinkedHashSets; import com.mojang.datafixers.util.Either; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -163,25 +164,33 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); + final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); if (nmsChunk != null) { + TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - return nmsWorld.getChunkAt(chunkX, chunkZ); + final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); + TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + return nmsChunkMain; } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - CraftChunk chunk = (CraftChunk) future.get(); + final CraftChunk chunk = (CraftChunk) future.get(); + TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); + return TaskManager.IMP.sync(() -> { + Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); + chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); + return chunk; + }); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int chunkX, final int chunkZ) { @@ -199,51 +208,49 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { return; } if (playerChunk.hasBeenLoaded()) { - TaskManager.IMP.sync(() -> { - ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); - Optional optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); - if (optional.isPresent()) { - PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535); + ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); + Optional optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + if (optional.isPresent()) { + PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535); + playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { + p.playerConnection.sendPacket(chunkpacket); + }); + + if (lighting) { + //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) + boolean trustEdges = true; + PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { - p.playerConnection.sendPacket(chunkpacket); + p.playerConnection.sendPacket(packet); }); + } + } else if (PaperLib.isPaper()) { + //Require generic here to work with multiple dependencies trying to take control. + PooledLinkedHashSets.PooledObjectLinkedOpenHashSet objects = + nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap.getObjectsInRange(chunkX, chunkZ); + if (objects == null) { + return; + } + for (Object obj : objects.getBackingSet()) { + if (obj == null) { + continue; + } + EntityPlayer p = (EntityPlayer) obj; + Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ); + if (chunk != null) { + PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535); + p.playerConnection.sendPacket(chunkpacket); - if (lighting) { - boolean trustEdges = true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) - PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); - playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { + if (lighting) { + //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) + boolean trustEdges = true; + PacketPlayOutLightUpdate packet = + new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); p.playerConnection.sendPacket(packet); - }); - } - } else if (PaperLib.isPaper()) { - //Require generic here to work with multiple dependencies trying to take control. - PooledLinkedHashSets.PooledObjectLinkedOpenHashSet objects = - nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap.getObjectsInRange(chunkX, chunkZ); - if (objects == null) { - return null; - } - for (Object obj : objects.getBackingSet()) { - if (obj == null) { - continue; - } - EntityPlayer p = (EntityPlayer) obj; - Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ); - if (chunk != null) { - PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535); - p.playerConnection.sendPacket(chunkpacket); - - if (lighting) { - boolean trustEdges = - true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) - PacketPlayOutLightUpdate packet = - new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); - p.playerConnection.sendPacket(packet); - } } } } - return null; - }); + } } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index 5a8873114..cb5b84019 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -612,6 +612,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { task.run(); } } + nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java index 6e0ca22a1..28293c93a 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java @@ -5,12 +5,14 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.NMSAdapter; import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; import com.destroystokyo.paper.util.misc.PooledLinkedHashSets; import com.mojang.datafixers.util.Either; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -163,25 +165,33 @@ public final class BukkitAdapter_1_16_4 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); + final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); if (nmsChunk != null) { + TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - return nmsWorld.getChunkAt(chunkX, chunkZ); + final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); + TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + return nmsChunkMain; } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - CraftChunk chunk = (CraftChunk) future.get(); + final CraftChunk chunk = (CraftChunk) future.get(); + TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); + return TaskManager.IMP.sync(() -> { + Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); + chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); + return chunk; + }); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int chunkX, final int chunkZ) { @@ -199,51 +209,52 @@ public final class BukkitAdapter_1_16_4 extends NMSAdapter { return; } if (playerChunk.hasBeenLoaded()) { - TaskManager.IMP.sync(() -> { - ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); - Optional optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); - if (optional.isPresent()) { - PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535); + ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); + Optional optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + if (optional.isPresent()) { + PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535); + playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { + p.playerConnection.sendPacket(chunkpacket); + }); + + if (lighting) { + //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) + boolean trustEdges = true; + PacketPlayOutLightUpdate packet = + new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), + trustEdges); playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { - p.playerConnection.sendPacket(chunkpacket); + p.playerConnection.sendPacket(packet); }); + } + } else if (PaperLib.isPaper()) { + //Require generic here to work with multiple dependencies trying to take control. + PooledLinkedHashSets.PooledObjectLinkedOpenHashSet objects = + nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap + .getObjectsInRange(chunkX, chunkZ); + if (objects == null) { + return; + } + for (Object obj : objects.getBackingSet()) { + if (obj == null) { + continue; + } + EntityPlayer p = (EntityPlayer) obj; + Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ); + if (chunk != null) { + PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535); + p.playerConnection.sendPacket(chunkpacket); - if (lighting) { - boolean trustEdges = true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) - PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); - playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { + if (lighting) { + //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) + boolean trustEdges = true; + PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, + nmsWorld.getChunkProvider().getLightEngine(), trustEdges); p.playerConnection.sendPacket(packet); - }); - } - } else if (PaperLib.isPaper()) { - //Require generic here to work with multiple dependencies trying to take control. - PooledLinkedHashSets.PooledObjectLinkedOpenHashSet objects = - nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap.getObjectsInRange(chunkX, chunkZ); - if (objects == null) { - return null; - } - for (Object obj : objects.getBackingSet()) { - if (obj == null) { - continue; - } - EntityPlayer p = (EntityPlayer) obj; - Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ); - if (chunk != null) { - PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535); - p.playerConnection.sendPacket(chunkpacket); - - if (lighting) { - boolean trustEdges = - true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) - PacketPlayOutLightUpdate packet = - new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); - p.playerConnection.sendPacket(packet); - } } } } - return null; - }); + } } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index 8fb195641..90807bca5 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -612,6 +612,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { task.run(); } } + nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); From efcca5b66f77fbb2ac91f6f6e42768f98d782e96 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 1 Jan 2021 19:49:11 +0000 Subject: [PATCH 42/55] it's better not to bother with tickets to avoid tickets not being removed all the time --- .../adapter/mc1_15_2/BukkitAdapter_1_15_2.java | 17 ++++------------- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 1 - .../adapter/mc1_16_1/BukkitAdapter_1_16_1.java | 17 ++++------------- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 1 - .../adapter/mc1_16_2/BukkitAdapter_1_16_2.java | 17 ++++------------- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 1 - .../adapter/mc1_16_4/BukkitAdapter_1_16_4.java | 18 ++++-------------- .../mc1_16_4/BukkitGetBlocks_1_16_4.java | 1 - 8 files changed, 16 insertions(+), 57 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java index 12a25e0fc..ea5fea77b 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitAdapter_1_15_2.java @@ -9,7 +9,6 @@ import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -155,33 +154,25 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); + Chunk nmsChunk = nmsWorld.getChunkIfLoaded(chunkX, chunkZ); if (nmsChunk != null) { - TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); - TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); - return nmsChunkMain; + return nmsWorld.getChunkAt(chunkX, chunkZ); } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - final CraftChunk chunk = (CraftChunk) future.get(); - TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + CraftChunk chunk = (CraftChunk) future.get(); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> { - Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); - chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); - return chunk; - }); + return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int cx, final int cz) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index daae13a16..b6b2380a2 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -607,7 +607,6 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { task.run(); } } - nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java index 559d1a6b1..d00432cb7 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java @@ -9,7 +9,6 @@ import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -152,33 +151,25 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); + Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); if (nmsChunk != null) { - TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); - TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); - return nmsChunkMain; + return nmsWorld.getChunkAt(chunkX, chunkZ); } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - final CraftChunk chunk = (CraftChunk) future.get(); - TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + CraftChunk chunk = (CraftChunk) future.get(); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> { - Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); - chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); - return chunk; - }); + return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int cx, final int cz) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 39f1e9681..3a5a68338 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -609,7 +609,6 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { task.run(); } } - nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java index 76fdbdece..9ac20c248 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java @@ -11,7 +11,6 @@ import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; import com.destroystokyo.paper.util.misc.PooledLinkedHashSets; import com.mojang.datafixers.util.Either; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -164,33 +163,25 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); + Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); if (nmsChunk != null) { - TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); - TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); - return nmsChunkMain; + return nmsWorld.getChunkAt(chunkX, chunkZ); } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - final CraftChunk chunk = (CraftChunk) future.get(); - TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + CraftChunk chunk = (CraftChunk) future.get(); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> { - Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); - chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); - return chunk; - }); + return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int chunkX, final int chunkZ) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index cb5b84019..5a8873114 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -612,7 +612,6 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { task.run(); } } - nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java index 28293c93a..e4101a22f 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java @@ -5,14 +5,12 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.NMSAdapter; import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; import com.destroystokyo.paper.util.misc.PooledLinkedHashSets; import com.mojang.datafixers.util.Either; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -165,33 +163,25 @@ public final class BukkitAdapter_1_16_4 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int chunkX, int chunkZ) { - final Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); + Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(chunkX, chunkZ, false); if (nmsChunk != null) { - TaskManager.IMP.task(() -> nmsChunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); return nmsChunk; } if (Fawe.isMainThread()) { - final Chunk nmsChunkMain = nmsWorld.getChunkAt(chunkX, chunkZ); - TaskManager.IMP.task(() -> nmsChunkMain.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); - return nmsChunkMain; + return nmsWorld.getChunkAt(chunkX, chunkZ); } if (PaperLib.isPaper()) { CraftWorld craftWorld = nmsWorld.getWorld(); CompletableFuture future = craftWorld.getChunkAtAsync(chunkX, chunkZ, true); try { - final CraftChunk chunk = (CraftChunk) future.get(); - TaskManager.IMP.task(() -> chunk.addPluginChunkTicket(WorldEditPlugin.getInstance())); + CraftChunk chunk = (CraftChunk) future.get(); return chunk.getHandle(); } catch (Throwable e) { e.printStackTrace(); } } // TODO optimize - return TaskManager.IMP.sync(() -> { - Chunk chunk = nmsWorld.getChunkAt(chunkX, chunkZ); - chunk.bukkitChunk.addPluginChunkTicket(WorldEditPlugin.getInstance()); - return chunk; - }); + return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(chunkX, chunkZ)); } public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int chunkX, final int chunkZ) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index 90807bca5..8fb195641 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -612,7 +612,6 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { task.run(); } } - nmsChunk.bukkitChunk.removePluginChunkTicket(WorldEditPlugin.getInstance()); if (callback == null) { if (finalizer != null) { finalizer.run(); From 3f0b9a2a923d4690f1df33bb6ee83c0e29ee5c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= <4096670+Citymonstret@users.noreply.github.com> Date: Mon, 4 Jan 2021 19:18:23 +0100 Subject: [PATCH 43/55] Reorder BuildInClipboardFormat and document changed JNBT classes (#807) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Get rid of FastSchematicReader/Writer and document changed JNBT classes This commit includes changes from upstream to the schematic classes (`com.sk89q.worldedit.extent.clipboard.io`). It also documents the JNBT classes, specifying what has been changed in FAWE. This was done in preparation for the upcoming move to adventure-nbt. The PlotSquared schematic handler classes will now use SpongeSchematicReader/Writer rather than FastSchematicReader/Writer. This is yet untested and the entire branch is a W.I.P. * Fix JNBT mutability misuse in FAWE FAWE previously had mutable compound and list tags. The previous commit changed that, and this commit will fix misuse of the tag API. I've tried to identify the places where mutability was assumed, but I might have missed something. This needs quite extensive testing. This is yet another change which increases upstream compatibility in FAWE. * Fix FAWE_Spigot_<..>#getEntity * Fix JNBT usage in the AsyncBlockState code * Readd FastSchematicReader/Writer and add a new schematic format (`FAST`) * Update dead repository * Implement missing AsyncChunk#getTileEntities * handle entities properly and add "brokenentity" format * Fix fast schematic reader lazily reading means it's read in order of appearance in the inputstream so we need to read schematic version first (skip past everything) and then reset the stream * Fix p2 FAWE * Go back to fast schematics in P2/CompressedSchematicTag (#819) * Fix compile Co-authored-by: N0tMyFaultOG Co-authored-by: Alexander Söderberg Co-authored-by: dordsor21 Co-authored-by: Aurora --- worldedit-bukkit/build.gradle.kts | 3 +- .../mc1_15_2/nbt/LazyCompoundTag_1_15_2.java | 15 +- .../mc1_16_1/nbt/LazyCompoundTag_1_16_1.java | 13 +- .../mc1_16_2/nbt/LazyCompoundTag_1_16_2.java | 13 +- .../mc1_16_4/nbt/LazyCompoundTag_1_16_4.java | 13 +- .../plotsquared/FaweSchematicHandler.java | 3 +- .../plotsquaredv4/FaweSchematicHandler.java | 3 +- .../fawe/bukkit/wrapper/AsyncBlockState.java | 52 +- .../wrapper/state/AsyncDataContainer.java | 40 +- .../fawe/bukkit/wrapper/state/AsyncSign.java | 23 +- .../adapter/impl/FAWE_Spigot_v1_15_R2.java | 18 +- .../adapter/impl/FAWE_Spigot_v1_16_R1.java | 16 +- .../adapter/impl/FAWE_Spigot_v1_16_R2.java | 18 +- .../adapter/impl/FAWE_Spigot_v1_16_R3.java | 14 +- .../object/changeset/AbstractChangeSet.java | 19 +- .../clipboard/DiskOptimizedClipboard.java | 6 +- .../java/com/boydti/fawe/util/MainUtil.java | 36 +- .../com/boydti/fawe/util/ReflectionUtils.java | 16 - .../java/com/sk89q/jnbt/ByteArrayTag.java | 12 +- .../src/main/java/com/sk89q/jnbt/ByteTag.java | 13 +- .../main/java/com/sk89q/jnbt/CompoundTag.java | 159 ++++-- .../main/java/com/sk89q/jnbt/DoubleTag.java | 13 +- .../src/main/java/com/sk89q/jnbt/EndTag.java | 12 +- .../main/java/com/sk89q/jnbt/FloatTag.java | 13 +- .../main/java/com/sk89q/jnbt/IntArrayTag.java | 12 +- .../src/main/java/com/sk89q/jnbt/IntTag.java | 13 +- .../src/main/java/com/sk89q/jnbt/ListTag.java | 27 +- .../java/com/sk89q/jnbt/LongArrayTag.java | 12 +- .../src/main/java/com/sk89q/jnbt/LongTag.java | 13 +- .../java/com/sk89q/jnbt/NBTConstants.java | 3 +- .../java/com/sk89q/jnbt/NBTInputStream.java | 4 +- .../java/com/sk89q/jnbt/NBTOutputStream.java | 2 + .../main/java/com/sk89q/jnbt/NBTUtils.java | 2 +- .../main/java/com/sk89q/jnbt/NamedData.java | 41 -- .../main/java/com/sk89q/jnbt/ShortTag.java | 13 +- .../main/java/com/sk89q/jnbt/StringTag.java | 12 +- .../src/main/java/com/sk89q/jnbt/Tag.java | 2 + .../{ => fawe}/CompressedCompoundTag.java | 2 + .../{ => fawe}/CompressedSchematicTag.java | 6 +- .../com/sk89q/jnbt/{ => fawe}/NumberTag.java | 9 +- .../com/sk89q/jnbt/fawe/package-info.java | 4 + .../clipboard/io/BuiltInClipboardFormat.java | 76 +-- .../clipboard/io/FastSchematicReader.java | 12 +- .../clipboard/io/FastSchematicWriter.java | 18 +- .../extent/clipboard/io/FaweFormat.java | 4 - .../clipboard/io/MCEditSchematicReader.java | 30 +- .../extent/clipboard/io/SchematicReader.java | 536 ------------------ .../clipboard/io/SpongeSchematicReader.java | 38 +- .../clipboard/io/SpongeSchematicWriter.java | 28 +- .../BannerBlockCompatibilityHandler.java | 23 +- .../BedBlockCompatibilityHandler.java | 34 +- .../FlowerPotCompatibilityHandler.java | 6 +- .../legacycompat/NBTCompatibilityHandler.java | 3 +- .../NoteBlockCompatibilityHandler.java | 4 +- .../SignCompatibilityHandler.java | 6 +- .../SkullBlockCompatibilityHandler.java | 16 +- 56 files changed, 559 insertions(+), 995 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/sk89q/jnbt/NamedData.java rename worldedit-core/src/main/java/com/sk89q/jnbt/{ => fawe}/CompressedCompoundTag.java (99%) rename worldedit-core/src/main/java/com/sk89q/jnbt/{ => fawe}/CompressedSchematicTag.java (90%) rename worldedit-core/src/main/java/com/sk89q/jnbt/{ => fawe}/NumberTag.java (52%) create mode 100644 worldedit-core/src/main/java/com/sk89q/jnbt/fawe/package-info.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FaweFormat.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index ccb2be692..69a08e31f 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -23,6 +23,7 @@ repositories { name = "ProtocolLib Repo" url = uri("https://repo.dmulloy2.net/nexus/repository/public/") } + maven { url = uri("https://repo.inventivetalent.org/content/groups/public/") } flatDir {dir(File("src/main/resources"))} } @@ -71,7 +72,7 @@ dependencies { "compile"("org.bstats:bstats-bukkit:1.8") "compile"("com.intellectualsites.paster:Paster:1.0.1-SNAPSHOT") // Third party - "implementation"("com.github.InventivetalentDev:MapManager:1.7.+") { isTransitive = false } + compileOnlyApi("org.inventivetalent:mapmanager:1.7.+") { isTransitive = false } "implementation"("com.github.TechFortress:GriefPrevention:16.+") { isTransitive = false } "implementation"("com.massivecraft:mcore:7.0.1") { isTransitive = false } "implementation"("com.bekvon.bukkit.residence:Residence:4.5._13.1") { isTransitive = false } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/nbt/LazyCompoundTag_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/nbt/LazyCompoundTag_1_15_2.java index 4b603d3b6..e37700956 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/nbt/LazyCompoundTag_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/nbt/LazyCompoundTag_1_15_2.java @@ -12,15 +12,18 @@ import net.minecraft.server.v1_15_R1.NBTTagList; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; public class LazyCompoundTag_1_15_2 extends CompoundTag { + private final Supplier nmsTag; + private CompoundTag cachedValue; public LazyCompoundTag_1_15_2(Supplier tag) { - super(null); + super(new HashMap<>()); this.nmsTag = tag; } @@ -34,12 +37,10 @@ public class LazyCompoundTag_1_15_2 extends CompoundTag { @Override public Map getValue() { - Map value = super.getValue(); - if (value == null) { - Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); - setValue(((CompoundTag) tag).getValue()); + if (cachedValue == null) { + cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); } - return super.getValue(); + return cachedValue.getValue(); } public boolean containsKey(String key) { @@ -149,4 +150,4 @@ public class LazyCompoundTag_1_15_2 extends CompoundTag { public String toString() { return nmsTag.get().toString(); } -} \ No newline at end of file +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/nbt/LazyCompoundTag_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/nbt/LazyCompoundTag_1_16_1.java index 07a6da3d5..cb77adb38 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/nbt/LazyCompoundTag_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/nbt/LazyCompoundTag_1_16_1.java @@ -12,15 +12,18 @@ import net.minecraft.server.v1_16_R1.NBTTagList; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; public class LazyCompoundTag_1_16_1 extends CompoundTag { + private final Supplier nmsTag; + private CompoundTag cachedValue; public LazyCompoundTag_1_16_1(Supplier tag) { - super(null); + super(new HashMap<>()); this.nmsTag = tag; } @@ -34,12 +37,10 @@ public class LazyCompoundTag_1_16_1 extends CompoundTag { @Override public Map getValue() { - Map value = super.getValue(); - if (value == null) { - Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); - setValue(((CompoundTag) tag).getValue()); + if (cachedValue == null) { + cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); } - return super.getValue(); + return cachedValue.getValue(); } public boolean containsKey(String key) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/nbt/LazyCompoundTag_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/nbt/LazyCompoundTag_1_16_2.java index bd1d869ff..d43ef3f11 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/nbt/LazyCompoundTag_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/nbt/LazyCompoundTag_1_16_2.java @@ -12,15 +12,18 @@ import net.minecraft.server.v1_16_R2.NBTTagList; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; public class LazyCompoundTag_1_16_2 extends CompoundTag { + private final Supplier nmsTag; + private CompoundTag cachedValue; public LazyCompoundTag_1_16_2(Supplier tag) { - super(null); + super(new HashMap<>()); this.nmsTag = tag; } @@ -34,12 +37,10 @@ public class LazyCompoundTag_1_16_2 extends CompoundTag { @Override public Map getValue() { - Map value = super.getValue(); - if (value == null) { - Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); - setValue(((CompoundTag) tag).getValue()); + if (cachedValue == null) { + cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); } - return super.getValue(); + return cachedValue.getValue(); } public boolean containsKey(String key) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/nbt/LazyCompoundTag_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/nbt/LazyCompoundTag_1_16_4.java index 7cc5cdc87..73e416f35 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/nbt/LazyCompoundTag_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/nbt/LazyCompoundTag_1_16_4.java @@ -12,15 +12,18 @@ import net.minecraft.server.v1_16_R3.NBTTagList; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; public class LazyCompoundTag_1_16_4 extends CompoundTag { + private final Supplier nmsTag; + private CompoundTag cachedValue; public LazyCompoundTag_1_16_4(Supplier tag) { - super(null); + super(new HashMap<>()); this.nmsTag = tag; } @@ -34,12 +37,10 @@ public class LazyCompoundTag_1_16_4 extends CompoundTag { @Override public Map getValue() { - Map value = super.getValue(); - if (value == null) { - Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); - setValue(((CompoundTag) tag).getValue()); + if (cachedValue == null) { + cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); } - return super.getValue(); + return cachedValue.getValue(); } public boolean containsKey(String key) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java index 6b92b4163..0a9b9b4f1 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquared/FaweSchematicHandler.java @@ -1,6 +1,5 @@ package com.boydti.fawe.bukkit.regions.plotsquared; -import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.clipboard.ReadOnlyClipboard; import com.boydti.fawe.object.io.PGZIPOutputStream; @@ -16,10 +15,10 @@ import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.task.RunnableVal; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompressedCompoundTag; -import com.sk89q.jnbt.CompressedSchematicTag; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.jnbt.Tag; +import com.sk89q.jnbt.fawe.CompressedSchematicTag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java index c0539e682..2a2199b60 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java @@ -15,7 +15,7 @@ import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompressedCompoundTag; -import com.sk89q.jnbt.CompressedSchematicTag; +import com.sk89q.jnbt.fawe.CompressedSchematicTag; import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; @@ -65,6 +65,7 @@ public class FaweSchematicHandler extends SchematicHandler { ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region, false, true); Clipboard holder = new BlockArrayClipboard(region, clipboard); + CompressedSchematicTag tag = new CompressedSchematicTag(holder); whenDone.run(tag); }); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlockState.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlockState.java index c8ab44cfe..03d1dd07c 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlockState.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncBlockState.java @@ -1,6 +1,7 @@ package com.boydti.fawe.bukkit.wrapper; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.world.block.BaseBlock; @@ -16,8 +17,12 @@ import org.bukkit.material.MaterialData; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; public class AsyncBlockState implements BlockState { @@ -25,10 +30,6 @@ public class AsyncBlockState implements BlockState { private BlockData blockData; private final AsyncBlock block; - public AsyncBlockState(AsyncBlock block) { - this(block, block.world.getFullBlock(block.x, block.y, block.z)); - } - public AsyncBlockState(AsyncBlock block, BaseBlock state) { this.state = state; this.block = block; @@ -112,11 +113,11 @@ public class AsyncBlockState implements BlockState { @Override public void setBlockData(BlockData blockData) { this.blockData = blockData; - CompoundTag nbt = state.getNbtData(); + CompoundTag nbt = this.getNbtData(); BlockType oldType = state.getBlockType(); com.sk89q.worldedit.world.block.BlockState newState = BukkitAdapter.adapt(blockData); if (nbt != null && newState.getBlockType() == oldType) { - state = newState.toBaseBlock(nbt); + this.setNbtData(nbt); } else { state = newState.toBaseBlock(); } @@ -146,14 +147,47 @@ public class AsyncBlockState implements BlockState { } } - public CompoundTag getNbtData() { + /** + * Returns the (unmodifiable) tag compound that belongs to this block state. + * If the block state is null, this will return null. + * + * @return NBT data + */ + public synchronized @Nullable CompoundTag getNbtData() { + if (this.state == null) { + return null; + } return state.getNbtData(); } - public void setNbtData(CompoundTag nbt) { + /** + * Clone the NBT {@link CompoundTag} into a new {@link Map}. + * + * @return Modifiable clone of NBT data + */ + public @NotNull Map cloneNbtMap() { + return Optional.ofNullable(this.getNbtData()).map(CompoundTag::getValue) + .map(HashMap::new).orElse(new HashMap<>()); + } + + /** + * Set the NBT data of the block. + * + * @param nbt New NBT data + */ + public synchronized void setNbtData(@Nullable final CompoundTag nbt) { state = this.state.toBaseBlock(nbt); } + /** + * Set the NBT data of the block. + * + * @param map New NBT data + */ + public void setNbtData(@NotNull final Map map) { + this.setNbtData(new CompoundTag(map)); + } + @Override public byte getRawData() { return (byte) (state.getInternalId() >> BlockTypesCache.BIT_OFFSET); @@ -163,7 +197,7 @@ public class AsyncBlockState implements BlockState { public void setRawData(byte data) { int combinedId = getTypeId() + (data << BlockTypesCache.BIT_OFFSET); state = com.sk89q.worldedit.world.block.BlockState.getFromInternalId(combinedId) - .toBaseBlock(state.getNbtData()); + .toBaseBlock(this.getNbtData()); this.blockData = BukkitAdapter.adapt(state); } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java index 0e29f2f19..f57ca8553 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java @@ -16,17 +16,24 @@ import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; public final class AsyncDataContainer implements PersistentDataContainer { - private final CompoundTag root; - public AsyncDataContainer(CompoundTag root) { - this.root = root; + private final Supplier supplier; + private final Consumer consumer; + + public AsyncDataContainer( + final @NotNull Supplier supplier, + final @NotNull Consumer consumer + ) { + this.supplier = supplier; + this.consumer = consumer; } private CompoundTag root() { - CompoundTag value = (CompoundTag) root.getValue().get("PublicBukkitValues"); - return value; + return (CompoundTag) supplier.get().getValue().get("PublicBukkitValues"); } private Map get() { @@ -40,8 +47,9 @@ public final class AsyncDataContainer implements PersistentDataContainer { if (!create) { return Collections.emptyMap(); } - Map map = root.getValue(); + final Map map = new HashMap<>(root().getValue()); map.put("PublicBukkitValues", new CompoundTag(raw = new HashMap<>())); + this.consumer.accept(new CompoundTag(map)); } else { raw = tag.getValue(); } @@ -52,7 +60,14 @@ public final class AsyncDataContainer implements PersistentDataContainer { Validate.notNull(key, "The provided key for the custom value was null"); Validate.notNull(type, "The provided type for the custom value was null"); Validate.notNull(value, "The provided value for the custom value was null"); - get().put(key.toString(), FaweCache.IMP.asTag(type.toPrimitive(value, null))); + // Modify public values + final Map publicValues = new HashMap<>(this.get()); + publicValues.put(key.toString(), FaweCache.IMP.asTag(type.toPrimitive(value, null))); + // Modify the root tag + final Map map = new HashMap<>(root().getValue()); + map.put("PublicBukkitValues", new CompoundTag(publicValues)); + // Update the owning object + this.consumer.accept(new CompoundTag(map)); } public boolean has(NamespacedKey key, PersistentDataType type) { @@ -60,7 +75,7 @@ public final class AsyncDataContainer implements PersistentDataContainer { Validate.notNull(type, "The provided type for the custom value was null"); Tag value = get(false).get(key.toString()); if (value == null) { - return type == null; + return false; } return type.getPrimitiveType() == value.getValue().getClass(); } @@ -93,7 +108,14 @@ public final class AsyncDataContainer implements PersistentDataContainer { public void remove(NamespacedKey key) { Validate.notNull(key, "The provided key for the custom value was null"); - get(false).remove(key.toString()); + // Modify public values + final Map publicValues = new HashMap<>(this.get(false)); + publicValues.remove(key.toString()); + // Modify the root tag + final Map map = new HashMap<>(root().getValue()); + map.put("PublicBukkitValues", new CompoundTag(publicValues)); + // Update the owning object + this.consumer.accept(new CompoundTag(map)); } public boolean isEmpty() { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncSign.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncSign.java index 85d7960e5..34e1c923e 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncSign.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncSign.java @@ -19,6 +19,7 @@ import java.util.Locale; import java.util.Map; public class AsyncSign extends AsyncBlockState implements Sign { + public AsyncSign(AsyncBlock block, BaseBlock state) { super(block, state); } @@ -59,11 +60,12 @@ public class AsyncSign extends AsyncBlockState implements Sign { @Override public void setLine(int index, String line) throws IndexOutOfBoundsException { - CompoundTag nbt = getNbtData(); - if (nbt != null) { - Map map = nbt.getValue(); - map.put("Text" + (index + 1), new StringTag(toJson(line))); + final Map map = this.cloneNbtMap(); + if (map.isEmpty()) { + return; } + map.put("Text" + (index + 1), new StringTag(toJson(line))); + this.setNbtData(map); } @Override @@ -79,13 +81,13 @@ public class AsyncSign extends AsyncBlockState implements Sign { @Override @NotNull public PersistentDataContainer getPersistentDataContainer() { - return new AsyncDataContainer(getNbtData()); + return new AsyncDataContainer(this::getNbtData, this::setNbtData); } @Override @Nullable public DyeColor getColor() { - CompoundTag nbt = getNbtData(); + CompoundTag nbt = this.getNbtData(); if (nbt != null) { String color = nbt.getString("Color").toUpperCase(Locale.ROOT); if (!color.isEmpty()) { @@ -97,10 +99,11 @@ public class AsyncSign extends AsyncBlockState implements Sign { @Override public void setColor(DyeColor color) { - CompoundTag nbt = getNbtData(); - if (nbt != null) { - Map map = nbt.getValue(); - map.put("Color", new StringTag(color.name().toLowerCase(Locale.ROOT))); + final Map map = this.cloneNbtMap(); + if (map.isEmpty()) { + return; } + map.put("Color", new StringTag(color.name().toLowerCase(Locale.ROOT))); + this.setNbtData(map); } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java index ee7fe2e58..dec7822ca 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.bukkit.adapter.impl; -import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.implementation.packet.ChunkPacket; @@ -93,15 +92,15 @@ import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; +import java.util.HashMap; import java.util.Map; import java.util.OptionalInt; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Stream; -import javax.annotation.Nullable; -import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { @@ -271,13 +270,13 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I if (id != null) { EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); Supplier saveTag = () -> { - NBTTagCompound tag = new NBTTagCompound(); - readEntityIntoTag(mcEntity, tag); - + final NBTTagCompound minecraftTag = new NBTTagCompound(); + readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - CompoundTag natve = (CompoundTag) toNative(tag); - natve.getValue().put("Id", new StringTag(id)); - return natve; + final CompoundTag tag = (CompoundTag) toNative(minecraftTag); + final Map tags = new HashMap<>(tag.getValue()); + tags.put("Id", new StringTag(id)); + return new CompoundTag(tags); }; return new LazyBaseEntity(type, saveTag); } else { @@ -351,7 +350,6 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I } } } - public int ordinalToIbdID(char ordinal) { synchronized (this) { try { diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java index 688bf8c11..1040c913a 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java @@ -92,15 +92,15 @@ import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; +import java.util.HashMap; import java.util.Map; import java.util.OptionalInt; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Stream; -import javax.annotation.Nullable; -import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { @@ -270,13 +270,13 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I if (id != null) { EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); Supplier saveTag = () -> { - NBTTagCompound tag = new NBTTagCompound(); - readEntityIntoTag(mcEntity, tag); - + final NBTTagCompound minecraftTag = new NBTTagCompound(); + readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - CompoundTag natve = (CompoundTag) toNative(tag); - natve.getValue().put("Id", new StringTag(id)); - return natve; + final CompoundTag tag = (CompoundTag) toNative(minecraftTag); + final Map tags = new HashMap<>(tag.getValue()); + tags.put("Id", new StringTag(id)); + return new CompoundTag(tags); }; return new LazyBaseEntity(type, saveTag); } else { diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java index 1121093ea..b22d4b3ef 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java @@ -92,15 +92,16 @@ import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack; import org.bukkit.entity.Player; + +import javax.annotation.Nullable; import java.lang.ref.WeakReference; +import java.util.HashMap; import java.util.Map; import java.util.OptionalInt; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Stream; -import javax.annotation.Nullable; -import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { @@ -271,13 +272,13 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I if (id != null) { EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); Supplier saveTag = () -> { - NBTTagCompound tag = new NBTTagCompound(); - readEntityIntoTag(mcEntity, tag); - + final NBTTagCompound minecraftTag = new NBTTagCompound(); + readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - CompoundTag natve = (CompoundTag) toNative(tag); - natve.getValue().put("Id", new StringTag(id)); - return natve; + final CompoundTag tag = (CompoundTag) toNative(minecraftTag); + final Map tags = new HashMap<>(tag.getValue()); + tags.put("Id", new StringTag(id)); + return new CompoundTag(tags); }; return new LazyBaseEntity(type, saveTag); } else { @@ -351,7 +352,6 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I } } } - public int ordinalToIbdID(char ordinal) { synchronized (this) { try { diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java index a49b342bd..0682cdee9 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.bukkit.adapter.impl; -import com.bekvon.bukkit.residence.commands.material; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.implementation.packet.ChunkPacket; @@ -96,6 +95,7 @@ import org.bukkit.entity.Player; import javax.annotation.Nullable; import java.lang.ref.WeakReference; +import java.util.HashMap; import java.util.Map; import java.util.OptionalInt; import java.util.Set; @@ -272,13 +272,13 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I if (id != null) { EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); Supplier saveTag = () -> { - NBTTagCompound tag = new NBTTagCompound(); - readEntityIntoTag(mcEntity, tag); - + final NBTTagCompound minecraftTag = new NBTTagCompound(); + readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - CompoundTag natve = (CompoundTag) toNative(tag); - natve.getValue().put("Id", new StringTag(id)); - return natve; + final CompoundTag tag = (CompoundTag) toNative(minecraftTag); + final Map tags = new HashMap<>(tag.getValue()); + tags.put("Id", new StringTag(id)); + return new CompoundTag(tags); }; return new LazyBaseEntity(type, saveTag); } else { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java index 29dbef3e3..5ba55d849 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java @@ -138,10 +138,8 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { } if (!tilesTo.isEmpty()) { for (Map.Entry entry : tilesTo.entrySet()) { - CompoundTag nbt = entry.getValue(); BlockVector3 pos = entry.getKey(); - MainUtil.setPosition(nbt, pos.getX() + bx, pos.getY(), pos.getZ() + bz); - addTileCreate(nbt); + addTileCreate(MainUtil.setPosition(entry.getValue(), pos.getX() + bx, pos.getY(), pos.getZ() + bz)); } } Set entRemoves = set.getEntityRemoves(); @@ -259,14 +257,12 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { public void add(EntityCreate change) { CompoundTag tag = change.state.getNbtData(); - MainUtil.setEntityInfo(tag, change.getEntity()); - addEntityCreate(tag); + addEntityCreate(MainUtil.setEntityInfo(tag, change.getEntity())); } public void add(EntityRemove change) { CompoundTag tag = change.state.getNbtData(); - MainUtil.setEntityInfo(tag, change.getEntity()); - addEntityRemove(tag); + addEntityRemove(MainUtil.setEntityInfo(tag, change.getEntity())); } @Override @@ -309,14 +305,12 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { if (from.hasNbtData()) { CompoundTag nbt = from.getNbtData(); assert nbt != null; - MainUtil.setPosition(nbt, x, y, z); - addTileRemove(nbt); + addTileRemove(MainUtil.setPosition(nbt, x, y, z)); } if (to.hasNbtData()) { CompoundTag nbt = to.getNbtData(); assert nbt != null; - MainUtil.setPosition(nbt, x, y, z); - addTileCreate(nbt); + addTileCreate(MainUtil.setPosition(nbt, x, y, z)); } int combinedFrom = from.getOrdinal(); int combinedTo = to.getOrdinal(); @@ -332,8 +326,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { if (to.hasNbtData()) { CompoundTag nbt = to.getNbtData(); assert nbt != null; - MainUtil.setPosition(nbt, x, y, z); - addTileCreate(nbt); + addTileCreate(MainUtil.setPosition(nbt, x, y, z)); } int combinedTo = to.getInternalId(); add(x, y, z, combinedFrom, combinedTo); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java index c7100a531..9b0dd5324 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java @@ -24,6 +24,7 @@ import com.sk89q.worldedit.world.block.BlockTypes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; import java.io.Closeable; import java.io.DataInputStream; import java.io.File; @@ -44,7 +45,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; -import javax.annotation.Nullable; /** * A clipboard with disk backed storage. (lower memory + loads on crash) @@ -390,11 +390,11 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - nbtMap.put(new IntTriple(x, y, z), tag); - Map values = tag.getValue(); + final Map values = new HashMap<>(tag.getValue()); values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); + nbtMap.put(new IntTriple(x, y, z), new CompoundTag(values)); return true; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java index 5993104a8..ec054018c 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java @@ -34,6 +34,9 @@ import net.jpountz.lz4.LZ4InputStream; import net.jpountz.lz4.LZ4Utils; import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.imageio.ImageIO; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; @@ -66,6 +69,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -83,8 +87,6 @@ import java.util.zip.GZIPInputStream; import java.util.zip.Inflater; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import javax.annotation.Nullable; -import javax.imageio.ImageIO; import static java.lang.System.arraycopy; import static org.slf4j.LoggerFactory.getLogger; @@ -448,24 +450,44 @@ public class MainUtil { } } - public static void setPosition(CompoundTag tag, int x, int y, int z) { - Map value = tag.getValue(); + /** + * Create a copy of the tag and modify the (x, y, z) coordinates + * + * @param tag Tag to copy + * @param x New X coordinate + * @param y New Y coordinate + * @param z New Z coordinate + * @return New tag + */ + public static @NotNull CompoundTag setPosition(@Nonnull CompoundTag tag, int x, int y, int z) { + Map value = new HashMap<>(tag.getValue()); value.put("x", new IntTag(x)); value.put("y", new IntTag(y)); value.put("z", new IntTag(z)); + return new CompoundTag(value); } - public static void setEntityInfo(CompoundTag tag, Entity entity) { - Map map = tag.getValue(); + /** + * Create a copy of the tag and modify the entity inf + * + * @param tag Tag to copy + * @param entity Entity + * @return New tag + */ + public static @NotNull CompoundTag setEntityInfo(@NotNull CompoundTag tag, @NotNull Entity entity) { + Map map = new HashMap<>(tag.getValue()); map.put("Id", new StringTag(entity.getState().getType().getId())); ListTag pos = (ListTag) map.get("Pos"); if (pos != null) { Location loc = entity.getLocation(); - List posList = ReflectionUtils.getList(pos.getValue()); + // Create a copy, because the list is immutable... + List posList = new ArrayList<>(pos.getValue()); posList.set(0, new DoubleTag(loc.getX())); posList.set(1, new DoubleTag(loc.getY())); posList.set(2, new DoubleTag(loc.getZ())); + map.put("Pos", new ListTag(pos.getType(), posList)); } + return new CompoundTag(map); } public static String getText(String url) throws IOException { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java b/worldedit-core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java index 869d5dce8..a7c8a3dc7 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java @@ -67,22 +67,6 @@ public class ReflectionUtils { blankField(enumClass, "enumConstants"); // IBM JDK } - public static List getList(List list) { - try { - Class> clazz = (Class>) Class - .forName("java.util.Collections$UnmodifiableList"); - if (!clazz.isInstance(list)) { - return list; - } - Field m = clazz.getDeclaredField("list"); - m.setAccessible(true); - return (List) m.get(list); - } catch (Throwable e) { - e.printStackTrace(); - return list; - } - } - public static Object getHandle(Object wrapper) { final Method getHandle = makeMethod(wrapper.getClass(), "getHandle"); return callMethod(getHandle, wrapper); diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java index 41c495426..8311b7c55 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java @@ -26,11 +26,6 @@ import java.util.Locale; */ public final class ByteArrayTag extends Tag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_BYTE_ARRAY; - } - private final byte[] value; /** @@ -61,4 +56,11 @@ public final class ByteArrayTag extends Tag { return "TAG_Byte_Array(" + hex + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_BYTE_ARRAY; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java index 4dcffa700..53a3adcd3 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java @@ -19,14 +19,12 @@ package com.sk89q.jnbt; +import com.sk89q.jnbt.fawe.NumberTag; + /** * The {@code TAG_Byte} tag. */ public final class ByteTag extends NumberTag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_BYTE; - } private final byte value; @@ -50,4 +48,11 @@ public final class ByteTag extends NumberTag { return "TAG_Byte(" + value + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_BYTE; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java index 82754e61a..01ab56e75 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java @@ -19,6 +19,7 @@ package com.sk89q.jnbt; +import com.sk89q.jnbt.fawe.NumberTag; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.util.Location; @@ -34,12 +35,7 @@ import java.util.UUID; */ public class CompoundTag extends Tag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_COMPOUND; - } - - private Map value; + private final Map value; /** * Creates the tag with an empty name. @@ -48,7 +44,7 @@ public class CompoundTag extends Tag { */ public CompoundTag(Map value) { super(); - this.value = value; + this.value = Collections.unmodifiableMap(value); } /** @@ -58,7 +54,7 @@ public class CompoundTag extends Tag { * @return true if the tag contains the given key */ public boolean containsKey(String key) { - return getValue().containsKey(key); + return value.containsKey(key); } @Override @@ -66,17 +62,6 @@ public class CompoundTag extends Tag { return value; } - /** - * Return a new compound tag with the given values. - * - * @param value the value - * @return the new compound tag - */ - public CompoundTag setValue(Map value) { - this.value = value; - return this; - } - /** * Create a compound tag builder. * @@ -96,7 +81,7 @@ public class CompoundTag extends Tag { * @return a byte array */ public byte[] getByteArray(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof ByteArrayTag) { return ((ByteArrayTag) tag).getValue(); } else { @@ -114,7 +99,7 @@ public class CompoundTag extends Tag { * @return a byte */ public byte getByte(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof ByteTag) { return ((ByteTag) tag).getValue(); } else { @@ -132,7 +117,7 @@ public class CompoundTag extends Tag { * @return a double */ public double getDouble(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof DoubleTag) { return ((DoubleTag) tag).getValue(); } else { @@ -151,9 +136,25 @@ public class CompoundTag extends Tag { * @return a double */ public double asDouble(String key) { - Tag tag = getValue().get(key); - if (tag instanceof NumberTag) { - return ((NumberTag) tag).getValue().doubleValue(); + Tag tag = value.get(key); + if (tag instanceof ByteTag) { + return ((ByteTag) tag).getValue(); + + } else if (tag instanceof ShortTag) { + return ((ShortTag) tag).getValue(); + + } else if (tag instanceof IntTag) { + return ((IntTag) tag).getValue(); + + } else if (tag instanceof LongTag) { + return ((LongTag) tag).getValue(); + + } else if (tag instanceof FloatTag) { + return ((FloatTag) tag).getValue(); + + } else if (tag instanceof DoubleTag) { + return ((DoubleTag) tag).getValue(); + } else { return 0; } @@ -169,7 +170,7 @@ public class CompoundTag extends Tag { * @return a float */ public float getFloat(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof FloatTag) { return ((FloatTag) tag).getValue(); } else { @@ -187,7 +188,7 @@ public class CompoundTag extends Tag { * @return an int array */ public int[] getIntArray(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof IntArrayTag) { return ((IntArrayTag) tag).getValue(); } else { @@ -205,7 +206,7 @@ public class CompoundTag extends Tag { * @return an int */ public int getInt(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof IntTag) { return ((IntTag) tag).getValue(); } else { @@ -224,9 +225,25 @@ public class CompoundTag extends Tag { * @return an int */ public int asInt(String key) { - Tag tag = getValue().get(key); - if (tag instanceof NumberTag) { - return ((NumberTag) tag).getValue().intValue(); + Tag tag = value.get(key); + if (tag instanceof ByteTag) { + return ((ByteTag) tag).getValue(); + + } else if (tag instanceof ShortTag) { + return ((ShortTag) tag).getValue(); + + } else if (tag instanceof IntTag) { + return ((IntTag) tag).getValue(); + + } else if (tag instanceof LongTag) { + return ((LongTag) tag).getValue().intValue(); + + } else if (tag instanceof FloatTag) { + return ((FloatTag) tag).getValue().intValue(); + + } else if (tag instanceof DoubleTag) { + return ((DoubleTag) tag).getValue().intValue(); + } else { return 0; } @@ -242,7 +259,7 @@ public class CompoundTag extends Tag { * @return a list of tags */ public List getList(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof ListTag) { return ((ListTag) tag).getValue(); } else { @@ -260,7 +277,7 @@ public class CompoundTag extends Tag { * @return a tag list instance */ public ListTag getListTag(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof ListTag) { return (ListTag) tag; } else { @@ -273,7 +290,7 @@ public class CompoundTag extends Tag { * *

If the key does not exist or its value is not a list tag, * then an empty list will be returned. If the given key references - * a list but the list of a different type, then an empty + * a list but the list of of a different type, then an empty * list will also be returned.

* * @param key the key @@ -283,7 +300,7 @@ public class CompoundTag extends Tag { */ @SuppressWarnings("unchecked") public List getList(String key, Class listType) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof ListTag) { ListTag listTag = (ListTag) tag; if (listTag.getType().equals(listType)) { @@ -299,14 +316,14 @@ public class CompoundTag extends Tag { /** * Get a {@code long[]} named with the given key. * - *

If the key does not exist or its value is not a long array tag, + *

If the key does not exist or its value is not an long array tag, * then an empty array will be returned.

* * @param key the key * @return an int array */ public long[] getLongArray(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof LongArrayTag) { return ((LongArrayTag) tag).getValue(); } else { @@ -324,7 +341,7 @@ public class CompoundTag extends Tag { * @return a long */ public long getLong(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof LongTag) { return ((LongTag) tag).getValue(); } else { @@ -343,9 +360,25 @@ public class CompoundTag extends Tag { * @return a long */ public long asLong(String key) { - Tag tag = getValue().get(key); - if (tag instanceof NumberTag) { - return ((NumberTag) tag).getValue().longValue(); + Tag tag = value.get(key); + if (tag instanceof ByteTag) { + return ((ByteTag) tag).getValue(); + + } else if (tag instanceof ShortTag) { + return ((ShortTag) tag).getValue(); + + } else if (tag instanceof IntTag) { + return ((IntTag) tag).getValue(); + + } else if (tag instanceof LongTag) { + return ((LongTag) tag).getValue(); + + } else if (tag instanceof FloatTag) { + return ((FloatTag) tag).getValue().longValue(); + + } else if (tag instanceof DoubleTag) { + return ((DoubleTag) tag).getValue().longValue(); + } else { return 0L; } @@ -361,7 +394,7 @@ public class CompoundTag extends Tag { * @return a short */ public short getShort(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof ShortTag) { return ((ShortTag) tag).getValue(); } else { @@ -379,7 +412,7 @@ public class CompoundTag extends Tag { * @return a string */ public String getString(String key) { - Tag tag = getValue().get(key); + Tag tag = value.get(key); if (tag instanceof StringTag) { return ((StringTag) tag).getValue(); } else { @@ -388,17 +421,17 @@ public class CompoundTag extends Tag { } @Override - public Map toRaw() { - HashMap raw = new HashMap<>(); - if (this.getValue().isEmpty()) { - return raw; + public String toString() { + StringBuilder bldr = new StringBuilder(); + bldr.append("TAG_Compound").append(": ").append(value.size()).append(" entries\r\n{\r\n"); + for (Map.Entry entry : value.entrySet()) { + bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n"); } - for (Map.Entry entry : getValue().entrySet()) { - raw.put(entry.getKey(), entry.getValue().toRaw()); - } - return raw; + bldr.append("}"); + return bldr.toString(); } + // FAWE Start public UUID getUUID() { long most = getLong("UUIDMost"); long least = getLong("UUIDLeast"); @@ -421,15 +454,21 @@ public class CompoundTag extends Tag { } @Override - public String toString() { - Map value = getValue(); - StringBuilder bldr = new StringBuilder(); - bldr.append("TAG_Compound").append(": ").append(getValue().size()).append(" entries\r\n{\r\n"); - for (Map.Entry entry : getValue().entrySet()) { - bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n"); - } - bldr.append("}"); - return bldr.toString(); + public int getTypeCode() { + return NBTConstants.TYPE_COMPOUND; } + @Override + public Map toRaw() { + HashMap raw = new HashMap<>(); + if (this.getValue().isEmpty()) { + return raw; + } + for (Map.Entry entry : getValue().entrySet()) { + raw.put(entry.getKey(), entry.getValue().toRaw()); + } + return raw; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java index 9dcfe6db2..211405791 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java @@ -19,14 +19,12 @@ package com.sk89q.jnbt; +import com.sk89q.jnbt.fawe.NumberTag; + /** * The {@code TAG_Double} tag. */ public final class DoubleTag extends NumberTag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_DOUBLE; - } private final double value; @@ -50,4 +48,11 @@ public final class DoubleTag extends NumberTag { return "TAG_Double(" + value + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_DOUBLE; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java index a845d636d..557f9173b 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java @@ -24,11 +24,6 @@ package com.sk89q.jnbt; */ public final class EndTag extends Tag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_END; - } - @Override public Object getValue() { return null; @@ -39,4 +34,11 @@ public final class EndTag extends Tag { return "TAG_End"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_END; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java index 78b5a87e8..6e107b154 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java @@ -19,14 +19,12 @@ package com.sk89q.jnbt; +import com.sk89q.jnbt.fawe.NumberTag; + /** * The {@code TAG_Float} tag. */ public final class FloatTag extends NumberTag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_FLOAT; - } private final float value; @@ -50,4 +48,11 @@ public final class FloatTag extends NumberTag { return "TAG_Float(" + value + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_FLOAT; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java index 22119aa9f..4fdb56be4 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java @@ -28,11 +28,6 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public final class IntArrayTag extends Tag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_INT_ARRAY; - } - private final int[] value; /** @@ -64,4 +59,11 @@ public final class IntArrayTag extends Tag { return "TAG_Int_Array(" + hex + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_INT_ARRAY; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java index dbcfd8f3c..8107a87b2 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java @@ -19,14 +19,12 @@ package com.sk89q.jnbt; +import com.sk89q.jnbt.fawe.NumberTag; + /** * The {@code TAG_Int} tag. */ public final class IntTag extends NumberTag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_INT; - } private final int value; @@ -50,4 +48,11 @@ public final class IntTag extends NumberTag { return "TAG_Int(" + value + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_INT; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java index 175375a24..afcde02bc 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java @@ -19,10 +19,9 @@ package com.sk89q.jnbt; -import java.util.ArrayList; +import javax.annotation.Nullable; import java.util.Collections; import java.util.List; -import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; @@ -31,11 +30,6 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public final class ListTag extends Tag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_LIST; - } - private final Class type; private final List value; @@ -421,18 +415,6 @@ public final class ListTag extends Tag { } } - @Override - public ArrayList toRaw() { - ArrayList raw = new ArrayList<>(); - if (this.value.isEmpty()) { - return raw; - } - for (Tag elem : this.value) { - raw.add(elem.toRaw()); - } - return raw; - } - @Override public String toString() { StringBuilder bldr = new StringBuilder(); @@ -444,4 +426,11 @@ public final class ListTag extends Tag { return bldr.toString(); } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_LIST; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java index 138029ce3..34c31d26b 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java @@ -28,11 +28,6 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class LongArrayTag extends Tag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_LONG_ARRAY; - } - private final long[] value; /** @@ -64,4 +59,11 @@ public class LongArrayTag extends Tag { return "TAG_Long_Array(" + hex + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_LONG_ARRAY; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java index cf5a7aee6..7b9c87858 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java @@ -19,14 +19,12 @@ package com.sk89q.jnbt; +import com.sk89q.jnbt.fawe.NumberTag; + /** * The {@code TAG_Long} tag. */ public final class LongTag extends NumberTag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_LONG; - } private final long value; @@ -50,4 +48,11 @@ public final class LongTag extends NumberTag { return "TAG_Long(" + value + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_LONG; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java index 1703fad79..db6689cb5 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java @@ -20,14 +20,13 @@ package com.sk89q.jnbt; import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; /** * A class which holds constant values. */ public final class NBTConstants { - public static final Charset CHARSET = StandardCharsets.UTF_8; + public static final Charset CHARSET = Charset.forName("UTF-8"); public static final int TYPE_END = 0; public static final int TYPE_BYTE = 1; diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java index c86179b4b..50c98ddc1 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java @@ -32,6 +32,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +// THIS CLASS HAS BEEN HEAVILY MODIFIED BY FAWE + /** * This class reads NBT, or Named Binary Tag * streams, and produces an object graph of subclasses of the {@code Tag} @@ -469,7 +471,7 @@ public final class NBTInputStream implements Closeable { case NBTConstants.TYPE_END: if (depth == 0) { throw new IOException( - "TAG_End found without a TAG_Compound/TAG_List tag preceding it."); + "TAG_End found without a TAG_Compound/TAG_List tag preceding it."); } else { return null; } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java index 4378e818b..9a4299841 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java @@ -32,6 +32,8 @@ import java.util.Map; import static com.google.common.base.Preconditions.checkNotNull; +// THIS CLASS HAS BEEN HEAVILY MODIFIED BY FAWE + /** * This class writes NBT, or Named Binary Tag * {@code Tag} objects to an underlying {@code OutputStream}. diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java index 82fbf940c..f2b6e008a 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java @@ -49,7 +49,7 @@ public final class NBTUtils { return "TAG_Byte_Array"; } else if (clazz.equals(ByteTag.class)) { return "TAG_Byte"; - } else if (CompoundTag.class.isAssignableFrom(clazz)) { + } else if (clazz.equals(CompoundTag.class)) { return "TAG_Compound"; } else if (clazz.equals(DoubleTag.class)) { return "TAG_Double"; diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NamedData.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NamedData.java deleted file mode 100644 index fbedac286..000000000 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NamedData.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sk89q.jnbt; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Some data with a name - */ -public class NamedData { - private final String name; - private final T data; - - /** - * Create a new named tag. - * - * @param name the name - * @param data the data - */ - public NamedData(String name, T data) { - checkNotNull(name); - this.name = name; - this.data = data; - } - - /** - * Get the name of the tag. - * - * @return the name - */ - public String getName() { - return name; - } - - /** - * Get the tag. - * - * @return the tag - */ - public T getValue() { - return data; - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java index 5f17df74f..87b69d480 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java @@ -19,14 +19,12 @@ package com.sk89q.jnbt; +import com.sk89q.jnbt.fawe.NumberTag; + /** * The {@code TAG_Short} tag. */ public final class ShortTag extends NumberTag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_SHORT; - } private final short value; @@ -50,4 +48,11 @@ public final class ShortTag extends NumberTag { return "TAG_Short(" + value + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_SHORT; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java index eb794ebf5..ae173441b 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java @@ -26,11 +26,6 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public final class StringTag extends Tag { - @Override - public int getTypeCode() { - return NBTConstants.TYPE_STRING; - } - private final String value; /** @@ -54,4 +49,11 @@ public final class StringTag extends Tag { return "TAG_String(" + value + ")"; } + // FAWE Start + @Override + public int getTypeCode() { + return NBTConstants.TYPE_STRING; + } + // FAWE End + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java index 7b105c950..3d415da86 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java @@ -31,10 +31,12 @@ public abstract class Tag { */ public abstract Object getValue(); + // FAWE Start public Object toRaw() { return getValue(); } public abstract int getTypeCode(); + // FAWE End } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedCompoundTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/CompressedCompoundTag.java similarity index 99% rename from worldedit-core/src/main/java/com/sk89q/jnbt/CompressedCompoundTag.java rename to worldedit-core/src/main/java/com/sk89q/jnbt/fawe/CompressedCompoundTag.java index ca9241ccb..39eca054c 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedCompoundTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/CompressedCompoundTag.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.Map; public abstract class CompressedCompoundTag extends CompoundTag { + private T in; public CompressedCompoundTag(T in) { @@ -41,4 +42,5 @@ public abstract class CompressedCompoundTag extends CompoundTag { throw new RuntimeException(e); } } + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedSchematicTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/CompressedSchematicTag.java similarity index 90% rename from worldedit-core/src/main/java/com/sk89q/jnbt/CompressedSchematicTag.java rename to worldedit-core/src/main/java/com/sk89q/jnbt/fawe/CompressedSchematicTag.java index 189b2bb2b..6c9812a20 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedSchematicTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/CompressedSchematicTag.java @@ -1,7 +1,9 @@ -package com.sk89q.jnbt; +package com.sk89q.jnbt.fawe; import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.object.io.FastByteArraysInputStream; +import com.sk89q.jnbt.CompressedCompoundTag; +import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.FastSchematicWriter; import net.jpountz.lz4.LZ4BlockInputStream; @@ -10,6 +12,7 @@ import net.jpountz.lz4.LZ4BlockOutputStream; import java.io.IOException; public class CompressedSchematicTag extends CompressedCompoundTag { + public CompressedSchematicTag(Clipboard holder) { super(holder); } @@ -26,4 +29,5 @@ public class CompressedSchematicTag extends CompressedCompoundTag { FastByteArraysInputStream in = new FastByteArraysInputStream(blocksOut.toByteArrays()); return new LZ4BlockInputStream(in); } + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NumberTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/NumberTag.java similarity index 52% rename from worldedit-core/src/main/java/com/sk89q/jnbt/NumberTag.java rename to worldedit-core/src/main/java/com/sk89q/jnbt/fawe/NumberTag.java index db7b78cb1..c90428e8d 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NumberTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/NumberTag.java @@ -1,6 +1,13 @@ -package com.sk89q.jnbt; +package com.sk89q.jnbt.fawe; +import com.sk89q.jnbt.Tag; + +/** + * A numerical {@link Tag} + */ public abstract class NumberTag extends Tag { + @Override public abstract Number getValue(); + } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/package-info.java b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/package-info.java new file mode 100644 index 000000000..e86928e02 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/fawe/package-info.java @@ -0,0 +1,4 @@ +/** + * These are classes added by FAWE. They do not exist in WorldEdit + */ +package com.sk89q.jnbt.fawe; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index cde698903..7d563d4ee 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -86,40 +86,6 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { }, - /** - * The Schematic format used by MCEdit. - */ - MCEDIT_SCHEMATIC("mcedit", "mce", "schematic") { - - @Override - public String getPrimaryFileExtension() { - return "schematic"; - } - - @Override - public ClipboardReader getReader(InputStream inputStream) throws IOException { - if (inputStream instanceof FileInputStream) { - inputStream = new ResettableFileInputStream((FileInputStream) inputStream); - } - BufferedInputStream buffered = new BufferedInputStream(inputStream); - NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered))); - SchematicReader input = new SchematicReader(nbtStream); - input.setUnderlyingStream(inputStream); - return input; - } - - @Override - public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { - throw new IOException("This format does not support saving, use `schem` or `sponge` as format"); // Is more helpful - } - - @Override - public boolean isFormat(File file) { - String name = file.getName().toLowerCase(Locale.ROOT); - return name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce"); - } - }, - SPONGE_SCHEMATIC("sponge", "schem") { @Override @@ -160,6 +126,48 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } }, + /** + * The Schematic format used by MCEdit. + */ + MCEDIT_SCHEMATIC("mcedit", "mce", "schematic") { + + @Override + public String getPrimaryFileExtension() { + return "schematic"; + } + + @Override + public ClipboardReader getReader(InputStream inputStream) throws IOException { + NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(inputStream)); + return new MCEditSchematicReader(nbtStream); + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + throw new IOException("This format does not support saving"); + } + + @Override + public boolean isFormat(File file) { + try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) { + NamedTag rootTag = str.readNamedTag(); + if (!rootTag.getName().equals("Schematic")) { + return false; + } + CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); + + // Check + Map schematic = schematicTag.getValue(); + if (!schematic.containsKey("Materials")) { + return false; + } + } catch (Exception e) { + return false; + } + return true; + } + }, + BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") { @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java index e4674b85f..35a2f379b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java @@ -58,6 +58,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -350,7 +351,7 @@ public class FastSchematicReader extends NBTSchematicReader { y = pos[1]; z = pos[2]; } - Map values = tile.getValue(); + Map values = new HashMap<>(tile.getValue()); Tag id = values.get("Id"); if (id != null) { values.put("x", new IntTag(x)); @@ -361,17 +362,14 @@ public class FastSchematicReader extends NBTSchematicReader { values.remove("Id"); values.remove("Pos"); - tile = fixBlockEntity(tile); - clipboard.setTile(x, y, z, tile); + clipboard.setTile(x, y, z, fixBlockEntity(new CompoundTag(values))); } } // entities if (entities != null && !entities.isEmpty()) { for (Map entRaw : entities) { - CompoundTag ent = FaweCache.IMP.asTag(entRaw); - - Map value = ent.getValue(); + Map value = new HashMap<>(FaweCache.IMP.asTag(entRaw).getValue()); StringTag id = (StringTag) value.get("Id"); if (id == null) { id = (StringTag) value.get("id"); @@ -384,7 +382,7 @@ public class FastSchematicReader extends NBTSchematicReader { EntityType type = EntityTypes.parse(id.getValue()); if (type != null) { - ent = fixEntity(ent); + final CompoundTag ent = fixEntity(new CompoundTag(value)); BaseEntity state = new BaseEntity(type, ent); Location loc = ent.getEntityLocation(clipboard); if (brokenEntities) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java index 6351c7f80..6b2a179af 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java @@ -121,15 +121,16 @@ public class FastSchematicWriter implements ClipboardWriter { outputStream.writeLazyCompoundTag("Schematic", out -> { out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()); out.writeNamedTag("Version", CURRENT_VERSION); + out.writeNamedTag("FAWE", Fawe.get().getVersion().build); 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(), + min.getBlockX(), + min.getBlockY(), + min.getBlockZ(), }); out.writeLazyCompoundTag("Metadata", out1 -> { @@ -162,7 +163,7 @@ public class FastSchematicWriter implements ClipboardWriter { BaseBlock block = pos.getFullBlock(finalClipboard); CompoundTag nbt = block.getNbtData(); if (nbt != null) { - Map values = nbt.getValue(); + Map values = new HashMap<>(nbt.getValue()); // Positions are kept in NBT, we don't want that. values.remove("x"); @@ -175,12 +176,13 @@ public class FastSchematicWriter implements ClipboardWriter { // Dum. values.remove("id"); values.put("Pos", new IntArrayTag(new int[]{ - pos.getX(), - pos.getY(), - pos.getZ() + pos.getX(), + pos.getY(), + pos.getZ() })); numTiles++; - tilesOut.writeTagPayload(block.getNbtData()); + + tilesOut.writeTagPayload(new CompoundTag(values)); } int ordinal = block.getOrdinal(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FaweFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FaweFormat.java deleted file mode 100644 index 0daf069f9..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FaweFormat.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.sk89q.worldedit.extent.clipboard.io; - -public class FaweFormat { -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java index cc56d5bb7..619c30037 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java @@ -68,26 +68,24 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Reads schematic files that are compatible with MCEdit and other editors. - * @deprecated Use SchematicStreamer */ -@Deprecated public class MCEditSchematicReader extends NBTSchematicReader { private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class); private final NBTInputStream inputStream; private final DataFixer fixer; private static final ImmutableList COMPATIBILITY_HANDLERS - = ImmutableList.of( - new SignCompatibilityHandler(), - new FlowerPotCompatibilityHandler(), - new NoteBlockCompatibilityHandler(), - new SkullBlockCompatibilityHandler(), - new BannerBlockCompatibilityHandler(), - new BedBlockCompatibilityHandler() + = ImmutableList.of( + new SignCompatibilityHandler(), + new FlowerPotCompatibilityHandler(), + new NoteBlockCompatibilityHandler(), + new SkullBlockCompatibilityHandler(), + new BannerBlockCompatibilityHandler(), + new BedBlockCompatibilityHandler() ); private static final ImmutableList ENTITY_COMPATIBILITY_HANDLERS - = ImmutableList.of( - new Pre13HangingCompatibilityHandler() + = ImmutableList.of( + new Pre13HangingCompatibilityHandler() ); /** @@ -99,8 +97,8 @@ public class MCEditSchematicReader extends NBTSchematicReader { checkNotNull(inputStream); this.inputStream = inputStream; this.fixer = null; - //com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability( - //com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer(); + //com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability( + //com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer(); } @Override @@ -207,7 +205,7 @@ public class MCEditSchematicReader extends NBTSchematicReader { if (newBlock != null) { for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) { if (handler.isAffectedBlock(newBlock)) { - newBlock = handler.updateNBT(block, values); + newBlock = handler.updateNBT(block, values).toImmutableState(); if (newBlock == null || values.isEmpty()) { break; } @@ -256,7 +254,7 @@ public class MCEditSchematicReader extends NBTSchematicReader { int combined = block << 8 | data; if (unknownBlocks.add(combined)) { log.warn("Unknown block when loading schematic: " - + block + ":" + data + ". This is most likely a bad schematic."); + + block + ":" + data + ". This is most likely a bad schematic."); } } } catch (WorldEditException ignored) { // BlockArrayClipboard won't throw this @@ -302,7 +300,7 @@ public class MCEditSchematicReader extends NBTSchematicReader { } private String convertEntityId(String id) { - switch(id) { + switch (id) { case "AreaEffectCloud": return "area_effect_cloud"; case "ArmorStand": return "armor_stand"; case "CaveSpider": return "cave_spider"; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java deleted file mode 100644 index e64bb3a97..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicReader.java +++ /dev/null @@ -1,536 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.extent.clipboard.io; - -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.jnbt.streamer.StreamDelegate; -import com.boydti.fawe.jnbt.streamer.ValueReader; -import com.boydti.fawe.object.FaweInputStream; -import com.boydti.fawe.object.FaweOutputStream; -import com.boydti.fawe.object.clipboard.LinearClipboard; -import com.boydti.fawe.object.io.FastByteArrayOutputStream; -import com.boydti.fawe.object.io.FastByteArraysInputStream; -import com.boydti.fawe.object.io.ResettableFileInputStream; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.NBTInputStream; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.BannerBlockCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.BedBlockCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.EntityNBTCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.FlowerPotCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.NBTCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.NoteBlockCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.Pre13HangingCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.SignCompatibilityHandler; -import com.sk89q.worldedit.extent.clipboard.io.legacycompat.SkullBlockCompatibilityHandler; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.registry.state.PropertyKey; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockCategories; -import com.sk89q.worldedit.world.block.BlockID; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypeSwitch; -import com.sk89q.worldedit.world.block.BlockTypeSwitchBuilder; -import com.sk89q.worldedit.world.entity.EntityType; -import com.sk89q.worldedit.world.entity.EntityTypes; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import com.sk89q.worldedit.world.registry.LegacyMapper; -import net.jpountz.lz4.LZ4BlockInputStream; -import net.jpountz.lz4.LZ4BlockOutputStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedInputStream; -import java.io.EOFException; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.function.Function; -import java.util.zip.GZIPInputStream; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.slf4j.LoggerFactory.getLogger; - -/** - * Reads schematic files based that are compatible with MCEdit and other editors. - */ -public class SchematicReader implements ClipboardReader { - - private static final Logger log = LoggerFactory.getLogger(SchematicReader.class); - - private static final NBTCompatibilityHandler[] COMPATIBILITY_HANDLERS = { - new SignCompatibilityHandler(), - new FlowerPotCompatibilityHandler(), - new NoteBlockCompatibilityHandler(), - new SkullBlockCompatibilityHandler(), - new BannerBlockCompatibilityHandler(), - new BedBlockCompatibilityHandler() - }; - private static final EntityNBTCompatibilityHandler[] ENTITY_COMPATIBILITY_HANDLERS = { - new Pre13HangingCompatibilityHandler() - }; - - private NBTInputStream inputStream; - private InputStream rootStream; - - // private final DataFixer fixer; TODO - - private FastByteArrayOutputStream idOut = new FastByteArrayOutputStream(); - private FastByteArrayOutputStream dataOut = new FastByteArrayOutputStream(); - private FastByteArrayOutputStream addOut; - private FastByteArrayOutputStream biomesOut; - - private FaweOutputStream ids; - private FaweOutputStream datas; - private FaweOutputStream adds; - private FaweOutputStream biomes; - - private List> tiles; - private List> entities; - - private int width; - private int height; - private int length; - private int offsetX; - private int offsetY; - private int offsetZ; - private int originX; - private int originY; - private int originZ; - - /** - * Create a new instance. - * - * @param inputStream the input stream to read from - */ - public SchematicReader(NBTInputStream inputStream) { - checkNotNull(inputStream); - this.inputStream = inputStream; - } - - public void setUnderlyingStream(InputStream in) { - this.rootStream = in; - } - - public StreamDelegate createDelegate() { - StreamDelegate root = new StreamDelegate(); - StreamDelegate schematic = root.add("Schematic"); - schematic.add("Width").withInt((i, v) -> width = v); - schematic.add("Height").withInt((i, v) -> height = v); - schematic.add("Length").withInt((i, v) -> length = v); - - schematic.add("WEOriginX").withInt((i, v) -> originX = v); - schematic.add("WEOriginY").withInt((i, v) -> originY = v); - schematic.add("WEOriginZ").withInt((i, v) -> originZ = v); - - StreamDelegate metadata = schematic.add("Metadata"); - metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v); - metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v); - metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v); - - StreamDelegate blocksDelegate = schematic.add("Blocks"); - blocksDelegate.withInfo((length, type) -> ids = new FaweOutputStream(new LZ4BlockOutputStream(idOut))); - blocksDelegate.withInt((index, value) -> ids.write(value)); - - StreamDelegate dataDelegate = schematic.add("Data"); - dataDelegate.withInfo((length, type) -> datas = new FaweOutputStream(new LZ4BlockOutputStream(dataOut))); - dataDelegate.withInt((index, value) -> datas.write(value)); - - StreamDelegate addDelegate = schematic.add("AddBlocks"); - addDelegate.withInfo((length, type) -> { - addOut = new FastByteArrayOutputStream(); - adds = new FaweOutputStream(new LZ4BlockOutputStream(addOut)); - }); - addDelegate.withInt((index, value) -> { - if (value != 0) { - int first = value & 0x0F; - int second = (value & 0xF0) >> 4; - adds.write(first); - adds.write(second); - } else { - adds.write(0); - adds.write(0); - } - }); - - StreamDelegate tilesDelegate = schematic.add("TileEntities"); - tilesDelegate.withInfo((length, type) -> tiles = new ArrayList<>(length)); - tilesDelegate.withElem((ValueReader>) (index, tile) -> tiles.add(tile)); - - StreamDelegate entitiesDelegate = schematic.add("Entities"); - entitiesDelegate.withInfo((length, type) -> entities = new ArrayList<>(length)); - entitiesDelegate.withElem( - (ValueReader>) (index, entity) -> entities.add(entity)); - return root; - } - - private int readCombined(InputStream idIn, InputStream dataIn) throws IOException { - return ((idIn.read() & 0xFF) << 4) + (dataIn.read() & 0xF); - } - - private int readCombined(InputStream idIn, InputStream dataIn, InputStream addIn) throws IOException { - return ((addIn.read() & 0xFF) << 8) + readCombined(idIn, dataIn); - } - - private BlockState getBlock(int combined) { - BlockState state = LegacyMapper.getInstance().getBlockFromLegacyCombinedId(combined); - return state; - } - - private void write(int index, BlockState block, LinearClipboard clipboard) { - clipboard.setBlock(index, block); - } - - private void write(int x, int y, int z, BlockState block, Clipboard clipboard) { - clipboard.setBlock(x, y, z, block); - } - - private void readwrite(int index, InputStream idIn, InputStream dataIn, LinearClipboard out) throws IOException { - readwrite(index, readCombined(idIn, dataIn), out); - } - - private void readwrite(int x, int y, int z, InputStream idIn, InputStream dataIn, Clipboard out) throws IOException { - readwrite(x, y, z, readCombined(idIn, dataIn), out); - } - - private void readwrite(int index, InputStream idIn, InputStream dataIn, InputStream addIn, LinearClipboard out) throws IOException { - readwrite(index, readCombined(idIn, dataIn, addIn), out); - } - - private void readwrite(int x, int y, int z, InputStream idIn, InputStream dataIn, InputStream addIn, Clipboard out) throws IOException { - readwrite(x, y, z, readCombined(idIn, dataIn, addIn), out); - } - - private void readwrite(int index, int combined, LinearClipboard out) throws IOException { - write(index, getBlock(combined), out); - } - - private void readwrite(int x, int y, int z, int combined, Clipboard out) throws IOException { - write(x, y, z, getBlock(combined), out); - } - - @Override - public Clipboard read(UUID uuid, Function createOutput) throws IOException { - try { - return readInternal(uuid, createOutput); - } catch (EOFException e) { - log.error("EOFException read in schematic. Did you give the schematic the wrong extension?"); - log.error("We will attempt to rectify your mistake for you and load the schematic assuming it is named .schem not .schematic"); - e.printStackTrace(); - final InputStream stream; - if (rootStream instanceof FileInputStream) { - stream = new ResettableFileInputStream((FileInputStream) rootStream); - } else { - stream = rootStream; - } - BufferedInputStream buffered = new BufferedInputStream(stream); - NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered))); - return (new FastSchematicReader(nbtStream)).read(uuid, createOutput); - } - } - - private Clipboard readInternal(UUID uuid, Function createOutput) throws IOException { - StreamDelegate root = createDelegate(); - inputStream.readNamedTagLazy(root); - - if (ids != null) { - ids.close(); - } - if (datas != null) { - datas.close(); - } - if (adds != null) { - adds.close(); - } - if (biomes != null) { - biomes.close(); - } - ids = null; - datas = null; - adds = null; - biomes = null; - - BlockVector3 dimensions = BlockVector3.at(width, height, length); - BlockVector3 origin = BlockVector3.ZERO; - if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) { - origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ); - } - - Clipboard clipboard = createOutput.apply(dimensions); - try (InputStream dataIn = new LZ4BlockInputStream(new FastByteArraysInputStream(dataOut.toByteArrays())); InputStream idIn = new LZ4BlockInputStream(new FastByteArraysInputStream(idOut.toByteArrays()))) { - if (addOut != null) { - try (FaweInputStream addIn = new FaweInputStream(new LZ4BlockInputStream(new FastByteArraysInputStream(addOut.toByteArrays())))) { - if (clipboard instanceof LinearClipboard) { - LinearClipboard linear = (LinearClipboard) clipboard; - for (int y = 0, index = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { - readwrite(index, idIn, dataIn, addIn, linear); - } - } - } - } else { - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++) { - readwrite(x, y, z, idIn, dataIn, addIn, clipboard); - } - } - } - } - } - } else { - if (clipboard instanceof LinearClipboard) { - LinearClipboard linear = (LinearClipboard) clipboard; - for (int y = 0, index = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { - readwrite(index, idIn, dataIn, linear); - } - } - } - } else { - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++) { - readwrite(x, y, z, idIn, dataIn, clipboard); - } - } - } - } - } - } - - // tiles - if (tiles != null && !tiles.isEmpty()) { - outer: - for (Map tileRaw : tiles) { - CompoundTag tile = FaweCache.IMP.asTag(tileRaw); - int x = (int) tileRaw.get("x"); - int y = (int) tileRaw.get("y"); - int z = (int) tileRaw.get("z"); - - BlockState block = clipboard.getBlock(x, y, z); - for (NBTCompatibilityHandler compat : COMPATIBILITY_HANDLERS) { - if (compat.isAffectedBlock(block)) { - block = compat.updateNBT(block, tile.getValue()); - BaseBlock baseBlock = block.toBaseBlock(tile); - clipboard.setBlock(x, y, z, baseBlock); - continue outer; - } - } - clipboard.setTile(x, y, z, tile); - } - } - - // entities - if (entities != null && !entities.isEmpty()) { - for (Map entRaw : entities) { - String id = (String) entRaw.get("id"); - if (id == null) { - continue; - } - entRaw.put("Id", id); - EntityType type = EntityTypes.parse(id); - if (type != null) { - CompoundTag ent = FaweCache.IMP.asTag(entRaw); - for (EntityNBTCompatibilityHandler compat : ENTITY_COMPATIBILITY_HANDLERS) { - if (compat.isAffectedEntity(type, ent)) { - ent = compat.updateNBT(type, ent); - } - } - BaseEntity state = new BaseEntity(type, ent); - Location loc = ent.getEntityLocation(clipboard); - clipboard.createEntity(loc, state); - } else { - getLogger(SchematicReader.class).debug("Invalid entity: " + id); - } - } - } - fixStates(clipboard); - clipboard.setOrigin(origin); - - BlockVector3 min = BlockVector3.at(originX, originY, originZ); - if (!min.equals(BlockVector3.ZERO)) { - clipboard = new BlockArrayClipboard(clipboard, min); - } - return clipboard; - } - - private void fixStates(Clipboard fc) { - for (BlockVector3 pos : fc) { - BlockState block = pos.getBlock(fc); - if (block.getMaterial().isAir()) { - continue; - } - - int x = pos.getX(); - int y = pos.getY(); - int z = pos.getZ(); - - BlockType type = block.getBlockType(); - if (BlockCategories.STAIRS.contains(type)) { - Direction facing = block.getState(PropertyKey.FACING); - - BlockVector3 forward = facing.toBlockVector(); - Direction left = facing.getLeft(); - Direction right = facing.getRight(); - - BlockState forwardBlock = fc.getBlock(x + forward.getBlockX(), y + forward.getBlockY(), z + forward.getBlockZ()); - BlockType forwardType = forwardBlock.getBlockType(); - if (forwardType.hasProperty(PropertyKey.SHAPE) && forwardType.hasProperty(PropertyKey.FACING)) { - Direction forwardFacing = forwardBlock.getState(PropertyKey.FACING); - if (forwardFacing == left) { - BlockState rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ()); - BlockType rightType = rightBlock.getBlockType(); - if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) { - pos.setBlock(fc, block.with(PropertyKey.SHAPE, "inner_left")); - } - return; - } else if (forwardFacing == right) { - BlockState leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ()); - BlockType leftType = leftBlock.getBlockType(); - if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) { - fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_right")); - } - return; - } - } - - BlockState backwardsBlock = fc.getBlock(x - forward.getBlockX(), y - forward.getBlockY(), z - forward.getBlockZ()); - BlockType backwardsType = backwardsBlock.getBlockType(); - if (backwardsType.hasProperty(PropertyKey.SHAPE) && backwardsType.hasProperty(PropertyKey.FACING)) { - Direction backwardsFacing = (Direction) backwardsBlock.getState(PropertyKey.FACING); - if (backwardsFacing == left) { - BlockState rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ()); - BlockType rightType = rightBlock.getBlockType(); - if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) { - pos.setBlock(fc, block.with(PropertyKey.SHAPE, "outer_left")); - } - return; - } else if (backwardsFacing == right) { - BlockState leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ()); - BlockType leftType = leftBlock.getBlockType(); - if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) { - pos.setBlock(fc, block.with(PropertyKey.SHAPE, "outer_right")); - } - return; - } - } - } else { - int group = group(type); - if (group == -1) { - return; - } - BlockState set = block; - - if (set.getState(PropertyKey.NORTH) == Boolean.FALSE && merge(fc, group, x, y, z - 1)) { - set = set.with(PropertyKey.NORTH, true); - } - if (set.getState(PropertyKey.EAST) == Boolean.FALSE && merge(fc, group, x + 1, y, z)) { - set = set.with(PropertyKey.EAST, true); - } - if (set.getState(PropertyKey.SOUTH) == Boolean.FALSE && merge(fc, group, x, y, z + 1)) { - set = set.with(PropertyKey.SOUTH, true); - } - if (set.getState(PropertyKey.WEST) == Boolean.FALSE && merge(fc, group, x - 1, y, z)) { - set = set.with(PropertyKey.WEST, true); - } - - if (group == 2) { - int ns = (set.getState(PropertyKey.NORTH) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.SOUTH) ? 1 : 0); - int ew = (set.getState(PropertyKey.EAST) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.WEST) ? 1 : 0); - if (Math.abs(ns - ew) != 2 || fc.getBlock(x, y + 1, z).getBlockType().getMaterial().isSolid()) { - set = set.with(PropertyKey.UP, true); - } - } - - if (set != block) { - pos.setBlock(fc, set); - } - } - } - } - - - private BlockTypeSwitch fullCube = new BlockTypeSwitchBuilder<>(false).add(type -> { - BlockMaterial mat = type.getMaterial(); - return (mat.isFullCube() && !mat.isFragileWhenPushed() && mat.getLightValue() == 0 && mat.isOpaque() && mat.isSolid() && !mat.isTranslucent()); - }, true).build(); - - private boolean merge(Clipboard fc, int group, int x, int y, int z) { - BlockState block = fc.getBlock(x, y, z); - BlockType type = block.getBlockType(); - return group(type) == group || fullCube.apply(type); - } - - private int group(BlockType type) { - switch (type.getInternalId()) { - case BlockID.ACACIA_FENCE: - case BlockID.BIRCH_FENCE: - case BlockID.DARK_OAK_FENCE: - case BlockID.JUNGLE_FENCE: - case BlockID.OAK_FENCE: - case BlockID.SPRUCE_FENCE: - return 0; - case BlockID.NETHER_BRICK_FENCE: - return 1; - case BlockID.COBBLESTONE_WALL: - case BlockID.MOSSY_COBBLESTONE_WALL: - return 2; - case BlockID.IRON_BARS: - case BlockID.BLACK_STAINED_GLASS_PANE: - case BlockID.BLUE_STAINED_GLASS_PANE: - case BlockID.BROWN_MUSHROOM_BLOCK: - case BlockID.BROWN_STAINED_GLASS_PANE: - case BlockID.CYAN_STAINED_GLASS_PANE: - case BlockID.GLASS_PANE: - case BlockID.GRAY_STAINED_GLASS_PANE: - case BlockID.GREEN_STAINED_GLASS_PANE: - case BlockID.LIGHT_BLUE_STAINED_GLASS_PANE: - case BlockID.LIGHT_GRAY_STAINED_GLASS_PANE: - case BlockID.LIME_STAINED_GLASS_PANE: - case BlockID.MAGENTA_STAINED_GLASS_PANE: - case BlockID.ORANGE_STAINED_GLASS_PANE: - case BlockID.PINK_STAINED_GLASS_PANE: - case BlockID.PURPLE_STAINED_GLASS_PANE: - case BlockID.RED_STAINED_GLASS_PANE: - case BlockID.WHITE_STAINED_GLASS_PANE: - case BlockID.YELLOW_STAINED_GLASS_PANE: - return 3; - default: - return -1; - } - } - - @Override - public void close() throws IOException { - inputStream.close(); - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java index 53e05567c..d3e6f2685 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java @@ -68,7 +68,6 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Reads schematic files using the Sponge Schematic Specification. */ -@Deprecated // High mem usage + slow public class SpongeSchematicReader extends NBTSchematicReader { private static final Logger log = LoggerFactory.getLogger(SpongeSchematicReader.class); @@ -93,7 +92,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { Map schematic = schematicTag.getValue(); final Platform platform = WorldEdit.getInstance().getPlatformManager() - .queryCapability(Capability.WORLD_EDITING); + .queryCapability(Capability.WORLD_EDITING); int liveDataVersion = platform.getDataVersion(); if (schematicVersion == 1) { @@ -102,17 +101,23 @@ public class SpongeSchematicReader extends NBTSchematicReader { return readVersion1(schematicTag); } else if (schematicVersion == 2) { dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue(); + if (dataVersion < 0) { + log.warn("Schematic has an unknown data version ({}). Data may be incompatible.", + dataVersion); + // Do not DFU unknown data + dataVersion = liveDataVersion; + } if (dataVersion > liveDataVersion) { log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.", - dataVersion, liveDataVersion); + dataVersion, liveDataVersion); } else if (dataVersion < liveDataVersion) { fixer = platform.getDataFixer(); if (fixer != null) { log.debug("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.", - dataVersion, liveDataVersion); + dataVersion, liveDataVersion); } else { log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.", - dataVersion, liveDataVersion); + dataVersion, liveDataVersion); } } @@ -130,7 +135,11 @@ public class SpongeSchematicReader extends NBTSchematicReader { if (schematicVersion == 1) { return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2); } else if (schematicVersion == 2) { - return OptionalInt.of(requireTag(schematic, "DataVersion", IntTag.class).getValue()); + int dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue(); + if (dataVersion < 0) { + return OptionalInt.empty(); + } + return OptionalInt.of(dataVersion); } return OptionalInt.empty(); } catch (IOException e) { @@ -140,9 +149,6 @@ public class SpongeSchematicReader extends NBTSchematicReader { private CompoundTag getBaseTag() throws IOException { NamedTag rootTag = inputStream.readNamedTag(); - if (!rootTag.getName().equals("Schematic")) { - throw new IOException("Tag 'Schematic' does not exist or is not first"); - } CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); // Check @@ -226,9 +232,9 @@ public class SpongeSchematicReader extends NBTSchematicReader { } if (tileEntities != null) { List> tileEntityTags = tileEntities.getValue().stream() - .map(tag -> (CompoundTag) tag) - .map(CompoundTag::getValue) - .collect(Collectors.toList()); + .map(tag -> (CompoundTag) tag) + .map(CompoundTag::getValue) + .collect(Collectors.toList()); for (Map tileEntity : tileEntityTags) { int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue(); @@ -321,8 +327,8 @@ public class SpongeSchematicReader extends NBTSchematicReader { } BiomeType biome = BiomeTypes.get(key); if (biome == null) { - log.warn("Unknown biome type :" + key + - " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?"); + log.warn("Unknown biome type :" + key + + " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?"); } Tag idTag = palettePart.getValue(); if (!(idTag instanceof IntTag)) { @@ -385,8 +391,8 @@ public class SpongeSchematicReader extends NBTSchematicReader { EntityType entityType = EntityTypes.get(id); if (entityType != null) { Location location = NBTConversions.toLocation(clipboard, - requireTag(tags, "Pos", ListTag.class), - requireTag(tags, "Rotation", ListTag.class)); + requireTag(tags, "Pos", ListTag.class), + requireTag(tags, "Rotation", ListTag.class)); BaseEntity state = new BaseEntity(entityType, entityTag); clipboard.createEntity(location, state); } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 00e7e8868..daaa5f1c8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -23,8 +23,6 @@ import com.boydti.fawe.Fawe; import com.google.common.collect.Maps; import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.DoubleTag; -import com.sk89q.jnbt.FloatTag; import com.sk89q.jnbt.IntArrayTag; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.ListTag; @@ -37,7 +35,6 @@ import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; @@ -57,7 +54,6 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Writes schematic files using the Sponge schematic format. */ -@Deprecated // High mem usage + slow public class SpongeSchematicWriter implements ClipboardWriter { private static final int CURRENT_VERSION = 2; @@ -109,7 +105,8 @@ public class SpongeSchematicWriter implements ClipboardWriter { Map schematic = new HashMap<>(); schematic.put("Version", new IntTag(CURRENT_VERSION)); schematic.put("DataVersion", new IntTag( - WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion())); + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion())); + schematic.put("FAWEVersion", new IntTag(Fawe.get().getVersion().build)); Map metadata = new HashMap<>(); metadata.put("WEOffsetX", new IntTag(offset.getBlockX())); @@ -125,9 +122,9 @@ public class SpongeSchematicWriter implements ClipboardWriter { // The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin' schematic.put("Offset", new IntArrayTag(new int[]{ - min.getBlockX(), - min.getBlockY(), - min.getBlockZ(), + min.getBlockX(), + min.getBlockY(), + min.getBlockZ(), })); int paletteMax = 0; @@ -270,21 +267,6 @@ public class SpongeSchematicWriter implements ClipboardWriter { schematic.put("Entities", new ListTag(CompoundTag.class, entities)); } - public Tag writeVector(Vector3 vector) { - List list = new ArrayList<>(); - list.add(new DoubleTag(vector.getX())); - list.add(new DoubleTag(vector.getY())); - list.add(new DoubleTag(vector.getZ())); - return new ListTag(DoubleTag.class, list); - } - - public Tag writeRotation(Location location) { - List list = new ArrayList<>(); - list.add(new FloatTag(location.getYaw())); - list.add(new FloatTag(location.getPitch())); - return new ListTag(FloatTag.class, list); - } - @Override public void close() throws IOException { outputStream.close(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java index 5144f4498..873f5b5bd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java @@ -24,9 +24,8 @@ import com.sk89q.jnbt.CompoundTagBuilder; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; @@ -38,15 +37,15 @@ import java.util.Map; public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler { - private static final DirectionalProperty FacingProperty; - private static final IntegerProperty RotationProperty; + private static final Property FacingProperty; + private static final Property RotationProperty; static { - DirectionalProperty tempFacing; - IntegerProperty tempRotation; + Property tempFacing; + Property tempRotation; try { - tempFacing = (DirectionalProperty) (Property) BlockTypes.WHITE_WALL_BANNER.getProperty("facing"); - tempRotation = (IntegerProperty) (Property) BlockTypes.WHITE_BANNER.getProperty("rotation"); + tempFacing = BlockTypes.WHITE_WALL_BANNER.getProperty("facing"); + tempRotation = BlockTypes.WHITE_BANNER.getProperty("rotation"); } catch (NullPointerException | IllegalArgumentException | ClassCastException e) { tempFacing = null; tempRotation = null; @@ -62,7 +61,7 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler } @Override - public > B updateNBT(B block, Map values) { + public > BlockStateHolder updateNBT(B block, Map values) { Tag typeTag = values.get("Base"); if (typeTag instanceof IntTag) { boolean isWall = block.getBlockType() == BlockTypes.WHITE_WALL_BANNER; @@ -73,10 +72,10 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler BlockState state = type.getDefaultState(); if (isWall) { - Property facingProp = type.getProperty("facing"); + Property facingProp = type.getProperty("facing"); state = state.with(facingProp, block.getState(FacingProperty)); } else { - Property rotationProp = type.getProperty("rotation"); + Property rotationProp = type.getProperty("rotation"); state = state.with(rotationProp, block.getState(RotationProperty)); } @@ -102,7 +101,7 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler } values.put("Patterns", new ListTag(((ListTag) patternsTag).getType(), tempList)); } - return (B) state; + return state; } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java index b7414b238..d95c2ac92 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java @@ -21,9 +21,8 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; @@ -31,23 +30,24 @@ import com.sk89q.worldedit.world.block.BlockTypes; import java.util.Map; +@SuppressWarnings("") public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler { - private static final DirectionalProperty FacingProperty; - private static final EnumProperty PartProperty; + private static final Property FACING_PROPERTY; + private static final Property PART_PROPERTY; static { - DirectionalProperty tempFacing; - EnumProperty tempPart; + Property tempFacing; + Property tempPart; try { - tempFacing = (DirectionalProperty) (Property) BlockTypes.RED_BED.getProperty("facing"); - tempPart = (EnumProperty) (Property) BlockTypes.RED_BED.getProperty("part"); + tempFacing = BlockTypes.RED_BED.getProperty("facing"); + tempPart = BlockTypes.RED_BED.getProperty("part"); } catch (NullPointerException | IllegalArgumentException | ClassCastException e) { tempFacing = null; tempPart = null; } - FacingProperty = tempFacing; - PartProperty = tempPart; + FACING_PROPERTY = tempFacing; + PART_PROPERTY = tempPart; } @Override @@ -56,7 +56,7 @@ public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler { } @Override - public > B updateNBT(B block, Map values) { + public > BlockStateHolder updateNBT(B block, Map values) { Tag typeTag = values.get("color"); if (typeTag instanceof IntTag) { String bedType = convertBedType(((IntTag) typeTag).getValue()); @@ -65,17 +65,17 @@ public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler { if (type != null) { BlockState state = type.getDefaultState(); - Property facingProp = type.getProperty("facing"); - state = state.with(facingProp, block.getState(FacingProperty)); + Property facingProp = type.getProperty("facing"); + state = state.with(facingProp, block.getState(FACING_PROPERTY)); - Property occupiedProp = type.getProperty("occupied"); + Property occupiedProp = type.getProperty("occupied"); state = state.with(occupiedProp, false); - Property partProp = type.getProperty("part"); - state = state.with(partProp, block.getState(PartProperty)); + Property partProp = type.getProperty("part"); + state = state.with(partProp, block.getState(PART_PROPERTY)); values.remove("color"); - return (B) state; + return state; } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java index 826fb46ce..f49779656 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java @@ -37,12 +37,12 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler { } @Override - public > B updateNBT(B block, Map values) { + public > BlockStateHolder updateNBT(B block, Map values) { Tag item = values.get("Item"); if (item instanceof StringTag) { String id = ((StringTag) item).getValue(); if (id.isEmpty()) { - return (B) BlockTypes.FLOWER_POT.getDefaultState(); + return BlockTypes.FLOWER_POT.getDefaultState(); } int data = 0; Tag dataTag = values.get("Data"); @@ -52,7 +52,7 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler { BlockState newState = convertLegacyBlockType(id, data); if (newState != null) { values.clear(); - return (B) newState; // generics pls :\ + return newState; } } return block; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java index af4011ad8..efded2896 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java @@ -26,5 +26,6 @@ import java.util.Map; public interface NBTCompatibilityHandler { > boolean isAffectedBlock(B block); - > B updateNBT(B block, Map values); + + > BlockStateHolder updateNBT(B block, Map values); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java index b425d1373..01d01cc92 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java @@ -47,7 +47,7 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler { } @Override - public > B updateNBT(B block, Map values) { + public > BlockStateHolder updateNBT(B block, Map values) { // note that instrument was not stored (in state or nbt) previously. // it will be updated to the block below when it gets set into the world for the first time Tag noteTag = values.get("note"); @@ -55,7 +55,7 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler { Byte note = ((ByteTag) noteTag).getValue(); if (note != null) { values.clear(); - return (B) block.with(NoteProperty, (int) note).toImmutableState(); + return block.with(NoteProperty, (int) note).toImmutableState(); } } return block; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java index 664faf1da..ea21e7b10 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java @@ -26,8 +26,8 @@ import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.internal.util.DeprecationUtil; import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockTypes; import java.util.Map; @@ -35,11 +35,11 @@ public class SignCompatibilityHandler implements NBTCompatibilityHandler { @Override public > boolean isAffectedBlock(B block) { - return block.getBlockType() == BlockTypes.SIGN || block.getBlockType() == BlockTypes.WALL_SIGN; + return DeprecationUtil.isSign(block.getBlockType()); } @Override - public > B updateNBT(B block, Map values) { + public > BlockStateHolder updateNBT(B block, Map values) { for (int i = 0; i < 4; ++i) { String key = "Text" + (i + 1); Tag value = values.get(key); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java index fe1774095..b728102c7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java @@ -21,8 +21,8 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; import com.sk89q.jnbt.ByteTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.registry.state.DirectionalProperty; import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; @@ -32,12 +32,12 @@ import java.util.Map; public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler { - private static final DirectionalProperty FacingProperty; + private static final Property FacingProperty; static { - DirectionalProperty tempFacing; + Property tempFacing; try { - tempFacing = (DirectionalProperty) (Property) BlockTypes.SKELETON_WALL_SKULL.getProperty("facing"); + tempFacing = BlockTypes.SKELETON_WALL_SKULL.getProperty("facing"); } catch (NullPointerException | IllegalArgumentException | ClassCastException e) { tempFacing = null; } @@ -51,7 +51,7 @@ public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler { } @Override - public > B updateNBT(B block, Map values) { + public > BlockStateHolder updateNBT(B block, Map values) { boolean isWall = block.getBlockType() == BlockTypes.SKELETON_WALL_SKULL; Tag typeTag = values.get("SkullType"); if (typeTag instanceof ByteTag) { @@ -61,18 +61,18 @@ public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler { if (type != null) { BlockState state = type.getDefaultState(); if (isWall) { - Property newProp = type.getProperty("facing"); + Property newProp = type.getProperty("facing"); state = state.with(newProp, block.getState(FacingProperty)); } else { Tag rotTag = values.get("Rot"); if (rotTag instanceof ByteTag) { - Property newProp = type.getProperty("rotation"); + Property newProp = type.getProperty("rotation"); state = state.with(newProp, (int) ((ByteTag) rotTag).getValue()); } } values.remove("SkullType"); values.remove("Rot"); - return (B) state; + return state; } } } From 916c0803103ef002666db6cafaba824db1d022b8 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Mon, 4 Jan 2021 19:10:10 +0000 Subject: [PATCH 44/55] 5000th commit: Fix //download --- .../java/com/sk89q/worldedit/command/ClipboardCommands.java | 2 +- .../worldedit/extent/clipboard/io/FastSchematicWriter.java | 1 - .../worldedit/extent/clipboard/io/SpongeSchematicWriter.java | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 1b324914d..468ded6b3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -277,7 +277,7 @@ public class ClipboardCommands { ) @Deprecated @CommandPermissions({"worldedit.clipboard.download"}) - public void download(final Player player, final LocalSession session, @Arg(name = "format", desc = "String", def = "schem") final String formatName) throws WorldEditException { + public void download(final Player player, final LocalSession session, @Arg(name = "format", desc = "String", def = "fast") final String formatName) throws WorldEditException { final ClipboardFormat format = ClipboardFormats.findByAlias(formatName); if (format == null) { player.print(Caption.of("fawe.worldedit.clipboard.clipboard.invalid.format", formatName)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java index 6b2a179af..c5e7fe56e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicWriter.java @@ -121,7 +121,6 @@ public class FastSchematicWriter implements ClipboardWriter { outputStream.writeLazyCompoundTag("Schematic", out -> { out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()); out.writeNamedTag("Version", CURRENT_VERSION); - out.writeNamedTag("FAWE", Fawe.get().getVersion().build); out.writeNamedTag("Width", (short) width); out.writeNamedTag("Height", (short) height); out.writeNamedTag("Length", (short) length); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index daaa5f1c8..b0753f623 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -106,7 +106,6 @@ public class SpongeSchematicWriter implements ClipboardWriter { schematic.put("Version", new IntTag(CURRENT_VERSION)); schematic.put("DataVersion", new IntTag( WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion())); - schematic.put("FAWEVersion", new IntTag(Fawe.get().getVersion().build)); Map metadata = new HashMap<>(); metadata.put("WEOffsetX", new IntTag(offset.getBlockX())); From 836b7a9750ab3c3bfddcdd441acc442a341e72ec Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Mon, 4 Jan 2021 21:25:29 +0000 Subject: [PATCH 45/55] ~1/3 faster history writing with small caching --- .../object/changeset/FaweStreamChangeSet.java | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java index aa90fa9bc..2b525ed93 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java @@ -132,6 +132,9 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { int lx; int ly; int lz; + // 16*16*4 + byte[] buff = new byte[1024]; + int index = 0; @Override public void write(OutputStream out, int x, int y, int z) throws IOException { @@ -144,13 +147,16 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { int x16 = (rx >> 8) & 0xF; int z16 = (rz >> 8) & 0xF; byte b4 = MathMan.pair16(x16, z16); - out.write(b1); - out.write(b2); - out.write(b3); - out.write(b4); + System.arraycopy(new byte[] {b1, b2, b3, b4}, 0, buff, index, 4); + index += 4; + if (index == 1024) { + out.write(buff); + buff = new byte[1024]; + index = 0; + } } - byte[] buffer = new byte[4]; + final byte[] buffer = new byte[4]; @Override public int readX(FaweInputStream in) throws IOException { @@ -170,23 +176,30 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { }; } else { posDel = new FaweStreamPositionDelegate() { - final byte[] buffer = new byte[5]; int lx; int ly; int lz; + // 16*16*5 + byte[] buff = new byte[1280]; + int index = 0; @Override - public void write(OutputStream stream, int x, int y, int z) throws IOException { + public void write(OutputStream out, int x, int y, int z) throws IOException { int rx = -lx + (lx = x); int ry = -ly + (ly = y); int rz = -lz + (lz = z); - stream.write((rx) & 0xff); - stream.write(((rx) >> 8) & 0xff); - stream.write((rz) & 0xff); - stream.write(((rz) >> 8) & 0xff); - stream.write((byte) ry); + System.arraycopy(new byte[] {(byte) ((rx) & 0xff), (byte) (((rx) >> 8) & 0xff), (byte) ((rz) & 0xff), + (byte) (((rz) >> 8) & 0xff), (byte) ry}, 0, buff, index, 5); + index += 5; + if (index == 1280) { + out.write(buff); + buff = new byte[1280]; + index = 0; + } } + final byte[] buffer = new byte[5]; + @Override public int readX(FaweInputStream is) throws IOException { is.readFully(buffer); From bfd04e4155f17067493bf673ea78d00a1f58592b Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 5 Jan 2021 00:50:26 +0000 Subject: [PATCH 46/55] Revert "~1/3 faster history writing with small caching" This reverts commit 836b7a9750ab3c3bfddcdd441acc442a341e72ec. --- .../object/changeset/FaweStreamChangeSet.java | 37 ++++++------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java index 2b525ed93..aa90fa9bc 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java @@ -132,9 +132,6 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { int lx; int ly; int lz; - // 16*16*4 - byte[] buff = new byte[1024]; - int index = 0; @Override public void write(OutputStream out, int x, int y, int z) throws IOException { @@ -147,16 +144,13 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { int x16 = (rx >> 8) & 0xF; int z16 = (rz >> 8) & 0xF; byte b4 = MathMan.pair16(x16, z16); - System.arraycopy(new byte[] {b1, b2, b3, b4}, 0, buff, index, 4); - index += 4; - if (index == 1024) { - out.write(buff); - buff = new byte[1024]; - index = 0; - } + out.write(b1); + out.write(b2); + out.write(b3); + out.write(b4); } - final byte[] buffer = new byte[4]; + byte[] buffer = new byte[4]; @Override public int readX(FaweInputStream in) throws IOException { @@ -176,30 +170,23 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { }; } else { posDel = new FaweStreamPositionDelegate() { + final byte[] buffer = new byte[5]; int lx; int ly; int lz; - // 16*16*5 - byte[] buff = new byte[1280]; - int index = 0; @Override - public void write(OutputStream out, int x, int y, int z) throws IOException { + public void write(OutputStream stream, int x, int y, int z) throws IOException { int rx = -lx + (lx = x); int ry = -ly + (ly = y); int rz = -lz + (lz = z); - System.arraycopy(new byte[] {(byte) ((rx) & 0xff), (byte) (((rx) >> 8) & 0xff), (byte) ((rz) & 0xff), - (byte) (((rz) >> 8) & 0xff), (byte) ry}, 0, buff, index, 5); - index += 5; - if (index == 1280) { - out.write(buff); - buff = new byte[1280]; - index = 0; - } + stream.write((rx) & 0xff); + stream.write(((rx) >> 8) & 0xff); + stream.write((rz) & 0xff); + stream.write(((rz) >> 8) & 0xff); + stream.write((byte) ry); } - final byte[] buffer = new byte[5]; - @Override public int readX(FaweInputStream is) throws IOException { is.readFully(buffer); From aece0229c4abc3e0ad2c1762b587adbc09137ea0 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Tue, 5 Jan 2021 14:01:11 +0100 Subject: [PATCH 47/55] Properly repeat extents for negative coordinates (#825) An extent's content was returned flipped when applied for negative positions, as e.g. `Math.abs(-2) % 3` returns 2 instead of 1 (as 1 + -1 * 3 = -2) (cherry picked from commit b0cf5dd2bf1b9bcbf1c7efff0fe25de7ee9a2090) --- .../worldedit/function/pattern/RepeatingExtentPattern.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java index e4d5488ef..d95ecfc4d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java @@ -21,7 +21,6 @@ package com.sk89q.worldedit.function.pattern; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.math.MutableBlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; import static com.google.common.base.Preconditions.checkNotNull; @@ -88,9 +87,9 @@ public class RepeatingExtentPattern extends AbstractExtentPattern { @Override public BaseBlock apply(BlockVector3 position) { - int x = Math.abs(position.getX() + offset.getX()) % size.getBlockX() + origin.getX(); - int y = Math.abs(position.getY() + offset.getY()) % size.getBlockY() + origin.getY(); - int z = Math.abs(position.getZ() + offset.getZ()) % size.getBlockZ() + origin.getZ(); + int x = Math.floorMod(position.getBlockX() + offset.getBlockX(), size.getBlockX()) + origin.getBlockX(); + int y = Math.floorMod(position.getBlockY() + offset.getBlockY(), size.getBlockY()) + origin.getBlockY(); + int z = Math.floorMod(position.getBlockZ() + offset.getBlockZ(), size.getBlockZ()) + origin.getBlockZ(); return getExtent().getFullBlock(x, y, z); } From 7c174ee6b37c88bf667e830e6e9ef1f230b7627b Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 5 Jan 2021 13:51:26 +0000 Subject: [PATCH 48/55] Return to static "sections" in CharBlocks. - Synchronise (lock) outside the static object - Reduces object creation --- .../implementation/blocks/CharBlocks.java | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index cce611d28..7264b47ba 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -9,13 +9,13 @@ import org.jetbrains.annotations.Range; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; +import java.util.concurrent.locks.ReentrantLock; public abstract class CharBlocks implements IBlocks { public static final Logger logger = LoggerFactory.getLogger(CharBlocks.class); - protected final Section FULL = new Section() { + protected static final Section FULL = new Section() { @Override public final char[] get(CharBlocks blocks, int layer) { return blocks.blocks[layer]; @@ -26,25 +26,30 @@ public abstract class CharBlocks implements IBlocks { return true; } }; - protected final Section EMPTY = new Section() { + protected static final Section EMPTY = new Section() { @Override - public final synchronized char[] get(CharBlocks blocks, int layer) { - char[] arr = blocks.blocks[layer]; - if (arr == null) { - arr = blocks.blocks[layer] = blocks.update(layer, null); + public final char[] get(CharBlocks blocks, int layer) { + blocks.loadLock.lock(); + try { + char[] arr = blocks.blocks[layer]; if (arr == null) { - throw new IllegalStateException("Array cannot be null: " + blocks.getClass()); + arr = blocks.blocks[layer] = blocks.update(layer, null); + if (arr == null) { + throw new IllegalStateException("Array cannot be null: " + blocks.getClass()); + } + } else { + blocks.blocks[layer] = blocks.update(layer, arr); + if (blocks.blocks[layer] == null) { + throw new IllegalStateException("Array cannot be null (update): " + blocks.getClass()); + } } - } else { - blocks.blocks[layer] = blocks.update(layer, arr); - if (blocks.blocks[layer] == null) { - throw new IllegalStateException("Array cannot be null (update): " + blocks.getClass()); + if (blocks.blocks[layer] != null) { + blocks.sections[layer] = FULL; } + return arr; + } finally { + blocks.loadLock.unlock(); } - if (blocks.blocks[layer] != null) { - blocks.sections[layer] = FULL; - } - return arr; } @Override @@ -54,7 +59,7 @@ public abstract class CharBlocks implements IBlocks { }; public final char[][] blocks; public final Section[] sections; - private final Object loadLock = new Object(); + private final ReentrantLock loadLock = new ReentrantLock (); public CharBlocks() { blocks = new char[16][]; @@ -117,13 +122,7 @@ public abstract class CharBlocks implements IBlocks { @Override public char[] load(@Range(from = 0, to = 15) int layer) { - Section section = sections[layer]; - if (section.isFull()) { - return section.get(this, layer); - } - synchronized (loadLock) { - return sections[layer].get(this, layer); - } + return sections[layer].get(this, layer); } @Override From 89cc2f9d9f1fed47b73fdd4cdfe07757ff61cdbe Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 5 Jan 2021 15:03:47 +0000 Subject: [PATCH 49/55] Large memory use reduction when PostProcessing history --- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 10 +-- .../mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java | 77 ++++++++++++++---- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 10 +-- .../mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java | 78 +++++++++++++++---- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 10 +-- .../mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java | 77 ++++++++++++++---- .../mc1_16_4/BukkitGetBlocks_1_16_4.java | 10 +-- .../mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java | 77 ++++++++++++++---- .../com/boydti/fawe/beta/IChunkGetCopy.java | 6 -- .../object/changeset/AbstractChangeSet.java | 11 +-- 10 files changed, 269 insertions(+), 97 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index b6b2380a2..c4a9dfc9c 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; -import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; @@ -318,7 +317,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; - copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world, getChunkX(), getChunkZ()) : null; + copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world) : null; try { WorldServer nmsWorld = world; Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); @@ -362,12 +361,9 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { bitMask |= 1 << layer; - char[] setArr = set.load(layer); - // If we're creating a copy, it's because we're delaying history so we do not want to write to - // the chunkSet yet. + char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer); - copy.storeSetBlocks(layer, setArr); + copy.storeSection(layer, load(layer).clone()); } ChunkSection newSection; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java index 837676daa..8fddf5db1 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2_Copy.java @@ -2,7 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_15_2; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.IChunkGetCopy; +import com.boydti.fawe.beta.IBlocks; +import com.boydti.fawe.beta.IChunkGet; +import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -22,23 +25,25 @@ import net.minecraft.server.v1_15_R1.TileEntity; import net.minecraft.server.v1_15_R1.WorldServer; import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Future; -public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 implements IChunkGetCopy { +public class BukkitGetBlocks_1_15_2_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; - private final char[][] blocks = new char[16][4096]; - private final char[][] newSetBlocks = new char[16][]; + private final char[][] blocks = new char[16][]; + private final WorldServer world; - protected BukkitGetBlocks_1_15_2_Copy(WorldServer world, int X, int Z) { - super(world, X, Z); + protected BukkitGetBlocks_1_15_2_Copy(WorldServer world) { + this.world = world; } protected void storeTile(TileEntity tile) { @@ -89,6 +94,16 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 implemen return null; } + @Override + public void setCreateCopy(boolean createCopy) { + + } + + @Override + public boolean isCreateCopy() { + return false; + } + protected void storeBiomes(BiomeStorage biomeStorage) { this.biomeStorage = new BiomeStorage(BukkitAdapter_1_15_2.getBiomeArray(biomeStorage).clone()); } @@ -107,8 +122,18 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 implemen return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null; } - protected void storeSection(int layer) { - blocks[layer] = load(layer).clone(); + @Override + public boolean trim(boolean aggressive, int layer) { + return false; + } + + @Override + public IBlocks reset() { + return null; + } + + protected void storeSection(int layer, char[] data) { + blocks[layer] = data; } @Override @@ -117,24 +142,50 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 implemen return state.toBaseBlock(this, x, y, z); } + @Override + public boolean hasSection(@Range(from = 0, to = 15) int layer) { + return blocks[layer] != null; + } + + @Override + public char[] load(int layer) { + return blocks[layer]; + } + @Override public BlockState getBlock(int x, int y, int z) { return BlockTypesCache.states[get(x, y, z)]; } @Override + public int getSkyLight(int x, int y, int z) { + return 0; + } + + @Override + public int getEmmittedLight(int x, int y, int z) { + return 0; + } + + @Override + public int[] getHeightMap(HeightMapType type) { + return new int[0]; + } + + @Override + public > T call(IChunkSet set, Runnable finalize) { + return null; + } + public char get(int x, int y, int z) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } - protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks.clone(); - } @Override - public char[] getNewSetArr(int layer) { - return newSetBlocks[layer]; + public boolean trim(boolean aggressive) { + return false; } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 3a5a68338..bf2ca9670 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; -import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; @@ -318,7 +317,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; - copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world, getChunkX(), getChunkZ()) : null; + copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world) : null; try { WorldServer nmsWorld = world; Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); @@ -362,12 +361,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { bitMask |= 1 << layer; - char[] setArr = set.load(layer); - // If we're creating a copy, it's because we're delaying history so we do not want to write to - // the chunkSet yet. + char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer); - copy.storeSetBlocks(layer, setArr); + copy.storeSection(layer, load(layer).clone()); } ChunkSection newSection; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java index 2cd174af9..634d2c5ff 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1_Copy.java @@ -2,7 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_1; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.IChunkGetCopy; +import com.boydti.fawe.beta.IBlocks; +import com.boydti.fawe.beta.IChunkGet; +import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -17,29 +20,30 @@ import com.sk89q.worldedit.world.block.BlockTypesCache; import net.minecraft.server.v1_16_R1.BiomeBase; import net.minecraft.server.v1_16_R1.BiomeStorage; import net.minecraft.server.v1_16_R1.Entity; -import net.minecraft.server.v1_16_R1.IRegistry; import net.minecraft.server.v1_16_R1.NBTTagCompound; import net.minecraft.server.v1_16_R1.TileEntity; import net.minecraft.server.v1_16_R1.WorldServer; import org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Future; -public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 implements IChunkGetCopy { +public class BukkitGetBlocks_1_16_1_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; - private final char[][] blocks = new char[16][4096]; - private final char[][] newSetBlocks = new char[16][]; + private final char[][] blocks = new char[16][]; + private final WorldServer world; - protected BukkitGetBlocks_1_16_1_Copy(WorldServer world, int X, int Z) { - super(world, X, Z); + protected BukkitGetBlocks_1_16_1_Copy(WorldServer world) { + this.world = world; } protected void storeTile(TileEntity tile) { @@ -90,6 +94,16 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 implemen return null; } + @Override + public void setCreateCopy(boolean createCopy) { + + } + + @Override + public boolean isCreateCopy() { + return false; + } + protected void storeBiomes(BiomeStorage biomeStorage) { this.biomeStorage = new BiomeStorage(BukkitAdapter_1_16_1.getBiomeArray(biomeStorage).clone()); } @@ -108,8 +122,18 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 implemen return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null; } - protected void storeSection(int layer) { - blocks[layer] = load(layer).clone(); + @Override + public boolean trim(boolean aggressive, int layer) { + return false; + } + + @Override + public IBlocks reset() { + return null; + } + + protected void storeSection(int layer, char[] data) { + blocks[layer] = data; } @Override @@ -118,24 +142,50 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 implemen return state.toBaseBlock(this, x, y, z); } + @Override + public boolean hasSection(@Range(from = 0, to = 15) int layer) { + return blocks[layer] != null; + } + + @Override + public char[] load(int layer) { + return blocks[layer]; + } + @Override public BlockState getBlock(int x, int y, int z) { return BlockTypesCache.states[get(x, y, z)]; } @Override + public int getSkyLight(int x, int y, int z) { + return 0; + } + + @Override + public int getEmmittedLight(int x, int y, int z) { + return 0; + } + + @Override + public int[] getHeightMap(HeightMapType type) { + return new int[0]; + } + + @Override + public > T call(IChunkSet set, Runnable finalize) { + return null; + } + public char get(int x, int y, int z) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } - protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks.clone(); - } @Override - public char[] getNewSetArr(int layer) { - return newSetBlocks[layer]; + public boolean trim(boolean aggressive) { + return false; } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index 5a8873114..e5c0dc447 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; -import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; @@ -321,7 +320,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; - copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world, getChunkX(), getChunkZ()) : null; + copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world) : null; try { WorldServer nmsWorld = world; Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); @@ -365,12 +364,9 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { bitMask |= 1 << layer; - char[] setArr = set.load(layer); - // If we're creating a copy, it's because we're delaying history so we do not want to write to - // the chunkSet yet. + char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer); - copy.storeSetBlocks(layer, setArr); + copy.storeSection(layer, load(layer).clone()); } ChunkSection newSection; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java index c0086e180..bb772de71 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2_Copy.java @@ -2,7 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_2; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.IChunkGetCopy; +import com.boydti.fawe.beta.IBlocks; +import com.boydti.fawe.beta.IChunkGet; +import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -23,23 +26,25 @@ import net.minecraft.server.v1_16_R2.TileEntity; import net.minecraft.server.v1_16_R2.WorldServer; import org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Future; -public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 implements IChunkGetCopy { +public class BukkitGetBlocks_1_16_2_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; - private final char[][] blocks = new char[16][4096]; - private final char[][] newSetBlocks = new char[16][]; + private final char[][] blocks = new char[16][]; + private final WorldServer world; - protected BukkitGetBlocks_1_16_2_Copy(WorldServer world, int X, int Z) { - super(world, X, Z); + protected BukkitGetBlocks_1_16_2_Copy(WorldServer world) { + this.world = world; } protected void storeTile(TileEntity tile) { @@ -90,6 +95,16 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 implemen return null; } + @Override + public void setCreateCopy(boolean createCopy) { + + } + + @Override + public boolean isCreateCopy() { + return false; + } + protected void storeBiomes(BiomeStorage biomeStorage) { this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_2.getBiomeArray(biomeStorage).clone()); } @@ -108,8 +123,18 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 implemen return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null; } - protected void storeSection(int layer) { - blocks[layer] = load(layer).clone(); + @Override + public boolean trim(boolean aggressive, int layer) { + return false; + } + + @Override + public IBlocks reset() { + return null; + } + + protected void storeSection(int layer, char[] data) { + blocks[layer] = data; } @Override @@ -118,24 +143,50 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 implemen return state.toBaseBlock(this, x, y, z); } + @Override + public boolean hasSection(@Range(from = 0, to = 15) int layer) { + return blocks[layer] != null; + } + + @Override + public char[] load(int layer) { + return blocks[layer]; + } + @Override public BlockState getBlock(int x, int y, int z) { return BlockTypesCache.states[get(x, y, z)]; } @Override + public int getSkyLight(int x, int y, int z) { + return 0; + } + + @Override + public int getEmmittedLight(int x, int y, int z) { + return 0; + } + + @Override + public int[] getHeightMap(HeightMapType type) { + return new int[0]; + } + + @Override + public > T call(IChunkSet set, Runnable finalize) { + return null; + } + public char get(int x, int y, int z) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } - protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks.clone(); - } @Override - public char[] getNewSetArr(int layer) { - return newSetBlocks[layer]; + public boolean trim(boolean aggressive) { + return false; } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index 8fb195641..d07e4b8f2 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; -import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; @@ -321,7 +320,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { @Override public > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; - copy = createCopy ? new BukkitGetBlocks_1_16_4_Copy(world, getChunkX(), getChunkZ()) : null; + copy = createCopy ? new BukkitGetBlocks_1_16_4_Copy(world) : null; try { WorldServer nmsWorld = world; Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); @@ -365,12 +364,9 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { bitMask |= 1 << layer; - char[] setArr = set.load(layer); - // If we're creating a copy, it's because we're delaying history so we do not want to write to - // the chunkSet yet. + char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer); - copy.storeSetBlocks(layer, setArr); + copy.storeSection(layer, load(layer).clone()); } ChunkSection newSection; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java index da2980d1e..3f1db2730 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java @@ -2,7 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_4; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.IChunkGetCopy; +import com.boydti.fawe.beta.IBlocks; +import com.boydti.fawe.beta.IChunkGet; +import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; @@ -23,23 +26,25 @@ import net.minecraft.server.v1_16_R3.TileEntity; import net.minecraft.server.v1_16_R3.WorldServer; import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Future; -public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 implements IChunkGetCopy { +public class BukkitGetBlocks_1_16_4_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private BiomeStorage biomeStorage; - private final char[][] blocks = new char[16][4096]; - private final char[][] newSetBlocks = new char[16][]; + private final char[][] blocks = new char[16][]; + private final WorldServer world; - protected BukkitGetBlocks_1_16_4_Copy(WorldServer world, int X, int Z) { - super(world, X, Z); + protected BukkitGetBlocks_1_16_4_Copy(WorldServer world) { + this.world = world; } protected void storeTile(TileEntity tile) { @@ -90,6 +95,16 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 implemen return null; } + @Override + public void setCreateCopy(boolean createCopy) { + + } + + @Override + public boolean isCreateCopy() { + return false; + } + protected void storeBiomes(BiomeStorage biomeStorage) { this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_4.getBiomeArray(biomeStorage).clone()); } @@ -108,8 +123,18 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 implemen return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null; } - protected void storeSection(int layer) { - blocks[layer] = load(layer).clone(); + @Override + public boolean trim(boolean aggressive, int layer) { + return false; + } + + @Override + public IBlocks reset() { + return null; + } + + protected void storeSection(int layer, char[] data) { + blocks[layer] = data; } @Override @@ -118,24 +143,50 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 implemen return state.toBaseBlock(this, x, y, z); } + @Override + public boolean hasSection(@Range(from = 0, to = 15) int layer) { + return blocks[layer] != null; + } + + @Override + public char[] load(int layer) { + return blocks[layer]; + } + @Override public BlockState getBlock(int x, int y, int z) { return BlockTypesCache.states[get(x, y, z)]; } @Override + public int getSkyLight(int x, int y, int z) { + return 0; + } + + @Override + public int getEmmittedLight(int x, int y, int z) { + return 0; + } + + @Override + public int[] getHeightMap(HeightMapType type) { + return new int[0]; + } + + @Override + public > T call(IChunkSet set, Runnable finalize) { + return null; + } + public char get(int x, int y, int z) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; return blocks[layer][index]; } - protected void storeSetBlocks(int layer, char[] blocks) { - newSetBlocks[layer] = blocks.clone(); - } @Override - public char[] getNewSetArr(int layer) { - return newSetBlocks[layer]; + public boolean trim(boolean aggressive) { + return false; } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java deleted file mode 100644 index 87b3b4396..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunkGetCopy.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.boydti.fawe.beta; - -public interface IChunkGetCopy { - - char[] getNewSetArr(int layer); -} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java index 5ba55d849..bf90ebc6a 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java @@ -5,7 +5,6 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunkGet; -import com.boydti.fawe.beta.IChunkGetCopy; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.object.HistoryExtent; import com.boydti.fawe.util.EditSessionBuilder; @@ -157,7 +156,6 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { addEntityCreate(tag); } } - boolean updateSet = get instanceof IChunkGetCopy; for (int layer = 0; layer < 16; layer++) { if (!set.hasSection(layer)) { continue; @@ -168,11 +166,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { blocksGet = FaweCache.IMP.EMPTY_CHAR_4096; } char[] blocksSet = set.load(layer); - char[] newBlocksSet = null; - if (updateSet) { - newBlocksSet = ((IChunkGetCopy) get).getNewSetArr(layer); - } -; + int by = layer << 4; for (int y = 0, index = 0; y < 16; y++) { int yy = y + by; @@ -189,9 +183,6 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { if (combinedTo != 0) { add(xx, yy, zz, combinedFrom, combinedTo); } - if (updateSet) { - blocksSet[index] = newBlocksSet[index]; - } } } } From 6db588a19f970282bdbcba5c73a10d4866a63a11 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 5 Jan 2021 16:42:53 +0000 Subject: [PATCH 50/55] Don't allow FAWE to "deadlock" itself when post-processing history by switching to the primary ForkJoinPool - With enough chunks waiting to write to history, it's possible to fill the secondary fork pool up with locked threads, and thus prevent any threads from actually writing their history. --- .../com/boydti/fawe/object/changeset/AbstractChangeSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java index bf90ebc6a..7ee81bb94 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java @@ -351,7 +351,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { wrappedTask.run(); return Futures.immediateCancelledFuture(); } else { - return Fawe.get().getQueueHandler().async(wrappedTask); + return Fawe.get().getQueueHandler().submit(wrappedTask); } } } From 91de441403bf9adfb232c20c8590e4ff83fb3a21 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 5 Jan 2021 17:21:35 +0000 Subject: [PATCH 51/55] No need to check WorldEdit schematics for bad entities --- .../worldedit/extent/clipboard/io/FastSchematicReader.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java index 35a2f379b..9fdebeb06 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/FastSchematicReader.java @@ -99,6 +99,7 @@ public class FastSchematicReader extends NBTSchematicReader { private char[] biomePalette; private BlockVector3 min = BlockVector3.ZERO; private boolean brokenEntities = false; + private boolean isWorldEdit = false; /** @@ -171,6 +172,10 @@ public class FastSchematicReader extends NBTSchematicReader { metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v); metadata.add("FAWEVersion").withInt((i, v) -> faweWritten = v); + StreamDelegate worldEditSection = metadata.add("WorldEdit"); + worldEditSection.withValue((ValueReader) (index, v) -> isWorldEdit = true); + + StreamDelegate paletteDelegate = schematic.add("Palette"); paletteDelegate.withValue((ValueReader>) (ignore, v) -> { palette = new char[v.size()]; @@ -389,7 +394,7 @@ public class FastSchematicReader extends NBTSchematicReader { clipboard.createEntity(loc, state); continue; } - if (faweWritten == -1) { + if (!isWorldEdit && faweWritten == -1) { int locX = loc.getBlockX(); int locY = loc.getBlockY(); int locZ = loc.getBlockZ(); From 280ade9994034471a6f5c234cced50ac209275ed Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 6 Jan 2021 13:29:52 +0000 Subject: [PATCH 52/55] fix NBT in memory optimized clipboard --- .../fawe/object/clipboard/MemoryOptimizedClipboard.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java index 766057964..65ec74564 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java @@ -257,11 +257,11 @@ public class MemoryOptimizedClipboard extends LinearClipboard { @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - nbtMap.put(new IntTriple(x, y, z), tag); - Map values = tag.getValue(); + final Map values = new HashMap<>(tag.getValue()); values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); + nbtMap.put(new IntTriple(x, y, z), new CompoundTag(values)); return true; } From 336b90be153aa8b689ad55c815534b004bc07310 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 6 Jan 2021 13:39:25 +0000 Subject: [PATCH 53/55] Also fix CPUOptimizedClipboard --- .../object/clipboard/CPUOptimizedClipboard.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java index 944fb5446..d1dfc1280 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java @@ -152,10 +152,8 @@ public class CPUOptimizedClipboard extends LinearClipboard { @Override public Collection getTileEntities() { convertTilesToIndex(); - for (Map.Entry entry : nbtMapIndex.entrySet()) { - int index = entry.getKey(); - CompoundTag tag = entry.getValue(); - Map values = tag.getValue(); + nbtMapIndex.replaceAll((index, tag) -> { + Map values = new HashMap<>(tag.getValue()); if (!values.containsKey("x")) { int y = index / getArea(); index -= y * getArea(); @@ -164,23 +162,26 @@ public class CPUOptimizedClipboard extends LinearClipboard { values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); + return new CompoundTag(values); + } else { + return tag; } - } + }); return nbtMapIndex.values(); } @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - nbtMapLoc.put(new IntTriple(x, y, z), tag); + nbtMapLoc.put(new IntTriple(x, y, z), new CompoundTag(tag.getValue())); return true; } public boolean setTile(int index, CompoundTag tag) { - nbtMapIndex.put(index, tag); - Map values = tag.getValue(); + final Map values = new HashMap<>(tag.getValue()); values.remove("x"); values.remove("y"); values.remove("z"); + nbtMapIndex.put(index, new CompoundTag(values)); return true; } From e40e86df5f0dc8ab8eeea6de56463253d39bd43f Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 6 Jan 2021 16:40:28 +0000 Subject: [PATCH 54/55] Add some more __internal__ <-> air logi Fixes #831 --- .../main/java/com/boydti/fawe/object/mask/AirMask.java | 5 +++++ .../java/com/boydti/fawe/object/mask/IdDataMask.java | 5 +++++ .../main/java/com/boydti/fawe/object/mask/IdMask.java | 5 +++++ .../worldedit/function/mask/BlockCategoryMask.java | 6 ++++++ .../com/sk89q/worldedit/function/mask/BlockMask.java | 8 +++----- .../com/sk89q/worldedit/function/mask/InverseMask.java | 5 +++++ .../function/mask/InverseSingleBlockTypeMask.java | 7 +++++++ .../worldedit/function/mask/MaskIntersection.java | 10 ++++++++++ .../com/sk89q/worldedit/function/mask/MaskUnion.java | 10 ++++++++++ 9 files changed, 56 insertions(+), 5 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AirMask.java b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AirMask.java index 950f1d9df..69f1bf9c2 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AirMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AirMask.java @@ -16,4 +16,9 @@ public class AirMask extends BlockMask { return new AirMask(getExtent()); } + @Override + public boolean replacesAir() { + return true; + } + } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdDataMask.java b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdDataMask.java index 0329f0b5c..105af3965 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdDataMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdDataMask.java @@ -37,4 +37,9 @@ public class IdDataMask extends AbstractExtentMask implements ResettableMask { return new IdDataMask(getExtent()); } + @Override + public boolean replacesAir() { + return true; + } + } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdMask.java b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdMask.java index 6528d5407..ebb2f5d9b 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/IdMask.java @@ -38,4 +38,9 @@ public class IdMask extends AbstractExtentMask implements ResettableMask { return new IdMask(getExtent()); } + @Override + public boolean replacesAir() { + return true; + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java index e600929b3..a38a77e04 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockCategory; +import com.sk89q.worldedit.world.block.BlockTypes; import javax.annotation.Nullable; @@ -61,4 +62,9 @@ public class BlockCategoryMask extends AbstractExtentMask { public Mask copy() { return new BlockCategoryMask(getExtent(), category); } + + @Override + public boolean replacesAir() { + return category.contains(BlockTypes.AIR); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java index 665415618..efe910dd3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java @@ -29,12 +29,12 @@ import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.ImmutableBaseBlock; +import javax.annotation.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.function.Predicate; -import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; @@ -185,7 +185,7 @@ public class BlockMask extends ABlockMask { @Override public boolean test(BlockState state) { - return ordinals[state.getOrdinal()] || replacesAir() && state.getOrdinal() <= 3; + return ordinals[state.getOrdinal()] || replacesAir() && state.getOrdinal() == 0; } @Override @@ -259,19 +259,16 @@ public class BlockMask extends ABlockMask { int setTypes = 0; BlockType setType = null; - BlockType unsetType = null; int totalTypes = 0; for (BlockType type : BlockTypesCache.values) { if (type != null) { totalTypes++; boolean hasAll = true; - boolean hasAny = false; List all = type.getAllStates(); for (BlockState state : all) { totalStates++; hasAll &= test(state); - hasAny = true; } if (hasAll) { setTypes++; @@ -326,6 +323,7 @@ public class BlockMask extends ABlockMask { cloned[BlockTypes.AIR.getDefaultState().getOrdinal()] = false; cloned[BlockTypes.CAVE_AIR.getDefaultState().getOrdinal()] = false; cloned[BlockTypes.VOID_AIR.getDefaultState().getOrdinal()] = false; + cloned[0] = false; } return new BlockMask(getExtent(), cloned); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseMask.java index ed86f6bc0..2389eb981 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseMask.java @@ -36,4 +36,9 @@ public class InverseMask extends AbstractMask { public Mask copy() { return new InverseMask(mask.copy()); } + + @Override + public boolean replacesAir() { + return mask.replacesAir(); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockTypeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockTypeMask.java index fa6da2278..a8dcd3c18 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockTypeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockTypeMask.java @@ -8,10 +8,12 @@ import com.sk89q.worldedit.world.block.BlockTypesCache; public class InverseSingleBlockTypeMask extends ABlockMask { private final int internalId; + private final boolean replacesAir; public InverseSingleBlockTypeMask(Extent extent, BlockType type) { super(extent); this.internalId = type.getInternalId(); + this.replacesAir = type.getMaterial().isAir(); } @Override @@ -33,4 +35,9 @@ public class InverseSingleBlockTypeMask extends ABlockMask { // The mask is not mutable. There is no need to clone it. return this; } + + @Override + public boolean replacesAir() { + return replacesAir; + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java index 2b3968744..ab8b95b0b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java @@ -275,4 +275,14 @@ public class MaskIntersection extends AbstractMask { return new MaskIntersection(masks); } + @Override + public boolean replacesAir() { + for (Mask mask : masksArray) { + if (mask.replacesAir()) { + return true; + } + } + return false; + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java index 25174efd6..4adf197de 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java @@ -118,4 +118,14 @@ public class MaskUnion extends MaskIntersection { Set masksCopy = masks.stream().map(Mask::copy).collect(Collectors.toSet()); return new MaskUnion(masksCopy); } + + @Override + public boolean replacesAir() { + for (Mask mask : getMasksArray()) { + if (mask.replacesAir()) { + return true; + } + } + return false; + } } From 1b870c5d78f65b018ed94cbf00ceb1c0dc358273 Mon Sep 17 00:00:00 2001 From: Aurora <21148213+aurorasmiles@users.noreply.github.com> Date: Wed, 6 Jan 2021 17:57:59 +0100 Subject: [PATCH 55/55] Upstream/add missing y variable to generate biome (#824) * Add the missing y variable to generate biome * Remove unused imports Co-authored-by: Octavia Togami Co-authored-by: NotMyFault --- .../java/com/sk89q/worldedit/EditSession.java | 21 ++++++++----------- .../src/main/resources/lang/strings.json | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index c627bdf99..0bb02566f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -125,8 +125,6 @@ import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockCategories; -import com.sk89q.worldedit.world.block.BlockID; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; @@ -148,6 +146,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -3008,23 +3007,21 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType, - final String expressionString, final boolean hollow) - throws ExpressionException, MaxChangedBlocksException { + final String expressionString, final boolean hollow) throws ExpressionException { return makeBiomeShape(region, zero, unit, biomeType, expressionString, hollow, WorldEdit.getInstance().getConfiguration().calculationTimeout); } public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType, - final String expressionString, final boolean hollow, final int timeout) - throws ExpressionException, MaxChangedBlocksException { + final String expressionString, final boolean hollow, final int timeout) throws ExpressionException { - final Expression expression = Expression.compile(expressionString, "x", "z"); + final Expression expression = Expression.compile(expressionString, "x", "y", "z"); expression.optimize(); final EditSession editSession = this; final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(editSession, unit, zero); expression.setEnvironment(environment); - final int[] timedOut = {0}; + AtomicInteger timedOut = new AtomicInteger(); final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) { @Override protected BiomeType getBiome(int x, int y, int z, BiomeType defaultBiomeType) { @@ -3041,7 +3038,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { // TODO: Allow biome setting via a script variable (needs BiomeType<->int mapping) return defaultBiomeType; } catch (ExpressionTimeoutException e) { - timedOut[0] = timedOut[0] + 1; + timedOut.getAndIncrement(); return null; } catch (Exception e) { log.warn("Failed to create shape", e); @@ -3050,10 +3047,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } }; int changed = shape.generate(this, biomeType, hollow); - if (timedOut[0] > 0) { + if (timedOut.get() > 0) { throw new ExpressionTimeoutException( - String.format("%d blocks changed. %d blocks took too long to evaluate (increase time with //timeout)", - changed, timedOut[0])); + String.format("%d biomes changed. %d biomes took too long to evaluate (increase time with //timeout)", + changed, timedOut.get())); } return changed; } diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 4bfae49f3..108294c80 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -397,7 +397,7 @@ "worldedit.pumpkins.created": "{0} pumpkin patches created.", "worldedit.pyramid.created": "{0} blocks have been created.", "worldedit.generate.created": "{0} blocks have been created.", - "worldedit.generate.changed": "{0} columns affected.", + "worldedit.generatebiome.changed": "{0} biomes affected.", "worldedit.reload.config": "Configuration reloaded!", "worldedit.report.written": "FAWE report written to {0}",