Revert "Revert matt's changes"

This reverts commit bfcc6184ad.
This commit is contained in:
IronApollo 2020-06-13 14:41:36 -04:00
parent bfcc6184ad
commit 238c56a3c6
75 changed files with 980 additions and 687 deletions

View File

@ -7,7 +7,7 @@ New contributions must be licensed under:
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@ -180,7 +180,7 @@ WorldEdit as a whole is licensed under:
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

View File

@ -1,8 +1,8 @@
import org.gradle.api.Project
object Versions {
const val TEXT = "3.0.3"
const val TEXT_EXTRAS = "3.0.3"
const val TEXT = "3.0.4"
const val TEXT_EXTRAS = "3.0.5"
const val PISTON = "0.5.5"
const val AUTO_VALUE = "1.7"
const val JUNIT = "5.6.1"

View File

@ -73,6 +73,7 @@
<allow pkg="org.spongepowered.api" />
<allow pkg="com.mojang.brigadier" />
<allow pkg="com.mojang.datafixers" />
<allow pkg="org.apache.commons" />
</subpackage>
<subpackage name="fabric">

View File

@ -128,6 +128,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
public int getSkyLight(int x, int y, int z) {
int layer = y >> 4;
if (skyLight[layer] == null) {
//getDataLayerData
skyLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(SectionPosition.a(nmsChunk.getPos(), layer));
}
long l = BlockPosition.a(x, y, z);
@ -138,6 +139,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
public int getEmmittedLight(int x, int y, int z) {
int layer = y >> 4;
if (blockLight[layer] == null) {
//getDataLayerData
blockLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(SectionPosition.a(nmsChunk.getPos(), layer));
}
long l = BlockPosition.a(x, y, z);

View File

@ -20,11 +20,6 @@
package com.sk89q.bukkit.util;
import com.sk89q.util.ReflectionUtil;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -33,6 +28,12 @@ import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CommandRegistration {
static {
@ -61,6 +62,7 @@ public class CommandRegistration {
}
return null;
}
public boolean register(List<CommandInfo> registered) {
CommandMap commandMap = getCommandMap();
if (registered == null || commandMap == null) {
@ -82,6 +84,7 @@ public class CommandRegistration {
if (fallbackCommands != null) {
return fallbackCommands;
}
CommandMap commandMap = ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap");
if (commandMap == null) {
Bukkit.getServer().getLogger().severe(plugin.getDescription().getName() +

View File

@ -31,7 +31,7 @@ import java.nio.charset.StandardCharsets;
*/
public class CUIChannelListener implements PluginMessageListener {
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
public static final Charset UTF_8_CHARSET = StandardCharsets.UTF_8;
private final WorldEditPlugin plugin;
public CUIChannelListener(WorldEditPlugin plugin) {

View File

@ -117,27 +117,6 @@ public class FaweAPI {
// return parser != null;
// }
public static <T> T getParser(Class<T> parserClass) {
try {
Field field = AbstractFactory.class.getDeclaredField("parsers");
field.setAccessible(true);
ArrayList<InputParser> parsers = new ArrayList<>();
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getMaskFactory()));
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getBlockFactory()));
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getItemFactory()));
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getPatternFactory()));
for (InputParser parser : parsers) {
if (parserClass.isAssignableFrom(parser.getClass())) {
return (T) parser;
}
}
return null;
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* You can either use a IQueueExtent or an EditSession to change blocks<br>
* - The IQueueExtent skips a bit of overhead so it's marginally faster<br>

View File

@ -50,7 +50,7 @@ public class AsyncPreloader implements Preloader, Runnable {
MutablePair<World, Set<BlockVector2>> existing = cancelAndGet(player);
try {
Region region = session.getSelection(world);
if (!(region instanceof CuboidRegion) || region.getArea() > 50466816) {
if (!(region instanceof CuboidRegion) || region.getVolume() > 50466816) {
// TOO LARGE or NOT CUBOID
return;
}

View File

@ -428,7 +428,7 @@ public class NMSRelighter implements Relighter {
}
}
for (int y = 255; y > 0; y--) {
for (RelightSkyEntry chunk : chunks) { // Propogate skylight
for (RelightSkyEntry chunk : chunks) { // Propagate skylight
int layer = y >> 4;
byte[] mask = chunk.mask;
if ((y & 15) == 15 && chunk.fix[layer] != SkipReason.NONE) {
@ -596,7 +596,7 @@ public class NMSRelighter implements Relighter {
}
}
private class RelightSkyEntry implements Comparable {
private class RelightSkyEntry implements Comparable<RelightSkyEntry> {
public final int x;
public final int z;
public final byte[] mask;
@ -625,18 +625,17 @@ public class NMSRelighter implements Relighter {
}
@Override
public int compareTo(Object o) {
RelightSkyEntry other = (RelightSkyEntry) o;
if (other.x < x) {
public int compareTo(RelightSkyEntry o) {
if (o.x < x) {
return 1;
}
if (other.x > x) {
if (o.x > x) {
return -1;
}
if (other.z < z) {
if (o.z < z) {
return 1;
}
if (other.z > z) {
if (o.z > z) {
return -1;
}
return 0;

View File

@ -52,7 +52,7 @@ public class LimitExtent extends PassthroughExtent {
@Override
public List<? extends Entity> getEntities(Region region) {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
try {
return getExtent().getEntities(region);
} catch (FaweException e) {
@ -223,8 +223,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public void addCaves(Region region) throws WorldEditException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
getExtent().addCaves(region);
} catch (FaweException e) {
@ -236,8 +236,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public void generate(Region region, GenBase gen) throws WorldEditException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
getExtent().generate(region, gen);
} catch (FaweException e) {
@ -249,8 +249,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
getExtent().addSchems(region, mask, clipboards, rarity, rotate);
} catch (FaweException e) {
@ -262,8 +262,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
getExtent().spawnResource(region, gen, rarity, frequency);
} catch (FaweException e) {
@ -275,8 +275,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
getExtent().addOre(region, mask, material, size, frequency, rarity, minY, maxY);
} catch (FaweException e) {
@ -288,8 +288,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public void addOres(Region region, Mask mask) throws WorldEditException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
getExtent().addOres(region, mask);
} catch (FaweException e) {
@ -301,7 +301,7 @@ public class LimitExtent extends PassthroughExtent {
@Override
public List<Countable<BlockType>> getBlockDistribution(Region region) {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
try {
return getExtent().getBlockDistribution(region);
} catch (FaweException e) {
@ -314,7 +314,7 @@ public class LimitExtent extends PassthroughExtent {
@Override
public List<Countable<BlockState>> getBlockDistributionWithData(Region region) {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
try {
return getExtent().getBlockDistributionWithData(region);
} catch (FaweException e) {
@ -327,7 +327,7 @@ public class LimitExtent extends PassthroughExtent {
@Override
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
try {
return getExtent().countBlocks(region, searchBlocks);
} catch (FaweException e) {
@ -340,7 +340,7 @@ public class LimitExtent extends PassthroughExtent {
@Override
public int countBlocks(Region region, Mask searchMask) {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
try {
return getExtent().countBlocks(region, searchMask);
} catch (FaweException e) {
@ -353,7 +353,7 @@ public class LimitExtent extends PassthroughExtent {
@Override
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
return getExtent().setBlocks(region, block);
} catch (FaweException e) {
@ -366,7 +366,7 @@ public class LimitExtent extends PassthroughExtent {
@Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
return getExtent().setBlocks(region, pattern);
} catch (FaweException e) {
@ -379,8 +379,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BaseBlock> filter, B replacement) throws MaxChangedBlocksException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
return getExtent().replaceBlocks(region, filter, replacement);
} catch (FaweException e) {
@ -393,8 +393,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
return getExtent().replaceBlocks(region, filter, pattern);
} catch (FaweException e) {
@ -407,8 +407,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
return getExtent().replaceBlocks(region, mask, pattern);
} catch (FaweException e) {
@ -421,8 +421,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
return getExtent().center(region, pattern);
} catch (FaweException e) {
@ -448,8 +448,8 @@ public class LimitExtent extends PassthroughExtent {
@Override
public <T extends Filter> T apply(Region region, T filter, boolean full) {
limit.THROW_MAX_CHECKS(region.getArea());
limit.THROW_MAX_CHANGES(region.getArea());
limit.THROW_MAX_CHECKS(region.getVolume());
limit.THROW_MAX_CHANGES(region.getVolume());
try {
return getExtent().apply(region, filter, full);
} catch (FaweException e) {

View File

@ -151,10 +151,6 @@ public abstract class QueueHandler implements Trimable, Runnable {
return forkJoinPoolPrimary.submit(call);
}
public <T> Future<T> sync(Runnable run, T value) {
return sync(run, value, syncTasks);
}
public <T> Future<T> sync(Runnable run) {
return sync(run, syncTasks);
}

View File

@ -1,22 +1,3 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.boydti.fawe.function.mask;
import com.sk89q.worldedit.extent.Extent;

View File

@ -1,22 +1,3 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.boydti.fawe.function.mask;
import com.sk89q.worldedit.extent.Extent;

View File

@ -9,6 +9,10 @@ public class XAxisMask extends AbstractMask implements ResettableMask {
private transient int layer = -1;
public XAxisMask(Extent extent) {
}
@Override
public boolean test(Extent extent, BlockVector3 vector) {
if (layer == -1) {

View File

@ -9,6 +9,9 @@ public class YAxisMask extends AbstractMask implements ResettableMask {
private transient int layer = -1;
public YAxisMask(Extent extent) {
}
@Override
public boolean test(Extent extent, BlockVector3 vector) {
if (layer == -1) {

View File

@ -9,6 +9,9 @@ public class ZAxisMask extends AbstractMask implements ResettableMask {
private transient int layer = -1;
public ZAxisMask(Extent extent) {
}
@Override
public boolean test(Extent extent, BlockVector3 vector) {
if (layer == -1) {

View File

@ -162,6 +162,9 @@ public class FaweLimit {
public void THROW_MAX_CHANGES(int amt) {
if ((MAX_CHANGES -= amt) <= 0) throw FaweCache.MAX_CHANGES;
}
public void THROW_MAX_CHANGES(long amt) {
if ((MAX_CHANGES -= amt) <= 0) throw FaweCache.MAX_CHANGES;
}
public void THROW_MAX_FAILS(int amt) {
if ((MAX_FAILS -= amt) <= 0) throw FaweCache.MAX_CHECKS;
@ -171,6 +174,10 @@ public class FaweLimit {
if ((MAX_CHECKS -= amt) <= 0) throw FaweCache.MAX_CHECKS;
}
public void THROW_MAX_CHECKS(long amt) {
if ((MAX_CHECKS -= amt) <= 0) throw FaweCache.MAX_CHECKS;
}
public void THROW_MAX_ITERATIONS(int amt) {
if ((MAX_ITERATIONS -= amt) <= 0) throw FaweCache.MAX_ITERATIONS;
}

View File

@ -2,9 +2,9 @@ package com.boydti.fawe.object;
public final class IntTriple {
public int x;
public int y;
public int z;
private final int x;
private final int y;
private final int z;
public IntTriple(int x, int y, int z) {
this.x = x;

View File

@ -1,8 +0,0 @@
package com.boydti.fawe.object;
import java.util.function.Supplier;
public interface Lazy<T> extends Supplier<T> {
Supplier<T> init();
public default T get() { return init().get(); }
}

View File

@ -1,33 +0,0 @@
package com.boydti.fawe.object;
import java.util.function.BiConsumer;
public abstract class RunnableVal2<T, U> implements Runnable, BiConsumer<T, U> {
public T value1;
public U value2;
public RunnableVal2() {
}
public RunnableVal2(T value1, U value2) {
this.value1 = value1;
this.value2 = value2;
}
@Override
public void run() {
run(this.value1, this.value2);
}
public abstract void run(T value1, U value2);
public RunnableVal2<T, U> runAndGet(T value1, U value2) {
run(value1, value2);
return this;
}
@Override
public void accept(T t, U u) {
run(t, u);
}
}

View File

@ -93,7 +93,7 @@ public class CPUOptimizedClipboard extends LinearClipboard {
}
for (Map.Entry<IntTriple, CompoundTag> entry : nbtMapLoc.entrySet()) {
IntTriple key = entry.getKey();
setTile(getIndex(key.x, key.y, key.z), entry.getValue());
setTile(getIndex(key.getX(), key.getY(), key.getZ()), entry.getValue());
}
nbtMapLoc.clear();
}

View File

@ -324,7 +324,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
nbt = null;
for (Map.Entry<IntTriple, CompoundTag> entry : nbtMap.entrySet()) {
IntTriple key = entry.getKey();
int index = getIndex(key.x, key.y, key.z);
int index = getIndex(key.getX(), key.getY(), key.getZ());
if (index == i) {
nbt = entry.getValue();
break;

View File

@ -200,7 +200,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
nbt = null;
for (Map.Entry<IntTriple, CompoundTag> entry : nbtMap.entrySet()) {
IntTriple trio = entry.getKey();
int index = getIndex(trio.x, trio.y, trio.z);
int index = getIndex(trio.getX(), trio.getY(), trio.getZ());
if (index == i) {
nbt = entry.getValue();
break;

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
@ -14,7 +15,7 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
private final CachedMask mask;
private final MutableBlockVector3 mutable;
public AdjacentAnyMask(Mask mask) {
public AdjacentAnyMask(AbstractExtentMask mask) {
this.mask = CachedMask.cache(mask);
mutable = new MutableBlockVector3();
}

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
@ -11,7 +12,7 @@ public class SurfaceMask extends AdjacentAnyMask {
super(getMask(extent));
}
public static Mask getMask(Extent extent) {
public static AbstractExtentMask getMask(Extent extent) {
return new BlockMaskBuilder()
.addTypes(BlockTypes.AIR, BlockTypes.CAVE_AIR, BlockTypes.VOID_AIR)
.addAll(b -> !b.getMaterial().isMovementBlocker())

View File

@ -87,14 +87,12 @@ public class FuzzyRegionSelector extends PassthroughExtent implements RegionSele
@Override
public void explainPrimarySelection(Actor actor, LocalSession session, BlockVector3 position) {
int size = this.region.getArea();
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos1", position, "(" + region.getArea() + ")"));
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos1", position, "(" + region.getVolume() + ")"));
}
@Override
public void explainSecondarySelection(Actor actor, LocalSession session, BlockVector3 position) {
int size = this.region.getArea();
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos2", position, "(" + region.getArea() + ")"));
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos2", position, "(" + region.getVolume() + ")"));
}
@Override

View File

@ -99,8 +99,8 @@ public abstract class DFSVisitor implements Operation {
// mutable2.mutY(from.getY() + direction.y);
// mutable2.mutZ(from.getZ() + direction.z);
BlockVector3 bv2 = BlockVector3
.at(from.getX() + direction.x, from.getY() + direction.y,
from.getZ() + direction.z);
.at(from.getX() + direction.getX(), from.getY() + direction.getY(),
from.getZ() + direction.getZ());
if (isVisitable(bv, bv2)) {
Node adjacent = new Node(bv2.getBlockX(), bv2.getBlockY(), bv2.getBlockZ());
if (!adjacent.equals(current.from)) {

View File

@ -5,29 +5,17 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IBatchProcessor;
import com.boydti.fawe.beta.IQueueChunk;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.lighting.NMSRelighter;
import com.boydti.fawe.beta.implementation.lighting.NullRelighter;
import com.boydti.fawe.beta.implementation.lighting.Relighter;
import com.boydti.fawe.beta.implementation.processors.LimitProcessor;
import com.boydti.fawe.beta.implementation.queue.ParallelQueueExtent;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.HistoryExtent;
import com.boydti.fawe.object.NullChangeSet;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RelightMode;
import com.boydti.fawe.object.*;
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.boydti.fawe.object.changeset.BlockBagChangeSet;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
import com.boydti.fawe.object.extent.FaweRegionExtent;
import com.boydti.fawe.object.extent.MultiRegionExtent;
import com.boydti.fawe.object.extent.NullExtent;
import com.boydti.fawe.object.extent.SingleRegionExtent;
import com.boydti.fawe.object.extent.SlowExtent;
import com.boydti.fawe.object.extent.StripNBTExtent;
import com.boydti.fawe.object.extent.*;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;

View File

@ -4,6 +4,7 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import java.lang.reflect.Field;
import org.jetbrains.annotations.NotNull;
public class ExtentTraverser<T extends Extent> {
@ -48,21 +49,8 @@ public class ExtentTraverser<T extends Extent> {
return last;
}
public boolean insert(T extent) {
try {
Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
field.setAccessible(true);
field.set(extent, field.get(root));
field.set(root, extent);
return true;
} catch (Throwable e) {
e.printStackTrace();
return false;
}
}
public <U> U findAndGet(Class<U> clazz) {
ExtentTraverser<Extent> traverser = find( clazz);
ExtentTraverser<Extent> traverser = find(clazz);
return (traverser != null) ? (U) traverser.get() : null;
}

View File

@ -1,92 +1,51 @@
package com.boydti.fawe.util;
import static java.lang.System.arraycopy;
import static org.slf4j.LoggerFactory.getLogger;
import com.boydti.fawe.Fawe;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
import com.boydti.fawe.object.io.AbstractDelegateOutputStream;
import com.github.luben.zstd.ZstdInputStream;
import com.github.luben.zstd.ZstdOutputStream;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.util.Location;
import java.awt.Graphics2D;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import it.unimi.dsi.fastutil.io.FastBufferedInputStream;
import net.jpountz.lz4.*;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.*;
import java.lang.reflect.Array;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import java.util.zip.*;
import it.unimi.dsi.fastutil.io.FastBufferedInputStream;
import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream;
import net.jpountz.lz4.LZ4Compressor;
import net.jpountz.lz4.LZ4Factory;
import net.jpountz.lz4.LZ4FastDecompressor;
import net.jpountz.lz4.LZ4InputStream;
import net.jpountz.lz4.LZ4Utils;
import org.jetbrains.annotations.NotNull;
import static java.lang.System.arraycopy;
import static org.slf4j.LoggerFactory.getLogger;
public class MainUtil {
@ -112,22 +71,22 @@ public class MainUtil {
public static long getTotalSize(Path path) {
final AtomicLong size = new AtomicLong(0);
traverse(path, new RunnableVal2<Path, BasicFileAttributes>() {
traverse(path, new RunnableVal<BasicFileAttributes>() {
@Override
public void run(Path path, BasicFileAttributes attrs) {
public void run(BasicFileAttributes attrs) {
size.addAndGet(attrs.size());
}
});
return size.get();
}
public static void traverse(Path path, final BiConsumer<Path, BasicFileAttributes> onEach) {
public static void traverse(Path path, final Consumer<BasicFileAttributes> onEach) {
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult
visitFile(Path file, BasicFileAttributes attrs) {
onEach.accept(file, attrs);
onEach.accept(attrs);
return FileVisitResult.CONTINUE;
}
@ -169,7 +128,7 @@ public class MainUtil {
return out.toString();
}
public static void forEachFile(Path path, final RunnableVal2<Path, BasicFileAttributes> onEach, Comparator<File> comparator) {
public static void forEachFile(Path path, final RunnableVal<BasicFileAttributes> onEach, Comparator<File> comparator) {
File dir = path.toFile();
if (!dir.exists()) return;
File[] files = path.toFile().listFiles();
@ -178,7 +137,7 @@ public class MainUtil {
Path filePath = file.toPath();
try {
BasicFileAttributes attr = Files.readAttributes(filePath, BasicFileAttributes.class);
onEach.run(file.toPath(), attr);
onEach.run(attr);
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -4,6 +4,8 @@ import com.boydti.fawe.object.mask.ResettableMask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import java.lang.reflect.Field;
import java.util.Collection;
@ -38,6 +40,18 @@ public class MaskTraverser {
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
if (mask instanceof MaskIntersection) {
MaskIntersection mask1 = (MaskIntersection) mask;
try {
Field field = mask1.getClass().getDeclaredField("masks");
field.setAccessible(true);
Collection<Mask> masks = (Collection<Mask>) field.get(mask);
for (Mask next : masks) {
reset(next, newExtent);
}
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
try {
Field field = current.getDeclaredField("mask");
field.setAccessible(true);

View File

@ -1,27 +0,0 @@
package com.boydti.fawe.util;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
public class RegionCacheUtil {
public RegionCacheUtil() {
}
public void cache(Region region) {
Iterator<BlockVector3> iter = region.iterator();
}
public void run() {
TaskManager.IMP.async(new Runnable() {
@Override
public void run() {
}
});
}
}

View File

@ -33,15 +33,9 @@ public class WEManager {
public void cancelEditSafe(AbstractDelegateExtent parent, FaweException reason) throws FaweException {
log.warn("CancelEditSafe was hit. Please ignore this message.");
try {
final Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
field.setAccessible(true);
Extent currentExtent = parent.getExtent();
if (!(currentExtent instanceof NullExtent)) {
field.set(parent, new NullExtent((Extent) field.get(parent), reason));
}
} catch (Exception e) {
e.printStackTrace();
parent.extent = new NullExtent(parent.extent, reason);
}
throw reason;
}

View File

@ -1102,7 +1102,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @param radius the radius of the spherical area to fill
* @param depth the maximum depth, starting from the origin
* @param direction the direction to fill
* @return number of blocks affected
* @return the number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int fillDirection(final BlockVector3 origin, final Pattern pattern, final double radius, final int depth, BlockVector3 direction) throws MaxChangedBlocksException {
@ -1181,7 +1181,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
visitor.visit(origin);
// Execute
Operations.completeBlindly(visitor);
Operations.completeLegacy(visitor);
return this.changes = visitor.getAffected();
}
@ -2185,10 +2185,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*
* @param position a position
* @param radius a radius
* @param onlyNormalDirt only affect normal dirt (data value 0)
* @param onlyNormalDirt only affect normal dirt (all default properties)
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
@Deprecated
public int green(BlockVector3 position, double radius, boolean onlyNormalDirt)
throws MaxChangedBlocksException {
final double radiusSq = radius * radius;
@ -2257,7 +2258,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
GroundFunction ground = new GroundFunction(new ExistingBlockMask(this), generator);
LayerVisitor visitor = new LayerVisitor(region, minimumBlockY(region), maximumBlockY(region), ground);
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
Operations.completeBlindly(visitor);
Operations.completeLegacy(visitor);
return this.changes = ground.getAffected();
}
@ -2403,11 +2404,42 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return changed;
}
/**
* Deforms the region by a given expression. A deform provides a block's x, y, and z coordinates (possibly scaled)
* to an expression, and then sets the block to the block given by the resulting values of the variables, if they
* have changed.
*
* @param region the region to deform
* @param zero the origin of the coordinate system
* @param unit the scale of the coordinate system
* @param expressionString the expression to evaluate for each block
*
* @return number of blocks changed
*
* @throws ExpressionException thrown on invalid expression input
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final String expressionString)
throws ExpressionException, MaxChangedBlocksException {
return deformRegion(region, zero, unit, expressionString, WorldEdit.getInstance().getConfiguration().calculationTimeout);
}
/**
* Deforms the region by a given expression. A deform provides a block's x, y, and z coordinates (possibly scaled)
* to an expression, and then sets the block to the block given by the resulting values of the variables, if they
* have changed.
*
* @param region the region to deform
* @param zero the origin of the coordinate system
* @param unit the scale of the coordinate system
* @param expressionString the expression to evaluate for each block
* @param timeout maximum time for the expression to evaluate for each block. -1 for unlimited.
*
* @return number of blocks changed
*
* @throws ExpressionException thrown on invalid expression input
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final String expressionString,
final int timeout) throws ExpressionException, MaxChangedBlocksException {
final Expression expression = Expression.compile(expressionString, "x", "y", "z");
@ -2425,7 +2457,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
final Vector3 zero2 = zero.add(0.5, 0.5, 0.5);
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
private final MutableBlockVector3 mutable = new MutableBlockVector3();
@Override
public boolean apply(BlockVector3 position) throws WorldEditException {

View File

@ -176,7 +176,7 @@ public class ClipboardCommands {
lazyClipboard.setOrigin(session.getPlacementPosition(actor));
session.setClipboard(new ClipboardHolder(lazyClipboard));
actor.print(Caption.of("fawe.worldedit.copy.command.copy" , region.getArea()));
actor.print(Caption.of("fawe.worldedit.copy.command.copy" , region.getVolume()));
}
// @Command(

View File

@ -104,14 +104,14 @@ public class ExpandCommands {
private static void expandVert(LocalSession session, Actor actor, World world) throws IncompleteRegionException {
Region region = session.getSelection(world);
try {
int oldSize = region.getArea();
long oldSize = region.getVolume();
region.expand(
BlockVector3.at(0, (world.getMaxY() + 1), 0),
BlockVector3.at(0, -(world.getMaxY() + 1), 0));
session.getRegionSelector(world).learnChanges();
int newSize = region.getArea();
long newSize = region.getVolume();
session.getRegionSelector(world).explainRegionAdjust(actor, session);
int changeSize = newSize - oldSize;
long changeSize = newSize - oldSize;
actor.printInfo(
TranslatableComponent.of("worldedit.expand.expanded.vert", TextComponent.of(changeSize))
);
@ -134,7 +134,7 @@ public class ExpandCommands {
@MultiDirection
List<BlockVector3> direction) throws WorldEditException {
Region region = session.getSelection(world);
int oldSize = region.getArea();
long oldSize = region.getVolume();
if (reverseAmount == 0) {
for (BlockVector3 dir : direction) {
@ -147,11 +147,11 @@ public class ExpandCommands {
}
session.getRegionSelector(world).learnChanges();
int newSize = region.getArea();
long newSize = region.getVolume();
session.getRegionSelector(world).explainRegionAdjust(actor, session);
int changeSize = newSize - oldSize;
long changeSize = newSize - oldSize;
actor.printInfo(TranslatableComponent.of("worldedit.expand.expanded", TextComponent.of(changeSize)));
}

View File

@ -7,10 +7,7 @@
//import com.boydti.fawe.object.mask.BiomeMask;
//import com.boydti.fawe.object.mask.BlockLightMask;
//import com.boydti.fawe.object.mask.BrightnessMask;
//import com.boydti.fawe.object.mask.DataMask;
//import com.boydti.fawe.object.mask.ExtremaMask;
//import com.boydti.fawe.object.mask.IdDataMask;
//import com.boydti.fawe.object.mask.IdMask;
//import com.boydti.fawe.object.mask.LightMask;
//import com.boydti.fawe.object.mask.OpacityMask;
//import com.boydti.fawe.object.mask.ROCAngleMask;
@ -171,22 +168,6 @@
// }
//
// @Command(
// name = "#id",
// desc = "Restrict to initial id"
// )
// public Mask id(Extent extent) {
// return new IdMask(extent);
// }
//
// @Command(
// name = "#data",
// desc = "Restrict to initial data"
// )
// public Mask data(Extent extent) {
// return new DataMask(extent);
// }
//
// @Command(
// name = "#iddata",
// desc = "Restrict to initial block id and data"
// )

View File

@ -205,7 +205,7 @@ public class RegionCommands {
desc = "Set block lighting in a selection"
)
@CommandPermissions("worldedit.light.set")
public void setlighting(Player player, EditSession editSession, @Selection Region region, @Range(from = 0, to = 15) int value) {
public void setlighting(Player player, EditSession editSession, @Selection Region region) {
player.print(TextComponent.of("Temporarily not working"));
}
@ -214,7 +214,7 @@ public class RegionCommands {
desc = "Set sky lighting in a selection"
)
@CommandPermissions("worldedit.light.set")
public void setskylighting(Player player, @Selection Region region, @Range(from = 0, to= 15) int value) {
public void setskylighting(Player player, @Selection Region region) {
player.printInfo(TextComponent.of("Temporarily not working"));
}

View File

@ -339,7 +339,7 @@ public class SelectionCommands {
List<BlockVector3> direction) throws WorldEditException {
try {
Region region = session.getSelection(world);
int oldSize = region.getArea();
long oldSize = region.getVolume();
if (reverseAmount == 0) {
for (BlockVector3 dir : direction) {
region.contract(dir.multiply(amount));
@ -350,7 +350,7 @@ public class SelectionCommands {
}
}
session.getRegionSelector(world).learnChanges();
int newSize = region.getArea();
long newSize = region.getVolume();
session.getRegionSelector(world).explainRegionAdjust(actor, session);
@ -501,7 +501,7 @@ public class SelectionCommands {
actor.printInfo(TranslatableComponent.of("worldedit.size.size", TextComponent.of(size.toString())));
actor.printInfo(TranslatableComponent.of("worldedit.size.distance", TextComponent.of(region.getMaximumPoint().distance(region.getMinimumPoint()))));
actor.printInfo(TranslatableComponent.of("worldedit.size.blocks", TextComponent.of(region.getArea())));
actor.printInfo(TranslatableComponent.of("worldedit.size.blocks", TextComponent.of(region.getVolume())));
}
@Command(

View File

@ -20,22 +20,7 @@
package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.mask.AirMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.BiomeMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.BlockCategoryMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.BlockStateMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.BlocksMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.ExistingMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.ExpressionMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.FalseMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.LazyRegionMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.LiquidMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.NegateMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.TrueMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.*;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -81,6 +66,9 @@ public final class MaskFactory extends AbstractFactory<Mask> {
register(new TrueMaskParser(worldEdit));
register(new AirMaskParser(worldEdit));
register(new LiquidMaskParser(worldEdit));
register(new XAxisMaskParser(worldEdit));
register(new YAxisMaskParser(worldEdit));
register(new ZAxisMaskParser(worldEdit));
}

View File

@ -1,22 +1,3 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.function.mask.AirMask;

View File

@ -1,22 +1,3 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.function.mask.LiquidMask;

View File

@ -0,0 +1,48 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.function.mask.XAxisMask;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import java.util.List;
public class XAxisMaskParser extends SimpleInputParser<Mask> {
private final List<String> aliases = ImmutableList.of("#xaxis");
public XAxisMaskParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return aliases;
}
@Override
public Mask parseFromSimpleInput(String input, ParserContext context) {
return new XAxisMask(context.getExtent());
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.function.mask.XAxisMask;
import com.boydti.fawe.function.mask.YAxisMask;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import java.util.List;
public class YAxisMaskParser extends SimpleInputParser<Mask> {
private final List<String> aliases = ImmutableList.of("#yaxis");
public YAxisMaskParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return aliases;
}
@Override
public Mask parseFromSimpleInput(String input, ParserContext context) {
return new YAxisMask(context.getExtent());
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.function.mask.XAxisMask;
import com.boydti.fawe.function.mask.ZAxisMask;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import java.util.List;
public class ZAxisMaskParser extends SimpleInputParser<Mask> {
private final List<String> aliases = ImmutableList.of("#zaxis");
public ZAxisMaskParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return aliases;
}
@Override
public Mask parseFromSimpleInput(String input, ParserContext context) {
return new ZAxisMask(context.getExtent());
}
}

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.extension.platform;
import com.boydti.fawe.config.Caption;
import com.boydti.fawe.object.task.AsyncNotifyQueue;
import com.sk89q.worldedit.EditSession;
@ -701,10 +700,10 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
* @return
*/
public Region getLargestRegion() {
int area = 0;
long area = 0;
Region max = null;
for (Region region : this.getCurrentRegions()) {
final int tmp = region.getArea();
final long tmp = region.getVolume();
if (tmp > area) {
area = tmp;
max = region;

View File

@ -59,7 +59,8 @@ public class AbstractDelegateExtent implements Extent {
private static final Logger logger = LoggerFactory.getLogger(AbstractDelegateExtent.class);
private final Extent extent;
//Not safe for public usage
public Extent extent;
/**
* Create a new instance.

View File

@ -27,8 +27,9 @@ public class SelectionPoint2DEvent implements CUIEvent {
protected final int id;
protected final int blockX;
protected final int blockZ;
protected final int area;
protected final long area;
@Deprecated
public SelectionPoint2DEvent(int id, BlockVector2 pos, int area) {
this.id = id;
this.blockX = pos.getX();
@ -36,6 +37,7 @@ public class SelectionPoint2DEvent implements CUIEvent {
this.area = area;
}
@Deprecated
public SelectionPoint2DEvent(int id, BlockVector3 pos, int area) {
this.id = id;
this.blockX = pos.getX();
@ -43,6 +45,20 @@ public class SelectionPoint2DEvent implements CUIEvent {
this.area = area;
}
public SelectionPoint2DEvent(int id, BlockVector2 pos, long area) {
this.id = id;
this.blockX = pos.getX();
this.blockZ = pos.getZ();
this.area = area;
}
public SelectionPoint2DEvent(int id, BlockVector3 pos, long area) {
this.id = id;
this.blockX = pos.getX();
this.blockZ = pos.getZ();
this.area = area;
}
@Override
public String getTypeId() {
return "p2";

View File

@ -25,14 +25,21 @@ public class SelectionPointEvent implements CUIEvent {
protected final int id;
protected final BlockVector3 pos;
protected final int area;
protected final long area;
@Deprecated
public SelectionPointEvent(int id, BlockVector3 pos, int area) {
this.id = id;
this.pos = pos;
this.area = area;
}
public SelectionPointEvent(int id, BlockVector3 pos, long area) {
this.id = id;
this.pos = pos;
this.area = area;
}
@Override
public String getTypeId() {
return "p";

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.regions;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.google.common.primitives.Longs;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -44,7 +45,7 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
@Override
public int size() {
return getArea();
return com.google.common.primitives.Ints.saturatedCast(getVolume());
}
@Override
@ -106,19 +107,14 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
return points;
}
/**
* Get the number of blocks in the region.
*
* @return number of blocks
*/
@Override
public int getArea() {
public long getVolume() {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return (max.getX() - min.getX() + 1) *
(max.getY() - min.getY() + 1) *
(max.getZ() - min.getZ() + 1);
return (max.getX() - min.getX() + 1L) *
(max.getY() - min.getY() + 1L) *
(max.getZ() - min.getZ() + 1L);
}
/**
@ -218,7 +214,7 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
int result = worldHash ^ (worldHash >>> 32);
result = 31 * result + this.getMinimumPoint().hashCode();
result = 31 * result + this.getMaximumPoint().hashCode();
result = 31 * result + this.getArea();
result = (int) (31 * result + this.getVolume());
return result;
}
@ -239,7 +235,7 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
if(this.getWorld().equals(region.getWorld())
&& this.getMinimumPoint().equals(region.getMinimumPoint())
&& this.getMaximumPoint().equals(region.getMaximumPoint())
&& this.getArea() == region.getArea()){
&& this.getVolume() == region.getVolume()){
return true;
}
return false;

View File

@ -35,6 +35,9 @@ import com.sk89q.worldedit.math.geom.Polygons;
import com.sk89q.worldedit.regions.iterator.FlatRegion3DIterator;
import com.sk89q.worldedit.regions.iterator.FlatRegionIterator;
import com.sk89q.worldedit.world.World;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Iterator;
import java.util.List;
@ -196,9 +199,16 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
return minY;
}
private static final BigDecimal PI = BigDecimal.valueOf(Math.PI);
@Override
public int getArea() {
return (int) Math.floor(radius.getX() * radius.getZ() * Math.PI * getHeight());
public long getVolume() {
return BigDecimal.valueOf(radius.getX())
.multiply(BigDecimal.valueOf(radius.getZ()))
.multiply(PI)
.multiply(BigDecimal.valueOf(getHeight()))
.setScale(0, RoundingMode.FLOOR)
.longValue();
}
@Override

View File

@ -32,6 +32,8 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.storage.ChunkStore;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashSet;
import java.util.Set;
@ -92,10 +94,16 @@ public class EllipsoidRegion extends AbstractRegion {
return center.toVector3().add(getRadius()).toBlockPoint();
}
private static final BigDecimal ELLIPSOID_BASE_MULTIPLIER = BigDecimal.valueOf((4.0 / 3.0) * Math.PI);
@Override
public int getArea() {
return (int) Math
.floor((4.0 / 3.0) * Math.PI * radius.getX() * radius.getY() * radius.getZ());
public long getVolume() {
return ELLIPSOID_BASE_MULTIPLIER
.multiply(BigDecimal.valueOf(radius.getX()))
.multiply(BigDecimal.valueOf(radius.getY()))
.multiply(BigDecimal.valueOf(radius.getZ()))
.setScale(0, RoundingMode.FLOOR)
.longValue();
}
@Override

View File

@ -53,7 +53,7 @@ public class NullRegion implements Region {
}
@Override
public int getArea() {
public long getVolume() {
return 0;
}

View File

@ -25,6 +25,8 @@ import com.sk89q.worldedit.regions.iterator.FlatRegion3DIterator;
import com.sk89q.worldedit.regions.iterator.FlatRegionIterator;
import com.sk89q.worldedit.world.World;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@ -197,18 +199,22 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion {
}
@Override
public int getArea() {
double area = 0;
public long getVolume() {
long area = 0;
int i, j = points.size() - 1;
for (i = 0; i < points.size(); ++i) {
area += (points.get(j).getBlockX() + points.get(i).getBlockX())
* (points.get(j).getBlockZ() - points.get(i).getBlockZ());
long x = points.get(j).getBlockX() + points.get(i).getBlockX();
long z = points.get(j).getBlockZ() - points.get(i).getBlockZ();
area += x * z;
j = i;
}
return (int) Math.floor(Math.abs(area * 0.5)
* (maxY - minY + 1));
return BigDecimal.valueOf(area)
.multiply(BigDecimal.valueOf(0.5))
.abs()
.setScale(0, RoundingMode.FLOOR)
.longValue() * (maxY - minY + 1);
}
@Override

View File

@ -32,8 +32,10 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
/**
@ -74,14 +76,40 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
* Get the number of blocks in the region.
*
* @return number of blocks
* @deprecated use {@link Region#getVolume()} to prevent overflows
*/
@Deprecated
default int getArea() {
return (int) getVolume();
}
/**
* Get the number of blocks in the region.
*
* <p>Note: This method <b>must</b> be overridden.</p>
*
* @return number of blocks
*/
default long getVolume() {
// TODO Remove default status when getArea is removed.
try {
if (getClass().getMethod("getArea").getDeclaringClass().equals(Region.class)) {
throw new IllegalStateException("Class " + getClass().getName() + " must override getVolume.");
}
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
return getArea();
}
/* FAWE code for getArea() before merge:
default int getArea() {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1);
}
*/
/**
* Get X-size.
*

View File

@ -135,8 +135,31 @@ public interface RegionSelector {
* Get the number of blocks inside the region.
*
* @return number of blocks, or -1 if undefined
* @deprecated use {@link RegionSelector#getVolume()}
*/
int getArea();
@Deprecated
default int getArea() {
return (int) getVolume();
}
/**
* Get the number of blocks inside the region.
*
* <p>Note: This method <b>must</b> be overridden.</p>
*
* @return number of blocks, or -1 if undefined
*/
default long getVolume() {
// TODO Remove default once getArea is removed
try {
if (getClass().getMethod("getArea").getDeclaringClass().equals(RegionSelector.class)) {
throw new IllegalStateException("Class " + getClass().getName() + " must override getVolume.");
}
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
return getArea();
}
/**
* Update the selector with changes to the region.

View File

@ -113,8 +113,8 @@ public class TransformRegion extends AbstractRegion {
}
@Override
public int getArea() {
return region.getArea(); // Cannot transform this
public long getVolume() {
return region.getVolume(); // Cannot transform this
}
@Override

View File

@ -170,8 +170,8 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion
}
@Override
public int getArea() {
return region.getArea();
public long getVolume() {
return region.getVolume();
}
@Override
@ -250,7 +250,7 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion
int lastVertexId = -1;
for (BlockVector3 vertex : vertices) {
vertexIds.put(vertex, ++lastVertexId);
session.dispatchCUIEvent(player, new SelectionPointEvent(lastVertexId, vertex, getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(lastVertexId, vertex, getVolume()));
}
for (Triangle triangle : triangles) {
@ -273,8 +273,8 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion
checkNotNull(session);
if (isDefined()) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getVolume()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getVolume()));
}
}

View File

@ -161,13 +161,13 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
player.printInfo(TranslatableComponent.of(
"worldedit.selection.cuboid.explain.primary-area",
TextComponent.of(position1.toString()),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
} else if (position1 != null) {
player.printInfo(TranslatableComponent.of("worldedit.selection.cuboid.explain.primary", TextComponent.of(position1.toString())));
}
session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos, getVolume()));
}
@Override
@ -180,13 +180,13 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
player.printInfo(TranslatableComponent.of(
"worldedit.selection.cuboid.explain.secondary-area",
TextComponent.of(position2.toString()),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
} else if (position2 != null) {
player.printInfo(TranslatableComponent.of("worldedit.selection.cuboid.explain.secondary", TextComponent.of(position2.toString())));
}
session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos, getVolume()));
}
@Override
@ -197,11 +197,11 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeID()));
if (position1 != null) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getVolume()));
}
if (position2 != null) {
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getVolume()));
}
}
@ -268,7 +268,7 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
}
@Override
public int getArea() {
public long getVolume() {
if (position1 == null) {
return -1;
}
@ -277,17 +277,17 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
return -1;
}
return region.getArea();
return region.getVolume();
}
@Override
public void describeCUI(LocalSession session, Actor player) {
if (position1 != null) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getVolume()));
}
if (position2 != null) {
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getVolume()));
}
}

View File

@ -188,7 +188,7 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
"worldedit.selection.cylinder.explain.secondary",
TextComponent.of(NUMBER_FORMAT.format(region.getRadius().getX())),
TextComponent.of(NUMBER_FORMAT.format(region.getRadius().getZ())),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
} else {
player.printError(TranslatableComponent.of("worldedit.selection.cylinder.explain.secondary-missing"));
@ -260,8 +260,8 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
}
@Override
public int getArea() {
return region.getArea();
public long getVolume() {
return region.getVolume();
}
@Override
@ -273,8 +273,8 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
@Override
public void describeLegacyCUI(LocalSession session, Actor player) {
if (isDefined()) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getVolume()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getVolume()));
}
}

View File

@ -151,7 +151,7 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
player.printInfo(TranslatableComponent.of(
"worldedit.selection.ellipsoid.explain.primary-area",
TextComponent.of(region.getCenter().toString()),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
} else {
player.printInfo(TranslatableComponent.of(
@ -169,7 +169,7 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
player.printInfo(TranslatableComponent.of(
"worldedit.selection.ellipsoid.explain.secondary-area",
TextComponent.of(region.getRadius().toString()),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
} else {
player.printInfo(TranslatableComponent.of(
@ -238,8 +238,8 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
}
@Override
public int getArea() {
return region.getArea();
public long getVolume() {
return region.getVolume();
}
@Override
@ -250,8 +250,8 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
@Override
public void describeLegacyCUI(LocalSession session, Actor player) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getVolume()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getVolume()));
}
@Override

View File

@ -134,7 +134,7 @@ public class ExtendingCuboidRegionSelector extends CuboidRegionSelector {
player.printInfo(TranslatableComponent.of(
"worldedit.selection.extend.explain.primary",
TextComponent.of(pos.toString()),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
explainRegionAdjust(player, session);
@ -145,7 +145,7 @@ public class ExtendingCuboidRegionSelector extends CuboidRegionSelector {
player.printInfo(TranslatableComponent.of(
"worldedit.selection.extend.explain.secondary",
TextComponent.of(pos.toString()),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
explainRegionAdjust(player, session);

View File

@ -174,7 +174,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
player.printInfo(TranslatableComponent.of("worldedit.selection.polygon2d.explain.primary", TextComponent.of(pos.toString())));
session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeID()));
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getVolume()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
}
@ -186,7 +186,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
TextComponent.of(pos.toString())
));
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getVolume()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
}
@ -247,8 +247,8 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
}
@Override
public int getArea() {
return region.getArea();
public long getVolume() {
return region.getVolume();
}
/**
@ -264,7 +264,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
public void describeCUI(LocalSession session, Actor player) {
final List<BlockVector2> points = region.getPoints();
for (int id = 0; id < points.size(); id++) {
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(id, points.get(id), getArea()));
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(id, points.get(id), getVolume()));
}
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));

View File

@ -93,7 +93,7 @@ public class SphereRegionSelector extends EllipsoidRegionSelector {
player.printInfo(TranslatableComponent.of(
"worldedit.selection.sphere.explain.secondary-defined",
TextComponent.of(region.getRadius().getX()),
TextComponent.of(region.getArea())
TextComponent.of(region.getVolume())
));
} else {
player.printInfo(TranslatableComponent.of("worldedit.selection.sphere.explain.secondary", TextComponent.of(region.getRadius().getX())));

View File

@ -78,8 +78,8 @@ public class RequestSelection implements Region {
}
@Override
public int getArea() {
return getRegion().getArea();
public long getVolume() {
return getRegion().getVolume();
}
@Override

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.util.collection;
import com.google.common.collect.AbstractIterator;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
@ -36,6 +35,7 @@ import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
@ -43,6 +43,7 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import static com.google.common.base.Preconditions.checkState;
import static com.sk89q.worldedit.math.BitMath.fixSign;
import static com.sk89q.worldedit.math.BitMath.mask;
@ -51,12 +52,6 @@ import static com.sk89q.worldedit.math.BitMath.mask;
*/
public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
/* =========================
IF YOU MAKE CHANGES TO THIS CLASS
Re-run BlockMapTest with the blockmap.fulltesting=true system property.
Or just temporarily remove the annotation disabling the related tests.
========================= */
public static <V> BlockMap<V> create() {
return create(() -> new Int2ObjectOpenHashMap<>(64, 0.9f));
}
@ -245,26 +240,65 @@ public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
entrySet = es = new AbstractSet<Entry<BlockVector3, V>>() {
@Override
public Iterator<Entry<BlockVector3, V>> iterator() {
return new AbstractIterator<Entry<BlockVector3, V>>() {
return new Iterator<Entry<BlockVector3,V>>() {
private final ObjectIterator<Long2ObjectMap.Entry<Int2ObjectMap<V>>> primaryIterator
= Long2ObjectMaps.fastIterator(maps);
private long currentGroupKey;
private Long2ObjectMap.Entry<Int2ObjectMap<V>> currentPrimaryEntry;
private ObjectIterator<Int2ObjectMap.Entry<V>> secondaryIterator;
private boolean finished;
private LazyEntry next;
@Override
protected Entry<BlockVector3, V> computeNext() {
if (secondaryIterator == null || !secondaryIterator.hasNext()) {
if (!primaryIterator.hasNext()) {
return endOfData();
public boolean hasNext() {
if (finished) {
return false;
}
if (next == null) {
LazyEntry proposedNext = computeNext();
if (proposedNext == null) {
finished = true;
return false;
}
next = proposedNext;
}
return true;
}
Long2ObjectMap.Entry<Int2ObjectMap<V>> next = primaryIterator.next();
currentGroupKey = next.getLongKey();
secondaryIterator = Int2ObjectMaps.fastIterator(next.getValue());
private LazyEntry computeNext() {
if (secondaryIterator == null || !secondaryIterator.hasNext()) {
if (!primaryIterator.hasNext()) {
return null;
}
currentPrimaryEntry = primaryIterator.next();
secondaryIterator = Int2ObjectMaps.fastIterator(currentPrimaryEntry.getValue());
// be paranoid
checkState(secondaryIterator.hasNext(),
"Should not have an empty map entry, it should have been removed!");
}
Int2ObjectMap.Entry<V> next = secondaryIterator.next();
return new LazyEntry(currentGroupKey, next.getIntKey(), next.getValue());
return new LazyEntry(currentPrimaryEntry.getLongKey(), next.getIntKey(), next.getValue());
}
@Override
public Entry<BlockVector3, V> next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
LazyEntry tmp = next;
next = null;
return tmp;
}
@Override
public void remove() {
secondaryIterator.remove();
// ensure invariants hold
if (currentPrimaryEntry.getValue().isEmpty()) {
// the remove call cleared this map. call remove on the primary iter
primaryIterator.remove();
}
}
};
}
@ -364,13 +398,14 @@ public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
@Override
public V remove(Object key) {
BlockVector3 vec = (BlockVector3) key;
Int2ObjectMap<V> activeMap = maps.get(toGroupKey(vec));
long groupKey = toGroupKey(vec);
Int2ObjectMap<V> activeMap = maps.get(groupKey);
if (activeMap == null) {
return null;
}
V removed = activeMap.remove(toInnerKey(vec));
if (activeMap.isEmpty()) {
maps.remove(toGroupKey(vec));
maps.remove(groupKey);
}
return removed;
}
@ -429,7 +464,9 @@ public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
}
if (o instanceof BlockMap) {
// optimize by skipping entry translations:
return maps.equals(((BlockMap) o).maps);
@SuppressWarnings("unchecked")
BlockMap<V> other = (BlockMap<V>) o;
return maps.equals(other.maps);
}
return super.equals(o);
}

View File

@ -91,6 +91,7 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
= Int2IntMaps.fastIterator(commonMap);
private final ObjectIterator<Entry<BaseBlock>> uncommonIter
= Int2ObjectMaps.fastIterator(uncommonMap);
private boolean lastNextFromCommon = false;
@Override
public boolean hasNext() {
@ -101,15 +102,26 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
public Entry<BaseBlock> next() {
if (commonIter.hasNext()) {
Int2IntMap.Entry e = commonIter.next();
lastNextFromCommon = true;
return new BasicEntry<>(
e.getIntKey(), assumeAsBlock(e.getIntValue())
);
}
if (uncommonIter.hasNext()) {
lastNextFromCommon = false;
return uncommonIter.next();
}
throw new NoSuchElementException();
}
@Override
public void remove() {
if (lastNextFromCommon) {
commonIter.remove();
} else {
uncommonIter.remove();
}
}
};
}

View File

@ -30,49 +30,54 @@ import java.util.Iterator;
class VectorPositionList implements PositionList {
private final IntList delegate = new IntArrayList();
private final IntList delegateX = new IntArrayList();
private final IntList delegateY = new IntArrayList();
private final IntList delegateZ = new IntArrayList();
@Override
public BlockVector3 get(int index) {
int ri = index * 3;
return BlockVector3.at(
delegate.getInt(ri),
delegate.getInt(ri + 1),
delegate.getInt(ri + 2));
delegateX.getInt(index),
delegateY.getInt(index),
delegateZ.getInt(index));
}
@Override
public void add(BlockVector3 vector) {
delegate.add(vector.getX());
delegate.add(vector.getY());
delegate.add(vector.getZ());
delegateX.add(vector.getX());
delegateY.add(vector.getY());
delegateZ.add(vector.getZ());
}
@Override
public int size() {
return delegate.size();
return delegateX.size();
}
@Override
public void clear() {
delegate.clear();
delegateX.clear();
delegateY.clear();
delegateZ.clear();
}
@Override
public Iterator<BlockVector3> iterator() {
return new AbstractIterator<BlockVector3>() {
private final IntIterator iterator = delegate.iterator();
private final IntIterator iteratorX = delegateX.iterator();
private final IntIterator iteratorY = delegateY.iterator();
private final IntIterator iteratorZ = delegateZ.iterator();
@Override
protected BlockVector3 computeNext() {
if (!iterator.hasNext()) {
if (!iteratorX.hasNext()) {
return endOfData();
}
return BlockVector3.at(
iterator.nextInt(),
iterator.nextInt(),
iterator.nextInt());
iteratorX.nextInt(),
iteratorY.nextInt(),
iteratorZ.nextInt());
}
};
}
@ -81,17 +86,19 @@ class VectorPositionList implements PositionList {
public Iterator<BlockVector3> reverseIterator() {
return new AbstractIterator<BlockVector3>() {
private final IntListIterator iterator = delegate.listIterator(delegate.size());
private final IntListIterator iteratorX = delegateX.listIterator(delegateX.size());
private final IntListIterator iteratorY = delegateY.listIterator(delegateY.size());
private final IntListIterator iteratorZ = delegateZ.listIterator(delegateZ.size());
@Override
protected BlockVector3 computeNext() {
if (!iterator.hasPrevious()) {
if (!iteratorX.hasPrevious()) {
return endOfData();
}
return BlockVector3.at(
iterator.previousInt(),
iterator.previousInt(),
iterator.previousInt());
iteratorX.previousInt(),
iteratorY.previousInt(),
iteratorZ.previousInt());
}
};
}

View File

@ -31,13 +31,7 @@ public class TaskStateComparator implements Comparator<Task<?>> {
public int compare(com.sk89q.worldedit.util.task.Task<?> o1, Task<?> o2) {
int ordinal1 = o1.getState().ordinal();
int ordinal2 = o2.getState().ordinal();
if (ordinal1 < ordinal2) {
return -1;
} else if (ordinal1 > ordinal2) {
return 1;
} else {
return 0;
}
return Integer.compare(ordinal1, ordinal2);
}
}

View File

@ -0,0 +1,36 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.math;
import com.sk89q.worldedit.util.test.VariedVectors;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.assertEquals;
@DisplayName("A 3D block vector")
public class BlockVector3Test {
@VariedVectors.Test(capToVanilla = true, divisionsXZ = 50, divisionsY = 50)
@DisplayName("survives a round-trip through long-packing")
void longPackingRoundTrip(BlockVector3 vec) {
assertEquals(vec, BlockVector3.fromLongPackedForm(vec.toLongPackedForm()));
}
}

View File

@ -1,133 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.sk89q.worldedit.math.BlockVector3;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.support.AnnotationConsumer;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Stream;
/**
* Argument provider for various vectors.
*/
public final class VariedVectorsProvider implements ArgumentsProvider, AnnotationConsumer<VariedVectorsProvider.Test> {
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ArgumentsSource(VariedVectorsProvider.class)
@ParameterizedTest(name = ParameterizedTest.ARGUMENTS_PLACEHOLDER)
public @interface Test {
/**
* If {@code true}, provide a non-matching vector from
* the existing vectors set as well. This will nearly
* square the number of tests executed, since it will
* test <em>every</em> non-matching vector.
*/
boolean provideNonMatching() default false;
}
private static final int WORLD_XZ_MINMAX = 30_000_000;
private static final long WORLD_Y_MAX = Integer.MAX_VALUE;
private static final long WORLD_Y_MIN = Integer.MIN_VALUE;
// For better coverage assurance, increase these values for a local Gradle run.
// Don't do it for IntelliJ, it'll probably run out of memory.
private static final int DIVISIONS_XZ = Integer.getInteger("variedvecs.divisions.xz", 5);
private static final int DIVISIONS_Y = Integer.getInteger("variedvecs.divisions.y", 5);
private static final int XZ_STEP = (WORLD_XZ_MINMAX * 2) / DIVISIONS_XZ;
private static final long Y_STEP = (WORLD_Y_MAX * 2) / DIVISIONS_Y;
private static final Set<BlockVector3> ALWAYS_INCLUDE =
ImmutableSet.of(BlockVector3.ZERO, BlockVector3.ONE,
BlockVector3.at(-WORLD_XZ_MINMAX, 0, -WORLD_XZ_MINMAX),
BlockVector3.at(WORLD_XZ_MINMAX, 0, WORLD_XZ_MINMAX),
BlockVector3.at(-WORLD_XZ_MINMAX, WORLD_Y_MAX, -WORLD_XZ_MINMAX),
BlockVector3.at(WORLD_XZ_MINMAX, WORLD_Y_MAX, WORLD_XZ_MINMAX));
private boolean provideNonMatching;
@Override
public void accept(Test test) {
provideNonMatching = test.provideNonMatching();
}
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
if (provideNonMatching) {
return makeVectorsStream()
.flatMap(vec -> makeVectorsStream().filter(v -> !v.equals(vec))
.map(v -> Arguments.of(vec, v)));
}
return makeVectorsStream().map(Arguments::of);
}
public static Stream<BlockVector3> makeVectorsStream() {
return Stream.concat(
ALWAYS_INCLUDE.stream(),
Streams.stream(generateVectors()).filter(v -> !ALWAYS_INCLUDE.contains(v))
);
}
private static Iterator<BlockVector3> generateVectors() {
return new AbstractIterator<BlockVector3>() {
private int x = -WORLD_XZ_MINMAX + 1;
private int z = -WORLD_XZ_MINMAX + 1;
private long y = WORLD_Y_MAX;
@Override
protected BlockVector3 computeNext() {
if (x > WORLD_XZ_MINMAX) {
return endOfData();
}
BlockVector3 newVector = BlockVector3.at(x, (int) y, z);
y += Y_STEP;
if (y > WORLD_Y_MAX) {
y = 0;
z += XZ_STEP;
if (z > WORLD_XZ_MINMAX) {
z = -WORLD_XZ_MINMAX;
x += XZ_STEP;
}
}
return newVector;
}
};
}
}

View File

@ -27,7 +27,8 @@ import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extension.platform.Preference;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.Registry;
import com.sk89q.worldedit.util.VariedVectorsProvider;
import com.sk89q.worldedit.util.test.VariedVectorGenerator;
import com.sk89q.worldedit.util.test.VariedVectors;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -45,11 +46,11 @@ import org.mockito.MockitoAnnotations;
import java.lang.reflect.Field;
import java.util.AbstractMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
@ -63,24 +64,23 @@ import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@DisplayName("An ordered block map")
class BlockMapTest {
/*
private static Platform mockedPlatform = mock(Platform.class);
private static final Platform MOCKED_PLATFORM = mock(Platform.class);
@BeforeAll
static void setupFakePlatform() {
when(mockedPlatform.getRegistries()).thenReturn(new BundledRegistries() {
when(MOCKED_PLATFORM.getRegistries()).thenReturn(new BundledRegistries() {
});
when(mockedPlatform.getCapabilities()).thenReturn(ImmutableMap.of(
when(MOCKED_PLATFORM.getCapabilities()).thenReturn(ImmutableMap.of(
Capability.WORLD_EDITING, Preference.PREFERRED,
Capability.GAME_HOOKS, Preference.PREFERRED
));
PlatformManager platformManager = WorldEdit.getInstance().getPlatformManager();
platformManager.register(mockedPlatform);
platformManager.register(MOCKED_PLATFORM);
registerBlock("minecraft:air");
registerBlock("minecraft:oak_wood");
@ -88,7 +88,7 @@ class BlockMapTest {
@AfterAll
static void tearDownFakePlatform() throws Exception {
WorldEdit.getInstance().getPlatformManager().unregister(mockedPlatform);
WorldEdit.getInstance().getPlatformManager().unregister(MOCKED_PLATFORM);
Field map = Registry.class.getDeclaredField("map");
map.setAccessible(true);
((Map<?, ?>) map.get(BlockType.REGISTRY)).clear();
@ -98,8 +98,6 @@ class BlockMapTest {
BlockType.REGISTRY.register(id, new BlockType(id));
}
@Mock
private Function<? super BlockVector3, ? extends BaseBlock> function;
@Mock
private BiFunction<? super BlockVector3, ? super BaseBlock, ? extends BaseBlock> biFunction;
@Mock
@ -110,7 +108,7 @@ class BlockMapTest {
private final BaseBlock air = checkNotNull(BlockTypes.AIR).getDefaultState().toBaseBlock();
private final BaseBlock oakWood = checkNotNull(BlockTypes.OAK_WOOD).getDefaultState().toBaseBlock();
private BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
private final BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
@BeforeEach
void setUp() {
@ -186,14 +184,14 @@ class BlockMapTest {
@DisplayName("never calls the forEach action")
void neverCallsForEachAction() {
map.forEach(biConsumer);
verifyZeroInteractions(biConsumer);
verifyNoMoreInteractions(biConsumer);
}
@Test
@DisplayName("never calls the replaceAll function")
void neverCallsReplaceAllFunction() {
map.replaceAll(biFunction);
verifyZeroInteractions(biFunction);
verifyNoMoreInteractions(biFunction);
}
@Test
@ -254,63 +252,62 @@ class BlockMapTest {
assertEquals(air, map.merge(BlockVector3.ZERO, air, mergeFunction));
assertEquals(1, map.size());
assertEquals(air, map.get(BlockVector3.ZERO));
verifyZeroInteractions(mergeFunction);
verifyNoMoreInteractions(mergeFunction);
}
}
@Nested
@DisplayName("after having an entry added")
@EnabledIfSystemProperty(named = "blockmap.fulltesting", matches = "true")
class AfterEntryAdded {
// Note: This section of tests would really benefit from
// being able to parameterize classes. It's not part of JUnit
// yet though: https://github.com/junit-team/junit5/issues/878
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("has a size of one")
void hasSizeOne(BlockVector3 vec) {
map.put(vec, air);
assertEquals(1, map.size());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("is equal to another map with the same entry")
void isEqualToSimilarMap(BlockVector3 vec) {
map.put(vec, air);
assertEquals(ImmutableMap.of(vec, air), map);
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("is not equal to another map with a different key")
void isNotEqualToDifferentKeyMap(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(nonMatch, air), map);
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("is not equal to another map with a different value")
void isNotEqualToDifferentValueMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(vec, oakWood), map);
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("is not equal to an empty map")
void isNotEqualToEmptyMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(), map);
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("has the same hashCode as another map with the same entry")
void isHashCodeEqualToSimilarMap(BlockVector3 vec) {
map.put(vec, air);
assertEquals(ImmutableMap.of(vec, air).hashCode(), map.hashCode());
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("has a different hashCode from another map with a different key")
void isHashCodeNotEqualToDifferentKeyMap(BlockVector3 vec, BlockVector3 nonMatch) {
assumeFalse(vec.hashCode() == nonMatch.hashCode(),
@ -319,35 +316,35 @@ class BlockMapTest {
assertNotEquals(ImmutableMap.of(nonMatch, air).hashCode(), map.hashCode());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("has a different hashCode from another map with a different value")
void isHashCodeNotEqualToDifferentValueMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(vec, oakWood).hashCode(), map.hashCode());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("has a different hashCode from an empty map")
void isHashCodeNotEqualToEmptyMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of().hashCode(), map.hashCode());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("returns value from get")
void returnsValueFromGet(BlockVector3 vec) {
map.put(vec, air);
assertEquals(air, map.get(vec));
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("returns `null` from get with different key")
void returnsValueFromGet(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertNotEquals(air, map.get(nonMatch));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("contains the key")
void containsTheKey(BlockVector3 vec) {
map.put(vec, air);
@ -356,7 +353,7 @@ class BlockMapTest {
assertTrue(map.containsKey(vec));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("contains the value")
void containsTheValue(BlockVector3 vec) {
map.put(vec, air);
@ -365,7 +362,7 @@ class BlockMapTest {
assertTrue(map.containsValue(air));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("contains the entry")
void containsTheEntry(BlockVector3 vec) {
map.put(vec, air);
@ -373,21 +370,21 @@ class BlockMapTest {
assertEquals(new AbstractMap.SimpleImmutableEntry<>(vec, air), map.entrySet().iterator().next());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("returns the provided value from getOrDefault")
void returnsProvidedFromGetOrDefault(BlockVector3 vec) {
map.put(vec, air);
assertEquals(air, map.getOrDefault(vec, oakWood));
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("returns the default value from getOrDefault with a different key")
void returnsDefaultFromGetOrDefaultWrongKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertEquals(oakWood, map.getOrDefault(nonMatch, oakWood));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("calls the forEach action once")
void neverCallsForEachAction(BlockVector3 vec) {
map.put(vec, air);
@ -396,7 +393,7 @@ class BlockMapTest {
verifyNoMoreInteractions(biConsumer);
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("replaces value using replaceAll")
void neverCallsReplaceAllFunction(BlockVector3 vec) {
map.put(vec, air);
@ -404,7 +401,7 @@ class BlockMapTest {
assertEquals(oakWood, map.get(vec));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("does not insert on `putIfAbsent`")
void noInsertOnPutIfAbsent(BlockVector3 vec) {
map.put(vec, air);
@ -413,7 +410,7 @@ class BlockMapTest {
assertEquals(air, map.get(vec));
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("inserts on `putIfAbsent` to a different key")
void insertOnPutIfAbsentDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
@ -423,7 +420,7 @@ class BlockMapTest {
assertEquals(oakWood, map.get(nonMatch));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("remove(key) returns the old value")
void removeKeyReturnsOldValue(BlockVector3 vec) {
map.put(vec, air);
@ -431,7 +428,27 @@ class BlockMapTest {
assertEquals(0, map.size());
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test
@DisplayName("keySet().remove(key) removes the entry from the map")
void keySetRemovePassesThrough(BlockVector3 vec) {
map.put(vec, air);
assertTrue(map.keySet().remove(vec));
assertEquals(0, map.size());
}
@VariedVectors.Test
@DisplayName("entrySet().iterator().remove() removes the entry from the map")
void entrySetIteratorRemovePassesThrough(BlockVector3 vec) {
map.put(vec, air);
Iterator<Map.Entry<BlockVector3, BaseBlock>> iterator = map.entrySet().iterator();
assertTrue(iterator.hasNext());
Map.Entry<BlockVector3, BaseBlock> entry = iterator.next();
assertEquals(entry.getKey(), vec);
iterator.remove();
assertEquals(0, map.size());
}
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("remove(nonMatch) returns null")
void removeNonMatchingKeyReturnsNull(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
@ -439,7 +456,7 @@ class BlockMapTest {
assertEquals(1, map.size());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("remove(key, value) returns true")
void removeKeyValueReturnsTrue(BlockVector3 vec) {
map.put(vec, air);
@ -447,7 +464,7 @@ class BlockMapTest {
assertEquals(0, map.size());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("remove(key, value) returns false for wrong value")
void removeKeyValueReturnsFalseWrongValue(BlockVector3 vec) {
map.put(vec, air);
@ -455,7 +472,7 @@ class BlockMapTest {
assertEquals(1, map.size());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("replaces value at key")
void replacesValueAtKey(BlockVector3 vec) {
map.put(vec, air);
@ -469,7 +486,7 @@ class BlockMapTest {
assertEquals(air, map.get(vec));
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("does not replace value at different key")
void doesNotReplaceAtDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
@ -483,7 +500,7 @@ class BlockMapTest {
assertEquals(air, map.get(vec));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("does not insert on computeIfAbsent")
void doesNotInsertComputeIfAbsent(BlockVector3 vec) {
map.put(vec, air);
@ -495,7 +512,7 @@ class BlockMapTest {
assertEquals(air, map.get(vec));
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("inserts on computeIfAbsent with different key")
void insertsOnComputeIfAbsentDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
@ -508,7 +525,7 @@ class BlockMapTest {
assertEquals(oakWood, map.get(nonMatch));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("replaces on compute")
void replaceOnCompute(BlockVector3 vec) {
map.put(vec, air);
@ -523,7 +540,7 @@ class BlockMapTest {
assertEquals(0, map.size());
}
@VariedVectorsProvider.Test(provideNonMatching = true)
@VariedVectors.Test(provideNonMatching = true)
@DisplayName("inserts on compute with different key")
void insertOnComputeDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
@ -540,7 +557,7 @@ class BlockMapTest {
assertEquals(air, map.get(vec));
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("replaces on computeIfPresent")
void replacesOnComputeIfPresent(BlockVector3 vec) {
map.put(vec, air);
@ -555,7 +572,7 @@ class BlockMapTest {
assertEquals(0, map.size());
}
@VariedVectorsProvider.Test
@VariedVectors.Test
@DisplayName("inserts on merge, with call to merge function")
void insertsOnMerge(BlockVector3 vec) {
map.put(vec, air);
@ -573,7 +590,9 @@ class BlockMapTest {
@Test
@DisplayName("contains all inserted vectors")
void containsAllInsertedVectors() {
Set<BlockVector3> allVectors = VariedVectorsProvider.makeVectorsStream().collect(Collectors.toSet());
Set<BlockVector3> allVectors = new VariedVectorGenerator()
.makeVectorsStream()
.collect(Collectors.toSet());
for (BlockVector3 vec : allVectors) {
map.put(vec, air);
}

View File

@ -0,0 +1,98 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.collection;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.test.VariedVectors;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
abstract class PositionListTest {
static class Long extends PositionListTest {
protected Long() {
super(new LongPositionList());
}
}
static class Vector extends PositionListTest {
protected Vector() {
super(new VectorPositionList());
}
}
private final PositionList positionList;
protected PositionListTest(PositionList positionList) {
this.positionList = positionList;
}
@VariedVectors.Test(capToVanilla = true)
@DisplayName("calling add(vec) increases size by 1")
void addIncreasesSizeByOne(BlockVector3 vec) {
positionList.add(vec);
assertEquals(1, positionList.size());
}
@VariedVectors.Test(capToVanilla = true)
@DisplayName("calling get(0) after add(vec) returns vec")
void canGetVectorAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertEquals(vec, positionList.get(0));
}
@VariedVectors.Test(capToVanilla = true)
@DisplayName("calling iterator().hasNext() after add(vec) returns true")
void hasNextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertTrue(positionList.iterator().hasNext());
}
@VariedVectors.Test(capToVanilla = true)
@DisplayName("calling iterator().next() after add(vec) returns vec")
void nextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertEquals(vec, positionList.iterator().next());
}
@VariedVectors.Test(capToVanilla = true)
@DisplayName("calling reverseIterator().hasNext() after add(vec) returns true")
void reverseHasNextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertTrue(positionList.reverseIterator().hasNext());
}
@VariedVectors.Test(capToVanilla = true)
@DisplayName("calling reverseIterator().next() after add(vec) returns vec")
void reverseNextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertEquals(vec, positionList.reverseIterator().next());
}
@VariedVectors.Test(capToVanilla = true)
@DisplayName("calling clear() after add(vec) makes the size() zero")
void clearAfterAdd(BlockVector3 vec) {
positionList.add(vec);
positionList.clear();
assertEquals(0, positionList.size());
}
}

View File

@ -0,0 +1,100 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.test;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.sk89q.worldedit.math.BlockVector3;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Stream;
public class VariedVectorGenerator {
// For better coverage assurance, increase these values for a local Gradle run.
// Don't do it for IntelliJ, it'll probably run out of memory.
private static final int DEFAULT_DIVISIONS_XZ =
Integer.getInteger("variedvecs.divisions.xz", 5);
private static final int DEFAULT_DIVISIONS_Y =
Integer.getInteger("variedvecs.divisions.y", 5);
public final int divisionsXZ;
public final int divisionsY;
public final int maxXZ;
public final long maxY;
public final int xzStep;
public final long yStep;
public final Set<BlockVector3> alwaysInclude;
public VariedVectorGenerator() {
this(false, -1, -1);
}
public VariedVectorGenerator(boolean vanilla, int divisionsXZ, int divisionsY) {
this.divisionsXZ = divisionsXZ == -1 ? DEFAULT_DIVISIONS_XZ : divisionsXZ;
this.divisionsY = divisionsY == -1 ? DEFAULT_DIVISIONS_Y : divisionsY;
maxXZ = 30_000_000;
maxY = vanilla ? 255 : Integer.MAX_VALUE;
xzStep = (maxXZ * 2) / this.divisionsXZ;
yStep = (maxY * 2) / this.divisionsY;
alwaysInclude =
ImmutableSet.of(BlockVector3.ZERO, BlockVector3.ONE,
BlockVector3.at(-maxXZ, 0, -maxXZ),
BlockVector3.at(maxXZ, 0, maxXZ),
BlockVector3.at(-maxXZ, maxY, -maxXZ),
BlockVector3.at(maxXZ, maxY, maxXZ));
}
public Stream<BlockVector3> makeVectorsStream() {
return Stream.concat(
alwaysInclude.stream(),
Streams.stream(generateVectors()).filter(v -> !alwaysInclude.contains(v))
);
}
private Iterator<BlockVector3> generateVectors() {
return new AbstractIterator<BlockVector3>() {
private int x = -maxXZ + 1;
private int z = -maxXZ + 1;
private long y = maxY;
@Override
protected BlockVector3 computeNext() {
if (x > maxXZ) {
return endOfData();
}
BlockVector3 newVector = BlockVector3.at(x, (int) y, z);
y += yStep;
if (y > maxY) {
y = 0;
z += xzStep;
if (z > maxXZ) {
z = -maxXZ;
x += xzStep;
}
}
return newVector;
}
};
}
}

View File

@ -0,0 +1,87 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.support.AnnotationConsumer;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.stream.Stream;
/**
* Argument provider for various vectors.
*/
public final class VariedVectors implements ArgumentsProvider, AnnotationConsumer<VariedVectors.Test> {
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ArgumentsSource(VariedVectors.class)
@ParameterizedTest(name = ParameterizedTest.ARGUMENTS_PLACEHOLDER)
public @interface Test {
/**
* If {@code true}, provide a non-matching vector from
* the existing vectors set as well. This will nearly
* square the number of tests executed, since it will
* test <em>every</em> non-matching vector.
*/
boolean provideNonMatching() default false;
/**
* If {@code true}, only provide vectors inside the range of Vanilla MC.
* This caps the Y value to 255.
*/
boolean capToVanilla() default false;
int divisionsXZ() default -1;
int divisionsY() default -1;
}
private boolean provideNonMatching;
private VariedVectorGenerator generator;
@Override
public void accept(Test test) {
provideNonMatching = test.provideNonMatching();
generator = new VariedVectorGenerator(test.capToVanilla(), test.divisionsXZ(), test.divisionsY());
}
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
if (provideNonMatching) {
return generator.makeVectorsStream()
.flatMap(vec -> generator.makeVectorsStream().filter(v -> !v.equals(vec))
.map(v -> Arguments.of(vec, v)));
}
return generator.makeVectorsStream().map(Arguments::of);
}
}