From d27daefd3e896aba95beb8454c73659998a7fd19 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Sun, 23 Jun 2019 01:03:18 -0700 Subject: [PATCH 01/52] Implement getBlock for chunk batching extent Also improve speed of comparators, by using ::comparingX and bitwise ops. --- .../extent/reorder/ChunkBatchingExtent.java | 66 +++++++++++++++---- .../sk89q/worldedit/math/BlockVector2.java | 33 +++++++--- .../sk89q/worldedit/math/BlockVector3.java | 40 +++++++---- 3 files changed, 108 insertions(+), 31 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java index b8f6082c4..30940e942 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java @@ -19,22 +19,25 @@ package com.sk89q.worldedit.extent.reorder; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.RunContext; -import com.sk89q.worldedit.function.operation.SetLocatedBlocks; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.util.collection.LocatedBlockList; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import java.util.Comparator; +import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.Map; +import java.util.Set; /** * A special extent that batches changes into Minecraft chunks. This helps @@ -49,10 +52,12 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent { * in. This allows for file caches to be used while loading the chunk. */ private static final Comparator REGION_OPTIMIZED_SORT = - Comparator.comparing((BlockVector2 vec) -> vec.divide(32), BlockVector2.COMPARING_GRID_ARRANGEMENT) + Comparator.comparing((BlockVector2 vec) -> vec.shr(5), BlockVector2.COMPARING_GRID_ARRANGEMENT) .thenComparing(BlockVector2.COMPARING_GRID_ARRANGEMENT); - private final SortedMap batches = new TreeMap<>(REGION_OPTIMIZED_SORT); + private final Table batches = + TreeBasedTable.create(REGION_OPTIMIZED_SORT, BlockVector3.sortByCoordsYzx()); + private final Set containedBlocks = new HashSet<>(); private boolean enabled; public ChunkBatchingExtent(Extent extent) { @@ -76,16 +81,51 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent { return enabled; } + private BlockVector2 getChunkPos(BlockVector3 location) { + return location.shr(4).toBlockVector2(); + } + + private BlockVector3 getInChunkPos(BlockVector3 location) { + return BlockVector3.at(location.getX() & 15, location.getY(), location.getZ() & 15); + } + @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { if (!enabled) { return getExtent().setBlock(location, block); } - BlockVector2 chunkPos = BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4); - batches.computeIfAbsent(chunkPos, k -> new LocatedBlockList()).add(location, block); + BlockVector2 chunkPos = getChunkPos(location); + BlockVector3 inChunkPos = getInChunkPos(location); + batches.put(chunkPos, inChunkPos, block.toBaseBlock()); + containedBlocks.add(location); return true; } + @Override + public BlockState getBlock(BlockVector3 position) { + BaseBlock internal = getInternalBlock(position); + if (internal != null) { + return internal.toImmutableState(); + } + return super.getBlock(position); + } + + @Override + public BaseBlock getFullBlock(BlockVector3 position) { + BaseBlock internal = getInternalBlock(position); + if (internal != null) { + return internal; + } + return super.getFullBlock(position); + } + + private BaseBlock getInternalBlock(BlockVector3 position) { + if (!containedBlocks.contains(position)) { + return null; + } + return batches.get(getChunkPos(position), getInChunkPos(position)); + } + @Override protected Operation commitBefore() { if (!commitRequired()) { @@ -94,17 +134,21 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent { return new Operation() { // we get modified between create/resume -- only create this on resume to prevent CME - private Iterator batchIterator; + private Iterator> batchIterator; @Override public Operation resume(RunContext run) throws WorldEditException { if (batchIterator == null) { - batchIterator = batches.values().iterator(); + batchIterator = batches.rowMap().values().iterator(); } if (!batchIterator.hasNext()) { return null; } - new SetLocatedBlocks(getExtent(), batchIterator.next()).resume(run); + Map next = batchIterator.next(); + for (Map.Entry block : next.entrySet()) { + getExtent().setBlock(block.getKey(), block.getValue()); + containedBlocks.remove(block.getKey()); + } batchIterator.remove(); return this; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java index 92548fc99..6e2dd17e1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.math; -import com.google.common.collect.ComparisonChain; import com.sk89q.worldedit.math.transform.AffineTransform; import java.util.Comparator; @@ -28,7 +27,7 @@ import java.util.Comparator; * An immutable 2-dimensional vector. */ public final class BlockVector2 { - + public static final BlockVector2 ZERO = new BlockVector2(0, 0); public static final BlockVector2 UNIT_X = new BlockVector2(1, 0); public static final BlockVector2 UNIT_Z = new BlockVector2(0, 1); @@ -48,12 +47,8 @@ public final class BlockVector2 { * cdef * */ - public static final Comparator COMPARING_GRID_ARRANGEMENT = (a, b) -> { - return ComparisonChain.start() - .compare(a.getBlockZ(), b.getBlockZ()) - .compare(a.getBlockX(), b.getBlockX()) - .result(); - }; + public static final Comparator COMPARING_GRID_ARRANGEMENT = + Comparator.comparingInt(BlockVector2::getZ).thenComparingInt(BlockVector2::getX); public static BlockVector2 at(double x, double z) { return at((int) Math.floor(x), (int) Math.floor(z)); @@ -303,6 +298,27 @@ public final class BlockVector2 { return divide(n, n); } + /** + * Shift all components right. + * + * @param x the value to shift x by + * @param z the value to shift z by + * @return a new vector + */ + public BlockVector2 shr(int x, int z) { + return at(this.x >> x, this.z >> z); + } + + /** + * Shift all components right by {@code n}. + * + * @param n the value to shift by + * @return a new vector + */ + public BlockVector2 shr(int n) { + return shr(n, n); + } + /** * Get the length of the vector. * @@ -532,5 +548,4 @@ public final class BlockVector2 { public String toString() { return "(" + x + ", " + z + ")"; } - } \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index ffb6f6347..71d058bd9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -19,13 +19,12 @@ package com.sk89q.worldedit.math; -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.collect.ComparisonChain; import com.sk89q.worldedit.math.transform.AffineTransform; import java.util.Comparator; +import static com.google.common.base.Preconditions.checkArgument; + /** * An immutable 3-dimensional vector. */ @@ -64,18 +63,15 @@ public final class BlockVector3 { // thread-safe initialization idiom private static final class YzxOrderComparator { - private static final Comparator YZX_ORDER = (a, b) -> { - return ComparisonChain.start() - .compare(a.y, b.y) - .compare(a.z, b.z) - .compare(a.x, b.x) - .result(); - }; + private static final Comparator YZX_ORDER = + Comparator.comparingInt(BlockVector3::getY) + .thenComparingInt(BlockVector3::getZ) + .thenComparingInt(BlockVector3::getX); } /** * Returns a comparator that sorts vectors first by Y, then Z, then X. - * + * *

* Useful for sorting by chunk block storage order. */ @@ -348,6 +344,28 @@ public final class BlockVector3 { return divide(n, n, n); } + /** + * Shift all components right. + * + * @param x the value to shift x by + * @param y the value to shift y by + * @param z the value to shift z by + * @return a new vector + */ + public BlockVector3 shr(int x, int y, int z) { + return at(this.x >> x, this.y >> y, this.z >> z); + } + + /** + * Shift all components right by {@code n}. + * + * @param n the value to shift by + * @return a new vector + */ + public BlockVector3 shr(int n) { + return shr(n, n, n); + } + /** * Get the length of the vector. * From 99ee32fe8e318d9d3714cfcf283fe86386ffa773 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Thu, 4 Jul 2019 11:43:36 -0700 Subject: [PATCH 02/52] Many fixes for buffered extents --- .../java/com/sk89q/worldedit/EditSession.java | 4 +- .../extent/AbstractBufferingExtent.java | 48 +++++++++++++++++++ .../worldedit/extent/buffer/ExtentBuffer.java | 24 +++------- .../extent/reorder/ChunkBatchingExtent.java | 42 +++++----------- .../extent/reorder/MultiStageReorder.java | 23 +++++++-- .../sk89q/worldedit/math/BlockVector3.java | 22 +++++++++ .../util/collection/LocatedBlockList.java | 46 ++++++++++-------- 7 files changed, 136 insertions(+), 73 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java 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 8501ba917..bd0afc352 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -565,12 +565,12 @@ public class EditSession implements Extent, AutoCloseable { @Override public BlockState getBlock(BlockVector3 position) { - return world.getBlock(position); + return bypassNone.getBlock(position); } @Override public BaseBlock getFullBlock(BlockVector3 position) { - return world.getFullBlock(position); + return bypassNone.getFullBlock(position); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java new file mode 100644 index 000000000..c7aead10a --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java @@ -0,0 +1,48 @@ +package com.sk89q.worldedit.extent; + +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; + +import java.util.Optional; + +/** + * Base extent class for buffering changes between {@link #setBlock(BlockVector3, BlockStateHolder)} + * and the delegate extent. This class ensures that {@link #getBlock(BlockVector3)} is properly + * handled, by returning buffered blocks. + */ +public abstract class AbstractBufferingExtent extends AbstractDelegateExtent { + /** + * Create a new instance. + * + * @param extent the extent + */ + protected AbstractBufferingExtent(Extent extent) { + super(extent); + } + + @Override + public abstract > boolean setBlock(BlockVector3 location, T block) throws WorldEditException; + + protected final > boolean setDelegateBlock(BlockVector3 location, T block) throws WorldEditException { + return super.setBlock(location, block); + } + + @Override + public BlockState getBlock(BlockVector3 position) { + return getBufferedBlock(position) + .map(BaseBlock::toImmutableState) + .orElseGet(() -> super.getBlock(position)); + } + + @Override + public BaseBlock getFullBlock(BlockVector3 position) { + return getBufferedBlock(position) + .orElseGet(() -> super.getFullBlock(position)); + } + + protected abstract Optional getBufferedBlock(BlockVector3 position); + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java index 562f094e5..8a974c6a6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java @@ -21,16 +21,16 @@ package com.sk89q.worldedit.extent.buffer; import com.google.common.collect.Maps; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.AbstractBufferingExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Masks; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import java.util.Map; +import java.util.Optional; import static com.google.common.base.Preconditions.checkNotNull; @@ -38,7 +38,7 @@ import static com.google.common.base.Preconditions.checkNotNull; * Buffers changes to an {@link Extent} and allows retrieval of the changed blocks, * without modifying the underlying extent. */ -public class ExtentBuffer extends AbstractDelegateExtent { +public class ExtentBuffer extends AbstractBufferingExtent { private final Map buffer = Maps.newHashMap(); private final Mask mask; @@ -67,23 +67,11 @@ public class ExtentBuffer extends AbstractDelegateExtent { } @Override - public BlockState getBlock(BlockVector3 position) { + protected Optional getBufferedBlock(BlockVector3 position) { if (mask.test(position)) { - return getOrDefault(position).toImmutableState(); + return Optional.of(buffer.computeIfAbsent(position, (pos -> getExtent().getFullBlock(pos)))); } - return super.getBlock(position); - } - - @Override - public BaseBlock getFullBlock(BlockVector3 position) { - if (mask.test(position)) { - return getOrDefault(position); - } - return super.getFullBlock(position); - } - - private BaseBlock getOrDefault(BlockVector3 position) { - return buffer.computeIfAbsent(position, (pos -> getExtent().getFullBlock(pos))); + return Optional.empty(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java index 30940e942..a44017fd1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java @@ -22,14 +22,13 @@ package com.sk89q.worldedit.extent.reorder; import com.google.common.collect.Table; import com.google.common.collect.TreeBasedTable; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.AbstractBufferingExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.RunContext; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import java.util.Comparator; @@ -37,6 +36,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -45,7 +45,7 @@ import java.util.Set; * loaded repeatedly, however it does take more memory due to caching the * blocks. */ -public class ChunkBatchingExtent extends AbstractDelegateExtent { +public class ChunkBatchingExtent extends AbstractBufferingExtent { /** * Comparator optimized for sorting chunks by the region file they reside @@ -92,7 +92,7 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent { @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { if (!enabled) { - return getExtent().setBlock(location, block); + return setDelegateBlock(location, block); } BlockVector2 chunkPos = getChunkPos(location); BlockVector3 inChunkPos = getInChunkPos(location); @@ -102,28 +102,11 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent { } @Override - public BlockState getBlock(BlockVector3 position) { - BaseBlock internal = getInternalBlock(position); - if (internal != null) { - return internal.toImmutableState(); - } - return super.getBlock(position); - } - - @Override - public BaseBlock getFullBlock(BlockVector3 position) { - BaseBlock internal = getInternalBlock(position); - if (internal != null) { - return internal; - } - return super.getFullBlock(position); - } - - private BaseBlock getInternalBlock(BlockVector3 position) { + protected Optional getBufferedBlock(BlockVector3 position) { if (!containedBlocks.contains(position)) { - return null; + return Optional.empty(); } - return batches.get(getChunkPos(position), getInChunkPos(position)); + return Optional.of(batches.get(getChunkPos(position), getInChunkPos(position))); } @Override @@ -134,19 +117,20 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent { return new Operation() { // we get modified between create/resume -- only create this on resume to prevent CME - private Iterator> batchIterator; + private Iterator>> batchIterator; @Override public Operation resume(RunContext run) throws WorldEditException { if (batchIterator == null) { - batchIterator = batches.rowMap().values().iterator(); + batchIterator = batches.rowMap().entrySet().iterator(); } if (!batchIterator.hasNext()) { return null; } - Map next = batchIterator.next(); - for (Map.Entry block : next.entrySet()) { - getExtent().setBlock(block.getKey(), block.getValue()); + Map.Entry> next = batchIterator.next(); + BlockVector3 chunkOffset = next.getKey().toBlockVector3().shl(4); + for (Map.Entry block : next.getValue().entrySet()) { + getExtent().setBlock(block.getKey().add(chunkOffset), block.getValue()); containedBlocks.remove(block.getKey()); } batchIterator.remove(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java index 55ddbcb73..011640709 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java @@ -20,7 +20,7 @@ package com.sk89q.worldedit.extent.reorder; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.AbstractBufferingExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.OperationQueue; @@ -36,13 +36,17 @@ import com.sk89q.worldedit.world.block.BlockTypes; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; /** * Re-orders blocks into several stages. */ -public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent { +public class MultiStageReorder extends AbstractBufferingExtent implements ReorderingExtent { private static final Map priorityMap = new HashMap<>(); @@ -139,6 +143,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL); } + private final Set containedBlocks = new HashSet<>(); private Map stages = new HashMap<>(); private boolean enabled; @@ -212,7 +217,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { if (!enabled) { - return super.setBlock(location, block); + return setDelegateBlock(location, block); } BlockState existing = getBlock(location); @@ -240,9 +245,21 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder } stages.get(priority).add(location, block); + containedBlocks.add(location); return !existing.equalsFuzzy(block); } + @Override + protected Optional getBufferedBlock(BlockVector3 position) { + if (!containedBlocks.contains(position)) { + return Optional.empty(); + } + return stages.values().stream() + .map(blocks -> blocks.get(position)) + .filter(Objects::nonNull) + .findAny(); + } + @Override public Operation commitBefore() { if (!commitRequired()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index 71d058bd9..e8192a128 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -366,6 +366,28 @@ public final class BlockVector3 { return shr(n, n, n); } + /** + * Shift all components left. + * + * @param x the value to shift x by + * @param y the value to shift y by + * @param z the value to shift z by + * @return a new vector + */ + public BlockVector3 shl(int x, int y, int z) { + return at(this.x << x, this.y << y, this.z << z); + } + + /** + * Shift all components left by {@code n}. + * + * @param n the value to shift by + * @return a new vector + */ + public BlockVector3 shl(int n) { + return shl(n, n, n); + } + /** * Get the length of the vector. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/LocatedBlockList.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/LocatedBlockList.java index 67280031d..b558a7102 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/LocatedBlockList.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/LocatedBlockList.java @@ -21,68 +21,72 @@ package com.sk89q.worldedit.util.collection; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableList; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.util.LocatedBlock; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; +import java.util.Map; /** * Wrapper around a list of blocks located in the world. */ public class LocatedBlockList implements Iterable { - private final List list; + private final Map map = new LinkedHashMap<>(); public LocatedBlockList() { - list = new ArrayList<>(); } public LocatedBlockList(Collection collection) { - list = new ArrayList<>(collection); + for (LocatedBlock locatedBlock : collection) { + map.put(locatedBlock.getLocation(), locatedBlock); + } } public void add(LocatedBlock setBlockCall) { checkNotNull(setBlockCall); - list.add(setBlockCall); + map.put(setBlockCall.getLocation(), setBlockCall); } public > void add(BlockVector3 location, B block) { add(new LocatedBlock(location, block.toBaseBlock())); } + public boolean containsLocation(BlockVector3 location) { + return map.containsKey(location); + } + + public @Nullable BaseBlock get(BlockVector3 location) { + return map.get(location).getBlock(); + } + public int size() { - return list.size(); + return map.size(); } public void clear() { - list.clear(); + map.clear(); } @Override public Iterator iterator() { - return list.iterator(); + return map.values().iterator(); } public Iterator reverseIterator() { - return new Iterator() { - - private final ListIterator backingIterator = list.listIterator(list.size()); - - @Override - public boolean hasNext() { - return backingIterator.hasPrevious(); - } - - @Override - public LocatedBlock next() { - return backingIterator.previous(); - } - }; + List data = new ArrayList<>(map.values()); + Collections.reverse(data); + return data.iterator(); } } From f2c47f375992c239a1e297664eb2b7e7079b6434 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Thu, 4 Jul 2019 11:55:27 -0700 Subject: [PATCH 03/52] License for new class --- .../extent/AbstractBufferingExtent.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java index c7aead10a..7e1b6466a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractBufferingExtent.java @@ -1,3 +1,22 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + package com.sk89q.worldedit.extent; import com.sk89q.worldedit.WorldEditException; From f0c0eedde7c65403f3274dc3e0d51830de27c155 Mon Sep 17 00:00:00 2001 From: wizjany Date: Fri, 5 Jul 2019 17:08:18 -0400 Subject: [PATCH 04/52] Fix handling CUI on Forge server. Probably. --- .../forge/net/handler/WECUIPacketHandler.java | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/WECUIPacketHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/WECUIPacketHandler.java index 2fd40fa23..8b26e9e33 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/WECUIPacketHandler.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/WECUIPacketHandler.java @@ -22,13 +22,8 @@ package com.sk89q.worldedit.forge.net.handler; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.forge.ForgePlayer; import com.sk89q.worldedit.forge.ForgeWorldEdit; -import net.minecraft.client.Minecraft; import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.network.ThreadQuickExitException; -import net.minecraft.network.play.server.SCustomPayloadPlayPacket; -import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.network.NetworkEvent.ClientCustomPayloadEvent; -import net.minecraftforge.fml.network.NetworkEvent.ServerCustomPayloadEvent; import net.minecraftforge.fml.network.event.EventNetworkChannel; import java.nio.charset.Charset; @@ -47,10 +42,9 @@ public final class WECUIPacketHandler { public static void init() { HANDLER.addListener(WECUIPacketHandler::onPacketData); - HANDLER.addListener(WECUIPacketHandler::callProcessPacket); } - public static void onPacketData(ServerCustomPayloadEvent event) { + public static void onPacketData(ClientCustomPayloadEvent event) { ServerPlayerEntity player = event.getSource().get().getSender(); LocalSession session = ForgeWorldEdit.inst.getSession(player); @@ -63,15 +57,5 @@ public final class WECUIPacketHandler { session.handleCUIInitializationMessage(text, actor); session.describeCUI(actor); } - - public static void callProcessPacket(ClientCustomPayloadEvent event) { - try { - new SCustomPayloadPlayPacket( - new ResourceLocation(ForgeWorldEdit.MOD_ID, ForgeWorldEdit.CUI_PLUGIN_CHANNEL), - event.getPayload() - ).processPacket(Minecraft.getInstance().player.connection); - } catch (ThreadQuickExitException ignored) { - } - } } \ No newline at end of file From 3ad80665d8163f336caa805c0c27255ddc65922e Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Sat, 6 Jul 2019 00:12:17 -0700 Subject: [PATCH 05/52] Fix gravity brush itself, not EditSession --- .../java/com/sk89q/worldedit/EditSession.java | 4 +- .../command/tool/brush/GravityBrush.java | 64 ++++++++++++------- 2 files changed, 43 insertions(+), 25 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 bd0afc352..8501ba917 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -565,12 +565,12 @@ public class EditSession implements Extent, AutoCloseable { @Override public BlockState getBlock(BlockVector3 position) { - return bypassNone.getBlock(position); + return world.getBlock(position); } @Override public BaseBlock getFullBlock(BlockVector3 position) { - return bypassNone.getFullBlock(position); + return world.getFullBlock(position); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java index aedcb578c..25c7c1f75 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java @@ -23,44 +23,62 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.util.LocatedBlock; +import com.sk89q.worldedit.util.collection.LocatedBlockList; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; public class GravityBrush implements Brush { private final boolean fullHeight; - + public GravityBrush(boolean fullHeight) { this.fullHeight = fullHeight; } @Override public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { - final double startY = fullHeight ? editSession.getWorld().getMaxY() : position.getBlockY() + size; - for (double x = position.getBlockX() + size; x > position.getBlockX() - size; --x) { - for (double z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) { - double y = startY; - final List blockTypes = new ArrayList<>(); - for (; y > position.getBlockY() - size; --y) { - final BlockVector3 pt = BlockVector3.at(x, y, z); - final BlockState block = editSession.getBlock(pt); - if (!block.getBlockType().getMaterial().isAir()) { - blockTypes.add(block); - editSession.setBlock(pt, BlockTypes.AIR.getDefaultState()); + double yMax = fullHeight ? editSession.getWorld().getMaxY() : position.getY() + size; + LocatedBlockList column = new LocatedBlockList(); + Set removedBlocks = new LinkedHashSet<>(); + for (double x = position.getX() - size; x <= position.getX() + size; x++) { + for (double z = position.getZ() - size; z <= position.getZ() + size; z++) { + for (double y = position.getY() - size; y <= yMax; y++) { + BlockVector3 newPos = BlockVector3.at(x, y - 1, z); + BlockVector3 pt = BlockVector3.at(x, y, z); + + BaseBlock block = editSession.getFullBlock(pt); + + if (block.getBlockType().getMaterial().isAir()) { + continue; } - } - BlockVector3 pt = BlockVector3.at(x, y, z); - Collections.reverse(blockTypes); - for (int i = 0; i < blockTypes.size();) { - if (editSession.getBlock(pt).getBlockType().getMaterial().isAir()) { - editSession.setBlock(pt, blockTypes.get(i++)); + + if (!removedBlocks.remove(newPos)) { + // we have not moved the block below this one. + // is it free in the edit session? + if (!editSession.getBlock(newPos).getBlockType().getMaterial().isAir()) { + // no -- do not move this block + continue; + } } - pt = pt.add(0, 1, 0); + + column.add(newPos, block); + removedBlocks.add(pt); } + + for (LocatedBlock block : column) { + editSession.setBlock(block.getLocation(), block.getBlock()); + } + + for (BlockVector3 removedBlock : removedBlocks) { + editSession.setBlock(removedBlock, BlockTypes.AIR.getDefaultState()); + } + + column.clear(); + removedBlocks.clear(); } } } From a18f26f8afc9693ff5ace7ad80dd1bdc715cc456 Mon Sep 17 00:00:00 2001 From: wizjany Date: Sat, 6 Jul 2019 09:44:53 -0400 Subject: [PATCH 06/52] Play nicer with naughty plugins. --- .../main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java index f311a9e1b..79526882f 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java @@ -335,7 +335,11 @@ public class BukkitAdapter { * @return WorldEdit EntityType */ public static EntityType adapt(org.bukkit.entity.EntityType entityType) { - return EntityTypes.get(entityType.getName().toLowerCase(Locale.ROOT)); + final String name = entityType.getName(); + if (name == null) { + return null; + } + return EntityTypes.get(name.toLowerCase(Locale.ROOT)); } public static org.bukkit.entity.EntityType adapt(EntityType entityType) { From 2ee71cc72f3465b4bfe551884d98f53179f306f0 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Sat, 6 Jul 2019 15:41:11 -0700 Subject: [PATCH 07/52] Grav brush: move to bottom, not down one --- .../command/tool/brush/GravityBrush.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java index 25c7c1f75..edd58c68b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java @@ -46,25 +46,40 @@ public class GravityBrush implements Brush { Set removedBlocks = new LinkedHashSet<>(); for (double x = position.getX() - size; x <= position.getX() + size; x++) { for (double z = position.getZ() - size; z <= position.getZ() + size; z++) { + /* + * Algorithm: + * 1. Find lowest air block in the selection -> $lowestAir = position + * 2. Move the first non-air block above it down to $lowestAir + * 3. Add 1 to $lowestAir's y-coord. + * 4. If more blocks above current position, repeat from 2 + */ + + BlockVector3 lowestAir = null; for (double y = position.getY() - size; y <= yMax; y++) { - BlockVector3 newPos = BlockVector3.at(x, y - 1, z); BlockVector3 pt = BlockVector3.at(x, y, z); BaseBlock block = editSession.getFullBlock(pt); if (block.getBlockType().getMaterial().isAir()) { + if (lowestAir == null) { + // we found the lowest air block + lowestAir = pt; + } continue; } - if (!removedBlocks.remove(newPos)) { - // we have not moved the block below this one. - // is it free in the edit session? - if (!editSession.getBlock(newPos).getBlockType().getMaterial().isAir()) { - // no -- do not move this block - continue; - } + if (lowestAir == null) { + // no place to move the block to + continue; } + BlockVector3 newPos = lowestAir; + // we know the block above must be air, + // since either this block is being moved into it, + // or there has been more air before this block + lowestAir = lowestAir.add(0, 1, 0); + + removedBlocks.remove(newPos); column.add(newPos, block); removedBlocks.add(pt); } From 5a464142ae96ead54068f32fc21048f0f48713ec Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 8 Jul 2019 20:21:31 -0700 Subject: [PATCH 08/52] Shade Rhino and truezip into Forge dist --- worldedit-core/build.gradle | 2 +- worldedit-forge/build.gradle | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle index 9ed0f8b2a..a39f678b5 100644 --- a/worldedit-core/build.gradle +++ b/worldedit-core/build.gradle @@ -17,7 +17,7 @@ configurations.all { Configuration it -> dependencies { compile project(':worldedit-libs:core') compile 'de.schlichtherle:truezip:6.8.3' - compile 'rhino:js:1.7R2' + compile 'org.mozilla:rhino:1.7R5' compile 'org.yaml:snakeyaml:1.9' compile 'com.google.guava:guava:21.0' compile 'com.google.code.findbugs:jsr305:1.3.9' diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle index 0cddf21e5..920903932 100644 --- a/worldedit-forge/build.gradle +++ b/worldedit-forge/build.gradle @@ -82,8 +82,7 @@ processResources { jar { manifest { - attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", - "WorldEdit-Version": version) + attributes("WorldEdit-Version": version) } } @@ -94,6 +93,8 @@ shadowJar { include(dependency('org.slf4j:slf4j-api')) include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) + include(dependency("de.schlichtherle:truezip")) + include(dependency("org.mozilla:rhino")) } } From 05bf211d7301de62b2c7de01189de73a6597adcd Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 8 Jul 2019 20:25:59 -0700 Subject: [PATCH 09/52] Prepare worldedit-libs for shadow upgrade --- worldedit-libs/build.gradle | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/worldedit-libs/build.gradle b/worldedit-libs/build.gradle index fa57aa1d0..b31760f52 100644 --- a/worldedit-libs/build.gradle +++ b/worldedit-libs/build.gradle @@ -13,6 +13,7 @@ dependents of `-core` to compile and work with WorldEdit's API. */ configure(subprojects + project("core:ap")) { + apply plugin: 'java' apply plugin: 'maven' apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'com.jfrog.artifactory' @@ -23,7 +24,8 @@ configure(subprojects + project("core:ap")) { group = rootProject.group + ".worldedit-libs" - tasks.register("jar", ShadowJar) { + tasks.replace("jar", ShadowJar) + tasks.withType(ShadowJar).named("jar").configure { configurations = [project.configurations.shade] classifier = "" @@ -69,11 +71,15 @@ configure(subprojects + project("core:ap")) { } artifacts { - add("default", jar) - add("archives", sourcesJar) + add("default", jar) { + builtBy(jar) + } + add("archives", sourcesJar) { + builtBy(sourcesJar) + } } - tasks.register("install", Upload) { + tasks.withType(Upload).named("install").configure { configuration = configurations.archives repositories.mavenInstaller { pom.version = project.version From c5c6a091fdf4a9662eba928f8081a7ee07208b9c Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Tue, 9 Jul 2019 18:21:21 -0700 Subject: [PATCH 10/52] Update to Gradle 5.5 --- gradle.properties | 5 +---- gradle/wrapper/gradle-wrapper.jar | Bin 54413 -> 55616 bytes gradle/wrapper/gradle-wrapper.properties | 3 +-- gradlew | 18 +++++++++++++++++- gradlew.bat | 18 +++++++++++++++++- worldedit-core/build.gradle | 3 ++- 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/gradle.properties b/gradle.properties index bca9aaf56..f7c837830 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -#org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false \ No newline at end of file +org.gradle.jvmargs=-Xmx1G diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 0d4a9516871afd710a9d84d89e31ba77745607bd..5c2d1cf016b3885f6930543d57b744ea8c220a1a 100644 GIT binary patch literal 55616 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a9534e761..e0c4de36d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Thu Mar 14 00:19:48 PDT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip diff --git a/gradlew b/gradlew index cccdd3d51..8e25e6c19 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index e95643d6a..24467a141 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle index 9ed0f8b2a..9cf070696 100644 --- a/worldedit-core/build.gradle +++ b/worldedit-core/build.gradle @@ -1,5 +1,5 @@ plugins { - id("net.ltgt.apt") version "0.21" + id("net.ltgt.apt") version "0.21" apply false } apply plugin: 'java-library' @@ -36,6 +36,7 @@ dependencies { } tasks.withType(JavaCompile).configureEach { + dependsOn(":worldedit-libs:build") it.options.compilerArgs.add("-Aarg.name.key.prefix=") } From e87a5559d68c8ba75712a99e304755af8203ae2d Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 14:10:22 -0700 Subject: [PATCH 11/52] Ensure blocks are not moved below world boundary --- .../com/sk89q/worldedit/command/tool/brush/GravityBrush.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java index edd58c68b..08288636e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java @@ -42,6 +42,7 @@ public class GravityBrush implements Brush { @Override public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { double yMax = fullHeight ? editSession.getWorld().getMaxY() : position.getY() + size; + double yMin = Math.max(position.getY() - size, 0); LocatedBlockList column = new LocatedBlockList(); Set removedBlocks = new LinkedHashSet<>(); for (double x = position.getX() - size; x <= position.getX() + size; x++) { @@ -55,7 +56,7 @@ public class GravityBrush implements Brush { */ BlockVector3 lowestAir = null; - for (double y = position.getY() - size; y <= yMax; y++) { + for (double y = yMin; y <= yMax; y++) { BlockVector3 pt = BlockVector3.at(x, y, z); BaseBlock block = editSession.getFullBlock(pt); From 59c2a15cdae831c90aa311050705f0d377727a22 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 11:07:00 -0700 Subject: [PATCH 12/52] Further minor cleanup from Gradle 5 change --- build.gradle | 29 ++++++----------------------- settings.gradle | 11 ----------- settings.gradle.kts | 11 +++++++++++ worldedit-forge/build.gradle | 2 +- worldedit-libs/build.gradle | 7 +++---- 5 files changed, 21 insertions(+), 39 deletions(-) delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts diff --git a/build.gradle b/build.gradle index dddd5470e..c3e908d37 100644 --- a/build.gradle +++ b/build.gradle @@ -1,25 +1,8 @@ -buildscript { - repositories { - mavenCentral() - maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" } - jcenter() - } - - configurations.all { - resolutionStrategy { - force 'commons-io:commons-io:2.4' - } - } - - dependencies { - classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4' - classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.8.1' - } -} - plugins { id 'net.minecrell.licenser' version '0.4.1' apply false - id "org.ajoberstar.grgit" version "2.3.0" + id "org.ajoberstar.grgit" version "3.1.1" + id "com.github.johnrengelman.shadow" version "5.1.0" + id "com.jfrog.artifactory" version "4.9.7" } println """ @@ -109,7 +92,7 @@ configure(['core', 'bukkit', 'forge', 'sponge', 'fabric'].collect { project(":wo } task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' + getArchiveClassifier().set('javadoc') from javadoc.destinationDir } @@ -120,7 +103,7 @@ configure(['core', 'bukkit', 'forge', 'sponge', 'fabric'].collect { project(":wo if (name == "worldedit-core" || name == "worldedit-bukkit") { task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' + getArchiveClassifier().set('sources') from sourceSets.main.allSource } @@ -146,7 +129,7 @@ configure(['core', 'bukkit', 'forge', 'sponge', 'fabric'].collect { project(":wo configure(['bukkit', 'forge', 'sponge', 'fabric'].collect { project(":worldedit-$it") }) { shadowJar { - classifier 'dist' + getArchiveClassifier().set('dist') dependencies { include(project(":worldedit-libs:core")) include(project(":worldedit-libs:${project.name.replace("worldedit-", "")}")) diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index a7c14e8ee..000000000 --- a/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -rootProject.name = 'worldedit' - -include 'worldedit-libs' - -['bukkit', 'core', 'forge', 'sponge', 'fabric'].forEach { - include "worldedit-libs:$it" - include "worldedit-$it" -} -include "worldedit-libs:core:ap" - -include "worldedit-core:doctools" diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..6da7bedcc --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,11 @@ +rootProject.name = "worldedit" + +include("worldedit-libs") + +listOf("bukkit", "core", "forge", "sponge", "fabric").forEach { + include("worldedit-libs:$it") + include("worldedit-$it") +} +include("worldedit-libs:core:ap") + +include("worldedit-core:doctools") diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle index 920903932..0c389e66f 100644 --- a/worldedit-forge/build.gradle +++ b/worldedit-forge/build.gradle @@ -108,7 +108,7 @@ afterEvaluate { task deobfJar(type: Jar) { from sourceSets.main.output - classifier = 'dev' + getArchiveClassifier().set("dev") } artifacts { diff --git a/worldedit-libs/build.gradle b/worldedit-libs/build.gradle index b31760f52..cc3c681a0 100644 --- a/worldedit-libs/build.gradle +++ b/worldedit-libs/build.gradle @@ -13,7 +13,7 @@ dependents of `-core` to compile and work with WorldEdit's API. */ configure(subprojects + project("core:ap")) { - apply plugin: 'java' + apply plugin: 'java-base' apply plugin: 'maven' apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'com.jfrog.artifactory' @@ -24,8 +24,7 @@ configure(subprojects + project("core:ap")) { group = rootProject.group + ".worldedit-libs" - tasks.replace("jar", ShadowJar) - tasks.withType(ShadowJar).named("jar").configure { + tasks.register("jar", ShadowJar) { configurations = [project.configurations.shade] classifier = "" @@ -79,7 +78,7 @@ configure(subprojects + project("core:ap")) { } } - tasks.withType(Upload).named("install").configure { + tasks.register("install", Upload) { configuration = configurations.archives repositories.mavenInstaller { pom.version = project.version From eccbad92e8b2312b02023f28dc5f00f2ac97c066 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 13:13:41 -0700 Subject: [PATCH 13/52] Move away from deprecation, move dependencies towards buildSrc --- build.gradle | 7 +++--- buildSrc/build.gradle.kts | 32 ++++++++++++++++++++++++ worldedit-core/build.gradle | 12 ++++----- worldedit-core/doctools/build.gradle.kts | 2 +- worldedit-fabric/build.gradle | 8 +++--- worldedit-sponge/build.gradle | 11 +------- 6 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 buildSrc/build.gradle.kts diff --git a/build.gradle b/build.gradle index c3e908d37..b39e4ebb3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,7 @@ plugins { - id 'net.minecrell.licenser' version '0.4.1' apply false - id "org.ajoberstar.grgit" version "3.1.1" - id "com.github.johnrengelman.shadow" version "5.1.0" - id "com.jfrog.artifactory" version "4.9.7" + id "org.ajoberstar.grgit" + id "com.github.johnrengelman.shadow" + id "com.jfrog.artifactory" } println """ diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..658143d8d --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,32 @@ +plugins { + `kotlin-dsl` + kotlin("jvm") version embeddedKotlinVersion +} + +repositories { + jcenter() + gradlePluginPortal() + maven { + name = "Forge Maven" + url = uri("https://files.minecraftforge.net/maven") + } +} + +configurations.all { + resolutionStrategy { + // Fabric needs this. + force("commons-io:commons-io:2.5", "org.ow2.asm:asm:7.1") + } +} + +dependencies { + implementation(gradleApi()) + implementation("gradle.plugin.net.minecrell:licenser:0.4.1") + implementation("org.ajoberstar.grgit:grgit-gradle:3.1.1") + implementation("com.github.jengelman.gradle.plugins:shadow:5.1.0") + implementation("net.ltgt.apt-eclipse:net.ltgt.apt-eclipse.gradle.plugin:0.21") + implementation("net.ltgt.apt-idea:net.ltgt.apt-idea.gradle.plugin:0.21") + implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.7") + implementation("gradle.plugin.org.spongepowered:spongegradle:0.9.0") + implementation("net.minecraftforge.gradle:ForgeGradle:3.0.130") +} diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle index 182702290..41efbff01 100644 --- a/worldedit-core/build.gradle +++ b/worldedit-core/build.gradle @@ -1,13 +1,11 @@ plugins { - id("net.ltgt.apt") version "0.21" apply false + id("java-library") + id("eclipse") + id("idea") + id("net.ltgt.apt-eclipse") + id("net.ltgt.apt-idea") } -apply plugin: 'java-library' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'net.ltgt.apt-eclipse' -apply plugin: 'net.ltgt.apt-idea' - configurations.all { Configuration it -> it.resolutionStrategy { ResolutionStrategy rs -> rs.force("com.google.guava:guava:21.0") diff --git a/worldedit-core/doctools/build.gradle.kts b/worldedit-core/doctools/build.gradle.kts index 002f367bd..75a347ece 100644 --- a/worldedit-core/doctools/build.gradle.kts +++ b/worldedit-core/doctools/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.3.31" + kotlin("jvm") version "1.3.41" } tasks.withType { diff --git a/worldedit-fabric/build.gradle b/worldedit-fabric/build.gradle index b27289bf9..6eee60e9e 100644 --- a/worldedit-fabric/build.gradle +++ b/worldedit-fabric/build.gradle @@ -77,7 +77,7 @@ jar { } shadowJar { - classifier = 'dist-dev' + archiveClassifier.set("dist-dev") dependencies { relocate "org.slf4j", "com.sk89q.worldedit.slf4j" relocate "org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge" @@ -89,7 +89,7 @@ shadowJar { task deobfJar(type: Jar) { from sourceSets.main.output - classifier = 'dev' + archiveClassifier.set("dev") } artifacts { @@ -97,8 +97,8 @@ artifacts { } task shadowJarRemap(type: RemapJarTask) { - input shadowJar.archivePath - output new File(shadowJar.archivePath.getAbsolutePath().replaceFirst('-dev\\.jar$', ".jar")) + input shadowJar.archiveFile + output new File(shadowJar.archiveFile.get().asFile.getAbsolutePath().replaceFirst('-dev\\.jar$', ".jar")) } shadowJarRemap.dependsOn(shadowJar) diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index a745869b6..8d6633de2 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -1,14 +1,5 @@ -buildscript { - repositories { - mavenCentral() - maven { url = "https://files.minecraftforge.net/maven" } - maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" } - jcenter() - } -} - plugins { - id 'org.spongepowered.plugin' version '0.9.0' + id("org.spongepowered.plugin") } repositories { From 19802e478ce3e9c08c500076041f4c75d5820825 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 16:33:21 -0700 Subject: [PATCH 14/52] Re-write root and libs to Kotlin DSL --- build.gradle | 141 ----------------- build.gradle.kts | 28 ++++ buildSrc/src/main/kotlin/ArtifactoryConfig.kt | 40 +++++ buildSrc/src/main/kotlin/CommonConfig.kt | 18 +++ buildSrc/src/main/kotlin/GradleExtras.kt | 6 + buildSrc/src/main/kotlin/LibsConfig.kt | 98 ++++++++++++ buildSrc/src/main/kotlin/PlatformConfig.kt | 101 ++++++++++++ buildSrc/src/main/kotlin/Versions.kt | 5 + gradle.properties | 3 + worldedit-bukkit/build.gradle | 2 + worldedit-core/build.gradle | 2 + worldedit-fabric/build.gradle | 3 + worldedit-forge/build.gradle | 14 +- worldedit-libs/README.md | 9 ++ worldedit-libs/build.gradle | 145 ------------------ worldedit-libs/bukkit/build.gradle.kts | 11 ++ worldedit-libs/core/ap/build.gradle.kts | 6 + worldedit-libs/core/build.gradle.kts | 16 ++ worldedit-libs/fabric/build.gradle.kts | 1 + worldedit-libs/forge/build.gradle.kts | 1 + worldedit-libs/sponge/build.gradle.kts | 11 ++ worldedit-sponge/build.gradle | 3 + 22 files changed, 366 insertions(+), 298 deletions(-) delete mode 100644 build.gradle create mode 100644 build.gradle.kts create mode 100644 buildSrc/src/main/kotlin/ArtifactoryConfig.kt create mode 100644 buildSrc/src/main/kotlin/CommonConfig.kt create mode 100644 buildSrc/src/main/kotlin/GradleExtras.kt create mode 100644 buildSrc/src/main/kotlin/LibsConfig.kt create mode 100644 buildSrc/src/main/kotlin/PlatformConfig.kt create mode 100644 buildSrc/src/main/kotlin/Versions.kt create mode 100644 worldedit-libs/README.md create mode 100644 worldedit-libs/bukkit/build.gradle.kts create mode 100644 worldedit-libs/core/ap/build.gradle.kts create mode 100644 worldedit-libs/core/build.gradle.kts create mode 100644 worldedit-libs/fabric/build.gradle.kts create mode 100644 worldedit-libs/forge/build.gradle.kts create mode 100644 worldedit-libs/sponge/build.gradle.kts diff --git a/build.gradle b/build.gradle deleted file mode 100644 index b39e4ebb3..000000000 --- a/build.gradle +++ /dev/null @@ -1,141 +0,0 @@ -plugins { - id "org.ajoberstar.grgit" - id "com.github.johnrengelman.shadow" - id "com.jfrog.artifactory" -} - -println """ -******************************************* - You are building WorldEdit! - - If you encounter trouble: - 1) Read COMPILING.md if you haven't yet - 2) Try running 'build' in a separate Gradle run - 3) Use gradlew and not gradle - 4) If you still need help, ask on Discord! https://discord.gg/enginehub - - Output files will be in [subproject]/build/libs -******************************************* -""" - -allprojects { - group = 'com.sk89q.worldedit' - version = '7.0.1-SNAPSHOT' -} - -if (!project.hasProperty("artifactory_contextUrl")) ext.artifactory_contextUrl = "http://localhost" -if (!project.hasProperty("artifactory_user")) ext.artifactory_user = "guest" -if (!project.hasProperty("artifactory_password")) ext.artifactory_password = "" - -if (!project.hasProperty("gitCommitHash") && !JavaVersion.current().isJava6()) { - try { - def repo = grgit.open() - ext.gitCommitHash = repo.head().abbreviatedId - } catch (Exception e) { - println "Error getting commit hash: " + e.getMessage() - } -} -if (!project.hasProperty("gitCommitHash")) { - ext.gitCommitHash = "no_git_id" -} - -apply plugin: 'com.jfrog.artifactory' -artifactory { - contextUrl = "${artifactory_contextUrl}" - publish { - repository { - repoKey = project.version.contains("SNAPSHOT") ? 'libs-snapshot-local' : 'libs-release-local' - username = "${artifactory_user}" - password = "${artifactory_password}" - maven = true - ivy = false - } - } -} -artifactoryPublish.skip = true - -subprojects { - repositories { - mavenCentral() - maven { url "http://maven.sk89q.com/repo/" } - maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } - } - configurations.all { - resolutionStrategy { - cacheChangingModulesFor 5, 'minutes' - } - } -} - -configure(['core', 'bukkit', 'forge', 'sponge', 'fabric'].collect { project(":worldedit-$it") }) { - apply plugin: 'java' - apply plugin: 'maven' - apply plugin: 'checkstyle' - apply plugin: 'com.github.johnrengelman.shadow' - apply plugin: 'com.jfrog.artifactory' - apply plugin: 'net.minecrell.licenser' - - ext.internalVersion = version + ";" + gitCommitHash - - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - - checkstyle.configFile = new File(rootProject.projectDir, "config/checkstyle/checkstyle.xml") - checkstyle.toolVersion = '7.6.1' - - if (JavaVersion.current().isJava8Compatible()) { - // Java 8 turns on doclint which we fail - tasks.withType(Javadoc) { - options.addStringOption('Xdoclint:none', '-quiet') - } - } - - task javadocJar(type: Jar, dependsOn: javadoc) { - getArchiveClassifier().set('javadoc') - from javadoc.destinationDir - } - - artifacts { - archives jar - archives javadocJar - } - - if (name == "worldedit-core" || name == "worldedit-bukkit") { - task sourcesJar(type: Jar, dependsOn: classes) { - getArchiveClassifier().set('sources') - from sourceSets.main.allSource - } - - artifacts { - archives sourcesJar - } - build.dependsOn(sourcesJar) - } - - build.dependsOn(checkstyleMain) - build.dependsOn(checkstyleTest) - build.dependsOn(javadocJar) - - artifactoryPublish { - publishConfigs('archives') - } - - license { - header = rootProject.file("HEADER.txt") - include '**/*.java' - } -} - -configure(['bukkit', 'forge', 'sponge', 'fabric'].collect { project(":worldedit-$it") }) { - shadowJar { - getArchiveClassifier().set('dist') - dependencies { - include(project(":worldedit-libs:core")) - include(project(":worldedit-libs:${project.name.replace("worldedit-", "")}")) - include(project(":worldedit-core")) - } - exclude 'GradleStart**' - exclude '.cache' - exclude 'LICENSE*' - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..7088d0893 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,28 @@ +import org.ajoberstar.grgit.Grgit + +println(""" +******************************************* + You are building WorldEdit! + + If you encounter trouble: + 1) Read COMPILING.md if you haven't yet + 2) Try running 'build' in a separate Gradle run + 3) Use gradlew and not gradle + 4) If you still need help, ask on Discord! https://discord.gg/enginehub + + Output files will be in [subproject]/build/libs +******************************************* +""") + +applyRootArtifactoryConfig() + +if (!project.hasProperty("gitCommitHash")) { + apply(plugin = "org.ajoberstar.grgit") + ext["gitCommitHash"] = try { + (ext["grgit"] as Grgit).head().abbreviatedId + } catch (e: Exception) { + println("Error getting commit hash: " + e.message) + + "no_git_id" + } +} diff --git a/buildSrc/src/main/kotlin/ArtifactoryConfig.kt b/buildSrc/src/main/kotlin/ArtifactoryConfig.kt new file mode 100644 index 000000000..d19f35238 --- /dev/null +++ b/buildSrc/src/main/kotlin/ArtifactoryConfig.kt @@ -0,0 +1,40 @@ +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.named +import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention +import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask + +private const val ARTIFACTORY_CONTEXT_URL = "artifactory_contextUrl" +private const val ARTIFACTORY_USER = "artifactory_user" +private const val ARTIFACTORY_PASSWORD = "artifactory_password" + +fun Project.applyRootArtifactoryConfig() { + if (!project.hasProperty(ARTIFACTORY_CONTEXT_URL)) ext[ARTIFACTORY_CONTEXT_URL] = "http://localhost" + if (!project.hasProperty(ARTIFACTORY_USER)) ext[ARTIFACTORY_USER] = "guest" + if (!project.hasProperty(ARTIFACTORY_PASSWORD)) ext[ARTIFACTORY_PASSWORD] = "" + + apply(plugin = "com.jfrog.artifactory") + configure { + setContextUrl("${project.property(ARTIFACTORY_CONTEXT_URL)}") + clientConfig.publisher.run { + repoKey = when { + "${project.version}".contains("SNAPSHOT") -> "libs-snapshot-local" + else -> "libs-release-local" + } + username = "${project.property(ARTIFACTORY_USER)}" + password = "${project.property(ARTIFACTORY_PASSWORD)}" + isMaven = true + isIvy = false + } + } + tasks.named("artifactoryPublish") { + isSkip = true + } +} + +fun Project.applyCommonArtifactoryConfig() { + tasks.named("artifactoryPublish") { + publishConfigs("archives") + } +} diff --git a/buildSrc/src/main/kotlin/CommonConfig.kt b/buildSrc/src/main/kotlin/CommonConfig.kt new file mode 100644 index 000000000..e93f4a2dd --- /dev/null +++ b/buildSrc/src/main/kotlin/CommonConfig.kt @@ -0,0 +1,18 @@ +import org.gradle.api.Project +import org.gradle.kotlin.dsl.repositories + +fun Project.applyCommonConfiguration() { + group = rootProject.group + version = rootProject.version + + repositories { + mavenCentral() + maven { url = uri("https://maven.sk89q.com/repo/") } + maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") } + } + configurations.all { + resolutionStrategy { + cacheChangingModulesFor(5, "minutes") + } + } +} diff --git a/buildSrc/src/main/kotlin/GradleExtras.kt b/buildSrc/src/main/kotlin/GradleExtras.kt new file mode 100644 index 000000000..5358f6b37 --- /dev/null +++ b/buildSrc/src/main/kotlin/GradleExtras.kt @@ -0,0 +1,6 @@ +import org.gradle.api.Project +import org.gradle.api.plugins.ExtraPropertiesExtension +import org.gradle.kotlin.dsl.getByType + +val Project.ext: ExtraPropertiesExtension + get() = extensions.getByType() diff --git a/buildSrc/src/main/kotlin/LibsConfig.kt b/buildSrc/src/main/kotlin/LibsConfig.kt new file mode 100644 index 000000000..c2754d487 --- /dev/null +++ b/buildSrc/src/main/kotlin/LibsConfig.kt @@ -0,0 +1,98 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.gradle.api.Project +import org.gradle.api.artifacts.ModuleDependency +import org.gradle.api.internal.HasConvention +import org.gradle.api.plugins.MavenRepositoryHandlerConvention +import org.gradle.api.tasks.Upload +import org.gradle.api.tasks.bundling.Jar +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.getPlugin +import org.gradle.kotlin.dsl.invoke +import org.gradle.kotlin.dsl.register + +fun Project.applyLibrariesConfiguration() { + applyCommonConfiguration() + apply(plugin = "java-base") + apply(plugin = "maven") + apply(plugin = "com.github.johnrengelman.shadow") + apply(plugin = "com.jfrog.artifactory") + + configurations { + create("shade") + getByName("archives").extendsFrom(getByName("default")) + } + + group = "${rootProject.group}.worldedit-libs" + + tasks.register("jar") { + configurations = listOf(project.configurations["shade"]) + archiveClassifier.set("") + + dependencies { + exclude(dependency("com.google.guava:guava")) + exclude(dependency("com.google.code.gson:gson")) + exclude(dependency("org.checkerframework:checker-qual")) + } + + relocate("net.kyori.text", "com.sk89q.worldedit.util.formatting.text") + } + val altConfigFiles = { artifactType: String -> + val deps = configurations["shade"].incoming.dependencies + .filterIsInstance() + .map { it.copy() } + .map { dependency -> + dependency.artifact { + name = dependency.name + type = artifactType + extension = "jar" + classifier = artifactType + } + dependency + } + + files(configurations.detachedConfiguration(*deps.toTypedArray()) + .resolvedConfiguration.lenientConfiguration.artifacts + .filter { it.classifier == artifactType } + .map { zipTree(it.file) }) + } + tasks.register("sourcesJar") { + from({ + altConfigFiles("sources") + }) + val filePattern = Regex("(.*)net/kyori/text((?:/|$).*)") + val textPattern = Regex("net\\.kyori\\.text") + eachFile { + filter { + it.replaceFirst(textPattern, "com.sk89q.worldedit.util.formatting.text") + } + path = path.replaceFirst(filePattern, "$1com/sk89q/worldedit/util/formatting/text$2") + } + archiveClassifier.set("sources") + } + + tasks.named("assemble").configure { + dependsOn("jar", "sourcesJar") + } + + artifacts { + val jar = tasks.named("jar") + add("default", jar) { + builtBy(jar) + } + val sourcesJar = tasks.named("sourcesJar") + add("archives", sourcesJar) { + builtBy(sourcesJar) + } + } + + tasks.register("install") { + configuration = configurations["archives"] + (repositories as HasConvention).convention.getPlugin().mavenInstaller { + pom.version = project.version.toString() + pom.artifactId = project.name + } + } + + applyCommonArtifactoryConfig() +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/PlatformConfig.kt b/buildSrc/src/main/kotlin/PlatformConfig.kt new file mode 100644 index 000000000..85042cc9f --- /dev/null +++ b/buildSrc/src/main/kotlin/PlatformConfig.kt @@ -0,0 +1,101 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import net.minecrell.gradle.licenser.LicenseExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.plugins.quality.CheckstyleExtension +import org.gradle.api.tasks.bundling.Jar +import org.gradle.api.tasks.javadoc.Javadoc +import org.gradle.external.javadoc.CoreJavadocOptions +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.getByName +import org.gradle.kotlin.dsl.getPlugin +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.the +import org.gradle.kotlin.dsl.withType +import org.gradle.kotlin.dsl.named + +fun Project.applyPlatformAndCoreConfiguration() { + applyCommonConfiguration() + apply(plugin = "java") + apply(plugin = "maven") + apply(plugin = "checkstyle") + apply(plugin = "com.github.johnrengelman.shadow") + apply(plugin = "com.jfrog.artifactory") + apply(plugin = "net.minecrell.licenser") + + ext["internalVersion"] = "$version;${rootProject.ext["gitCommitHash"]}" + + configure { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + configure { + configFile = rootProject.file("config/checkstyle/checkstyle.xml") + toolVersion = "7.6.1" + } + + // Java 8 turns on doclint which we fail + tasks.withType().configureEach { + (options as CoreJavadocOptions).addStringOption("Xdoclint:none", "-quiet") + } + + tasks.register("javadocJar") { + dependsOn("javadoc") + archiveClassifier.set("javadoc") + from(tasks.getByName("javadoc").destinationDir) + } + + tasks.named("assemble").configure { + dependsOn("javadocJar") + } + + artifacts { + add("archives", tasks.named("jar")) + add("archives", tasks.named("javadocJar")) + } + + if (name == "worldedit-core" || name == "worldedit-bukkit") { + tasks.register("sourcesJar") { + dependsOn("classes") + archiveClassifier.set("sources") + from(project.the().sourceSets["main"].allSource) + } + + artifacts { + add("archives", tasks.named("sourcesJar")) + } + tasks.named("assemble").configure { + dependsOn("sourcesJar") + } + } + + tasks.named("check").configure { + dependsOn("checkstyleMain", "checkstyleTest") + } + + applyCommonArtifactoryConfig() + + configure { + header = rootProject.file("HEADER.txt") + include("**/*.java") + } +} + +fun Project.applyShadowConfiguration() { + tasks.named("shadowJar") { + archiveClassifier.set("dist") + dependencies { + include(project(":worldedit-libs:core")) + include(project(":worldedit-libs:${project.name.replace("worldedit-", "")}")) + include(project(":worldedit-core")) + } + exclude("GradleStart**") + exclude(".cache") + exclude("LICENSE*") + minimize() + } +} diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt new file mode 100644 index 000000000..fd61ee13b --- /dev/null +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -0,0 +1,5 @@ +object Versions { + const val TEXT = "3.0.1" + const val TEXT_EXTRAS = "3.0.2" + const val PISTON = "0.4.2" +} diff --git a/gradle.properties b/gradle.properties index f7c837830..a2cc53d8e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,4 @@ +group=com.sk89q.worldedit +version=7.0.1-SNAPSHOT + org.gradle.jvmargs=-Xmx1G diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle index ba7a34f31..b81612b0c 100644 --- a/worldedit-bukkit/build.gradle +++ b/worldedit-bukkit/build.gradle @@ -1,3 +1,5 @@ +PlatformConfigKt.applyPlatformAndCoreConfiguration(project) +PlatformConfigKt.applyShadowConfiguration(project) apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'maven' diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle index 41efbff01..a5b3bba63 100644 --- a/worldedit-core/build.gradle +++ b/worldedit-core/build.gradle @@ -6,6 +6,8 @@ plugins { id("net.ltgt.apt-idea") } +PlatformConfigKt.applyPlatformAndCoreConfiguration(project) + configurations.all { Configuration it -> it.resolutionStrategy { ResolutionStrategy rs -> rs.force("com.google.guava:guava:21.0") diff --git a/worldedit-fabric/build.gradle b/worldedit-fabric/build.gradle index 6eee60e9e..70acc7a1d 100644 --- a/worldedit-fabric/build.gradle +++ b/worldedit-fabric/build.gradle @@ -19,6 +19,9 @@ buildscript { } } +PlatformConfigKt.applyPlatformAndCoreConfiguration(project) +PlatformConfigKt.applyShadowConfiguration(project) + apply plugin: 'eclipse' apply plugin: 'fabric-loom' diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle index 0c389e66f..fc3dcaee8 100644 --- a/worldedit-forge/build.gradle +++ b/worldedit-forge/build.gradle @@ -1,15 +1,5 @@ -buildscript { - repositories { - mavenLocal() - mavenCentral() - maven { url = "https://files.minecraftforge.net/maven" } - jcenter() - } - - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true - } -} +PlatformConfigKt.applyPlatformAndCoreConfiguration(project) +PlatformConfigKt.applyShadowConfiguration(project) apply plugin: 'eclipse' apply plugin: 'net.minecraftforge.gradle' diff --git a/worldedit-libs/README.md b/worldedit-libs/README.md new file mode 100644 index 000000000..6387fde12 --- /dev/null +++ b/worldedit-libs/README.md @@ -0,0 +1,9 @@ +This project shades _API_ libraries, i.e. those libraries +whose classes are publicly referenced from `-core` classes. + +This project _does not_ shade implementation libraries, i.e. +those libraries whose classes are internally depended on. + +This is because the main reason for shading those libraries is for +their internal usage in each platform, not because we need them available to +dependents of `-core` to compile and work with WorldEdit's API. diff --git a/worldedit-libs/build.gradle b/worldedit-libs/build.gradle index cc3c681a0..29c096e2d 100644 --- a/worldedit-libs/build.gradle +++ b/worldedit-libs/build.gradle @@ -1,148 +1,3 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -/* - -This project shades API libraries, i.e. those libraries -whose classes are publicly referenced from `-core` classes. - -This project does not shade implementation libraries, i.e. -those libraries whose classes are internally depended on. - -This is because the main reason for shading those libraries is for -their internal usage in each platform, not because we need them available to -dependents of `-core` to compile and work with WorldEdit's API. - - */ -configure(subprojects + project("core:ap")) { - apply plugin: 'java-base' - apply plugin: 'maven' - apply plugin: 'com.github.johnrengelman.shadow' - apply plugin: 'com.jfrog.artifactory' - configurations { - create("shade") - getByName("archives").extendsFrom(getByName("default")) - } - - group = rootProject.group + ".worldedit-libs" - - tasks.register("jar", ShadowJar) { - configurations = [project.configurations.shade] - classifier = "" - - dependencies { - exclude(dependency("com.google.guava:guava")) - exclude(dependency("com.google.code.gson:gson")) - exclude(dependency("org.checkerframework:checker-qual")) - } - - relocate('net.kyori.text', 'com.sk89q.worldedit.util.formatting.text') - } - def altConfigFiles = { String artifactType -> - def deps = configurations.shade.incoming.dependencies - .collect { it.copy() } - .collect { dependency -> - dependency.artifact { artifact -> - artifact.name = dependency.name - artifact.type = artifactType - artifact.extension = 'jar' - artifact.classifier = artifactType - } - dependency - } - - return files(configurations.detachedConfiguration(deps as Dependency[]) - .resolvedConfiguration.lenientConfiguration.getArtifacts() - .findAll { it.classifier == artifactType } - .collect { zipTree(it.file) }) - } - tasks.register("sourcesJar", Jar) { - from { - altConfigFiles('sources') - } - def filePattern = ~'(.*)net/kyori/text((?:/|$).*)' - def textPattern = ~/net\.kyori\.text/ - eachFile { - it.filter { String line -> - line.replaceFirst(textPattern, 'com.sk89q.worldedit.util.formatting.text') - } - it.path = it.path.replaceFirst(filePattern, '$1com/sk89q/worldedit/util/formatting/text$2') - } - classifier = "sources" - } - - artifacts { - add("default", jar) { - builtBy(jar) - } - add("archives", sourcesJar) { - builtBy(sourcesJar) - } - } - - tasks.register("install", Upload) { - configuration = configurations.archives - repositories.mavenInstaller { - pom.version = project.version - pom.artifactId = project.name - } - } - - artifactoryPublish { - publishConfigs('default') - } - - build.dependsOn(jar, sourcesJar) -} - -def textExtrasVersion = "3.0.2" -project("core") { - def textVersion = "3.0.1" - def pistonVersion = '0.4.2' - - dependencies { - shade "net.kyori:text-api:$textVersion" - shade "net.kyori:text-serializer-gson:$textVersion" - shade "net.kyori:text-serializer-legacy:$textVersion" - shade "net.kyori:text-serializer-plain:$textVersion" - shade('com.sk89q:jchronic:0.2.4a') { - exclude(group: "junit", module: "junit") - } - shade 'com.thoughtworks.paranamer:paranamer:2.6' - shade 'com.sk89q.lib:jlibnoise:1.0.0' - shade "org.enginehub.piston:core:$pistonVersion" - shade "org.enginehub.piston.core-ap:runtime:$pistonVersion" - shade "org.enginehub.piston:default-impl:$pistonVersion" - } - - project("ap") { - dependencies { - shade "org.enginehub.piston.core-ap:annotations:$pistonVersion" - shade "org.enginehub.piston.core-ap:processor:$pistonVersion" - } - } -} -project("bukkit") { - repositories { - maven { - name = "SpigotMC" - url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" - } - } - dependencies { - shade "net.kyori:text-adapter-bukkit:$textExtrasVersion" - } -} -project("sponge") { - repositories { - maven { - name = "Sponge" - url = "https://repo.spongepowered.org/maven" - } - } - dependencies { - shade "net.kyori:text-adapter-spongeapi:$textExtrasVersion" - } -} - tasks.register("build") { dependsOn(subprojects.collect { it.tasks.named("build") }) } diff --git a/worldedit-libs/bukkit/build.gradle.kts b/worldedit-libs/bukkit/build.gradle.kts new file mode 100644 index 000000000..79734ff82 --- /dev/null +++ b/worldedit-libs/bukkit/build.gradle.kts @@ -0,0 +1,11 @@ +applyLibrariesConfiguration() + +repositories { + maven { + name = "SpigotMC" + url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") + } +} +dependencies { + "shade"("net.kyori:text-adapter-bukkit:${Versions.TEXT_EXTRAS}") +} \ No newline at end of file diff --git a/worldedit-libs/core/ap/build.gradle.kts b/worldedit-libs/core/ap/build.gradle.kts new file mode 100644 index 000000000..44374359b --- /dev/null +++ b/worldedit-libs/core/ap/build.gradle.kts @@ -0,0 +1,6 @@ +applyLibrariesConfiguration() + +dependencies { + "shade"("org.enginehub.piston.core-ap:annotations:${Versions.PISTON}") + "shade"("org.enginehub.piston.core-ap:processor:${Versions.PISTON}") +} diff --git a/worldedit-libs/core/build.gradle.kts b/worldedit-libs/core/build.gradle.kts new file mode 100644 index 000000000..d669216d6 --- /dev/null +++ b/worldedit-libs/core/build.gradle.kts @@ -0,0 +1,16 @@ +applyLibrariesConfiguration() + +dependencies { + "shade"("net.kyori:text-api:${Versions.TEXT}") + "shade"("net.kyori:text-serializer-gson:${Versions.TEXT}") + "shade"("net.kyori:text-serializer-legacy:${Versions.TEXT}") + "shade"("net.kyori:text-serializer-plain:${Versions.TEXT}") + "shade"("com.sk89q:jchronic:0.2.4a") { + exclude(group = "junit", module = "junit") + } + "shade"("com.thoughtworks.paranamer:paranamer:2.6") + "shade"("com.sk89q.lib:jlibnoise:1.0.0") + "shade"("org.enginehub.piston:core:${Versions.PISTON}") + "shade"("org.enginehub.piston.core-ap:runtime:${Versions.PISTON}") + "shade"("org.enginehub.piston:default-impl:${Versions.PISTON}") +} diff --git a/worldedit-libs/fabric/build.gradle.kts b/worldedit-libs/fabric/build.gradle.kts new file mode 100644 index 000000000..388618cea --- /dev/null +++ b/worldedit-libs/fabric/build.gradle.kts @@ -0,0 +1 @@ +applyLibrariesConfiguration() diff --git a/worldedit-libs/forge/build.gradle.kts b/worldedit-libs/forge/build.gradle.kts new file mode 100644 index 000000000..388618cea --- /dev/null +++ b/worldedit-libs/forge/build.gradle.kts @@ -0,0 +1 @@ +applyLibrariesConfiguration() diff --git a/worldedit-libs/sponge/build.gradle.kts b/worldedit-libs/sponge/build.gradle.kts new file mode 100644 index 000000000..5854dd616 --- /dev/null +++ b/worldedit-libs/sponge/build.gradle.kts @@ -0,0 +1,11 @@ +applyLibrariesConfiguration() + +repositories { + maven { + name = "Sponge" + url = uri("https://repo.spongepowered.org/maven") + } +} +dependencies { + "shade"("net.kyori:text-adapter-spongeapi:${Versions.TEXT_EXTRAS}") +} \ No newline at end of file diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index 8d6633de2..81d445a5d 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -2,6 +2,9 @@ plugins { id("org.spongepowered.plugin") } +PlatformConfigKt.applyPlatformAndCoreConfiguration(project) +PlatformConfigKt.applyShadowConfiguration(project) + repositories { maven { url "https://repo.codemc.org/repository/maven-public" } } From ab8397e517eeab1e34f37b38772cc5b50a5ad871 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 16:45:12 -0700 Subject: [PATCH 15/52] Migrate Bukkit to Kotlin DSL --- buildSrc/src/main/kotlin/PlatformConfig.kt | 2 + worldedit-bukkit/build.gradle | 65 -------------------- worldedit-bukkit/build.gradle.kts | 69 ++++++++++++++++++++++ 3 files changed, 71 insertions(+), 65 deletions(-) delete mode 100644 worldedit-bukkit/build.gradle create mode 100644 worldedit-bukkit/build.gradle.kts diff --git a/buildSrc/src/main/kotlin/PlatformConfig.kt b/buildSrc/src/main/kotlin/PlatformConfig.kt index 85042cc9f..faf7a785a 100644 --- a/buildSrc/src/main/kotlin/PlatformConfig.kt +++ b/buildSrc/src/main/kotlin/PlatformConfig.kt @@ -20,6 +20,8 @@ import org.gradle.kotlin.dsl.named fun Project.applyPlatformAndCoreConfiguration() { applyCommonConfiguration() apply(plugin = "java") + apply(plugin = "eclipse") + apply(plugin = "idea") apply(plugin = "maven") apply(plugin = "checkstyle") apply(plugin = "com.github.johnrengelman.shadow") diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle deleted file mode 100644 index b81612b0c..000000000 --- a/worldedit-bukkit/build.gradle +++ /dev/null @@ -1,65 +0,0 @@ -PlatformConfigKt.applyPlatformAndCoreConfiguration(project) -PlatformConfigKt.applyShadowConfiguration(project) -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'maven' -apply plugin: 'java-library' - -repositories { - maven { url "https://hub.spigotmc.org/nexus/content/groups/public" } - maven { url "https://repo.codemc.org/repository/maven-public" } - maven { url "https://papermc.io/repo/repository/maven-public/" } -} - -configurations.all { Configuration it -> - it.resolutionStrategy { ResolutionStrategy rs -> - rs.force("com.google.guava:guava:21.0") - } -} - -dependencies { - api project(':worldedit-core') - api project(':worldedit-libs:bukkit') - api 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT' // zzz - compileOnly 'com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT' - implementation 'io.papermc:paperlib:1.0.2' - compileOnly 'com.sk89q:dummypermscompat:1.10' - implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.1' - implementation 'org.bstats:bstats-bukkit:1.5' - testCompile 'org.mockito:mockito-core:1.9.0-rc1' -} - -processResources { - filesMatching('plugin.yml') { - expand 'internalVersion': project.internalVersion - } - from (zipTree('src/main/resources/worldedit-adapters.jar').matching { - exclude 'META-INF/' - }) - exclude '**/worldedit-adapters.jar' -} - -jar { - manifest { - attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", - "WorldEdit-Version": version) - } -} - -shadowJar { - dependencies { - relocate "org.slf4j", "com.sk89q.worldedit.slf4j" - relocate "org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge" - include(dependency(':worldedit-core')) - include(dependency('org.slf4j:slf4j-api')) - include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) - relocate ("org.bstats", "com.sk89q.worldedit.bukkit.bstats") { - include(dependency("org.bstats:bstats-bukkit:1.5")) - } - relocate ("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") { - include(dependency("io.papermc:paperlib:1.0.2")) - } - } -} - -build.dependsOn(shadowJar) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts new file mode 100644 index 000000000..ee1b94c27 --- /dev/null +++ b/worldedit-bukkit/build.gradle.kts @@ -0,0 +1,69 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + `java-library` +} + +applyPlatformAndCoreConfiguration() +applyShadowConfiguration() + +repositories { + maven { url = uri("https://hub.spigotmc.org/nexus/content/groups/public") } + maven { url = uri("https://repo.codemc.org/repository/maven-public") } + maven { url = uri("https://papermc.io/repo/repository/maven-public/") } +} + +configurations.all { + resolutionStrategy { + force("com.google.guava:guava:21.0") + } +} + +dependencies { + "api"(project(":worldedit-core")) + "api"(project(":worldedit-libs:bukkit")) + "api"("org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT") + "compileOnly"("com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT") + "implementation"("io.papermc:paperlib:1.0.2") + "compileOnly"("com.sk89q:dummypermscompat:1.10") + "implementation"("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1") + "implementation"("org.bstats:bstats-bukkit:1.5") + "testCompile"("org.mockito:mockito-core:1.9.0-rc1") +} + +tasks.named("processResources") { + filesMatching("plugin.yml") { + expand("internalVersion" to project.ext["internalVersion"]) + } + from(zipTree("src/main/resources/worldedit-adapters.jar").matching { + exclude("META-INF/") + }) + exclude("**/worldedit-adapters.jar") +} + +tasks.named("jar") { + manifest { + attributes("Class-Path" to "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", + "WorldEdit-Version" to project.version) + } +} + +tasks.named("shadowJar") { + dependencies { + relocate("org.slf4j", "com.sk89q.worldedit.slf4j") + relocate("org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge") + include(dependency(":worldedit-core")) + include(dependency("org.slf4j:slf4j-api")) + include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) + relocate("org.bstats", "com.sk89q.worldedit.bukkit.bstats") { + include(dependency("org.bstats:bstats-bukkit:1.5")) + } + relocate("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") { + include(dependency("io.papermc:paperlib:1.0.2")) + } + } +} + +tasks.named("assemble").configure { + dependsOn("shadowJar") +} From 55100761a33c5c0086e06078ed641ed86bf56a78 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 17:07:37 -0700 Subject: [PATCH 16/52] Migrate Core to Kotlin DSL --- buildSrc/src/main/kotlin/Versions.kt | 1 + worldedit-core/build.gradle | 53 ------------------------ worldedit-core/build.gradle.kts | 50 ++++++++++++++++++++++ worldedit-core/doctools/build.gradle.kts | 6 +-- 4 files changed, 53 insertions(+), 57 deletions(-) delete mode 100644 worldedit-core/build.gradle create mode 100644 worldedit-core/build.gradle.kts diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index fd61ee13b..0f79cbfd1 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -2,4 +2,5 @@ object Versions { const val TEXT = "3.0.1" const val TEXT_EXTRAS = "3.0.2" const val PISTON = "0.4.2" + const val AUTO_VALUE = "1.6.5" } diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle deleted file mode 100644 index a5b3bba63..000000000 --- a/worldedit-core/build.gradle +++ /dev/null @@ -1,53 +0,0 @@ -plugins { - id("java-library") - id("eclipse") - id("idea") - id("net.ltgt.apt-eclipse") - id("net.ltgt.apt-idea") -} - -PlatformConfigKt.applyPlatformAndCoreConfiguration(project) - -configurations.all { Configuration it -> - it.resolutionStrategy { ResolutionStrategy rs -> - rs.force("com.google.guava:guava:21.0") - } -} - -dependencies { - compile project(':worldedit-libs:core') - compile 'de.schlichtherle:truezip:6.8.3' - compile 'org.mozilla:rhino:1.7R5' - compile 'org.yaml:snakeyaml:1.9' - compile 'com.google.guava:guava:21.0' - compile 'com.google.code.findbugs:jsr305:1.3.9' - compile 'com.google.code.gson:gson:2.8.0' - compile 'com.googlecode.json-simple:json-simple:1.1.1' - compile 'org.slf4j:slf4j-api:1.7.26' - - compileOnly project(':worldedit-libs:core:ap') - annotationProcessor project(':worldedit-libs:core:ap') - annotationProcessor "com.google.guava:guava:21.0" - def avVersion = "1.6.5" - compileOnly "com.google.auto.value:auto-value-annotations:$avVersion" - annotationProcessor "com.google.auto.value:auto-value:$avVersion" - //compile 'net.sf.trove4j:trove4j:3.0.3' - testCompile 'org.mockito:mockito-core:1.9.0-rc1' -} - -tasks.withType(JavaCompile).configureEach { - dependsOn(":worldedit-libs:build") - it.options.compilerArgs.add("-Aarg.name.key.prefix=") -} - -sourceSets { - main { - java { - srcDir 'src/main/java' - srcDir 'src/legacy/java' - } - resources { - srcDir 'src/main/resources' - } - } -} diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts new file mode 100644 index 000000000..6d268e843 --- /dev/null +++ b/worldedit-core/build.gradle.kts @@ -0,0 +1,50 @@ +plugins { + id("java-library") + id("net.ltgt.apt-eclipse") + id("net.ltgt.apt-idea") +} + +applyPlatformAndCoreConfiguration() + +configurations.all { + resolutionStrategy { + force("com.google.guava:guava:21.0") + } +} + +dependencies { + "compile"(project(":worldedit-libs:core")) + "compile"("de.schlichtherle:truezip:6.8.3") + "compile"("rhino:js:1.7R2") + "compile"("org.yaml:snakeyaml:1.9") + "compile"("com.google.guava:guava:21.0") + "compile"("com.google.code.findbugs:jsr305:1.3.9") + "compile"("com.google.code.gson:gson:2.8.0") + "compile"("com.googlecode.json-simple:json-simple:1.1.1") + "compile"("org.slf4j:slf4j-api:1.7.26") + + "compileOnly"(project(":worldedit-libs:core:ap")) + "annotationProcessor"(project(":worldedit-libs:core:ap")) + // ensure this is on the classpath for the AP + "annotationProcessor"("com.google.guava:guava:21.0") + "compileOnly"("com.google.auto.value:auto-value-annotations:${Versions.AUTO_VALUE}") + "annotationProcessor"("com.google.auto.value:auto-value:${Versions.AUTO_VALUE}") + "testCompile"("org.mockito:mockito-core:1.9.0-rc1") +} + +tasks.withType().configureEach { + dependsOn(":worldedit-libs:build") + options.compilerArgs.add("-Aarg.name.key.prefix=") +} + +sourceSets { + main { + java { + srcDir("src/main/java") + srcDir("src/legacy/java") + } + resources { + srcDir("src/main/resources") + } + } +} diff --git a/worldedit-core/doctools/build.gradle.kts b/worldedit-core/doctools/build.gradle.kts index 75a347ece..803e1078e 100644 --- a/worldedit-core/doctools/build.gradle.kts +++ b/worldedit-core/doctools/build.gradle.kts @@ -4,14 +4,12 @@ plugins { kotlin("jvm") version "1.3.41" } +applyCommonConfiguration() + tasks.withType { kotlinOptions.jvmTarget = "1.8" } -repositories { - jcenter() -} - dependencies { "implementation"(project(":worldedit-libs:core:ap")) "implementation"(project(":worldedit-core")) From 47b9716bdcae6754c44f42702ce4871e45a4f90d Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 17:29:43 -0700 Subject: [PATCH 17/52] Migrate Fabric to Kotlin DSL --- worldedit-fabric/build.gradle | 108 ----------------------------- worldedit-fabric/build.gradle.kts | 109 ++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 108 deletions(-) delete mode 100644 worldedit-fabric/build.gradle create mode 100644 worldedit-fabric/build.gradle.kts diff --git a/worldedit-fabric/build.gradle b/worldedit-fabric/build.gradle deleted file mode 100644 index 70acc7a1d..000000000 --- a/worldedit-fabric/build.gradle +++ /dev/null @@ -1,108 +0,0 @@ -import net.fabricmc.loom.task.RemapJarTask - -buildscript { - repositories { - jcenter() - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - maven { - name = 'sponge' - url = 'https://repo.spongepowered.org/maven' - } - } - - dependencies { - classpath 'net.fabricmc:fabric-loom:0.2.4-SNAPSHOT' - classpath 'org.spongepowered:mixin:0.7.11-SNAPSHOT' - } -} - -PlatformConfigKt.applyPlatformAndCoreConfiguration(project) -PlatformConfigKt.applyShadowConfiguration(project) - -apply plugin: 'eclipse' -apply plugin: 'fabric-loom' - -def minecraftVersion = "1.14.3" -def fabricVersion = "0.3.0+build.187" -def yarnMappings = "1.14.3+build.1" -def loaderVersion = "0.4.8+build.155" - -configurations.all { Configuration it -> - it.resolutionStrategy { ResolutionStrategy rs -> - rs.force("com.google.guava:guava:21.0") - } -} - -dependencies { - compile project(':worldedit-core') - compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.1' - - minecraft "com.mojang:minecraft:${minecraftVersion}" - mappings "net.fabricmc:yarn:${yarnMappings}" - modCompile "net.fabricmc:fabric-loader:${loaderVersion}" - - modCompile "net.fabricmc.fabric-api:fabric-api:${fabricVersion}" - - testCompile group: 'org.mockito', name: 'mockito-core', version: '1.9.0-rc1' -} - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -minecraft { -} - -project.archivesBaseName = "${project.archivesBaseName}-mc${minecraftVersion}" - -processResources { - // this will ensure that this task is redone when the versions change. - inputs.property 'version', project.internalVersion - - from(sourceSets.main.resources.srcDirs) { - include "fabric.mod.json" - expand "version": project.internalVersion - } - - // copy everything else except the mod json - from(sourceSets.main.resources.srcDirs) { - exclude "fabric.mod.json" - } -} - -jar { - manifest { - attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", - "WorldEdit-Version": version) - } -} - -shadowJar { - archiveClassifier.set("dist-dev") - dependencies { - relocate "org.slf4j", "com.sk89q.worldedit.slf4j" - relocate "org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge" - - include(dependency('org.slf4j:slf4j-api')) - include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) - } -} - -task deobfJar(type: Jar) { - from sourceSets.main.output - archiveClassifier.set("dev") -} - -artifacts { - archives deobfJar -} - -task shadowJarRemap(type: RemapJarTask) { - input shadowJar.archiveFile - output new File(shadowJar.archiveFile.get().asFile.getAbsolutePath().replaceFirst('-dev\\.jar$', ".jar")) -} - -shadowJarRemap.dependsOn(shadowJar) -build.dependsOn(shadowJarRemap) \ No newline at end of file diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts new file mode 100644 index 000000000..f6417686a --- /dev/null +++ b/worldedit-fabric/build.gradle.kts @@ -0,0 +1,109 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import net.fabricmc.loom.task.RemapJarTask + +buildscript { + repositories { + jcenter() + maven { + name = "Fabric" + url = uri("https://maven.fabricmc.net/") + } + maven { + name = "sponge" + url = uri("https://repo.spongepowered.org/maven") + } + } + + dependencies { + "classpath"("net.fabricmc:fabric-loom:0.2.4-SNAPSHOT") + "classpath"("org.spongepowered:mixin:0.7.11-SNAPSHOT") + } +} + +applyPlatformAndCoreConfiguration() +applyShadowConfiguration() + +apply(plugin = "fabric-loom") + +val minecraftVersion = "1.14.3" +val fabricVersion = "0.3.0+build.187" +val yarnMappings = "1.14.3+build.1" +val loaderVersion = "0.4.8+build.155" + +configurations.all { + resolutionStrategy { + force("com.google.guava:guava:21.0") + } +} + +dependencies { + "compile"(project(":worldedit-core")) + "compile"("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1") + + "minecraft"("com.mojang:minecraft:$minecraftVersion") + "mappings"("net.fabricmc:yarn:$yarnMappings") + "modCompile"("net.fabricmc:fabric-loader:$loaderVersion") + + "modCompile"("net.fabricmc.fabric-api:fabric-api:$fabricVersion") + + "testCompile"("org.mockito:mockito-core:1.9.0-rc1") +} + +configure { + archivesBaseName = "$archivesBaseName-mc$minecraftVersion" +} + +val sourceSets = project.the().sourceSets + +tasks.named("processResources") { + // this will ensure that this task is redone when the versions change. + inputs.property("version", project.ext["internalVersion"]) + + from(sourceSets["main"].resources.srcDirs) { + include("fabric.mod.json") + expand("version" to project.ext["internalVersion"]) + } + + // copy everything else except the mod json + from(sourceSets["main"].resources.srcDirs) { + exclude("fabric.mod.json") + } +} + +tasks.named("jar") { + manifest { + attributes("Class-Path" to "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", + "WorldEdit-Version" to project.version) + } +} + +tasks.named("shadowJar") { + archiveClassifier.set("dist-dev") + dependencies { + relocate("org.slf4j", "com.sk89q.worldedit.slf4j") + relocate("org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge") + + include(dependency("org.slf4j:slf4j-api")) + include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) + } +} + +tasks.register("deobfJar") { + from(sourceSets["main"].output) + archiveClassifier.set("dev") +} + +artifacts { + add("archives", tasks.named("deobfJar")) +} + +tasks.register("remapShadowJar") { + val shadowJar = tasks.getByName("shadowJar") + dependsOn(shadowJar) + setInput(shadowJar.archiveFile) + setOutput(shadowJar.archiveFile.get().asFile.getAbsolutePath().replaceFirst("-dev\\.jar$", ".jar")) +} + +tasks.named("assemble").configure { + dependsOn("remapShadowJar") +} From 3d4025c75738731c7ac1b8c51f0e1dd9be38f663 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 17:45:33 -0700 Subject: [PATCH 18/52] Migrate Forge to Kotlin DSL --- buildSrc/src/main/kotlin/GradleExtras.kt | 6 ++ buildSrc/src/main/kotlin/PlatformConfig.kt | 8 +- worldedit-fabric/build.gradle.kts | 2 - worldedit-forge/build.gradle | 106 -------------------- worldedit-forge/build.gradle.kts | 110 +++++++++++++++++++++ 5 files changed, 119 insertions(+), 113 deletions(-) delete mode 100644 worldedit-forge/build.gradle create mode 100644 worldedit-forge/build.gradle.kts diff --git a/buildSrc/src/main/kotlin/GradleExtras.kt b/buildSrc/src/main/kotlin/GradleExtras.kt index 5358f6b37..e7d1e0ede 100644 --- a/buildSrc/src/main/kotlin/GradleExtras.kt +++ b/buildSrc/src/main/kotlin/GradleExtras.kt @@ -1,6 +1,12 @@ import org.gradle.api.Project import org.gradle.api.plugins.ExtraPropertiesExtension +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.SourceSetContainer import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.the val Project.ext: ExtraPropertiesExtension get() = extensions.getByType() + +val Project.sourceSets: SourceSetContainer + get() = the().sourceSets diff --git a/buildSrc/src/main/kotlin/PlatformConfig.kt b/buildSrc/src/main/kotlin/PlatformConfig.kt index faf7a785a..c57dbdd20 100644 --- a/buildSrc/src/main/kotlin/PlatformConfig.kt +++ b/buildSrc/src/main/kotlin/PlatformConfig.kt @@ -11,11 +11,9 @@ import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.get import org.gradle.kotlin.dsl.getByName -import org.gradle.kotlin.dsl.getPlugin -import org.gradle.kotlin.dsl.register -import org.gradle.kotlin.dsl.the -import org.gradle.kotlin.dsl.withType import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType fun Project.applyPlatformAndCoreConfiguration() { applyCommonConfiguration() @@ -64,7 +62,7 @@ fun Project.applyPlatformAndCoreConfiguration() { tasks.register("sourcesJar") { dependsOn("classes") archiveClassifier.set("sources") - from(project.the().sourceSets["main"].allSource) + from(sourceSets["main"].allSource) } artifacts { diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index f6417686a..acaa4fb25 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -53,8 +53,6 @@ configure { archivesBaseName = "$archivesBaseName-mc$minecraftVersion" } -val sourceSets = project.the().sourceSets - tasks.named("processResources") { // this will ensure that this task is redone when the versions change. inputs.property("version", project.ext["internalVersion"]) diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle deleted file mode 100644 index fc3dcaee8..000000000 --- a/worldedit-forge/build.gradle +++ /dev/null @@ -1,106 +0,0 @@ -PlatformConfigKt.applyPlatformAndCoreConfiguration(project) -PlatformConfigKt.applyShadowConfiguration(project) - -apply plugin: 'eclipse' -apply plugin: 'net.minecraftforge.gradle' - -def minecraftVersion = "1.14.3" -def forgeVersion = "27.0.13" - -configurations.all { Configuration it -> - it.resolutionStrategy { ResolutionStrategy rs -> - rs.force("com.google.guava:guava:21.0") - } -} - -dependencies { - compile project(':worldedit-core') - compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.11.2' - - minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}" - - testCompile group: 'org.mockito', name: 'mockito-core', version: '1.9.0-rc1' -} - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -minecraft { - mappings channel: 'snapshot', version: "20190626-${minecraftVersion}" - - runs { - client = { - // recommended logging data for a userdev environment - properties 'forge.logging.markers': 'SCAN,REGISTRIES,REGISTRYDUMP' - // recommended logging level for the console - properties 'forge.logging.console.level': 'debug' - workingDirectory project.file('run').canonicalPath - source sourceSets.main - } - server = { - // recommended logging data for a userdev environment - properties 'forge.logging.markers': 'SCAN,REGISTRIES,REGISTRYDUMP' - // recommended logging level for the console - properties 'forge.logging.console.level': 'debug' - workingDirectory project.file('run').canonicalPath - source sourceSets.main - } - } - -} - -project.archivesBaseName = "${project.archivesBaseName}-mc${minecraftVersion}" - -processResources { - // this will ensure that this task is redone when the versions change. - inputs.property 'version', project.internalVersion - inputs.property 'forgeVersion', forgeVersion - - // replace stuff in mcmod.info, nothing else - from(sourceSets.main.resources.srcDirs) { - include 'META-INF/mods.toml' - - // replace version and mcversion - expand 'version': project.internalVersion, 'forgeVersion': forgeVersion - } - - // copy everything else except the mcmod.info - from(sourceSets.main.resources.srcDirs) { - exclude 'META-INF/mods.toml' - } -} - -jar { - manifest { - attributes("WorldEdit-Version": version) - } -} - -shadowJar { - dependencies { - relocate "org.slf4j", "com.sk89q.worldedit.slf4j" - relocate "org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge" - - include(dependency('org.slf4j:slf4j-api')) - include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) - include(dependency("de.schlichtherle:truezip")) - include(dependency("org.mozilla:rhino")) - } -} - -afterEvaluate { - reobf { - shadowJar { - mappings = createMcpToSrg.output - } - } -} - -task deobfJar(type: Jar) { - from sourceSets.main.output - getArchiveClassifier().set("dev") -} - -artifacts { - archives deobfJar -} diff --git a/worldedit-forge/build.gradle.kts b/worldedit-forge/build.gradle.kts new file mode 100644 index 000000000..25e159344 --- /dev/null +++ b/worldedit-forge/build.gradle.kts @@ -0,0 +1,110 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import net.minecraftforge.gradle.common.util.RunConfig +import net.minecraftforge.gradle.userdev.UserDevExtension +import net.minecraftforge.gradle.userdev.tasks.GenerateSRG +import net.minecraftforge.gradle.userdev.tasks.RenameJarInPlace + +plugins { + id("net.minecraftforge.gradle") +} + +applyPlatformAndCoreConfiguration() +applyShadowConfiguration() + +val minecraftVersion = "1.14.3" +val forgeVersion = "27.0.13" + +configurations.all { + resolutionStrategy { + force("com.google.guava:guava:21.0") + } +} + +dependencies { + "compile"(project(":worldedit-core")) + "compile"("org.apache.logging.log4j:log4j-slf4j-impl:2.11.2") + + "minecraft"("net.minecraftforge:forge:$minecraftVersion-$forgeVersion") + + "testCompile"("org.mockito:mockito-core:1.9.0-rc1") +} + +configure { + mappings(mapOf( + "channel" to "snapshot", + "version" to "20190626-$minecraftVersion" + )) + + runs { + val runConfig = Action { + properties(mapOf( + "forge.logging.markers" to "SCAN,REGISTRIES,REGISTRYDUMP", + "forge.logging.console.level" to "debug" + )) + workingDirectory = project.file("run").canonicalPath + source(sourceSets["main"]) + } + create("client", runConfig) + create("server", runConfig) + } + +} + +configure { + archivesBaseName = "$archivesBaseName-mc$minecraftVersion" +} + +tasks.named("processResources") { + // this will ensure that this task is redone when the versions change. + inputs.property("version", project.ext["internalVersion"]) + inputs.property("forgeVersion", forgeVersion) + + // replace stuff in mcmod.info, nothing else + from(sourceSets["main"].resources.srcDirs) { + include("META-INF/mods.toml") + + // replace version and mcversion + expand( + "version" to project.ext["internalVersion"], + "forgeVersion" to forgeVersion + ) + } + + // copy everything else except the mcmod.info + from(sourceSets["main"].resources.srcDirs) { + exclude("META-INF/mods.toml") + } +} + +tasks.named("jar") { + manifest { + attributes("Class-Path" to "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", + "WorldEdit-Version" to project.version) + } +} + +tasks.named("shadowJar") { + dependencies { + relocate("org.slf4j", "com.sk89q.worldedit.slf4j") + relocate("org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge") + + include(dependency("org.slf4j:slf4j-api")) + include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) + } +} + +afterEvaluate { + val reobf = extensions.getByName>("reobf") + reobf.maybeCreate("shadowJar").run { + mappings = tasks.getByName("createMcpToSrg").output + } +} + +tasks.register("deobfJar") { + from(sourceSets["main"].output) + archiveClassifier.set("dev") +} + +artifacts { + add("archives", tasks.named("deobfJar")) +} From 3bdc1c1cf2e838b9d8d074970d715c052a6f2699 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 17:48:31 -0700 Subject: [PATCH 19/52] Fixup after shade rhino merge --- worldedit-core/build.gradle.kts | 2 +- worldedit-forge/build.gradle.kts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 6d268e843..939679383 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -15,7 +15,7 @@ configurations.all { dependencies { "compile"(project(":worldedit-libs:core")) "compile"("de.schlichtherle:truezip:6.8.3") - "compile"("rhino:js:1.7R2") + "compile"("org.mozilla:rhino:1.7R5") "compile"("org.yaml:snakeyaml:1.9") "compile"("com.google.guava:guava:21.0") "compile"("com.google.code.findbugs:jsr305:1.3.9") diff --git a/worldedit-forge/build.gradle.kts b/worldedit-forge/build.gradle.kts index 25e159344..76abc2ac7 100644 --- a/worldedit-forge/build.gradle.kts +++ b/worldedit-forge/build.gradle.kts @@ -90,6 +90,9 @@ tasks.named("shadowJar") { include(dependency("org.slf4j:slf4j-api")) include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) + include(dependency("de.schlichtherle:truezip")) + include(dependency("org.mozilla:rhino")) + } } From 5a14693aa95f24026a68e69350032f59f73008fd Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 17:59:23 -0700 Subject: [PATCH 20/52] Migrate Sponge, Libs to Kotlin DSL --- worldedit-forge/build.gradle.kts | 3 +- worldedit-libs/build.gradle | 3 -- worldedit-libs/build.gradle.kts | 3 ++ worldedit-sponge/build.gradle | 52 ------------------------------ worldedit-sponge/build.gradle.kts | 53 +++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 57 deletions(-) delete mode 100644 worldedit-libs/build.gradle create mode 100644 worldedit-libs/build.gradle.kts delete mode 100644 worldedit-sponge/build.gradle create mode 100644 worldedit-sponge/build.gradle.kts diff --git a/worldedit-forge/build.gradle.kts b/worldedit-forge/build.gradle.kts index 76abc2ac7..78c23c898 100644 --- a/worldedit-forge/build.gradle.kts +++ b/worldedit-forge/build.gradle.kts @@ -78,8 +78,7 @@ tasks.named("processResources") { tasks.named("jar") { manifest { - attributes("Class-Path" to "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", - "WorldEdit-Version" to project.version) + attributes("WorldEdit-Version" to project.version) } } diff --git a/worldedit-libs/build.gradle b/worldedit-libs/build.gradle deleted file mode 100644 index 29c096e2d..000000000 --- a/worldedit-libs/build.gradle +++ /dev/null @@ -1,3 +0,0 @@ -tasks.register("build") { - dependsOn(subprojects.collect { it.tasks.named("build") }) -} diff --git a/worldedit-libs/build.gradle.kts b/worldedit-libs/build.gradle.kts new file mode 100644 index 000000000..40b3746a9 --- /dev/null +++ b/worldedit-libs/build.gradle.kts @@ -0,0 +1,3 @@ +tasks.register("build") { + dependsOn(subprojects.map { it.tasks.named("build") }) +} diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle deleted file mode 100644 index 81d445a5d..000000000 --- a/worldedit-sponge/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -plugins { - id("org.spongepowered.plugin") -} - -PlatformConfigKt.applyPlatformAndCoreConfiguration(project) -PlatformConfigKt.applyShadowConfiguration(project) - -repositories { - maven { url "https://repo.codemc.org/repository/maven-public" } -} - -dependencies { - compile project(':worldedit-core') - compile project(':worldedit-libs:sponge') - compile 'org.spongepowered:spongeapi:7.1.0' - compile 'org.bstats:bstats-sponge:1.5' - testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.0-rc1' -} - -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 - -sponge { - plugin { - id = 'worldedit' - } -} - -jar { - manifest { - attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", - "WorldEdit-Version": version) - } -} - -shadowJar { - dependencies { - relocate ("org.bstats", "com.sk89q.worldedit.sponge.bstats") { - include(dependency('org.bstats:bstats-sponge:1.5')) - } - } -} - -if (project.hasProperty("signing")) { - apply plugin: 'signing' - - signing { - sign shadowJar - } - - build.dependsOn('signShadowJar') -} \ No newline at end of file diff --git a/worldedit-sponge/build.gradle.kts b/worldedit-sponge/build.gradle.kts new file mode 100644 index 000000000..1c5fa9453 --- /dev/null +++ b/worldedit-sponge/build.gradle.kts @@ -0,0 +1,53 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + id("org.spongepowered.plugin") +} + +applyPlatformAndCoreConfiguration() +applyShadowConfiguration() + +repositories { + maven { url = uri("https://repo.codemc.org/repository/maven-public") } +} + +dependencies { + compile(project(":worldedit-core")) + compile(project(":worldedit-libs:sponge")) + compile("org.spongepowered:spongeapi:7.1.0") + compile("org.bstats:bstats-sponge:1.5") + testCompile("org.mockito:mockito-core:1.9.0-rc1") +} + +sponge { + plugin { + id = "worldedit" + } +} + +tasks.named("jar") { + manifest { + attributes("Class-Path" to "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", + "WorldEdit-Version" to project.version) + } +} + +tasks.named("shadowJar") { + dependencies { + relocate ("org.bstats", "com.sk89q.worldedit.sponge.bstats") { + include(dependency("org.bstats:bstats-sponge:1.5")) + } + } +} + +if (project.hasProperty("signing")) { + apply(plugin = "signing") + + configure { + sign("shadowJar") + } + + tasks.named("build").configure { + dependsOn("signShadowJar") + } +} \ No newline at end of file From 5277f99bf28d57ada505dedfb1c425948bcc1c84 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 10 Jul 2019 18:55:09 -0700 Subject: [PATCH 21/52] Minor fixes for craftscripts in Forge --- worldedit-core/build.gradle.kts | 2 +- .../MinecraftHidingClassShutter.java | 41 +++++ .../scripting/RhinoCraftScriptEngine.java | 1 + .../scripting/java/RhinoScriptEngine.java | 134 --------------- .../java/RhinoScriptEngineFactory.java | 153 ------------------ worldedit-forge/build.gradle.kts | 4 +- 6 files changed, 46 insertions(+), 289 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/scripting/MinecraftHidingClassShutter.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngine.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngineFactory.java diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 939679383..6a9266247 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -15,7 +15,7 @@ configurations.all { dependencies { "compile"(project(":worldedit-libs:core")) "compile"("de.schlichtherle:truezip:6.8.3") - "compile"("org.mozilla:rhino:1.7R5") + "compile"("org.mozilla:rhino:1.7.11") "compile"("org.yaml:snakeyaml:1.9") "compile"("com.google.guava:guava:21.0") "compile"("com.google.code.findbugs:jsr305:1.3.9") diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/MinecraftHidingClassShutter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/MinecraftHidingClassShutter.java new file mode 100644 index 000000000..20324ed59 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/MinecraftHidingClassShutter.java @@ -0,0 +1,41 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.scripting; + +import org.mozilla.javascript.ClassShutter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Hides Minecraft's obfuscated & de-obfuscated names from scripts. + */ +class MinecraftHidingClassShutter implements ClassShutter { + + private static final Logger LOGGER = LoggerFactory.getLogger(MinecraftHidingClassShutter.class); + + @Override + public boolean visibleToScripts(String fullClassName) { + if (!fullClassName.contains(".")) { + // Default package -- probably Minecraft + return false; + } + return !fullClassName.startsWith("net.minecraft"); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/RhinoCraftScriptEngine.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/RhinoCraftScriptEngine.java index 79d51cefb..8cad2670b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/RhinoCraftScriptEngine.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/RhinoCraftScriptEngine.java @@ -50,6 +50,7 @@ public class RhinoCraftScriptEngine implements CraftScriptEngine { throws ScriptException, Throwable { RhinoContextFactory factory = new RhinoContextFactory(timeLimit); Context cx = factory.enterContext(); + cx.setClassShutter(new MinecraftHidingClassShutter()); ScriptableObject scriptable = new ImporterTopLevel(cx); Scriptable scope = cx.initStandardObjects(scriptable); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngine.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngine.java deleted file mode 100644 index afab20c3a..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngine.java +++ /dev/null @@ -1,134 +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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.scripting.java; - -import com.sk89q.worldedit.scripting.RhinoContextFactory; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.ImporterTopLevel; -import org.mozilla.javascript.JavaScriptException; -import org.mozilla.javascript.RhinoException; -import org.mozilla.javascript.Scriptable; -import org.mozilla.javascript.ScriptableObject; - -import java.io.IOException; -import java.io.Reader; - -import javax.script.AbstractScriptEngine; -import javax.script.Bindings; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptException; -import javax.script.SimpleBindings; - -public class RhinoScriptEngine extends AbstractScriptEngine { - private ScriptEngineFactory factory; - private Context cx; - - public RhinoScriptEngine() { - RhinoContextFactory factory = new RhinoContextFactory(3000); - factory.enterContext(); - } - - @Override - public Bindings createBindings() { - return new SimpleBindings(); - } - - @Override - public Object eval(String script, ScriptContext context) - throws ScriptException { - - Scriptable scope = setupScope(cx, context); - - String filename = (filename = (String) get(ScriptEngine.FILENAME)) == null - ? "" : filename; - - try { - return cx.evaluateString(scope, script, filename, 1, null); - } catch (RhinoException e) { - String msg; - int line = (line = e.lineNumber()) == 0 ? -1 : line; - - if (e instanceof JavaScriptException) { - msg = String.valueOf(((JavaScriptException) e).getValue()); - } else { - msg = e.getMessage(); - } - - ScriptException scriptException = - new ScriptException(msg, e.sourceName(), line); - scriptException.initCause(e); - - throw scriptException; - } finally { - Context.exit(); - } - } - - @Override - public Object eval(Reader reader, ScriptContext context) - throws ScriptException { - - Scriptable scope = setupScope(cx, context); - - String filename = (filename = (String) get(ScriptEngine.FILENAME)) == null - ? "" : filename; - - try { - return cx.evaluateReader(scope, reader, filename, 1, null); - } catch (RhinoException e) { - String msg; - int line = (line = e.lineNumber()) == 0 ? -1 : line; - - if (e instanceof JavaScriptException) { - msg = String.valueOf(((JavaScriptException) e).getValue()); - } else { - msg = e.getMessage(); - } - - ScriptException scriptException = - new ScriptException(msg, e.sourceName(), line); - scriptException.initCause(e); - - throw scriptException; - } catch (IOException e) { - throw new ScriptException(e); - } finally { - Context.exit(); - } - } - - @Override - public ScriptEngineFactory getFactory() { - if (factory != null) { - return factory; - } else { - return new RhinoScriptEngineFactory(); - } - } - - private Scriptable setupScope(Context cx, ScriptContext context) { - ScriptableObject scriptable = new ImporterTopLevel(cx); - Scriptable scope = cx.initStandardObjects(scriptable); - //ScriptableObject.putProperty(scope, "argv", Context.javaToJS(args, scope)); - return scope; - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngineFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngineFactory.java deleted file mode 100644 index ee312229c..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/java/RhinoScriptEngineFactory.java +++ /dev/null @@ -1,153 +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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.scripting.java; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; - -public class RhinoScriptEngineFactory implements ScriptEngineFactory { - private static List names; - private static List mimeTypes; - private static List extensions; - - static { - names = new ArrayList<>(5); - names.add("ECMAScript"); - names.add("ecmascript"); - names.add("JavaScript"); - names.add("javascript"); - names.add("js"); - names = Collections.unmodifiableList(names); - - mimeTypes = new ArrayList<>(4); - mimeTypes.add("application/ecmascript"); - mimeTypes.add("text/ecmascript"); - mimeTypes.add("application/javascript"); - mimeTypes.add("text/javascript"); - mimeTypes = Collections.unmodifiableList(mimeTypes); - - extensions = new ArrayList<>(2); - extensions.add("emcascript"); - extensions.add("js"); - extensions = Collections.unmodifiableList(extensions); - } - - @Override - public String getEngineName() { - return "Rhino JavaScript Engine (SK)"; - } - - @Override - public String getEngineVersion() { - return "unknown"; - } - - @Override - public List getExtensions() { - return extensions; - } - - @Override - public String getLanguageName() { - return "EMCAScript"; - } - - @Override - public String getLanguageVersion() { - return "1.8"; - } - - @Override - public String getMethodCallSyntax(String obj, String m, String... args) { - StringBuilder s = new StringBuilder(); - s.append(obj); - s.append("."); - s.append(m); - s.append("("); - - for (int i = 0; i < args.length; ++i) { - s.append(args[i]); - if (i < args.length - 1) { - s.append(","); - } - } - - s.append(")"); - - return s.toString(); - } - - @Override - public List getMimeTypes() { - return mimeTypes; - } - - @Override - public List getNames() { - return names; - } - - @Override - public String getOutputStatement(String str) { - return "print(" + str.replace("\\", "\\\\") - .replace("\"", "\\\\\"") - .replace(";", "\\\\;") + ")"; - } - - @Override - public Object getParameter(String key) { - switch (key) { - case ScriptEngine.ENGINE: - return getEngineName(); - case ScriptEngine.ENGINE_VERSION: - return getEngineVersion(); - case ScriptEngine.NAME: - return getEngineName(); - case ScriptEngine.LANGUAGE: - return getLanguageName(); - case ScriptEngine.LANGUAGE_VERSION: - return getLanguageVersion(); - case "THREADING": - return "MULTITHREADED"; - default: - throw new IllegalArgumentException("Invalid key"); - } - } - - @Override - public String getProgram(String... statements) { - StringBuilder s = new StringBuilder(); - for (String stmt : statements) { - s.append(stmt); - s.append(";"); - } - return s.toString(); - } - - @Override - public ScriptEngine getScriptEngine() { - return new RhinoScriptEngine(); - } - -} diff --git a/worldedit-forge/build.gradle.kts b/worldedit-forge/build.gradle.kts index 78c23c898..235900181 100644 --- a/worldedit-forge/build.gradle.kts +++ b/worldedit-forge/build.gradle.kts @@ -91,7 +91,9 @@ tasks.named("shadowJar") { include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) include(dependency("de.schlichtherle:truezip")) include(dependency("org.mozilla:rhino")) - + } + minimize { + exclude(dependency("org.mozilla:rhino")) } } From 52a62b984ba5ce29c14bd0a90e9fb78ef4db553b Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Sat, 13 Jul 2019 22:16:16 -0700 Subject: [PATCH 22/52] Improve logging, update to 5.5.1 --- build.gradle.kts | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7088d0893..07b943531 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ import org.ajoberstar.grgit.Grgit -println(""" +logger.lifecycle(""" ******************************************* You are building WorldEdit! @@ -19,9 +19,9 @@ applyRootArtifactoryConfig() if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") ext["gitCommitHash"] = try { - (ext["grgit"] as Grgit).head().abbreviatedId + (ext["grgit"] as Grgit?)?.head()?.abbreviatedId } catch (e: Exception) { - println("Error getting commit hash: " + e.message) + logger.warn("Error getting commit hash", e) "no_git_id" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0c4de36d..430dfabc5 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-5.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 58863c22e8d79602f50dc9b667866bdc1e2c1316 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Sat, 13 Jul 2019 23:26:31 -0700 Subject: [PATCH 23/52] Try downgrading fabric --- worldedit-fabric/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index acaa4fb25..f0843a651 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -15,7 +15,7 @@ buildscript { } dependencies { - "classpath"("net.fabricmc:fabric-loom:0.2.4-SNAPSHOT") + "classpath"("net.fabricmc:fabric-loom:0.2.3-SNAPSHOT") "classpath"("org.spongepowered:mixin:0.7.11-SNAPSHOT") } } From 98e29f634fc0cf57181b9147ccc1cc59b3d5976c Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Sun, 14 Jul 2019 00:00:11 -0700 Subject: [PATCH 24/52] Fix fabric output jar --- worldedit-fabric/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index f0843a651..d41010624 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -99,7 +99,7 @@ tasks.register("remapShadowJar") { val shadowJar = tasks.getByName("shadowJar") dependsOn(shadowJar) setInput(shadowJar.archiveFile) - setOutput(shadowJar.archiveFile.get().asFile.getAbsolutePath().replaceFirst("-dev\\.jar$", ".jar")) + setOutput(shadowJar.archiveFile.get().asFile.absolutePath.replace(Regex("-dev\\.jar$"), ".jar")) } tasks.named("assemble").configure { From ad5dcbea5864f4fbc21ae4e66b378e0341a7a9e5 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 15 Jul 2019 09:14:02 -0700 Subject: [PATCH 25/52] Attempt to fix ASM conflict --- buildSrc/build.gradle.kts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 658143d8d..1d1da51c1 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -15,7 +15,11 @@ repositories { configurations.all { resolutionStrategy { // Fabric needs this. - force("commons-io:commons-io:2.5", "org.ow2.asm:asm:7.1") + force( + "commons-io:commons-io:2.5", + "org.ow2.asm:asm:7.1", + "org.ow2.asm:asm-commons:7.1" + ) } } From 5fa311be48e18f24a67f1bc8a12fd36d3133b8c2 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 15 Jul 2019 09:42:28 -0700 Subject: [PATCH 26/52] Account for IntelliJ bug --- worldedit-fabric/build.gradle.kts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index d41010624..7b11f0aca 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -1,5 +1,6 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.fabricmc.loom.task.RemapJarTask +import kotlin.reflect.KClass buildscript { repositories { @@ -95,11 +96,16 @@ artifacts { add("archives", tasks.named("deobfJar")) } -tasks.register("remapShadowJar") { - val shadowJar = tasks.getByName("shadowJar") - dependsOn(shadowJar) - setInput(shadowJar.archiveFile) - setOutput(shadowJar.archiveFile.get().asFile.absolutePath.replace(Regex("-dev\\.jar$"), ".jar")) +// intellij has trouble detecting RemapJarTask as a subclass of Task +@Suppress("UNCHECKED_CAST") +val remapJarIntellijHack = RemapJarTask::class as KClass +tasks.register("remapShadowJar", remapJarIntellijHack) { + (this as RemapJarTask).run { + val shadowJar = tasks.getByName("shadowJar") + dependsOn(shadowJar) + setInput(shadowJar.archiveFile) + setOutput(shadowJar.archiveFile.get().asFile.absolutePath.replace(Regex("-dev\\.jar$"), ".jar")) + } } tasks.named("assemble").configure { From e98b99edcd523e6690a9b5b963fd52b2f310eb9b Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 15 Jul 2019 15:25:17 -0700 Subject: [PATCH 27/52] Properly acquire JUnit 4, drop json-simple --- buildSrc/src/main/kotlin/PlatformConfig.kt | 5 +++++ worldedit-core/build.gradle.kts | 1 - .../sk89q/worldedit/util/paste/EngineHubPaste.java | 13 ++++++++----- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/buildSrc/src/main/kotlin/PlatformConfig.kt b/buildSrc/src/main/kotlin/PlatformConfig.kt index c57dbdd20..e4ab9629a 100644 --- a/buildSrc/src/main/kotlin/PlatformConfig.kt +++ b/buildSrc/src/main/kotlin/PlatformConfig.kt @@ -9,6 +9,7 @@ import org.gradle.api.tasks.javadoc.Javadoc import org.gradle.external.javadoc.CoreJavadocOptions import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.get import org.gradle.kotlin.dsl.getByName import org.gradle.kotlin.dsl.named @@ -38,6 +39,10 @@ fun Project.applyPlatformAndCoreConfiguration() { toolVersion = "7.6.1" } + dependencies { + "testImplementation"("junit:junit:4.12") + } + // Java 8 turns on doclint which we fail tasks.withType().configureEach { (options as CoreJavadocOptions).addStringOption("Xdoclint:none", "-quiet") diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 6a9266247..274cf2e06 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -20,7 +20,6 @@ dependencies { "compile"("com.google.guava:guava:21.0") "compile"("com.google.code.findbugs:jsr305:1.3.9") "compile"("com.google.code.gson:gson:2.8.0") - "compile"("com.googlecode.json-simple:json-simple:1.1.1") "compile"("org.slf4j:slf4j-api:1.7.26") "compileOnly"(project(":worldedit-libs:core:ap")) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java index ac7484846..ab8ebe029 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java @@ -19,8 +19,9 @@ package com.sk89q.worldedit.util.paste; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import com.sk89q.worldedit.util.net.HttpRequest; -import org.json.simple.JSONValue; import java.io.IOException; import java.net.URL; @@ -33,6 +34,8 @@ public class EngineHubPaste implements Paster { private static final Pattern URL_PATTERN = Pattern.compile("https?://.+$"); + private static final Gson GSON = new Gson(); + @Override public Callable paste(String content) { return new PasteTask(content); @@ -59,10 +62,10 @@ public class EngineHubPaste implements Paster { .returnContent() .asString("UTF-8").trim(); - Object object = JSONValue.parse(result); - if (object instanceof Map) { - @SuppressWarnings("unchecked") - String urlString = String.valueOf(((Map) object).get("url")); + Map object = GSON.fromJson(result, new TypeToken>() { + }.getType()); + if (object != null) { + String urlString = String.valueOf(object.get("url")); Matcher m = URL_PATTERN.matcher(urlString); if (m.matches()) { From 429d022752af0951bb53990907c2130a901cfab1 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 15 Jul 2019 16:07:11 -0700 Subject: [PATCH 28/52] Move Core to JUnit 5 --- buildSrc/src/main/kotlin/PlatformConfig.kt | 8 ++++- buildSrc/src/main/kotlin/Versions.kt | 1 + worldedit-bukkit/build.gradle.kts | 4 ++- .../util/commands/CommandContextTest.java | 25 +++++++------ .../transform/BlockTransformExtentTest.java | 18 +++++----- .../command/CommandArgParserTest.java | 4 +-- .../internal/expression/ExpressionTest.java | 35 +++++++++---------- .../sk89q/worldedit/util/LocationTest.java | 8 ++--- .../worldedit/util/eventbus/EventBusTest.java | 4 +-- 9 files changed, 59 insertions(+), 48 deletions(-) diff --git a/buildSrc/src/main/kotlin/PlatformConfig.kt b/buildSrc/src/main/kotlin/PlatformConfig.kt index e4ab9629a..c5deea857 100644 --- a/buildSrc/src/main/kotlin/PlatformConfig.kt +++ b/buildSrc/src/main/kotlin/PlatformConfig.kt @@ -6,6 +6,7 @@ import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.plugins.quality.CheckstyleExtension import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.javadoc.Javadoc +import org.gradle.api.tasks.testing.Test import org.gradle.external.javadoc.CoreJavadocOptions import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure @@ -39,8 +40,13 @@ fun Project.applyPlatformAndCoreConfiguration() { toolVersion = "7.6.1" } + tasks.withType().configureEach { + useJUnitPlatform() + } + dependencies { - "testImplementation"("junit:junit:4.12") + "testImplementation"("org.junit.jupiter:junit-jupiter-api:${Versions.JUNIT}") + "testRuntime"("org.junit.jupiter:junit-jupiter-engine:${Versions.JUNIT}") } // Java 8 turns on doclint which we fail diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 0f79cbfd1..4679c2d40 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -3,4 +3,5 @@ object Versions { const val TEXT_EXTRAS = "3.0.2" const val PISTON = "0.4.2" const val AUTO_VALUE = "1.6.5" + const val JUNIT = "5.5.0" } diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index ee1b94c27..1343ff2be 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -22,7 +22,9 @@ configurations.all { dependencies { "api"(project(":worldedit-core")) "api"(project(":worldedit-libs:bukkit")) - "api"("org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT") + "api"("org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT") { + exclude("junit", "junit") + } "compileOnly"("com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT") "implementation"("io.papermc:paperlib:1.0.2") "compileOnly"("com.sk89q:dummypermscompat:1.10") diff --git a/worldedit-core/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java b/worldedit-core/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java index 555c83889..19bd552ec 100644 --- a/worldedit-core/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java +++ b/worldedit-core/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java @@ -19,19 +19,20 @@ package com.sk89q.minecraft.util.commands; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Arrays; import java.util.HashSet; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; public class CommandContextTest { @@ -39,7 +40,7 @@ public class CommandContextTest { private static final String firstCmdString = "herpderp -opw testers \"mani world\" 'another thing' because something"; CommandContext firstCommand; - @Before + @BeforeEach public void setUpTest() { try { firstCommand = new CommandContext(firstCmdString, new HashSet<>(Arrays.asList('o', 'w'))); @@ -49,10 +50,12 @@ public class CommandContextTest { } } - @Test(expected = CommandException.class) - public void testInvalidFlags() throws CommandException { + @Test + public void testInvalidFlags() { final String failingCommand = "herpderp -opw testers"; - new CommandContext(failingCommand, new HashSet<>(Arrays.asList('o', 'w'))); + assertThrows(CommandException.class, () -> { + new CommandContext(failingCommand, new HashSet<>(Arrays.asList('o', 'w'))); + }); } @Test diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/extent/transform/BlockTransformExtentTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/extent/transform/BlockTransformExtentTest.java index 633e359f8..101509aa4 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/extent/transform/BlockTransformExtentTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/extent/transform/BlockTransformExtentTest.java @@ -19,33 +19,33 @@ package com.sk89q.worldedit.extent.transform; -import static org.junit.Assert.assertEquals; - import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import java.util.HashSet; import java.util.Set; -@Ignore("A platform is currently required to get properties, preventing this test.") +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Disabled("A platform is currently required to get properties, preventing this test.") public class BlockTransformExtentTest { private static final Transform ROTATE_90 = new AffineTransform().rotateY(-90); private static final Transform ROTATE_NEG_90 = new AffineTransform().rotateY(90); private final Set ignored = new HashSet<>(); - @Before - public void setUp() throws Exception { + @BeforeEach + public void setUp() { BlockType.REGISTRY.register("worldedit:test", new BlockType("worldedit:test")); } @Test - public void testTransform() throws Exception { + public void testTransform() { for (BlockType type : BlockType.REGISTRY.values()) { if (ignored.contains(type)) { continue; diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/command/CommandArgParserTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/command/CommandArgParserTest.java index 7c75de4a6..c696bdabb 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/command/CommandArgParserTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/command/CommandArgParserTest.java @@ -21,10 +21,10 @@ package com.sk89q.worldedit.internal.command; import com.google.common.collect.ImmutableList; import com.sk89q.worldedit.internal.util.Substring; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static com.sk89q.worldedit.internal.command.CommandArgParser.spaceSplit; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class CommandArgParserTest { @Test diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java index 28ad67b37..4fe511925 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java @@ -19,16 +19,6 @@ package com.sk89q.worldedit.internal.expression; -import static java.lang.Math.atan2; -import static java.lang.Math.sin; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.platform.Platform; @@ -36,9 +26,18 @@ import com.sk89q.worldedit.internal.expression.lexer.LexerException; import com.sk89q.worldedit.internal.expression.parser.ParserException; import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import static java.lang.Math.atan2; +import static java.lang.Math.sin; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; public class ExpressionTest { - @Before + @BeforeEach public void setup() { Platform mockPlat = Mockito.mock(Platform.class); Mockito.when(mockPlat.getConfiguration()).thenReturn(new LocalConfiguration() { @@ -51,7 +50,7 @@ public class ExpressionTest { @Test public void testEvaluate() throws ExpressionException { - // check + // check assertEquals(1 - 2 + 3, simpleEval("1 - 2 + 3"), 0); // check unary ops @@ -74,7 +73,7 @@ public class ExpressionTest { compile("#"); fail("Error expected"); } catch (LexerException e) { - assertEquals("Error position", 0, e.getPosition()); + assertEquals(0, e.getPosition(), "Error position"); } // test parser errors @@ -82,13 +81,13 @@ public class ExpressionTest { compile("x"); fail("Error expected"); } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); + assertEquals(0, e.getPosition(), "Error position"); } try { compile("x()"); fail("Error expected"); } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); + assertEquals(0, e.getPosition(), "Error position"); } try { compile("("); @@ -104,19 +103,19 @@ public class ExpressionTest { compile("atan2(1)"); fail("Error expected"); } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); + assertEquals(0, e.getPosition(), "Error position"); } try { compile("atan2(1, 2, 3)"); fail("Error expected"); } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); + assertEquals(0, e.getPosition(), "Error position"); } try { compile("rotate(1, 2, 3)"); fail("Error expected"); } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); + assertEquals(0, e.getPosition(), "Error position"); } } diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java index 50dfa649e..2c990ab74 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java @@ -19,12 +19,12 @@ package com.sk89q.worldedit.util; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.world.World; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; /** * Tests {@link Location}. diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/eventbus/EventBusTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/eventbus/EventBusTest.java index 6289301dc..82fdb11c0 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/util/eventbus/EventBusTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/eventbus/EventBusTest.java @@ -19,14 +19,14 @@ package com.sk89q.worldedit.util.eventbus; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class EventBusTest { From 3b157b67c3fb56d26ad800fe3da38386c88db276 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 15 Jul 2019 16:10:50 -0700 Subject: [PATCH 29/52] Move Bukkit to JUnit 5 --- .../sk89q/wepif/DinnerPermsResolverTest.java | 30 +++++++++---------- .../worldedit/bukkit/BukkitWorldTest.java | 7 +++-- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/worldedit-bukkit/src/test/java/com/sk89q/wepif/DinnerPermsResolverTest.java b/worldedit-bukkit/src/test/java/com/sk89q/wepif/DinnerPermsResolverTest.java index e207e7b8d..37deab330 100644 --- a/worldedit-bukkit/src/test/java/com/sk89q/wepif/DinnerPermsResolverTest.java +++ b/worldedit-bukkit/src/test/java/com/sk89q/wepif/DinnerPermsResolverTest.java @@ -19,26 +19,26 @@ package com.sk89q.wepif; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import org.bukkit.Server; import org.bukkit.plugin.PluginManager; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class DinnerPermsResolverTest { private DinnerPermsResolver resolver; - @Before + @BeforeEach public void setUp() { Server server = mock(Server.class); when(server.getPluginManager()).thenReturn(mock(PluginManager.class)); resolver = new DinnerPermsResolver(server); } - + @Test public void testBasicResolving() { final TestOfflinePermissible permissible = new TestOfflinePermissible(); @@ -49,7 +49,7 @@ public class DinnerPermsResolverTest { assertFalse(resolver.hasPermission(permissible, "completely.unrelated")); permissible.clearPermissions(); } - + @Test public void testBasicWildcardResolution() { final TestOfflinePermissible permissible = new TestOfflinePermissible(); @@ -59,7 +59,7 @@ public class DinnerPermsResolverTest { assertTrue(resolver.hasPermission(permissible, "commandbook.spawnmob.spider.skeleton")); permissible.clearPermissions(); } - + @Test public void testNegatingNodes() { final TestOfflinePermissible permissible = new TestOfflinePermissible(); @@ -67,16 +67,16 @@ public class DinnerPermsResolverTest { permissible.setPermission("commandbook.cuteasianboys", false); permissible.setPermission("commandbook.warp.*", false); permissible.setPermission("commandbook.warp.create", true); - + assertTrue(resolver.hasPermission(permissible, "commandbook.motd")); assertFalse(resolver.hasPermission(permissible, "commandbook.cuteasianboys")); assertFalse(resolver.hasPermission(permissible, "commandbook.warp.remove")); assertTrue(resolver.hasPermission(permissible, "commandbook.warp.create")); - + permissible.clearPermissions(); } - - + + @Test public void testInGroup() { final TestOfflinePermissible permissible = new TestOfflinePermissible(); diff --git a/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java b/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java index e6776cf8c..8851fb926 100644 --- a/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java +++ b/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java @@ -20,15 +20,16 @@ package com.sk89q.worldedit.bukkit; import com.sk89q.worldedit.util.TreeGenerator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; public class BukkitWorldTest { @Test public void testTreeTypeMapping() { for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) { - Assert.assertNotNull("No mapping for: " + type, BukkitWorld.toBukkitTreeType(type)); + assertNotNull(BukkitWorld.toBukkitTreeType(type), "No mapping for: " + type); } } From 5c5c822f4b8fc1ba771a85ed868d49632241a861 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 15 Jul 2019 16:19:28 -0700 Subject: [PATCH 30/52] Replace try-fail-catch-assert with assertThrows --- .../internal/expression/ExpressionTest.java | 105 ++++++++---------- 1 file changed, 47 insertions(+), 58 deletions(-) diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java index 4fe511925..5cbb6e7b2 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java @@ -32,9 +32,10 @@ import org.mockito.Mockito; import static java.lang.Math.atan2; import static java.lang.Math.sin; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; public class ExpressionTest { @BeforeEach @@ -67,56 +68,46 @@ public class ExpressionTest { } @Test - public void testErrors() throws ExpressionException { - // test lexer errors - try { - compile("#"); - fail("Error expected"); - } catch (LexerException e) { - assertEquals(0, e.getPosition(), "Error position"); - } - - // test parser errors - try { - compile("x"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals(0, e.getPosition(), "Error position"); - } - try { - compile("x()"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals(0, e.getPosition(), "Error position"); - } - try { - compile("("); - fail("Error expected"); - } catch (ParserException ignored) {} - try { - compile("x("); - fail("Error expected"); - } catch (ParserException ignored) {} - - // test overloader errors - try { - compile("atan2(1)"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals(0, e.getPosition(), "Error position"); - } - try { - compile("atan2(1, 2, 3)"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals(0, e.getPosition(), "Error position"); - } - try { - compile("rotate(1, 2, 3)"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals(0, e.getPosition(), "Error position"); - } + public void testErrors() { + assertAll( + // test lexer errors + () -> { + LexerException e = assertThrows(LexerException.class, + () -> compile("#")); + assertEquals(0, e.getPosition(), "Error position"); + }, + // test parser errors + () -> { + ParserException e = assertThrows(ParserException.class, + () -> compile("x")); + assertEquals(0, e.getPosition(), "Error position"); + }, + () -> { + ParserException e = assertThrows(ParserException.class, + () -> compile("x()")); + assertEquals(0, e.getPosition(), "Error position"); + }, + () -> assertThrows(ParserException.class, + () -> compile("(")), + () -> assertThrows(ParserException.class, + () -> compile("x(")), + // test overloader errors + () -> { + ParserException e = assertThrows(ParserException.class, + () -> compile("atan2(1)")); + assertEquals(0, e.getPosition(), "Error position"); + }, + () -> { + ParserException e = assertThrows(ParserException.class, + () -> compile("atan2(1, 2, 3)")); + assertEquals(0, e.getPosition(), "Error position"); + }, + () -> { + ParserException e = assertThrows(ParserException.class, + () -> compile("rotate(1, 2, 3)")); + assertEquals(0, e.getPosition(), "Error position"); + } + ); } @Test @@ -180,13 +171,11 @@ public class ExpressionTest { } @Test - public void testTimeout() throws Exception { - try { - simpleEval("for(i=0;i<256;i++){for(j=0;j<256;j++){for(k=0;k<256;k++){for(l=0;l<256;l++){ln(pi)}}}}"); - fail("Loop was not stopped."); - } catch (EvaluationException e) { - assertTrue(e.getMessage().contains("Calculations exceeded time limit")); - } + public void testTimeout() { + EvaluationException e = assertThrows(EvaluationException.class, + () -> simpleEval("for(i=0;i<256;i++){for(j=0;j<256;j++){for(k=0;k<256;k++){for(l=0;l<256;l++){ln(pi)}}}}"), + "Loop was not stopped."); + assertTrue(e.getMessage().contains("Calculations exceeded time limit")); } private double simpleEval(String expressionString) throws ExpressionException { From c1f4eecd774c5fd13f69a8364e473d948986dd9b Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Mon, 15 Jul 2019 17:18:10 -0700 Subject: [PATCH 31/52] Narrow timeout test exception type --- .../sk89q/worldedit/internal/expression/ExpressionTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java index 5cbb6e7b2..d26d955d0 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java @@ -26,6 +26,7 @@ import com.sk89q.worldedit.internal.expression.lexer.LexerException; import com.sk89q.worldedit.internal.expression.parser.ParserException; import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment; +import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -172,7 +173,7 @@ public class ExpressionTest { @Test public void testTimeout() { - EvaluationException e = assertThrows(EvaluationException.class, + ExpressionTimeoutException e = assertThrows(ExpressionTimeoutException.class, () -> simpleEval("for(i=0;i<256;i++){for(j=0;j<256;j++){for(k=0;k<256;k++){for(l=0;l<256;l++){ln(pi)}}}}"), "Loop was not stopped."); assertTrue(e.getMessage().contains("Calculations exceeded time limit")); From f75104f2accf733987379d45effb17a63537188d Mon Sep 17 00:00:00 2001 From: wizjany Date: Tue, 16 Jul 2019 19:45:27 -0400 Subject: [PATCH 32/52] Actually use fixed IDs in MCEdit reader. Fixes WORLDEDIT-3947. --- .../extent/clipboard/io/MCEditSchematicReader.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 bcba783a4..f3180df2d 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 @@ -206,6 +206,8 @@ public class MCEditSchematicReader extends NBTSchematicReader { } if (values.isEmpty()) { t = null; + } else { + t = new CompoundTag(values); } if (fixer != null && t != null) { @@ -378,6 +380,10 @@ public class MCEditSchematicReader extends NBTSchematicReader { return "note_block"; case "Structure": return "structure_block"; + case "Chest": + return "chest"; + case "Sign": + return "sign"; default: return id; } From 05cee0a30b305e1bb2a003c71183992a2296e46f Mon Sep 17 00:00:00 2001 From: wizjany Date: Tue, 16 Jul 2019 21:43:14 -0400 Subject: [PATCH 33/52] Don't overwrite history during changes. Fixes issues with some changes not being undone. I mean, the sphere algorithm needs to not set blocks 20 times, but other things can trigger this too. Also allow radius 0 sphere via //sphere (because /br sphere allows it). --- .../sk89q/worldedit/command/GenerationCommands.java | 10 +++++----- .../history/changeset/BlockOptimizedHistory.java | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) 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 4ae72b9d7..9fcfd2c37 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 @@ -162,13 +162,13 @@ public class GenerationCommands { final double radiusX, radiusY, radiusZ; switch (radii.size()) { case 1: - radiusX = radiusY = radiusZ = Math.max(1, radii.get(0)); + radiusX = radiusY = radiusZ = Math.max(0, radii.get(0)); break; case 3: - radiusX = Math.max(1, radii.get(0)); - radiusY = Math.max(1, radii.get(1)); - radiusZ = Math.max(1, radii.get(2)); + radiusX = Math.max(0, radii.get(0)); + radiusY = Math.max(0, radii.get(1)); + radiusZ = Math.max(0, radii.get(2)); break; default: @@ -205,7 +205,7 @@ public class GenerationCommands { @Arg(desc = "The density of the forest, between 0 and 100", def = "5") double density) throws WorldEditException { checkCommandArgument(0 <= density && density <= 100, "Density must be between 0 and 100"); - density = density / 100; + density /= 100; int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type); player.print(affected + " trees created."); return affected; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java index 9c9ad2a85..05ac90c78 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java @@ -55,7 +55,9 @@ public class BlockOptimizedHistory extends ArrayListHistory { if (change instanceof BlockChange) { BlockChange blockChange = (BlockChange) change; BlockVector3 position = blockChange.getPosition(); - previous.add(position, blockChange.getPrevious()); + if (!previous.containsLocation(position)) { + previous.add(position, blockChange.getPrevious()); + } current.add(position, blockChange.getCurrent()); } else { super.add(change); From 1d413cde76e01482409d5dea1d3bb4dc5161bcb2 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Thu, 18 Jul 2019 00:38:59 +1000 Subject: [PATCH 34/52] BrushTool typo --- .../main/java/com/sk89q/worldedit/command/tool/BrushTool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java index 2e324f9ee..e8724208b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java @@ -92,7 +92,7 @@ public class BrushTool implements TraceTool { * @return the mask used to stop block traces */ public @Nullable Mask getTraceMask() { - return mask; + return this.traceMask; } /** From 89753477039e8bec08765c96951c7a81e1d352f2 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Wed, 17 Jul 2019 18:02:45 -0700 Subject: [PATCH 35/52] Fix Forge regen, by retaining the world reference. Also close the world. --- .../com/sk89q/worldedit/forge/ForgeWorld.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java index 6abda18d1..dca8f1c1f 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -96,6 +96,7 @@ import net.minecraft.world.storage.WorldInfo; import javax.annotation.Nullable; import java.io.File; +import java.io.IOException; import java.lang.ref.WeakReference; import java.nio.file.Path; import java.util.Collections; @@ -329,19 +330,22 @@ public class ForgeWorld extends AbstractWorld { MinecraftServer server = originalWorld.getServer(); SaveHandler saveHandler = new SaveHandler(saveFolder, originalWorld.getSaveHandler().getWorldDirectory().getName(), server, server.getDataFixer()); - World freshWorld = new ServerWorld(server, server.getBackgroundExecutor(), saveHandler, originalWorld.getWorldInfo(), - originalWorld.dimension.getType(), originalWorld.getProfiler(), new NoOpChunkStatusListener()); + try (World freshWorld = new ServerWorld(server, server.getBackgroundExecutor(), saveHandler, originalWorld.getWorldInfo(), + originalWorld.dimension.getType(), originalWorld.getProfiler(), new NoOpChunkStatusListener())) { - // Pre-gen all the chunks - // We need to also pull one more chunk in every direction - CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16)); - for (BlockVector2 chunk : expandedPreGen.getChunks()) { - freshWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ()); - } + // Pre-gen all the chunks + // We need to also pull one more chunk in every direction + CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16)); + for (BlockVector2 chunk : expandedPreGen.getChunks()) { + freshWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ()); + } - ForgeWorld from = new ForgeWorld(freshWorld); - for (BlockVector3 vec : region) { - editSession.setBlock(vec, from.getFullBlock(vec)); + ForgeWorld from = new ForgeWorld(freshWorld); + for (BlockVector3 vec : region) { + editSession.setBlock(vec, from.getFullBlock(vec)); + } + } catch (IOException e) { + throw new RuntimeException(e); } } catch (MaxChangedBlocksException e) { throw new RuntimeException(e); From 7b9075c0bfabaf8b9a36efb97cbcb334c0b203ef Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Fri, 19 Jul 2019 21:44:13 +1000 Subject: [PATCH 36/52] Update Fabric to 1.14.4 and fix physics updates --- worldedit-fabric/build.gradle.kts | 6 +++--- .../java/com/sk89q/worldedit/fabric/FabricWorld.java | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index 7b11f0aca..f8cb056eb 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -26,9 +26,9 @@ applyShadowConfiguration() apply(plugin = "fabric-loom") -val minecraftVersion = "1.14.3" -val fabricVersion = "0.3.0+build.187" -val yarnMappings = "1.14.3+build.1" +val minecraftVersion = "1.14.4" +val fabricVersion = "0.3.0+build.200" +val yarnMappings = "1.14.4+build.1" val loaderVersion = "0.4.8+build.155" configurations.all { diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java index 8125fb0cb..afc6cc99e 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java @@ -211,7 +211,12 @@ public class FabricWorld extends AbstractWorld { if (successful && notifyAndLight) { world.getChunkManager().getLightingProvider().enqueueLightUpdate(pos); + world.scheduleBlockRender(pos, old, newState); world.updateListeners(pos, old, newState, UPDATE | NOTIFY); + world.updateNeighbors(pos, newState.getBlock()); + if (old.hasComparatorOutput()) { + world.updateHorizontalAdjacent(pos, newState.getBlock()); + } } return successful; @@ -220,7 +225,9 @@ public class FabricWorld extends AbstractWorld { @Override public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException { BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ()); - getWorld().updateListeners(pos, FabricAdapter.adapt(previousType), getWorld().getBlockState(pos), 1 | 2); + net.minecraft.block.BlockState state = getWorld().getBlockState(pos); + getWorld().updateListeners(pos, FabricAdapter.adapt(previousType), state, 1 | 2); + getWorld().updateNeighbors(pos, state.getBlock()); return true; } From 7c41949f40ce686c834b7a39c7b25fa8dc7c859a Mon Sep 17 00:00:00 2001 From: wizjany Date: Fri, 19 Jul 2019 20:27:27 -0400 Subject: [PATCH 37/52] Update bukkit adapters for 1.14.4. --- .../src/main/resources/worldedit-adapters.jar | Bin 657067 -> 857125 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/worldedit-bukkit/src/main/resources/worldedit-adapters.jar b/worldedit-bukkit/src/main/resources/worldedit-adapters.jar index b940ae841de83467e67a4c60e56ac37cce3aef6c..1dfbc9f9a8037215f08fa2a500dd5a9840d35e02 100644 GIT binary patch delta 155956 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 delta 37746 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 Date: Fri, 19 Jul 2019 21:19:09 -0400 Subject: [PATCH 38/52] Don't load old adapters. --- .../src/main/resources/worldedit-adapters.jar | Bin 857125 -> 857125 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/worldedit-bukkit/src/main/resources/worldedit-adapters.jar b/worldedit-bukkit/src/main/resources/worldedit-adapters.jar index 1dfbc9f9a8037215f08fa2a500dd5a9840d35e02..d1659adf24c493d50954aa4767a0ce884cf8a0fe 100644 GIT binary patch delta 24947 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 VJq-kY*+wca+bH$_eH)R&{2%WIS=9gl delta 24947 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 d>k%+f5Mkx{{XpCFHryh From edb2e919e793470b22631157ec4e8bdda8f034de Mon Sep 17 00:00:00 2001 From: wizjany Date: Fri, 19 Jul 2019 21:45:25 -0400 Subject: [PATCH 39/52] Add more id conversions. Bukkit apparently lower cases these for us, but not Forge. (And invalid block entities are fine - invalid keys are not). --- .../extent/clipboard/io/MCEditSchematicReader.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 f3180df2d..61110ea09 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 @@ -384,6 +384,20 @@ public class MCEditSchematicReader extends NBTSchematicReader { return "chest"; case "Sign": return "sign"; + case "Banner": + return "banner"; + case "Beacon": + return "beacon"; + case "Comparator": + return "comparator"; + case "Dropper": + return "dropper"; + case "Furnace": + return "furnace"; + case "Hopper": + return "hopper"; + case "Skull": + return "skull"; default: return id; } From 5c2b9e4157b322247607b2e175ab30d6c83a02e7 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Mon, 22 Jul 2019 21:18:52 +1000 Subject: [PATCH 40/52] 7.0.1 RC1 --- CHANGELOG.txt | 24 ++++++++++++++++++++++++ gradle.properties | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c49cdaaca..afa6f8601 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,27 @@ +7.0.1 Release Candidate 1 +- Improve //naturalize over large areas +- Fixed //restore with 1.14 worlds +- Added item brush support to WorldEdit for Bukkit (Formerly just Forge) +- Create an internal state ID mapping for performance +- Improve rotation for some blocks +- Added .self permission node to undo/redo to only allow undoing and redoing own history +- Improve sponge schematic implementation +- Re-add the delchunks command +- Added 1.14 blocks, items, tags, etc to the API (Remains compatible with 1.13) +- Made the navigation and selection wands normal tools that can be rebound per-user with //selwand and //navwand +- Added //wand -n to get the navigation wand +- Improved movement of paintings +- Allow command suggestions for selectors +- Allow block replacer to work with tile entities +- Fixed pasting leashed entities +- Fixed setting player heads with names +- Added a mask flag to //count +- Setup pagination for //distr +- Fixed an entity-related error being caused by plugins improperly using Spigot. +- Fixed gravity brush +- Modify chunk batching for performance +- Further legacy schematic loading improvements + 7.0.0 See https://matthewmiller.dev/blog/introducing-worldedit-7/ for a friendlier explanation of some new features diff --git a/gradle.properties b/gradle.properties index a2cc53d8e..d6e9d6737 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ group=com.sk89q.worldedit -version=7.0.1-SNAPSHOT +version=7.0.1-rc1 org.gradle.jvmargs=-Xmx1G From c3e3ae49566708911673a7b1056ebe7e2350ae84 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Mon, 22 Jul 2019 21:19:04 +1000 Subject: [PATCH 41/52] Back to snapshots --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d6e9d6737..a2cc53d8e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ group=com.sk89q.worldedit -version=7.0.1-rc1 +version=7.0.1-SNAPSHOT org.gradle.jvmargs=-Xmx1G From 449b0991f33e794a90f13cb7b0bfe57cd193ac82 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Mon, 22 Jul 2019 21:20:40 +1000 Subject: [PATCH 42/52] Bump to Piston 0.4.3 --- buildSrc/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 4679c2d40..e0c2b4763 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -1,7 +1,7 @@ object Versions { const val TEXT = "3.0.1" const val TEXT_EXTRAS = "3.0.2" - const val PISTON = "0.4.2" + const val PISTON = "0.4.3" const val AUTO_VALUE = "1.6.5" const val JUNIT = "5.5.0" } From a9b3fb14298f6c73073385c7ff87d08da175f590 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Mon, 22 Jul 2019 22:24:45 +1000 Subject: [PATCH 43/52] Fixed tile entity interaction with Fabric --- .../sk89q/worldedit/fabric/FabricWorld.java | 14 +++- .../worldedit/fabric/TileEntityUtils.java | 79 ------------------- 2 files changed, 10 insertions(+), 83 deletions(-) delete mode 100644 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/TileEntityUtils.java diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java index afc6cc99e..93d14b753 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java @@ -202,9 +202,13 @@ public class FabricWorld extends AbstractWorld { CompoundTag tag = ((BaseBlock) block).getNbtData(); if (tag != null) { net.minecraft.nbt.CompoundTag nativeTag = NBTConverter.toNative(tag); - nativeTag.putString("id", ((BaseBlock) block).getNbtId()); - TileEntityUtils.setTileEntity(world, position, nativeTag); - successful = true; // update if TE changed as well + BlockEntity tileEntity = getWorld().getWorldChunk(pos).getBlockEntity(pos); + if (tileEntity != null) { + tileEntity.fromTag(nativeTag); + tileEntity.setPos(pos); + tileEntity.setWorld(world); + successful = true; // update if TE changed as well + } } } } @@ -503,7 +507,9 @@ public class FabricWorld extends AbstractWorld { BlockEntity tile = ((WorldChunk) getWorld().getChunk(pos)).getBlockEntity(pos, WorldChunk.CreationType.CHECK); if (tile != null) { - return getBlock(position).toBaseBlock(NBTConverter.fromNative(TileEntityUtils.copyNbtData(tile))); + net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); + tile.toTag(tag); + return getBlock(position).toBaseBlock(NBTConverter.fromNative(tag)); } else { return getBlock(position).toBaseBlock(); } diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/TileEntityUtils.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/TileEntityUtils.java deleted file mode 100644 index 4faec9d9e..000000000 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/TileEntityUtils.java +++ /dev/null @@ -1,79 +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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.fabric; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.sk89q.worldedit.math.BlockVector3; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.IntTag; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -import javax.annotation.Nullable; - -/** - * Utility methods for setting tile entities in the world. - */ -final class TileEntityUtils { - - private TileEntityUtils() { - } - - /** - * Update the given tag compound with position information. - * - * @param tag the tag - * @param position the position - */ - private static void updateForSet(CompoundTag tag, BlockVector3 position) { - checkNotNull(tag); - checkNotNull(position); - - tag.put("x", new IntTag(position.getBlockX())); - tag.put("y", new IntTag(position.getBlockY())); - tag.put("z", new IntTag(position.getBlockZ())); - } - - /** - * Set a tile entity at the given location using the tile entity ID from - * the tag. - * - * @param world the world - * @param position the position - * @param tag the tag for the tile entity (may be null to do nothing) - */ - static void setTileEntity(World world, BlockVector3 position, @Nullable CompoundTag tag) { - if (tag != null) { - updateForSet(tag, position); - BlockEntity tileEntity = BlockEntity.createFromTag(tag); - if (tileEntity != null) { - world.setBlockEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); - } - } - } - - public static CompoundTag copyNbtData(BlockEntity tile) { - CompoundTag tag = new CompoundTag(); - tile.toTag(tag); - return tag; - } -} From 917f8a18420e30da17e6784a1b20316a6aae35f4 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 29 Jun 2019 17:52:40 -0400 Subject: [PATCH 44/52] Pass through wall improvements This change simplifies the algorithm greatly. Additionally, this fixes a bug where if standing in a non-solid block i.e. a glass pane, //thru, and the nav wand would not work. --- .../platform/AbstractPlayerActor.java | 91 +++++++++++-------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index f51f992ac..c25c33f39 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -394,51 +394,62 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { } } + private boolean canPassThroughBlock(Location curBlock) { + BlockVector3 blockPos = curBlock.toVector().toBlockPoint(); + BlockState block = curBlock.getExtent().getBlock(blockPos); + return !block.getBlockType().getMaterial().isMovementBlocker(); + } + /** - * Get the player's view yaw. - * - * @return yaw + * Advances the block target block until the current block is a wall + * @return true if a wall is found */ - - @Override - public boolean passThroughForwardWall(int range) { - int searchDist = 0; - TargetBlock hitBlox = new TargetBlock(this, range, 0.2); - Extent world = getLocation().getExtent(); - Location block; - boolean firstBlock = true; - int freeToFind = 2; - boolean inFree = false; - - while ((block = hitBlox.getNextBlock()) != null) { - boolean free = !world.getBlock(block.toVector().toBlockPoint()).getBlockType().getMaterial().isMovementBlocker(); - - if (firstBlock) { - firstBlock = false; - - if (!free) { - --freeToFind; - continue; - } - } - - ++searchDist; - if (searchDist > 20) { - return false; - } - - if (inFree != free) { - if (free) { - --freeToFind; - } - } - - if (freeToFind == 0) { - setOnGround(block); + private boolean advanceToWall(TargetBlock hitBlox) { + Location curBlock; + while ((curBlock = hitBlox.getCurrentBlock()) != null) { + if (!canPassThroughBlock(curBlock)) { return true; } - inFree = free; + hitBlox.getNextBlock(); + } + + return false; + } + + /** + * Advances the block target block until the current block is a free + * @return true if a free spot is found + */ + private boolean advanceToFree(TargetBlock hitBlox) { + Location curBlock; + while ((curBlock = hitBlox.getCurrentBlock()) != null) { + if (canPassThroughBlock(curBlock)) { + return true; + } + + hitBlox.getNextBlock(); + } + + return false; + } + + @Override + public boolean passThroughForwardWall(int range) { + TargetBlock hitBlox = new TargetBlock(this, range, 0.2); + + if (!advanceToWall(hitBlox)) { + return false; + } + + if (!advanceToFree(hitBlox)) { + return false; + } + + Location foundBlock = hitBlox.getCurrentBlock(); + if (foundBlock != null) { + setOnGround(foundBlock); + return true; } return false; From e504c29df672c32f2baf851def5647492b2e2297 Mon Sep 17 00:00:00 2001 From: wizjany Date: Tue, 23 Jul 2019 21:41:13 -0400 Subject: [PATCH 45/52] Fix potential race condition. I guess. --- .../main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 977985df7..438c43cbd 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -316,15 +316,16 @@ public class BukkitWorld extends AbstractWorld { @Override public boolean equals(Object other) { - if (worldRef.get() == null) { + final World ref = worldRef.get(); + if (ref == null) { return false; } else if (other == null) { return false; } else if ((other instanceof BukkitWorld)) { World otherWorld = ((BukkitWorld) other).worldRef.get(); - return otherWorld != null && otherWorld.equals(getWorld()); + return ref.equals(otherWorld); } else if (other instanceof com.sk89q.worldedit.world.World) { - return ((com.sk89q.worldedit.world.World) other).getName().equals(getName()); + return ((com.sk89q.worldedit.world.World) other).getName().equals(ref.getName()); } else { return false; } From 8545417b3a4c926d204a8972493ff1a3c83a0ec9 Mon Sep 17 00:00:00 2001 From: wizjany Date: Wed, 10 Jul 2019 18:25:34 -0400 Subject: [PATCH 46/52] Fix error in /up when used out of bounds. Also reduce calls to Entity#getLocation() all over since it's more expensive than it needs to be (adapts world/vector every time). --- .../worldedit/command/BiomeCommands.java | 3 +- .../platform/AbstractPlayerActor.java | 41 +++++++++++++------ .../extension/platform/PlayerProxy.java | 5 +++ .../clipboard/io/SpongeSchematicWriter.java | 5 ++- .../internal/cui/ServerCUIHandler.java | 10 +++-- .../sk89q/worldedit/fabric/FabricPlayer.java | 16 +++++++- .../sk89q/worldedit/forge/ForgePlayer.java | 16 +++++++- .../sk89q/worldedit/sponge/SpongePlayer.java | 12 ++++++ 8 files changed, 86 insertions(+), 22 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index 4e2b714e2..29747852e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -180,7 +180,8 @@ public class BiomeCommands { Mask2D mask2d = mask != null ? mask.toMask2D() : null; if (atPosition) { - region = new CuboidRegion(player.getLocation().toVector().toBlockPoint(), player.getLocation().toVector().toBlockPoint()); + final BlockVector3 pos = player.getLocation().toVector().toBlockPoint(); + region = new CuboidRegion(pos, pos); } else { region = session.getSelection(world); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index f51f992ac..cea7d8d47 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -19,7 +19,10 @@ package com.sk89q.worldedit.extension.platform; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.NotABlockException; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.Extent; @@ -32,6 +35,7 @@ import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TargetBlock; import com.sk89q.worldedit.util.auth.AuthorizationException; +import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; @@ -173,7 +177,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { if (spots == 2) { final BlockVector3 platform = BlockVector3.at(x, y - 2, z); final BlockState block = world.getBlock(platform); - final com.sk89q.worldedit.world.block.BlockType type = block.getBlockType(); + final BlockType type = block.getBlockType(); // Don't get put in lava! if (type == BlockTypes.LAVA) { @@ -259,6 +263,13 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { // Found a ceiling! if (world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) { int platformY = Math.max(initialY, y - 3 - clearance); + if (platformY < initialY) { // if ==, they already have the given clearance, if <, clearance is too large + printError("Not enough space above you!"); + return false; + } else if (platformY == initialY) { + printError("You're already at the ceiling."); + return false; + } floatAt(x, platformY + 1, z, alwaysGlass); return true; } @@ -302,25 +313,27 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public void floatAt(int x, int y, int z, boolean alwaysGlass) { - try { - BlockVector3 spot = BlockVector3.at(x, y - 1, z); - if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) { - getLocation().getExtent().setBlock(spot, BlockTypes.GLASS.getDefaultState()); + BlockVector3 spot = BlockVector3.at(x, y - 1, z); + final World world = (World) getLocation().getExtent(); + if (!world.getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) { + try (EditSession session = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, 1, this)) { + session.setBlock(spot, BlockTypes.GLASS.getDefaultState()); + } catch (MaxChangedBlocksException ignored) { } - } catch (WorldEditException e) { - e.printStackTrace(); } setPosition(Vector3.at(x + 0.5, y, z + 0.5)); } @Override public Location getBlockIn() { - return getLocation().setPosition(getLocation().toVector().floor()); + final Location location = getLocation(); + return location.setPosition(location.toVector().floor()); } @Override public Location getBlockOn() { - return getLocation().setPosition(getLocation().setY(getLocation().getY() - 1).toVector().floor()); + final Location location = getLocation(); + return location.setPosition(location.setY(location.getY() - 1).toVector().floor()); } @Override @@ -369,15 +382,16 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public Direction getCardinalDirection(int yawOffset) { - if (getLocation().getPitch() > 67.5) { + final Location location = getLocation(); + if (location.getPitch() > 67.5) { return Direction.DOWN; } - if (getLocation().getPitch() < -67.5) { + if (location.getPitch() < -67.5) { return Direction.UP; } // From hey0's code - double rot = (getLocation().getYaw() + yawOffset) % 360; //let's use real yaw now + double rot = (location.getYaw() + yawOffset) % 360; //let's use real yaw now if (rot < 0) { rot += 360.0; } @@ -446,7 +460,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public void setPosition(Vector3 pos) { - setPosition(pos, getLocation().getPitch(), getLocation().getYaw()); + final Location location = getLocation(); + setPosition(pos, location.getPitch(), location.getYaw()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java index 8ecf3cc10..120dd47ac 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java @@ -178,4 +178,9 @@ class PlayerProxy extends AbstractPlayerActor { public > void sendFakeBlock(BlockVector3 pos, B block) { basePlayer.sendFakeBlock(pos, block); } + + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + basePlayer.floatAt(x, y, z, alwaysGlass); + } } 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 2ed06cc03..fcc8c8e93 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 @@ -260,8 +260,9 @@ public class SpongeSchematicWriter implements ClipboardWriter { } values.remove("id"); values.put("Id", new StringTag(state.getType().getId())); - values.put("Pos", writeVector(e.getLocation().toVector())); - values.put("Rotation", writeRotation(e.getLocation())); + final Location location = e.getLocation(); + values.put("Pos", writeVector(location.toVector())); + values.put("Rotation", writeRotation(location)); return new CompoundTag(values); }).filter(Objects::nonNull).collect(Collectors.toList()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java index 5a13140db..2ca8f3bd3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java @@ -32,6 +32,7 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; @@ -114,11 +115,12 @@ public class ServerCUIHandler { } // Borrowed this math from FAWE - double rotX = player.getLocation().getYaw(); - double rotY = player.getLocation().getPitch(); + final Location location = player.getLocation(); + double rotX = location.getYaw(); + double rotY = location.getPitch(); double xz = Math.cos(Math.toRadians(rotY)); - int x = (int) (player.getLocation().getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 12); - int z = (int) (player.getLocation().getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 12); + int x = (int) (location.getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 12); + int z = (int) (location.getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 12); int y = Math.max(0, Math.min(Math.min(255, posY + 32), posY + 3)); Map structureTag = new HashMap<>(); diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java index d96e0f81f..2d0681c1b 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java @@ -106,7 +106,7 @@ public class FabricPlayer extends AbstractPlayerActor { } @Override - public com.sk89q.worldedit.world.World getWorld() { + public World getWorld() { return FabricWorldEdit.inst.getWorld(this.player.world); } @@ -188,6 +188,20 @@ public class FabricPlayer extends AbstractPlayerActor { return null; } + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.abilities.allowFlying) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(Vector3.at(x + 0.5, y, z + 0.5)); + if (!player.abilities.flying) { + player.abilities.flying = true; + player.sendAbilitiesUpdate(); + } + } + @Override public > void sendFakeBlock(BlockVector3 pos, B block) { World world = getWorld(); diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index a48ff6256..e55761da3 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -107,7 +107,7 @@ public class ForgePlayer extends AbstractPlayerActor { } @Override - public com.sk89q.worldedit.world.World getWorld() { + public World getWorld() { return ForgeWorldEdit.inst.getWorld(this.player.world); } @@ -189,6 +189,20 @@ public class ForgePlayer extends AbstractPlayerActor { return null; } + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.abilities.allowFlying) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(Vector3.at(x + 0.5, y, z + 0.5)); + if (!player.abilities.isFlying) { + player.abilities.isFlying = true; + player.sendPlayerAbilities(); + } + } + @Override public > void sendFakeBlock(BlockVector3 pos, B block) { World world = getWorld(); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 82723fe93..45fc43000 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -38,6 +38,7 @@ import com.sk89q.worldedit.world.gamemode.GameMode; import com.sk89q.worldedit.world.gamemode.GameModes; import com.sk89q.worldedit.world.item.ItemTypes; import org.spongepowered.api.Sponge; +import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.item.ItemType; @@ -202,6 +203,17 @@ public class SpongePlayer extends AbstractPlayerActor { gameMode.getId()).get()); } + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.get(Keys.CAN_FLY).orElse(false)) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(Vector3.at(x + 0.5, y, z + 0.5)); + player.offer(Keys.IS_FLYING, true); + } + @Override public > void sendFakeBlock(BlockVector3 pos, B block) { org.spongepowered.api.world.Location loc = player.getWorld().getLocation(pos.getX(), pos.getY(), pos.getZ()); From 2cc6a367c623183200ee59b3e6e337315ce67290 Mon Sep 17 00:00:00 2001 From: wizjany Date: Thu, 11 Jul 2019 20:27:05 -0400 Subject: [PATCH 47/52] Move floatAt logic to AbstractPlayer, add isAllowedToFly and setFlying. --- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 13 ++++++------- .../com/sk89q/worldedit/entity/Player.java | 18 ++++++++++++++++++ .../platform/AbstractPlayerActor.java | 16 ++++++++++------ .../sk89q/worldedit/fabric/FabricPlayer.java | 15 +++++++-------- .../com/sk89q/worldedit/forge/ForgePlayer.java | 15 +++++++-------- .../sk89q/worldedit/sponge/SpongePlayer.java | 13 ++++++------- 6 files changed, 54 insertions(+), 36 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index b5cd6bd37..3e12279ea 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -185,14 +185,13 @@ public class BukkitPlayer extends AbstractPlayerActor { } @Override - public void floatAt(int x, int y, int z, boolean alwaysGlass) { - if (alwaysGlass || !player.getAllowFlight()) { - super.floatAt(x, y, z, alwaysGlass); - return; - } + public boolean isAllowedToFly() { + return player.getAllowFlight(); + } - setPosition(Vector3.at(x + 0.5, y, z + 0.5)); - player.setFlying(true); + @Override + public void setFlying(boolean flying) { + player.setFlying(flying); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java index 3673d8842..a51864ee4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java @@ -187,6 +187,24 @@ public interface Player extends Entity, Actor { */ void floatAt(int x, int y, int z, boolean alwaysGlass); + /** + * Check whether the player is allowed to fly. + * + * @return true if allowed flight + */ + default boolean isAllowedToFly() { + return false; + } + + /** + * Set whether the player is currently flying. + * + * @param flying true to fly + */ + default void setFlying(boolean flying) { + throw new UnsupportedOperationException("setFlying unimplemented but isAllowedToFly was true (or unchecked)"); + } + /** * Get the point of the block that is being stood in. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index cea7d8d47..fb70c77ba 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -313,13 +313,17 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public void floatAt(int x, int y, int z, boolean alwaysGlass) { - BlockVector3 spot = BlockVector3.at(x, y - 1, z); - final World world = (World) getLocation().getExtent(); - if (!world.getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) { - try (EditSession session = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, 1, this)) { - session.setBlock(spot, BlockTypes.GLASS.getDefaultState()); - } catch (MaxChangedBlocksException ignored) { + if (alwaysGlass || !isAllowedToFly()) { + BlockVector3 spot = BlockVector3.at(x, y - 1, z); + final World world = getWorld(); + if (!world.getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) { + try (EditSession session = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, 1, this)) { + session.setBlock(spot, BlockTypes.GLASS.getDefaultState()); + } catch (MaxChangedBlocksException ignored) { + } } + } else { + setFlying(true); } setPosition(Vector3.at(x + 0.5, y, z + 0.5)); } diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java index 2d0681c1b..6bd1171d7 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java @@ -189,15 +189,14 @@ public class FabricPlayer extends AbstractPlayerActor { } @Override - public void floatAt(int x, int y, int z, boolean alwaysGlass) { - if (alwaysGlass || !player.abilities.allowFlying) { - super.floatAt(x, y, z, alwaysGlass); - return; - } + public boolean isAllowedToFly() { + return player.abilities.allowFlying; + } - setPosition(Vector3.at(x + 0.5, y, z + 0.5)); - if (!player.abilities.flying) { - player.abilities.flying = true; + @Override + public void setFlying(boolean flying) { + if (player.abilities.flying != flying) { + player.abilities.flying = flying; player.sendAbilitiesUpdate(); } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index e55761da3..94dfb8c10 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -190,15 +190,14 @@ public class ForgePlayer extends AbstractPlayerActor { } @Override - public void floatAt(int x, int y, int z, boolean alwaysGlass) { - if (alwaysGlass || !player.abilities.allowFlying) { - super.floatAt(x, y, z, alwaysGlass); - return; - } + public boolean isAllowedToFly() { + return player.abilities.allowFlying; + } - setPosition(Vector3.at(x + 0.5, y, z + 0.5)); - if (!player.abilities.isFlying) { - player.abilities.isFlying = true; + @Override + public void setFlying(boolean flying) { + if (player.abilities.isFlying != flying) { + player.abilities.isFlying = flying; player.sendPlayerAbilities(); } } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 45fc43000..3a5f94933 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -204,14 +204,13 @@ public class SpongePlayer extends AbstractPlayerActor { } @Override - public void floatAt(int x, int y, int z, boolean alwaysGlass) { - if (alwaysGlass || !player.get(Keys.CAN_FLY).orElse(false)) { - super.floatAt(x, y, z, alwaysGlass); - return; - } + public boolean isAllowedToFly() { + return player.get(Keys.CAN_FLY).orElse(super.isAllowedToFly()); + } - setPosition(Vector3.at(x + 0.5, y, z + 0.5)); - player.offer(Keys.IS_FLYING, true); + @Override + public void setFlying(boolean flying) { + player.offer(Keys.IS_FLYING, flying); } @Override From 4ee2d3b47cef5b17898702f7bc6a031b6b206523 Mon Sep 17 00:00:00 2001 From: wizjany Date: Tue, 16 Jul 2019 22:17:19 -0400 Subject: [PATCH 48/52] Move isAllowedToFly and setFlying to AbstractPlayer, protect them. --- .../com/sk89q/worldedit/entity/Player.java | 18 ------------------ .../platform/AbstractPlayerActor.java | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java index a51864ee4..3673d8842 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java @@ -187,24 +187,6 @@ public interface Player extends Entity, Actor { */ void floatAt(int x, int y, int z, boolean alwaysGlass); - /** - * Check whether the player is allowed to fly. - * - * @return true if allowed flight - */ - default boolean isAllowedToFly() { - return false; - } - - /** - * Set whether the player is currently flying. - * - * @param flying true to fly - */ - default void setFlying(boolean flying) { - throw new UnsupportedOperationException("setFlying unimplemented but isAllowedToFly was true (or unchecked)"); - } - /** * Get the point of the block that is being stood in. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index fb70c77ba..9c9319e58 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -328,6 +328,24 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { setPosition(Vector3.at(x + 0.5, y, z + 0.5)); } + /** + * Check whether the player is allowed to fly. + * + * @return true if allowed flight + */ + protected boolean isAllowedToFly() { + return false; + } + + /** + * Set whether the player is currently flying. + * + * @param flying true to fly + */ + protected void setFlying(boolean flying) { + } + + @Override public Location getBlockIn() { final Location location = getLocation(); From 415cdc0ab2a8f2dd5d1439cf46e8e7a15a53a3ae Mon Sep 17 00:00:00 2001 From: wizjany Date: Wed, 24 Jul 2019 19:05:39 -0400 Subject: [PATCH 49/52] Output to debug only if we have a valid DFU for schematics. Warn for backwards (since we can't DFU) and info for missing DFU (since it might still be compatible). Under normal circumstances, a DFU should be available so we'll only log to debug (which is generally off). --- .../worldedit/extent/clipboard/io/SpongeSchematicReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 865dae6fd..b2deb51f0 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 @@ -111,7 +111,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { } else if (dataVersion < liveDataVersion) { fixer = platform.getDataFixer(); if (fixer != null) { - log.info("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.", + log.debug("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.", dataVersion, liveDataVersion); } else { log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.", From c8cf0d8ba64ced99dbe18063caa7ba80b6cbbd03 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Thu, 25 Jul 2019 19:19:03 -0700 Subject: [PATCH 50/52] [Forge] Update to 1.14.4, pending Forge bugfixes --- worldedit-forge/build.gradle.kts | 9 ++++----- .../java/com/sk89q/worldedit/forge/ForgePlatform.java | 2 +- .../java/com/sk89q/worldedit/forge/ForgeWorld.java | 10 +++++----- .../com/sk89q/worldedit/forge/WorldEditFakePlayer.java | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/worldedit-forge/build.gradle.kts b/worldedit-forge/build.gradle.kts index 235900181..89ae7fc27 100644 --- a/worldedit-forge/build.gradle.kts +++ b/worldedit-forge/build.gradle.kts @@ -11,8 +11,9 @@ plugins { applyPlatformAndCoreConfiguration() applyShadowConfiguration() -val minecraftVersion = "1.14.3" -val forgeVersion = "27.0.13" +val minecraftVersion = "1.14.4" +val mappingsMinecraftVersion = "1.14.3" +val forgeVersion = "28.0.16" configurations.all { resolutionStrategy { @@ -25,14 +26,12 @@ dependencies { "compile"("org.apache.logging.log4j:log4j-slf4j-impl:2.11.2") "minecraft"("net.minecraftforge:forge:$minecraftVersion-$forgeVersion") - - "testCompile"("org.mockito:mockito-core:1.9.0-rc1") } configure { mappings(mapOf( "channel" to "snapshot", - "version" to "20190626-$minecraftVersion" + "version" to "20190724-$mappingsMinecraftVersion" )) runs { diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java index 99ef0103e..93fea255f 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java @@ -35,7 +35,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.PlayerList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SharedConstants; -import net.minecraft.world.ServerWorld; +import net.minecraft.world.server.ServerWorld; import net.minecraftforge.fml.server.ServerLifecycleHooks; import org.enginehub.piston.Command; import org.enginehub.piston.CommandManager; diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java index dca8f1c1f..542cf884c 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -65,13 +65,11 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.ChunkPos; -import net.minecraft.world.ServerWorld; import net.minecraft.world.World; import net.minecraft.world.chunk.AbstractChunkProvider; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkStatus; import net.minecraft.world.chunk.IChunk; -import net.minecraft.world.chunk.ServerChunkProvider; import net.minecraft.world.chunk.listener.IChunkStatusListener; import net.minecraft.world.gen.feature.BigBrownMushroomFeature; import net.minecraft.world.gen.feature.BigMushroomFeatureConfig; @@ -91,6 +89,8 @@ import net.minecraft.world.gen.feature.ShrubFeature; import net.minecraft.world.gen.feature.SwampTreeFeature; import net.minecraft.world.gen.feature.TallTaigaTreeFeature; import net.minecraft.world.gen.feature.TreeFeature; +import net.minecraft.world.server.ServerChunkProvider; +import net.minecraft.world.server.ServerWorld; import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.WorldInfo; @@ -583,15 +583,15 @@ public class ForgeWorld extends AbstractWorld { private static class NoOpChunkStatusListener implements IChunkStatusListener { @Override - public void func_219509_a(ChunkPos chunkPos) { + public void start(ChunkPos chunkPos) { } @Override - public void func_219508_a(ChunkPos chunkPos, @Nullable ChunkStatus chunkStatus) { + public void statusChanged(ChunkPos chunkPos, @Nullable ChunkStatus chunkStatus) { } @Override - public void func_219510_b() { + public void stop() { } } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WorldEditFakePlayer.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WorldEditFakePlayer.java index 53897176e..971179339 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WorldEditFakePlayer.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WorldEditFakePlayer.java @@ -21,7 +21,7 @@ package com.sk89q.worldedit.forge; import com.mojang.authlib.GameProfile; import net.minecraft.inventory.container.INamedContainerProvider; -import net.minecraft.world.ServerWorld; +import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.util.FakePlayer; import javax.annotation.Nullable; From 8f33e0d550fa63365b4cf1f94ebeec677acb4f43 Mon Sep 17 00:00:00 2001 From: wizjany Date: Sat, 27 Jul 2019 00:35:38 -0400 Subject: [PATCH 51/52] Make a bunch of paginations internal, generify command boxes. (#509) --- .../worldedit/command/ChunkCommands.java | 39 ++++++-- .../worldedit/command/SchematicCommands.java | 46 +++++++++- .../worldedit/command/SelectionCommands.java | 66 +++++++++++++- .../worldedit/command/UtilityCommands.java | 3 +- .../worldedit/command/WorldEditCommands.java | 3 +- .../command/util/PrintCommandHelp.java | 19 ++-- .../component/BlockDistributionResult.java | 90 ------------------- .../formatting/component/CommandListBox.java | 8 +- .../formatting/component/CommandUsageBox.java | 16 ++-- .../component/SchematicPaginationBox.java | 75 ---------------- 10 files changed, 170 insertions(+), 195 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/BlockDistributionResult.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SchematicPaginationBox.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java index e9a9e231d..5d5d245d1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java @@ -26,6 +26,7 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.command.util.CommandPermissions; import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.Logging; +import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.internal.anvil.ChunkDeleter; import com.sk89q.worldedit.internal.anvil.ChunkDeletionInfo; @@ -34,6 +35,7 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.formatting.component.PaginationBox; +import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; import com.sk89q.worldedit.util.formatting.text.format.TextColor; @@ -50,8 +52,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.ZonedDateTime; import java.util.ArrayList; +import java.util.List; import java.util.Set; -import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION; @@ -93,11 +95,11 @@ public class ChunkCommands { @CommandPermissions("worldedit.listchunks") public void listChunks(Player player, LocalSession session, @ArgFlag(name = 'p', desc = "Page number.", def = "1") int page) throws WorldEditException { - Set chunks = session.getSelection(player.getWorld()).getChunks(); + final Region region = session.getSelection(player.getWorld()); - PaginationBox paginationBox = PaginationBox.fromStrings("Selected Chunks", "/listchunks -p %page%", - chunks.stream().map(BlockVector2::toString).collect(Collectors.toList())); - player.print(paginationBox.create(page)); + WorldEditAsyncCommandBuilder.createAndSendMessage(player, + () -> new ChunkListPaginationBox(region).create(page), + "Listing chunks for " + player.getName()); } @Command( @@ -134,8 +136,8 @@ public class ChunkCommands { newBatch.backup = true; final Region selection = session.getSelection(player.getWorld()); if (selection instanceof CuboidRegion) { - newBatch.minChunk = BlockVector2.at(selection.getMinimumPoint().getBlockX() >> 4, selection.getMinimumPoint().getBlockZ() >> 4); - newBatch.maxChunk = BlockVector2.at(selection.getMaximumPoint().getBlockX() >> 4, selection.getMaximumPoint().getBlockZ() >> 4); + newBatch.minChunk = selection.getMinimumPoint().shr(4).toBlockVector2(); + newBatch.maxChunk = selection.getMaximumPoint().shr(4).toBlockVector2(); } else { // this has a possibility to OOM for very large selections still Set chunks = selection.getChunks(); @@ -168,4 +170,27 @@ public class ChunkCommands { .clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/stop")))); } + private static class ChunkListPaginationBox extends PaginationBox { + //private final Region region; + private final List chunks; + + ChunkListPaginationBox(Region region) { + super("Selected Chunks", "/listchunks -p %page%"); + // TODO make efficient/streamable/calculable implementations of this + // for most region types, so we can just store the region and random-access get one page of chunks + // (this is non-trivial for some types of selections...) + //this.region = region.clone(); + this.chunks = new ArrayList<>(region.getChunks()); + } + + @Override + public Component getComponent(int number) { + return TextComponent.of(chunks.get(number).toString()); + } + + @Override + public int getComponentsSize() { + return chunks.size(); + } + } } 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 47f3daf9e..a2b59ffbd 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 @@ -19,6 +19,8 @@ package com.sk89q.worldedit.command; +import com.google.common.collect.Multimap; +import com.google.common.io.Files; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; @@ -42,10 +44,10 @@ import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.formatting.component.CodeFormat; import com.sk89q.worldedit.util.formatting.component.ErrorFormat; import com.sk89q.worldedit.util.formatting.component.PaginationBox; -import com.sk89q.worldedit.util.formatting.component.SchematicPaginationBox; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; +import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.util.io.Closer; import com.sk89q.worldedit.util.io.file.FilenameException; @@ -68,7 +70,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; +import java.util.regex.Pattern; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; /** @@ -404,4 +408,44 @@ public class SchematicCommands { } return fileList; } + + private static class SchematicPaginationBox extends PaginationBox { + private final String prefix; + private final File[] files; + + SchematicPaginationBox(String rootDir, File[] files, String pageCommand) { + super("Available schematics", pageCommand); + this.prefix = rootDir == null ? "" : rootDir; + this.files = files; + } + + @Override + public Component getComponent(int number) { + checkArgument(number < files.length && number >= 0); + File file = files[number]; + Multimap exts = ClipboardFormats.getFileExtensionMap(); + String format = exts.get(Files.getFileExtension(file.getName())) + .stream().findFirst().map(ClipboardFormat::getName).orElse("Unknown"); + boolean inRoot = file.getParentFile().getName().equals(prefix); + + String path = inRoot ? file.getName() : file.getPath().split(Pattern.quote(prefix + File.separator))[1]; + + return TextComponent.builder() + .content("") + .append(TextComponent.of("[L]") + .color(TextColor.GOLD) + .clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/schem load " + path)) + .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to load")))) + .append(TextComponent.space()) + .append(TextComponent.of(path) + .color(TextColor.DARK_GREEN) + .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of(format)))) + .build(); + } + + @Override + public int getComponentsSize() { + return files.length; + } + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index d0dd6ef5a..88285e475 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.command; +import com.google.common.base.Strings; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; @@ -56,16 +57,19 @@ import com.sk89q.worldedit.regions.selector.SphereRegionSelector; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.formatting.component.BlockDistributionResult; import com.sk89q.worldedit.util.formatting.component.CommandListBox; +import com.sk89q.worldedit.util.formatting.component.InvalidComponentException; import com.sk89q.worldedit.util.formatting.component.PaginationBox; import com.sk89q.worldedit.util.formatting.component.SubtleFormat; import com.sk89q.worldedit.util.formatting.component.TextComponentProducer; +import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; +import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.storage.ChunkStore; @@ -570,7 +574,7 @@ public class SelectionCommands { } case LIST: default: - CommandListBox box = new CommandListBox("Selection modes", null); + CommandListBox box = new CommandListBox("Selection modes", null, null); box.setHidingHelp(true); TextComponentProducer contents = box.getContents(); contents.append(SubtleFormat.wrap("Select one of the modes below:")).newline(); @@ -608,4 +612,62 @@ public class SelectionCommands { session.dispatchCUISelection(player); } + private static class BlockDistributionResult extends PaginationBox { + + private final List> distribution; + private final int totalBlocks; + private final boolean separateStates; + + BlockDistributionResult(List> distribution, boolean separateStates) { + super("Block Distribution", "//distr -p %page%" + (separateStates ? " -d" : "")); + this.distribution = distribution; + // note: doing things like region.getArea is inaccurate for non-cuboids. + this.totalBlocks = distribution.stream().mapToInt(Countable::getAmount).sum(); + this.separateStates = separateStates; + setComponentsPerPage(7); + } + + @Override + public Component getComponent(int number) { + Countable c = distribution.get(number); + TextComponent.Builder line = TextComponent.builder(); + + final int count = c.getAmount(); + + final double perc = count / (double) totalBlocks * 100; + final int maxDigits = (int) (Math.log10(totalBlocks) + 1); + final int curDigits = (int) (Math.log10(count) + 1); + line.append(String.format("%s%.3f%% ", perc < 10 ? " " : "", perc), TextColor.GOLD); + final int space = maxDigits - curDigits; + String pad = Strings.repeat(" ", space == 0 ? 2 : 2 * space + 1); + line.append(String.format("%s%s", count, pad), TextColor.YELLOW); + + final BlockState state = c.getID(); + final BlockType blockType = state.getBlockType(); + TextComponent blockName = TextComponent.of(blockType.getName(), TextColor.LIGHT_PURPLE); + TextComponent toolTip; + if (separateStates && state != blockType.getDefaultState()) { + toolTip = TextComponent.of(state.getAsString(), TextColor.GRAY); + blockName = blockName.append(TextComponent.of("*", TextColor.LIGHT_PURPLE)); + } else { + toolTip = TextComponent.of(blockType.getId(), TextColor.GRAY); + } + blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip)); + line.append(blockName); + + return line.build(); + } + + @Override + public int getComponentsSize() { + return distribution.size(); + } + + @Override + public Component create(int page) throws InvalidComponentException { + super.getContents().append(TextComponent.of("Total Block Count: " + totalBlocks, TextColor.GRAY)) + .append(TextComponent.newline()); + return super.create(page); + } + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 76e5d441e..9d3765943 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -523,7 +523,8 @@ public class UtilityCommands { int page, @Arg(desc = "The command to retrieve help for", def = "", variable = true) List command) throws WorldEditException { - PrintCommandHelp.help(command, page, listSubCommands, we, actor); + PrintCommandHelp.help(command, page, listSubCommands, + we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "//help"); } } 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 02ab382a4..25329885a 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 @@ -164,6 +164,7 @@ public class WorldEditCommands { int page, @Arg(desc = "The command to retrieve help for", def = "", variable = true) List command) throws WorldEditException { - PrintCommandHelp.help(command, page, listSubCommands, we, actor); + PrintCommandHelp.help(command, page, listSubCommands, + we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "/worldedit help"); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/PrintCommandHelp.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/PrintCommandHelp.java index ad7dad226..dc3e97865 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/PrintCommandHelp.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/PrintCommandHelp.java @@ -67,11 +67,11 @@ public class PrintCommandHelp { return mapping.orElse(null); } - public static void help(List commandPath, int page, boolean listSubCommands, WorldEdit we, Actor actor) throws InvalidComponentException { - CommandManager manager = we.getPlatformManager().getPlatformCommandManager().getCommandManager(); + public static void help(List commandPath, int page, boolean listSubCommands, + CommandManager manager, Actor actor, String helpRootCommand) throws InvalidComponentException { if (commandPath.isEmpty()) { - printCommands(page, manager.getAllCommands(), actor, ImmutableList.of()); + printCommands(page, manager.getAllCommands(), actor, ImmutableList.of(), helpRootCommand); return; } @@ -93,7 +93,7 @@ public class PrintCommandHelp { toCommandString(visited), subCommand)); // full help for single command CommandUsageBox box = new CommandUsageBox(visited, visited.stream() - .map(Command::getName).collect(Collectors.joining(" "))); + .map(Command::getName).collect(Collectors.joining(" ")), helpRootCommand); actor.print(box.create()); return; } @@ -105,7 +105,7 @@ public class PrintCommandHelp { actor.printError(String.format("The sub-command '%s' under '%s' could not be found.", subCommand, toCommandString(visited))); // list subcommands for currentCommand - printCommands(page, getSubCommands(Iterables.getLast(visited)).values().stream(), actor, visited); + printCommands(page, getSubCommands(Iterables.getLast(visited)).values().stream(), actor, visited, helpRootCommand); return; } } @@ -114,10 +114,10 @@ public class PrintCommandHelp { if (subCommands.isEmpty() || !listSubCommands) { // Create the message - CommandUsageBox box = new CommandUsageBox(visited, toCommandString(visited)); + CommandUsageBox box = new CommandUsageBox(visited, toCommandString(visited), helpRootCommand); actor.print(box.create()); } else { - printCommands(page, subCommands.values().stream(), actor, visited); + printCommands(page, subCommands.values().stream(), actor, visited, helpRootCommand); } } @@ -126,7 +126,7 @@ public class PrintCommandHelp { } private static void printCommands(int page, Stream commandStream, Actor actor, - List commandList) throws InvalidComponentException { + List commandList, String helpRootCommand) throws InvalidComponentException { // Get a list of aliases List commands = commandStream .sorted(byCleanName()) @@ -135,7 +135,8 @@ public class PrintCommandHelp { String used = commandList.isEmpty() ? null : toCommandString(commandList); CommandListBox box = new CommandListBox( (used == null ? "Help" : "Subcommands: " + used), - "//help -s -p %page%" + (used == null ? "" : " " + used)); + helpRootCommand + " -s -p %page%" + (used == null ? "" : " " + used), + helpRootCommand); if (!actor.isPlayer()) { box.formatForConsole(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/BlockDistributionResult.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/BlockDistributionResult.java deleted file mode 100644 index 797557a52..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/BlockDistributionResult.java +++ /dev/null @@ -1,90 +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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util.formatting.component; - -import com.google.common.base.Strings; -import com.sk89q.worldedit.util.Countable; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TextComponent; -import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; -import com.sk89q.worldedit.util.formatting.text.format.TextColor; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockType; - -import java.util.List; - -public class BlockDistributionResult extends PaginationBox { - - private final List> distribution; - private final int totalBlocks; - private final boolean separateStates; - - public BlockDistributionResult(List> distribution, boolean separateStates) { - super("Block Distribution", "//distr -p %page%" + (separateStates ? " -d" : "")); - this.distribution = distribution; - // note: doing things like region.getArea is inaccurate for non-cuboids. - this.totalBlocks = distribution.stream().mapToInt(Countable::getAmount).sum(); - this.separateStates = separateStates; - setComponentsPerPage(7); - } - - @Override - public Component getComponent(int number) { - Countable c = distribution.get(number); - TextComponent.Builder line = TextComponent.builder(); - - final int count = c.getAmount(); - - final double perc = count / (double) totalBlocks * 100; - final int maxDigits = (int) (Math.log10(totalBlocks) + 1); - final int curDigits = (int) (Math.log10(count) + 1); - line.append(String.format("%s%.3f%% ", perc < 10 ? " " : "", perc), TextColor.GOLD); - final int space = maxDigits - curDigits; - String pad = Strings.repeat(" ", space == 0 ? 2 : 2 * space + 1); - line.append(String.format("%s%s", count, pad), TextColor.YELLOW); - - final BlockState state = c.getID(); - final BlockType blockType = state.getBlockType(); - TextComponent blockName = TextComponent.of(blockType.getName(), TextColor.LIGHT_PURPLE); - TextComponent toolTip; - if (separateStates && state != blockType.getDefaultState()) { - toolTip = TextComponent.of(state.getAsString(), TextColor.GRAY); - blockName = blockName.append(TextComponent.of("*", TextColor.LIGHT_PURPLE)); - } else { - toolTip = TextComponent.of(blockType.getId(), TextColor.GRAY); - } - blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip)); - line.append(blockName); - - return line.build(); - } - - @Override - public int getComponentsSize() { - return distribution.size(); - } - - @Override - public Component create(int page) throws InvalidComponentException { - super.getContents().append(TextComponent.of("Total Block Count: " + totalBlocks, TextColor.GRAY)) - .append(TextComponent.newline()); - return super.create(page); - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java index fd579c6fb..2efc8b7b3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java @@ -32,14 +32,16 @@ public class CommandListBox extends PaginationBox { private List commands = Lists.newArrayList(); private boolean hideHelp; + private String helpCommand; /** * Create a new box. * * @param title the title */ - public CommandListBox(String title, String pageCommand) { + public CommandListBox(String title, String pageCommand, String helpCommand) { super(title, pageCommand); + this.helpCommand = helpCommand; } @Override @@ -72,7 +74,7 @@ public class CommandListBox extends PaginationBox { this.hideHelp = hideHelp; } - private static class CommandEntry { + private class CommandEntry { private final String alias; private final Component description; private final String insertion; @@ -87,7 +89,7 @@ public class CommandListBox extends PaginationBox { TextComponentProducer line = new TextComponentProducer(); if (!hideHelp) { line.append(SubtleFormat.wrap("? ") - .clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "//help " + insertion)) + .clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, CommandListBox.this.helpCommand + " " + insertion)) .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Additional Help")))); } TextComponent command = TextComponent.of(alias, TextColor.GOLD); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java index e8abe0e38..579bd44a9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java @@ -45,9 +45,10 @@ public class CommandUsageBox extends TextComponentProducer { * * @param commands the commands to describe * @param commandString the commands that were used, such as "/we" or "/brush sphere" + * @param helpRootCommand the command used to get subcommand help */ - public CommandUsageBox(List commands, String commandString) throws InvalidComponentException { - this(commands, commandString, null); + public CommandUsageBox(List commands, String commandString, String helpRootCommand) throws InvalidComponentException { + this(commands, commandString, helpRootCommand, null); } /** @@ -55,15 +56,18 @@ public class CommandUsageBox extends TextComponentProducer { * * @param commands the commands to describe * @param commandString the commands that were used, such as "/we" or "/brush sphere" + * @param helpRootCommand the command used to get subcommand help * @param parameters list of parameters to use */ - public CommandUsageBox(List commands, String commandString, @Nullable CommandParameters parameters) throws InvalidComponentException { + public CommandUsageBox(List commands, String commandString, String helpRootCommand, + @Nullable CommandParameters parameters) throws InvalidComponentException { checkNotNull(commands); checkNotNull(commandString); - attachCommandUsage(commands, commandString); + checkNotNull(helpRootCommand); + attachCommandUsage(commands, commandString, helpRootCommand); } - private void attachCommandUsage(List commands, String commandString) { + private void attachCommandUsage(List commands, String commandString, String helpRootCommand) { TextComponentProducer boxContent = new TextComponentProducer() .append(HelpGenerator.create(commands).getFullHelp()); if (getSubCommands(Iterables.getLast(commands)).size() > 0) { @@ -73,7 +77,7 @@ public class CommandUsageBox extends TextComponentProducer { .append(TextComponent.builder("List Subcommands") .color(ColorConfig.getMainText()) .decoration(TextDecoration.ITALIC, true) - .clickEvent(ClickEvent.runCommand("//help -s " + commandString)) + .clickEvent(ClickEvent.runCommand(helpRootCommand + " -s " + commandString)) .hoverEvent(HoverEvent.showText(TextComponent.of("List all subcommands of this command"))) .build()) .build()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SchematicPaginationBox.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SchematicPaginationBox.java deleted file mode 100644 index ae052d137..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SchematicPaginationBox.java +++ /dev/null @@ -1,75 +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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util.formatting.component; - -import com.google.common.collect.Multimap; -import com.google.common.io.Files; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; -import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TextComponent; -import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; -import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; -import com.sk89q.worldedit.util.formatting.text.format.TextColor; - -import java.io.File; -import java.util.regex.Pattern; - -import static com.google.common.base.Preconditions.checkArgument; - -public class SchematicPaginationBox extends PaginationBox { - private final String prefix; - private final File[] files; - - public SchematicPaginationBox(String rootDir, File[] files, String pageCommand) { - super("Available schematics", pageCommand); - this.prefix = rootDir == null ? "" : rootDir; - this.files = files; - } - - @Override - public Component getComponent(int number) { - checkArgument(number < files.length && number >= 0); - File file = files[number]; - Multimap exts = ClipboardFormats.getFileExtensionMap(); - String format = exts.get(Files.getFileExtension(file.getName())) - .stream().findFirst().map(ClipboardFormat::getName).orElse("Unknown"); - boolean inRoot = file.getParentFile().getName().equals(prefix); - - String path = inRoot ? file.getName() : file.getPath().split(Pattern.quote(prefix + File.separator))[1]; - - return TextComponent.builder() - .content("") - .append(TextComponent.of("[L]") - .color(TextColor.GOLD) - .clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/schem load " + path)) - .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to load")))) - .append(TextComponent.space()) - .append(TextComponent.of(path) - .color(TextColor.DARK_GREEN) - .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of(format)))) - .build(); - } - - @Override - public int getComponentsSize() { - return files.length; - } -} From 0f420f02ff112b5a4d05a4a22d8358b079acfc8c Mon Sep 17 00:00:00 2001 From: wizjany Date: Sat, 27 Jul 2019 11:45:09 -0400 Subject: [PATCH 52/52] Fix some load-order issues probably. Edge cases might still exist around plugins which use WE for initial world-gen, or in general plugins that try to access the platform before it's ready. --- .../worldedit/bukkit/WorldEditPlugin.java | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 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 a81aab7c5..e4fb3ea8c 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 @@ -96,7 +96,6 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter { private static final Logger log = LoggerFactory.getLogger(WorldEditPlugin.class); public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui"; private static WorldEditPlugin INSTANCE; - private static WorldInitListener worldInitListener = null; private BukkitImplAdapter bukkitAdapter; private BukkitServerInterface server; @@ -139,22 +138,19 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter { getServer().getPluginManager().registerEvents(new AsyncTabCompleteListener(), this); } - // register this so we can load world-dependent data right as the first world is loading - if (worldInitListener != null) { + initializeRegistries(); // this creates the objects matching Bukkit's enums - but doesn't fill them with data yet + if (Bukkit.getWorlds().isEmpty()) { + setupPreWorldData(); + // register this so we can load world-dependent data right as the first world is loading + getServer().getPluginManager().registerEvents(new WorldInitListener(), this); + } else { getLogger().warning("Server reload detected. This may cause various issues with WorldEdit and dependent plugins."); try { - // these don't stick around between reload - loadAdapter(); - loadConfig(); - WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); + setupPreWorldData(); + // since worlds are loaded already, we can do this now + setupWorldData(); } catch (Throwable ignored) { } - } else { - getServer().getPluginManager().registerEvents((worldInitListener = new WorldInitListener()), this); - loadAdapter(); // Need an adapter to work with special blocks with NBT data - setupRegistries(); - WorldEdit.getInstance().loadMappings(); - loadConfig(); // Load configuration } // Enable metrics @@ -162,12 +158,19 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter { PaperLib.suggestPaper(this); } + private void setupPreWorldData() { + loadAdapter(); + loadConfig(); + WorldEdit.getInstance().loadMappings(); + } + private void setupWorldData() { - setupTags(); + setupTags(); // datapacks aren't loaded until just before the world is, and bukkit has no event for this + // so the earliest we can do this is in WorldInit WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); } - private void setupRegistries() { + private void initializeRegistries() { // Biome for (Biome biome : Biome.values()) { String lowerCaseBiomeName = biome.name().toLowerCase(Locale.ROOT); @@ -487,9 +490,9 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter { if (!event.isCommand()) return; String buffer = event.getBuffer(); - final String[] parts = buffer.split(" "); - if (parts.length < 1) return; - final String label = parts[0]; + int firstSpace = buffer.indexOf(' '); + if (firstSpace < 0) return; + final String label = buffer.substring(0, firstSpace); final Optional command = WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().getCommand(label); if (!command.isPresent()) return;