diff --git a/LICENSE.txt b/LICENSE.txt index ca7fc7c14..61f60d2be 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -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. + Copyright (C) 2007 Free Software Foundation, Inc. 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. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 225ebb2cb..4b3bb46e9 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -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" diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml index 06c7c3edc..d15b7ac92 100644 --- a/config/checkstyle/import-control.xml +++ b/config/checkstyle/import-control.xml @@ -73,6 +73,7 @@ + diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java index 848d127c5..eace17737 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java @@ -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); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java b/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java index 079e14a29..f5daf2fc9 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java @@ -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 registered) { CommandMap commandMap = getCommandMap(); if (registered == null || commandMap == null) { @@ -82,12 +84,13 @@ 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() + - ": Could not retrieve server CommandMap, using fallback instead!"); - fallbackCommands = commandMap = new SimpleCommandMap(Bukkit.getServer()); - Bukkit.getServer().getPluginManager().registerEvents(new FallbackRegistrationListener(fallbackCommands), plugin); + Bukkit.getServer().getLogger().severe(plugin.getDescription().getName() + + ": Could not retrieve server CommandMap, using fallback instead!"); + fallbackCommands = commandMap = new SimpleCommandMap(Bukkit.getServer()); + Bukkit.getServer().getPluginManager().registerEvents(new FallbackRegistrationListener(fallbackCommands), plugin); } else { serverCommandMap = commandMap; } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/CUIChannelListener.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/CUIChannelListener.java index 3bd5702f7..11dc865cf 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/CUIChannelListener.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/CUIChannelListener.java @@ -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) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java index 245db7791..f725f7e39 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java @@ -117,27 +117,6 @@ public class FaweAPI { // return parser != null; // } - public static T getParser(Class parserClass) { - try { - Field field = AbstractFactory.class.getDeclaredField("parsers"); - field.setAccessible(true); - ArrayList parsers = new ArrayList<>(); - parsers.addAll((List) field.get(WorldEdit.getInstance().getMaskFactory())); - parsers.addAll((List) field.get(WorldEdit.getInstance().getBlockFactory())); - parsers.addAll((List) field.get(WorldEdit.getInstance().getItemFactory())); - parsers.addAll((List) 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
* - The IQueueExtent skips a bit of overhead so it's marginally faster
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/cache/preloader/AsyncPreloader.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/cache/preloader/AsyncPreloader.java index 9154248f3..31745548d 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/cache/preloader/AsyncPreloader.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/cache/preloader/AsyncPreloader.java @@ -50,7 +50,7 @@ public class AsyncPreloader implements Preloader, Runnable { MutablePair> 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; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java index 505ae5f20..15284cbbb 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java @@ -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 { 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; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/LimitExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/LimitExtent.java index 1c59fc96d..6e3b13281 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/LimitExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/LimitExtent.java @@ -52,7 +52,7 @@ public class LimitExtent extends PassthroughExtent { @Override public List 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 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> 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> 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 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 > 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 > int replaceBlocks(Region region, Set 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 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 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) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java index 60a8e5bb8..f5b1bc600 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java @@ -151,10 +151,6 @@ public abstract class QueueHandler implements Trimable, Runnable { return forkJoinPoolPrimary.submit(call); } - public Future sync(Runnable run, T value) { - return sync(run, value, syncTasks); - } - public Future sync(Runnable run) { return sync(run, syncTasks); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/AirMask.java b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/AirMask.java index 75099c30f..48d7f3e17 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/AirMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/AirMask.java @@ -1,22 +1,3 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - package com.boydti.fawe.function.mask; import com.sk89q.worldedit.extent.Extent; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/LiquidMask.java b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/LiquidMask.java index 0eb2f6def..cde52cc5e 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/LiquidMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/LiquidMask.java @@ -1,22 +1,3 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - package com.boydti.fawe.function.mask; import com.sk89q.worldedit.extent.Extent; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/XAxisMask.java b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/XAxisMask.java index 2a82b89ef..dbee08f69 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/XAxisMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/XAxisMask.java @@ -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) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/YAxisMask.java b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/YAxisMask.java index 219da3012..3eff19eb2 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/YAxisMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/YAxisMask.java @@ -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) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/ZAxisMask.java b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/ZAxisMask.java index d76c88e08..7f584c3ca 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/function/mask/ZAxisMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/function/mask/ZAxisMask.java @@ -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) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/FaweLimit.java b/worldedit-core/src/main/java/com/boydti/fawe/object/FaweLimit.java index d3f366538..9b67bb819 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/FaweLimit.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/FaweLimit.java @@ -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; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/IntTriple.java b/worldedit-core/src/main/java/com/boydti/fawe/object/IntTriple.java index 42bd767fc..9c684ff17 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/IntTriple.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/IntTriple.java @@ -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; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/Lazy.java b/worldedit-core/src/main/java/com/boydti/fawe/object/Lazy.java deleted file mode 100644 index 0110f624b..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/Lazy.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.boydti.fawe.object; - -import java.util.function.Supplier; - -public interface Lazy extends Supplier { - Supplier init(); - public default T get() { return init().get(); } -} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/RunnableVal2.java b/worldedit-core/src/main/java/com/boydti/fawe/object/RunnableVal2.java deleted file mode 100644 index 4c3d7ca0e..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/RunnableVal2.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.boydti.fawe.object; - -import java.util.function.BiConsumer; - -public abstract class RunnableVal2 implements Runnable, BiConsumer { - 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 runAndGet(T value1, U value2) { - run(value1, value2); - return this; - } - - @Override - public void accept(T t, U u) { - run(t, u); - } -} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java index 0a1507828..592285128 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java @@ -93,7 +93,7 @@ public class CPUOptimizedClipboard extends LinearClipboard { } for (Map.Entry 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(); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java index a66f9b84c..21b2f5713 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java @@ -324,7 +324,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable nbt = null; for (Map.Entry 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; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java index 7a30348e2..0a9b01282 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java @@ -200,7 +200,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard { nbt = null; for (Map.Entry 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; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AdjacentAnyMask.java b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AdjacentAnyMask.java index c9603a5d6..0f0ea9698 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AdjacentAnyMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/AdjacentAnyMask.java @@ -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(); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/SurfaceMask.java b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/SurfaceMask.java index 266f5e587..de5e901c5 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/SurfaceMask.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/SurfaceMask.java @@ -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()) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java b/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java index 031ae7d4b..b9a348126 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java @@ -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 diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java b/worldedit-core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java index aff85f1fb..32edff280 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/visitor/DFSVisitor.java @@ -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)) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java b/worldedit-core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java index 1cc771d9d..153ae6442 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java @@ -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; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/ExtentTraverser.java b/worldedit-core/src/main/java/com/boydti/fawe/util/ExtentTraverser.java index 6c7c06ce0..80eb91bdb 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/ExtentTraverser.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/ExtentTraverser.java @@ -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 { @@ -48,21 +49,8 @@ public class ExtentTraverser { 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 findAndGet(Class clazz) { - ExtentTraverser traverser = find( clazz); + ExtentTraverser traverser = find(clazz); return (traverser != null) ? (U) traverser.get() : null; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java index a3dfdd2f8..73de0e462 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java @@ -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() { + traverse(path, new RunnableVal() { @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 onEach) { + public static void traverse(Path path, final Consumer onEach) { try { Files.walkFileTree(path, new SimpleFileVisitor() { @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 onEach, Comparator comparator) { + public static void forEachFile(Path path, final RunnableVal onEach, Comparator 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(); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/MaskTraverser.java b/worldedit-core/src/main/java/com/boydti/fawe/util/MaskTraverser.java index a5e4897ff..6ed28593a 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/MaskTraverser.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/MaskTraverser.java @@ -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 masks = (Collection) field.get(mask); + for (Mask next : masks) { + reset(next, newExtent); + } + } catch (NoSuchFieldException | IllegalAccessException ignored) { + } + } try { Field field = current.getDeclaredField("mask"); field.setAccessible(true); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/RegionCacheUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/RegionCacheUtil.java deleted file mode 100644 index f5c02d65e..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/RegionCacheUtil.java +++ /dev/null @@ -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 iter = region.iterator(); - } - - public void run() { - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - - } - }); - } -} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/WEManager.java b/worldedit-core/src/main/java/com/boydti/fawe/util/WEManager.java index d435ebb1f..3512829bc 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/WEManager.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/WEManager.java @@ -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(); + Extent currentExtent = parent.getExtent(); + if (!(currentExtent instanceof NullExtent)) { + parent.extent = new NullExtent(parent.extent, reason); } throw reason; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 48769df5a..efc4eaa51 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -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,12 +2185,13 @@ 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 { + throws MaxChangedBlocksException { final double radiusSq = radius * radius; final int ox = position.getBlockX(); @@ -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 { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 59817d210..cf57ae922 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -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( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ExpandCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ExpandCommands.java index 96910e63f..6cfd12ef4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ExpandCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ExpandCommands.java @@ -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 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))); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java index 1668a1231..773313b94 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java @@ -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" // ) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index 9640adcc1..0e6b19089 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -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")); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index 89cdbf862..12a5fce77 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -339,7 +339,7 @@ public class SelectionCommands { List 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( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index 144d3c2fc..d11c479d9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -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 { register(new TrueMaskParser(worldEdit)); register(new AirMaskParser(worldEdit)); register(new LiquidMaskParser(worldEdit)); + register(new XAxisMaskParser(worldEdit)); + register(new YAxisMaskParser(worldEdit)); + register(new ZAxisMaskParser(worldEdit)); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/AirMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/AirMaskParser.java index aa18cdf7a..e8c5ef423 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/AirMaskParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/AirMaskParser.java @@ -1,22 +1,3 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - package com.sk89q.worldedit.extension.factory.parser.mask; import com.boydti.fawe.function.mask.AirMask; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LiquidMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LiquidMaskParser.java index ce3769d48..444ac1c40 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LiquidMaskParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LiquidMaskParser.java @@ -1,22 +1,3 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - package com.sk89q.worldedit.extension.factory.parser.mask; import com.boydti.fawe.function.mask.LiquidMask; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/XAxisMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/XAxisMaskParser.java new file mode 100644 index 000000000..d33eb0749 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/XAxisMaskParser.java @@ -0,0 +1,48 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.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 { + + private final List aliases = ImmutableList.of("#xaxis"); + + public XAxisMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return aliases; + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) { + return new XAxisMask(context.getExtent()); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/YAxisMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/YAxisMaskParser.java new file mode 100644 index 000000000..12108010d --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/YAxisMaskParser.java @@ -0,0 +1,49 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.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 { + + private final List aliases = ImmutableList.of("#yaxis"); + + public YAxisMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return aliases; + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) { + return new YAxisMask(context.getExtent()); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ZAxisMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ZAxisMaskParser.java new file mode 100644 index 000000000..754c2876d --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ZAxisMaskParser.java @@ -0,0 +1,49 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.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 { + + private final List aliases = ImmutableList.of("#zaxis"); + + public ZAxisMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return aliases; + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) { + return new ZAxisMask(context.getExtent()); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index afa19ab77..040c5bb74 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -19,7 +19,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; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java index 66acf6fb0..aa0eb90a2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java @@ -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. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java index 1586dced9..a80791b32 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java @@ -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"; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java index baac3ab1f..777a32770 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java @@ -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"; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java index 03fad6968..0cdd5348a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java @@ -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 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 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 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 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; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java index a682f48c4..faf78b7f7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java @@ -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 diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java index aece100fc..273f642ae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java @@ -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; @@ -68,7 +70,7 @@ public class EllipsoidRegion extends AbstractRegion { /** * Construct a new instance of this ellipsoid region. * - * @param world the world + * @param world the world * @param center the center * @param radius the radius */ @@ -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 @@ -118,7 +126,7 @@ public class EllipsoidRegion extends AbstractRegion { if ((diff.getBlockX() & 1) + (diff.getBlockY() & 1) + (diff.getBlockZ() & 1) != 0) { throw new RegionOperationException( - "Ellipsoid changes must be even for each dimensions."); + "Ellipsoid changes must be even for each dimensions."); } return diff.divide(2).floor(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java index 58e1d2197..7e8e19dfb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java @@ -53,7 +53,7 @@ public class NullRegion implements Region { } @Override - public int getArea() { + public long getVolume() { return 0; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java index d51f6e465..f6c94859a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java @@ -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 diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java index ae7d3abe2..549faf501 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -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, 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. + * + *

Note: This method must be overridden.

+ * + * @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. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java index e38f2a9c2..f607c5172 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java @@ -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. + * + *

Note: This method must be overridden.

+ * + * @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. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java index 911e40b8b..733313421 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java @@ -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 diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java index e98522623..09156446b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java @@ -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())); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java index 1a4cecc71..dab4721d8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java @@ -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())); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java index 1b477f755..10de56191 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java @@ -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())); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java index 86c9d595a..c42de1fad 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java @@ -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 diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java index 29fda872d..7a8c7b2ec 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java @@ -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); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java index 26b48f2da..3ab10dfc2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java @@ -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 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())); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java index ae909a077..641262a1a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java @@ -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()))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java index 9e37e4da0..212f93e19 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java @@ -78,8 +78,8 @@ public class RequestSelection implements Region { } @Override - public int getArea() { - return getRegion().getArea(); + public long getVolume() { + return getRegion().getVolume(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java index 3074a4aa7..ea9061752 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java @@ -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 extends AbstractMap { - /* ========================= - 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 BlockMap create() { return create(() -> new Int2ObjectOpenHashMap<>(64, 0.9f)); } @@ -245,26 +240,65 @@ public class BlockMap extends AbstractMap { entrySet = es = new AbstractSet>() { @Override public Iterator> iterator() { - return new AbstractIterator>() { + return new Iterator>() { private final ObjectIterator>> primaryIterator = Long2ObjectMaps.fastIterator(maps); - private long currentGroupKey; + private Long2ObjectMap.Entry> currentPrimaryEntry; private ObjectIterator> secondaryIterator; + private boolean finished; + private LazyEntry next; @Override - protected Entry computeNext() { + public boolean hasNext() { + if (finished) { + return false; + } + if (next == null) { + LazyEntry proposedNext = computeNext(); + if (proposedNext == null) { + finished = true; + return false; + } + next = proposedNext; + } + return true; + } + + private LazyEntry computeNext() { if (secondaryIterator == null || !secondaryIterator.hasNext()) { if (!primaryIterator.hasNext()) { - return endOfData(); + return null; } - Long2ObjectMap.Entry> next = primaryIterator.next(); - currentGroupKey = next.getLongKey(); - secondaryIterator = Int2ObjectMaps.fastIterator(next.getValue()); + 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 next = secondaryIterator.next(); - return new LazyEntry(currentGroupKey, next.getIntKey(), next.getValue()); + return new LazyEntry(currentPrimaryEntry.getLongKey(), next.getIntKey(), next.getValue()); + } + + @Override + public Entry 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 extends AbstractMap { @Override public V remove(Object key) { BlockVector3 vec = (BlockVector3) key; - Int2ObjectMap activeMap = maps.get(toGroupKey(vec)); + long groupKey = toGroupKey(vec); + Int2ObjectMap 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 extends AbstractMap { } if (o instanceof BlockMap) { // optimize by skipping entry translations: - return maps.equals(((BlockMap) o).maps); + @SuppressWarnings("unchecked") + BlockMap other = (BlockMap) o; + return maps.equals(other.maps); } return super.equals(o); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java index 7120c68e2..906f64c86 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java @@ -91,6 +91,7 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { = Int2IntMaps.fastIterator(commonMap); private final ObjectIterator> uncommonIter = Int2ObjectMaps.fastIterator(uncommonMap); + private boolean lastNextFromCommon = false; @Override public boolean hasNext() { @@ -101,15 +102,26 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { public Entry 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(); + } + } }; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java index 6c8d27ddf..1617edf1b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java @@ -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 iterator() { return new AbstractIterator() { - 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 reverseIterator() { return new AbstractIterator() { - 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()); } }; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/TaskStateComparator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/TaskStateComparator.java index 38b77e73e..894c102d2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/TaskStateComparator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/TaskStateComparator.java @@ -31,13 +31,7 @@ public class TaskStateComparator implements Comparator> { 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); } } diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/math/BlockVector3Test.java b/worldedit-core/src/test/java/com/sk89q/worldedit/math/BlockVector3Test.java new file mode 100644 index 000000000..e47c2432a --- /dev/null +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/math/BlockVector3Test.java @@ -0,0 +1,36 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.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())); + } + +} diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/VariedVectorsProvider.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/VariedVectorsProvider.java deleted file mode 100644 index 10a835392..000000000 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/util/VariedVectorsProvider.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util; - -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 { - - @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 every 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 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 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 makeVectorsStream() { - return Stream.concat( - ALWAYS_INCLUDE.stream(), - Streams.stream(generateVectors()).filter(v -> !ALWAYS_INCLUDE.contains(v)) - ); - } - - private static Iterator generateVectors() { - return new AbstractIterator() { - - 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; - } - }; - } -} diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/collection/BlockMapTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/collection/BlockMapTest.java index cab27786f..6a9fda239 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/util/collection/BlockMapTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/collection/BlockMapTest.java @@ -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 function; @Mock private BiFunction 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 map = BlockMap.createForBaseBlock(); + private final BlockMap 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> iterator = map.entrySet().iterator(); + assertTrue(iterator.hasNext()); + Map.Entry 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 allVectors = VariedVectorsProvider.makeVectorsStream().collect(Collectors.toSet()); + Set allVectors = new VariedVectorGenerator() + .makeVectorsStream() + .collect(Collectors.toSet()); for (BlockVector3 vec : allVectors) { map.put(vec, air); } diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/collection/PositionListTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/collection/PositionListTest.java new file mode 100644 index 000000000..d287558ef --- /dev/null +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/collection/PositionListTest.java @@ -0,0 +1,98 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.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()); + } +} diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/test/VariedVectorGenerator.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/test/VariedVectorGenerator.java new file mode 100644 index 000000000..6818c7aa2 --- /dev/null +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/test/VariedVectorGenerator.java @@ -0,0 +1,100 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.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 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 makeVectorsStream() { + return Stream.concat( + alwaysInclude.stream(), + Streams.stream(generateVectors()).filter(v -> !alwaysInclude.contains(v)) + ); + } + + private Iterator generateVectors() { + return new AbstractIterator() { + + 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; + } + }; + } +} diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/test/VariedVectors.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/test/VariedVectors.java new file mode 100644 index 000000000..daadda021 --- /dev/null +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/test/VariedVectors.java @@ -0,0 +1,87 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.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 { + + @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 every 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 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); + } + +}