From 77cf4ec34c989ba6a0d5a85640ae8b44615c1c81 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Tue, 27 Feb 2018 01:58:12 +1100 Subject: [PATCH] Support for non cuboid regions + add #liquid mask --- .../fawe/bukkit/regions/Worldguard.java | 76 ++- .../main/java/com/boydti/fawe/FaweAPI.java | 2 +- .../com/boydti/fawe/example/Relighter.java | 2 +- .../com/boydti/fawe/object/FawePlayer.java | 84 +-- .../boydti/fawe/object/MaskedFaweQueue.java | 5 +- .../com/boydti/fawe/object/RegionWrapper.java | 48 +- .../object/changeset/DiskStorageHistory.java | 3 +- .../fawe/object/changeset/FaweChangeSet.java | 4 +- .../fawe/object/extent/FaweRegionExtent.java | 6 +- .../fawe/object/extent/HeightBoundExtent.java | 3 +- .../fawe/object/extent/MultiRegionExtent.java | 22 +- .../boydti/fawe/object/extent/NullExtent.java | 3 +- .../object/extent/SingleRegionExtent.java | 12 +- .../object/io/RandomFileOutputStream.java | 110 ++++ .../com/boydti/fawe/regions/FaweMask.java | 76 +-- .../boydti/fawe/regions/FaweMaskManager.java | 1 + .../com/boydti/fawe/regions/SimpleRegion.java | 48 ++ .../general/plot/PlotSquaredFeature.java | 36 +- .../boydti/fawe/util/EditSessionBuilder.java | 15 +- .../java/com/boydti/fawe/util/MathMan.java | 7 +- .../java/com/boydti/fawe/util/WEManager.java | 52 +- .../com/boydti/fawe/util/metrics/BStats.java | 2 +- core/src/main/java/com/sk89q/jnbt/Tag.java | 2 + .../java/com/sk89q/worldedit/EditSession.java | 123 +--- .../sk89q/worldedit/MutableBlockVector2D.java | 3 +- .../worldedit/command/HistoryCommands.java | 10 +- .../sk89q/worldedit/command/MaskCommands.java | 46 +- .../worldedit/command/UtilityCommands.java | 2 +- .../com/sk89q/worldedit/extent/Extent.java | 51 +- .../extent/clipboard/io/WavefrontReader.java | 553 ++++++++++++++++++ .../function/mask/ConditionalMask.java | 18 + .../sk89q/worldedit/regions/CuboidRegion.java | 8 +- .../worldedit/regions/IDelegateRegion.java | 110 ++++ .../com/sk89q/worldedit/regions/Region.java | 182 ++++++ .../ConvexPolyhedralRegionSelector.java | 5 + .../selector/CylinderRegionSelector.java | 5 + .../selector/Polygonal2DRegionSelector.java | 5 + .../com/thevoxelbox/voxelsniper/Sniper.java | 17 +- nukkit/build.gradle | 3 +- 39 files changed, 1391 insertions(+), 369 deletions(-) create mode 100644 core/src/main/java/com/boydti/fawe/object/io/RandomFileOutputStream.java create mode 100644 core/src/main/java/com/boydti/fawe/regions/SimpleRegion.java create mode 100644 core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/WavefrontReader.java create mode 100644 core/src/main/java/com/sk89q/worldedit/function/mask/ConditionalMask.java create mode 100644 core/src/main/java/com/sk89q/worldedit/regions/IDelegateRegion.java create mode 100644 core/src/main/java/com/sk89q/worldedit/regions/Region.java diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/regions/Worldguard.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/regions/Worldguard.java index 8a4f6078..64c929e0 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/regions/Worldguard.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/regions/Worldguard.java @@ -3,11 +3,22 @@ package com.boydti.fawe.bukkit.regions; import com.boydti.fawe.bukkit.FaweBukkit; import com.boydti.fawe.bukkit.filter.WorldGuardFilter; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.RegionWrapper; +import com.boydti.fawe.regions.FaweMask; import com.boydti.fawe.regions.general.RegionFilter; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.regions.AbstractRegion; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Polygonal2DRegion; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -81,7 +92,7 @@ public class Worldguard extends BukkitMaskManager implements Listener { } @Override - public BukkitMask getMask(final FawePlayer fp) { + public FaweMask getMask(FawePlayer fp, MaskType type) { final Player player = fp.parent; final com.sk89q.worldguard.LocalPlayer localplayer = this.worldguard.wrapPlayer(player); final Location location = player.getLocation(); @@ -93,8 +104,17 @@ public class Worldguard extends BukkitMaskManager implements Listener { pos1 = new Location(location.getWorld(), Integer.MIN_VALUE, 0, Integer.MIN_VALUE); pos2 = new Location(location.getWorld(), Integer.MAX_VALUE, 255, Integer.MAX_VALUE); } else { - pos1 = new Location(location.getWorld(), myregion.getMinimumPoint().getBlockX(), myregion.getMinimumPoint().getBlockY(), myregion.getMinimumPoint().getBlockZ()); - pos2 = new Location(location.getWorld(), myregion.getMaximumPoint().getBlockX(), myregion.getMaximumPoint().getBlockY(), myregion.getMaximumPoint().getBlockZ()); + if (myregion instanceof ProtectedCuboidRegion) { + pos1 = new Location(location.getWorld(), myregion.getMinimumPoint().getBlockX(), myregion.getMinimumPoint().getBlockY(), myregion.getMinimumPoint().getBlockZ()); + pos2 = new Location(location.getWorld(), myregion.getMaximumPoint().getBlockX(), myregion.getMaximumPoint().getBlockY(), myregion.getMaximumPoint().getBlockZ()); + } else { + return new FaweMask(adapt(myregion), myregion.getId()) { + @Override + public boolean isValid(FawePlayer player, MaskType type) { + return isAllowed(worldguard.wrapPlayer((Player) player.parent), myregion); + } + }; + } } return new BukkitMask(pos1, pos2) { @Override @@ -116,4 +136,54 @@ public class Worldguard extends BukkitMaskManager implements Listener { public RegionFilter getFilter(String world) { return new WorldGuardFilter(Bukkit.getWorld(world)); } + + private static class AdaptedRegion extends AbstractRegion { + private final ProtectedRegion region; + + public AdaptedRegion(ProtectedRegion region) { + super(null); + this.region = region; + } + + @Override + public Vector getMinimumPoint() { + return region.getMinimumPoint(); + } + + @Override + public Vector getMaximumPoint() { + return region.getMaximumPoint(); + } + + @Override + public void expand(Vector... changes) { + throw new UnsupportedOperationException("Region is immutable"); + } + + @Override + public void contract(Vector... changes) { + throw new UnsupportedOperationException("Region is immutable"); + } + + @Override + public boolean contains(Vector position) { + return region.contains(position); + } + } + + private static Region adapt(ProtectedRegion region) { + if (region instanceof ProtectedCuboidRegion) { + return new CuboidRegion(region.getMinimumPoint(), region.getMaximumPoint()); + } + if (region instanceof GlobalProtectedRegion) { + return RegionWrapper.GLOBAL(); + } + if (region instanceof ProtectedPolygonalRegion) { + ProtectedPolygonalRegion casted = (ProtectedPolygonalRegion) region; + BlockVector max = region.getMaximumPoint(); + BlockVector min = region.getMinimumPoint(); + return new Polygonal2DRegion(null, casted.getPoints(), min.getBlockY(), max.getBlockY()); + } + return new AdaptedRegion(region); + } } diff --git a/core/src/main/java/com/boydti/fawe/FaweAPI.java b/core/src/main/java/com/boydti/fawe/FaweAPI.java index 6f0dab29..d7b5b7ce 100644 --- a/core/src/main/java/com/boydti/fawe/FaweAPI.java +++ b/core/src/main/java/com/boydti/fawe/FaweAPI.java @@ -267,7 +267,7 @@ public class FaweAPI { * @param player * @return */ - public static RegionWrapper[] getRegions(FawePlayer player) { + public static Region[] getRegions(FawePlayer player) { return WEManager.IMP.getMask(player); } diff --git a/core/src/main/java/com/boydti/fawe/example/Relighter.java b/core/src/main/java/com/boydti/fawe/example/Relighter.java index 3bdc4fc6..82f5ea0b 100644 --- a/core/src/main/java/com/boydti/fawe/example/Relighter.java +++ b/core/src/main/java/com/boydti/fawe/example/Relighter.java @@ -27,4 +27,4 @@ public interface Relighter { public static final byte AIR = 1; public static final byte SOLID = 2; } -} +} \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java index ecfb65dc..a34b30bd 100644 --- a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java +++ b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java @@ -9,46 +9,29 @@ import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.regions.FaweMaskManager; -import com.boydti.fawe.util.EditSessionBuilder; -import com.boydti.fawe.util.MainUtil; -import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; -import com.boydti.fawe.util.WEManager; +import com.boydti.fawe.util.*; import com.boydti.fawe.wrappers.FakePlayer; import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper; import com.boydti.fawe.wrappers.PlayerWrapper; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EmptyClipboardException; -import com.sk89q.worldedit.IncompleteRegionException; -import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.*; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.Tool; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.event.platform.CommandEvent; -import com.sk89q.worldedit.extension.platform.Actor; -import com.sk89q.worldedit.extension.platform.Capability; -import com.sk89q.worldedit.extension.platform.CommandManager; -import com.sk89q.worldedit.extension.platform.PlatformManager; -import com.sk89q.worldedit.extension.platform.PlayerProxy; +import com.sk89q.worldedit.extension.platform.*; import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.regions.RegionOperationException; -import com.sk89q.worldedit.regions.RegionSelector; +import com.sk89q.worldedit.regions.*; +import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; +import com.sk89q.worldedit.regions.selector.CylinderRegionSelector; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.registry.WorldData; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicInteger; @@ -181,13 +164,9 @@ public abstract class FawePlayer extends Metadatable { } } - public void checkAllowedRegion(Region selection) { - checkAllowedRegion(new RegionWrapper(selection.getMinimumPoint(), selection.getMaximumPoint())); - } - - public void checkAllowedRegion(RegionWrapper wrappedSelection) { - RegionWrapper[] allowed = WEManager.IMP.getMask(this, FaweMaskManager.MaskType.OWNER); - HashSet allowedSet = new HashSet<>(Arrays.asList(allowed)); + public void checkAllowedRegion(Region wrappedSelection) { + Region[] allowed = WEManager.IMP.getMask(this, FaweMaskManager.MaskType.OWNER); + HashSet allowedSet = new HashSet<>(Arrays.asList(allowed)); if (allowed.length == 0) { throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_NO_REGION); } else if (!WEManager.IMP.regionContains(wrappedSelection, allowedSet)) { @@ -371,7 +350,7 @@ public abstract class FawePlayer extends Metadatable { public FaweQueue getMaskedFaweQueue(boolean autoQueue) { FaweQueue queue = getFaweQueue(autoQueue); - RegionWrapper[] allowedRegions = getCurrentRegions(); + Region[] allowedRegions = getCurrentRegions(); if (allowedRegions.length == 1 && allowedRegions[0].isGlobal()) { return queue; } @@ -507,11 +486,13 @@ public abstract class FawePlayer extends Metadatable { * * @return */ - public RegionWrapper[] getCurrentRegions() { + @Deprecated + public Region[] getCurrentRegions() { return WEManager.IMP.getMask(this); } - public RegionWrapper[] getCurrentRegions(FaweMaskManager.MaskType type) { + @Deprecated + public Region[] getCurrentRegions(FaweMaskManager.MaskType type) { return WEManager.IMP.getMask(this, type); } @@ -520,11 +501,34 @@ public abstract class FawePlayer extends Metadatable { * * @param region */ + @Deprecated public void setSelection(final RegionWrapper region) { final Player player = this.getPlayer(); - Vector top = region.getTopVector(); + Vector top = region.getMaximumPoint(); top.mutY(getWorld().getMaxY()); - final RegionSelector selector = new CuboidRegionSelector(player.getWorld(), region.getBottomVector(), top); + final RegionSelector selector = new CuboidRegionSelector(player.getWorld(), region.getMinimumPoint(), top); + this.getSession().setRegionSelector(player.getWorld(), selector); + } + + public void setSelection(Region region) { + RegionSelector selector; + switch (region.getClass().getName()) { + case "ConvexPolyhedralRegion": + selector = new ConvexPolyhedralRegionSelector((ConvexPolyhedralRegion) region); + break; + case "CylinderRegion": + selector = new CylinderRegionSelector((CylinderRegion) region); + break; + case "Polygonal2DRegion": + selector = new com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector((Polygonal2DRegion) region); + break; + default: + selector = new CuboidRegionSelector(null, region.getMinimumPoint(), region.getMaximumPoint()); + break; + } + selector.setWorld(region.getWorld()); + + final Player player = this.getPlayer(); this.getSession().setRegionSelector(player.getWorld(), selector); } @@ -542,11 +546,11 @@ public abstract class FawePlayer extends Metadatable { * * @return */ - public RegionWrapper getLargestRegion() { + public Region getLargestRegion() { int area = 0; - RegionWrapper max = null; - for (final RegionWrapper region : this.getCurrentRegions()) { - final int tmp = (region.maxX - region.minX) * (region.maxZ - region.minZ); + Region max = null; + for (final Region region : this.getCurrentRegions()) { + final int tmp = region.getArea(); if (tmp > area) { area = tmp; max = region; diff --git a/core/src/main/java/com/boydti/fawe/object/MaskedFaweQueue.java b/core/src/main/java/com/boydti/fawe/object/MaskedFaweQueue.java index 3df29ba2..57bafcc2 100644 --- a/core/src/main/java/com/boydti/fawe/object/MaskedFaweQueue.java +++ b/core/src/main/java/com/boydti/fawe/object/MaskedFaweQueue.java @@ -10,17 +10,18 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.biome.BaseBiome; public class MaskedFaweQueue extends DelegateFaweQueue { private FaweRegionExtent region; - public MaskedFaweQueue(FaweQueue parent, RegionWrapper[] mask) { + public MaskedFaweQueue(FaweQueue parent, Region[] mask) { super(parent); setMask(mask); } - public void setMask(RegionWrapper[] mask) { + public void setMask(Region[] mask) { switch (mask.length) { case 0: region = new HeightBoundExtent(this, FaweLimit.MAX.copy(), Integer.MIN_VALUE, Integer.MAX_VALUE); diff --git a/core/src/main/java/com/boydti/fawe/object/RegionWrapper.java b/core/src/main/java/com/boydti/fawe/object/RegionWrapper.java index 9f6155ab..cb4d3533 100644 --- a/core/src/main/java/com/boydti/fawe/object/RegionWrapper.java +++ b/core/src/main/java/com/boydti/fawe/object/RegionWrapper.java @@ -1,17 +1,20 @@ package com.boydti.fawe.object; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.regions.CuboidRegion; -public class RegionWrapper { - public final int minX; - public final int maxX; - public final int minY; - public final int maxY; - public final int minZ; - public final int maxZ; +public class RegionWrapper extends CuboidRegion { + private final static RegionWrapper GLOBAL = new RegionWrapper(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE); + + public int minX; + public int maxX; + public int minY; + public int maxY; + public int minZ; + public int maxZ; public static RegionWrapper GLOBAL() { - return new RegionWrapper(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE); + return GLOBAL; } public RegionWrapper(final int minX, final int maxX, final int minZ, final int maxZ) { @@ -19,15 +22,24 @@ public class RegionWrapper { } public RegionWrapper(final int minX, final int maxX, final int minY, final int maxY, final int minZ, final int maxZ) { - this.maxX = maxX; - this.minX = minX; - this.maxZ = maxZ; - this.minZ = minZ; - this.minY = minY; - this.maxY = Math.min(255, maxY); + this(new Vector(minX, 0, minZ), new Vector(maxX, 255, maxZ)); } public RegionWrapper(final Vector pos1, final Vector pos2) { + super(pos1, pos2); + this.minX = Math.min(pos1.getBlockX(), pos2.getBlockX()); + this.minZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); + this.maxX = Math.max(pos1.getBlockX(), pos2.getBlockX()); + this.maxZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ()); + this.minY = Math.min(pos1.getBlockY(), pos2.getBlockY()); + this.maxY = Math.max(pos1.getBlockY(), pos2.getBlockY()); + } + + @Override + protected void recalculate() { + super.recalculate(); + Vector pos1 = getMinimumPoint(); + Vector pos2 = getMaximumPoint(); this.minX = Math.min(pos1.getBlockX(), pos2.getBlockX()); this.minZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); this.maxX = Math.max(pos1.getBlockX(), pos2.getBlockX()); @@ -112,14 +124,6 @@ public class RegionWrapper { return this.minX + "," + this.minY + "," + this.minZ + "->" + this.maxX + "," + this.maxY + "," + this.maxZ; } - public Vector getBottomVector() { - return new Vector(this.minX, 1, this.minZ); - } - - public Vector getTopVector() { - return new Vector(this.maxX, 255, this.maxZ); - } - public boolean isGlobal() { return minX == Integer.MIN_VALUE && minZ == Integer.MIN_VALUE && maxX == Integer.MAX_VALUE && maxZ == Integer.MAX_VALUE && minY <= 0 && maxY >= 255; } diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java b/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java index 5facd362..7a01024e 100644 --- a/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java +++ b/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java @@ -12,6 +12,7 @@ import com.boydti.fawe.util.MainUtil; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.World; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import java.io.DataOutput; @@ -136,7 +137,7 @@ public class DiskStorageHistory extends FaweStreamChangeSet { enttFile.delete(); } - public void undo(FawePlayer fp, RegionWrapper[] regions) { + public void undo(FawePlayer fp, Region[] regions) { EditSession session = toEditSession(fp, regions); session.undo(session); deleteFiles(); diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java b/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java index 66502d6e..dc81ee72 100644 --- a/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java +++ b/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java @@ -7,7 +7,6 @@ import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.FaweQueue; -import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal2; import com.boydti.fawe.util.EditSessionBuilder; import com.boydti.fawe.util.MainUtil; @@ -23,6 +22,7 @@ import com.sk89q.worldedit.history.change.Change; import com.sk89q.worldedit.history.change.EntityCreate; import com.sk89q.worldedit.history.change.EntityRemove; import com.sk89q.worldedit.history.changeset.ChangeSet; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BaseBiome; import java.util.Iterator; @@ -151,7 +151,7 @@ public abstract class FaweChangeSet implements ChangeSet { return toEditSession(player, null); } - public EditSession toEditSession(FawePlayer player, RegionWrapper[] regions) { + public EditSession toEditSession(FawePlayer player, Region[] regions) { EditSessionBuilder builder = new EditSessionBuilder(getWorld()).player(player).autoQueue(false).fastmode(false).checkMemory(false).changeSet(this).limitUnlimited(); if (regions != null) { builder.allowedRegions(regions); diff --git a/core/src/main/java/com/boydti/fawe/object/extent/FaweRegionExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/FaweRegionExtent.java index f94c86e4..0914925f 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/FaweRegionExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/FaweRegionExtent.java @@ -2,7 +2,6 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweLimit; -import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.util.WEManager; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; @@ -12,6 +11,7 @@ import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BaseBiome; import java.util.Collection; @@ -34,10 +34,10 @@ public abstract class FaweRegionExtent extends ResettableExtent { public abstract boolean contains(int x, int z); - public abstract Collection getRegions(); + public abstract Collection getRegions(); public boolean isGlobal() { - for (RegionWrapper region : getRegions()) { + for (Region region : getRegions()) { if (region.isGlobal()) { return true; } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/HeightBoundExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/HeightBoundExtent.java index c14833b5..f69ef88f 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/HeightBoundExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/HeightBoundExtent.java @@ -3,6 +3,7 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.RegionWrapper; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.regions.Region; import java.util.Arrays; import java.util.Collection; @@ -33,7 +34,7 @@ public class HeightBoundExtent extends FaweRegionExtent { } @Override - public Collection getRegions() { + public Collection getRegions() { return Arrays.asList(new RegionWrapper(Integer.MIN_VALUE, Integer.MAX_VALUE, min, max, Integer.MIN_VALUE, Integer.MAX_VALUE)); } } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/MultiRegionExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/MultiRegionExtent.java index 7e6a7df3..6c9c1fd9 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/MultiRegionExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/MultiRegionExtent.java @@ -1,15 +1,15 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.object.FaweLimit; -import com.boydti.fawe.object.RegionWrapper; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.regions.Region; import java.util.Arrays; import java.util.Collection; public class MultiRegionExtent extends FaweRegionExtent { - private RegionWrapper region; - private final RegionWrapper[] regions; + private Region region; + private final Region[] regions; private int index; /** @@ -17,7 +17,7 @@ public class MultiRegionExtent extends FaweRegionExtent { * * @param extent the extent */ - public MultiRegionExtent(Extent extent, FaweLimit limit, RegionWrapper[] regions) { + public MultiRegionExtent(Extent extent, FaweLimit limit, Region[] regions) { super(extent, limit); this.index = 0; this.region = regions[0]; @@ -26,13 +26,13 @@ public class MultiRegionExtent extends FaweRegionExtent { @Override public boolean contains(int x, int y, int z) { - if (region.isIn(x, y, z)) { + if (region.contains(x, y, z)) { return true; } for (int i = 0; i < regions.length; i++) { if (i != index) { - RegionWrapper current = regions[i]; - if (current.isIn(x, y, z)) { + Region current = regions[i]; + if (current.contains(x, y, z)) { region = current; index = i; return true; @@ -44,13 +44,13 @@ public class MultiRegionExtent extends FaweRegionExtent { @Override public boolean contains(int x, int z) { - if (region.isIn(x, z)) { + if (region.contains(x, z)) { return true; } for (int i = 0; i < regions.length; i++) { if (i != index) { - RegionWrapper current = regions[i]; - if (current.isIn(x, z)) { + Region current = regions[i]; + if (current.contains(x, z)) { region = current; index = i; return true; @@ -61,7 +61,7 @@ public class MultiRegionExtent extends FaweRegionExtent { } @Override - public Collection getRegions() { + public Collection getRegions() { return Arrays.asList(regions); } } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java index 1118e4ca..a8cb8ce4 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java @@ -2,7 +2,6 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweLimit; -import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.exception.FaweException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -115,7 +114,7 @@ public class NullExtent extends FaweRegionExtent { } @Override - public Collection getRegions() { + public Collection getRegions() { return Collections.emptyList(); } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/SingleRegionExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/SingleRegionExtent.java index 86557f6f..b991ad92 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/SingleRegionExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/SingleRegionExtent.java @@ -1,37 +1,37 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.object.FaweLimit; -import com.boydti.fawe.object.RegionWrapper; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.regions.Region; import java.util.Arrays; import java.util.Collection; public class SingleRegionExtent extends FaweRegionExtent { - private final RegionWrapper region; + private final Region region; /** * Create a new instance. * * @param extent the extent */ - public SingleRegionExtent(Extent extent, FaweLimit limit, RegionWrapper region) { + public SingleRegionExtent(Extent extent, FaweLimit limit, Region region) { super(extent, limit); this.region = region; } @Override public boolean contains(int x, int y, int z) { - return region.isIn(x, y, z); + return region.contains(x, y, z); } @Override public boolean contains(int x, int z) { - return region.isIn(x, z); + return region.contains(x, z); } @Override - public Collection getRegions() { + public Collection getRegions() { return Arrays.asList(region); } } diff --git a/core/src/main/java/com/boydti/fawe/object/io/RandomFileOutputStream.java b/core/src/main/java/com/boydti/fawe/object/io/RandomFileOutputStream.java new file mode 100644 index 00000000..648d0de8 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/io/RandomFileOutputStream.java @@ -0,0 +1,110 @@ +package com.boydti.fawe.object.io; + +import java.io.*; + +/** + * A positionable file output stream. + *

+ * Threading Design : [x] Single Threaded [ ] Threadsafe [ ] Immutable [ ] Isolated + */ + +public class RandomFileOutputStream extends OutputStream +{ + +// ***************************************************************************** +// INSTANCE PROPERTIES +// ***************************************************************************** + + protected RandomAccessFile randomFile; // the random file to write to + protected boolean sync; // whether to synchronize every write + protected boolean closeParent; + +// ***************************************************************************** +// INSTANCE CONSTRUCTION/INITIALIZATON/FINALIZATION, OPEN/CLOSE +// ***************************************************************************** + + public RandomFileOutputStream(String fnm) throws IOException { + this(fnm,false); + } + + public RandomFileOutputStream(String fnm, boolean syn) throws IOException { + this(new File(fnm),syn); + } + + public RandomFileOutputStream(File fil) throws IOException { + this(fil,false); + } + + public RandomFileOutputStream(File fil, boolean syn) throws IOException { + super(); + + File par; // parent file + + fil=fil.getAbsoluteFile(); + if((par=fil.getParentFile())!=null) { par.mkdirs(); } + randomFile=new RandomAccessFile(fil,"rw"); + sync=syn; + this.closeParent = true; + } + + public RandomFileOutputStream(RandomAccessFile randomFile, boolean syn, boolean closeParent) { + super(); + this.randomFile = randomFile; + sync=syn; + this.closeParent = closeParent; + } + +// ***************************************************************************** +// INSTANCE METHODS - OUTPUT STREAM IMPLEMENTATION +// ***************************************************************************** + + public void write(int val) throws IOException { + randomFile.write(val); + if(sync) { randomFile.getFD().sync(); } + } + + public void write(byte[] val) throws IOException { + randomFile.write(val); + if(sync) { randomFile.getFD().sync(); } + } + + public void write(byte[] val, int off, int len) throws IOException { + randomFile.write(val,off,len); + if(sync) { randomFile.getFD().sync(); } + } + + public void flush() throws IOException { + if(sync) { randomFile.getFD().sync(); } + } + + public void close() throws IOException { + if (closeParent) { + randomFile.close(); + } + } + +// ***************************************************************************** +// INSTANCE METHODS - RANDOM ACCESS EXTENSIONS +// ***************************************************************************** + + public long getFilePointer() throws IOException { + return randomFile.getFilePointer(); + } + + public void setFilePointer(long pos) throws IOException { + randomFile.seek(pos); + } + + public long getFileSize() throws IOException { + return randomFile.length(); + } + + public void setFileSize(long len) throws IOException { + randomFile.setLength(len); + } + + public FileDescriptor getFD() throws IOException { + return randomFile.getFD(); + } + +} // END PUBLIC CLASS \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/regions/FaweMask.java b/core/src/main/java/com/boydti/fawe/regions/FaweMask.java index c6214cd4..99e9aa4b 100644 --- a/core/src/main/java/com/boydti/fawe/regions/FaweMask.java +++ b/core/src/main/java/com/boydti/fawe/regions/FaweMask.java @@ -1,25 +1,21 @@ package com.boydti.fawe.regions; import com.boydti.fawe.object.FawePlayer; -import com.boydti.fawe.object.RegionWrapper; import com.sk89q.worldedit.BlockVector; -import java.util.Arrays; -import java.util.HashSet; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.IDelegateRegion; +import com.sk89q.worldedit.regions.Region; -public class FaweMask { +public class FaweMask implements IDelegateRegion { + private final Region region; private String description = null; - private BlockVector position1; - private BlockVector position2; + @Deprecated public FaweMask(final BlockVector pos1, final BlockVector pos2, final String id) { - if ((pos1 == null) || (pos2 == null)) { - throw new IllegalArgumentException("BlockVectors cannot be null!"); - } - this.description = id; - this.position1 = new BlockVector(Math.min(pos1.getBlockX(), pos2.getBlockX()), pos1.getBlockY(), Math.min(pos1.getBlockZ(), pos2.getBlockZ())); - this.position2 = new BlockVector(Math.max(pos1.getBlockX(), pos2.getBlockX()), pos2.getBlockY(), Math.max(pos1.getBlockZ(), pos2.getBlockZ())); + this(new CuboidRegion(pos1, pos2), id); } + @Deprecated public FaweMask(final BlockVector pos1, final BlockVector pos2) { this(pos1, pos2, null); if ((pos1 == null) || (pos2 == null)) { @@ -27,60 +23,26 @@ public class FaweMask { } } - public HashSet getRegions() { - final BlockVector lower = this.getLowerBound(); - final BlockVector upper = this.getUpperBound(); - return new HashSet<>(Arrays.asList(new RegionWrapper(lower.getBlockX(), upper.getBlockX(), lower.getBlockY(), upper.getBlockY(), lower.getBlockZ(), upper.getBlockZ()))); + public FaweMask(Region region, String id) { + this.region = region; + this.description = id; + } + + @Override + public Region getRegion() { + return region; } public String getName() { return this.description; } - public BlockVector getLowerBound() { - return this.position1; - } - - public BlockVector getUpperBound() { - return this.position2; - } - - public void setBounds(final BlockVector pos1, final BlockVector pos2) { - if ((pos1 == null) || (pos2 == null)) { - throw new IllegalArgumentException("BlockVectors cannot be null!"); - } - this.position1 = new BlockVector(Math.min(pos1.getBlockX(), pos2.getBlockX()), 0, Math.min(pos1.getBlockZ(), pos2.getBlockZ())); - this.position2 = new BlockVector(Math.max(pos1.getBlockX(), pos2.getBlockX()), 256, Math.max(pos1.getBlockZ(), pos2.getBlockZ())); - } - public boolean isValid(FawePlayer player, FaweMaskManager.MaskType type) { return false; } - public BlockVector[] getBounds() { - final BlockVector[] BlockVectors = {this.position1, this.position2}; - return BlockVectors; - } - - public boolean contains(final BlockVector loc) { - if (loc.getBlockX() < this.position1.getBlockX()) { - return false; - } - if (loc.getBlockX() > this.position2.getBlockX()) { - return false; - } - if (loc.getBlockZ() < this.position1.getBlockZ()) { - return false; - } - if (loc.getBlockZ() > this.position2.getBlockZ()) { - return false; - } - if (loc.getBlockY() < this.position1.getBlockY()) { - return false; - } - if (loc.getBlockY() > this.position2.getBlockY()) { - return false; - } - return true; + @Override + public Region clone() { + throw new UnsupportedOperationException("Clone not supported"); } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/regions/FaweMaskManager.java b/core/src/main/java/com/boydti/fawe/regions/FaweMaskManager.java index 22dbd242..be506a3a 100644 --- a/core/src/main/java/com/boydti/fawe/regions/FaweMaskManager.java +++ b/core/src/main/java/com/boydti/fawe/regions/FaweMaskManager.java @@ -25,6 +25,7 @@ public abstract class FaweMaskManager { return this.key; } + @Deprecated public FaweMask getMask(final FawePlayer player) { return getMask(player, MaskType.MEMBER); } diff --git a/core/src/main/java/com/boydti/fawe/regions/SimpleRegion.java b/core/src/main/java/com/boydti/fawe/regions/SimpleRegion.java new file mode 100644 index 00000000..f01b054b --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/regions/SimpleRegion.java @@ -0,0 +1,48 @@ +package com.boydti.fawe.regions; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.regions.AbstractRegion; +import com.sk89q.worldedit.regions.RegionOperationException; +import com.sk89q.worldedit.world.World; + +public abstract class SimpleRegion extends AbstractRegion { + private final Vector max; + private final Vector min; + + public SimpleRegion(World world, Vector min, Vector max) { + super(world); + this.min = min; + this.max = max; + } + + @Override + public Vector getMinimumPoint() { + return min; + } + + @Override + public Vector getMaximumPoint() { + return max; + } + + @Override + public void expand(Vector... changes) throws RegionOperationException { + throw new UnsupportedOperationException("Region is immutable"); + } + + @Override + public void contract(Vector... changes) throws RegionOperationException { + throw new UnsupportedOperationException("Region is immutable"); + } + + @Override + public boolean contains(Vector p) { + return contains(p.getBlockX(), p.getBlockY(), p.getBlockZ()); + } + + @Override + public abstract boolean contains(int x, int y, int z); + + @Override + public abstract boolean contains(int x, int z); +} diff --git a/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java b/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java index ef28a453..091f6cde 100644 --- a/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java +++ b/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java @@ -1,9 +1,11 @@ package com.boydti.fawe.regions.general.plot; import com.boydti.fawe.Fawe; +import com.boydti.fawe.FaweAPI; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.regions.FaweMask; import com.boydti.fawe.regions.FaweMaskManager; +import com.boydti.fawe.regions.SimpleRegion; import com.boydti.fawe.regions.general.RegionFilter; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.commands.MainCommand; @@ -21,6 +23,8 @@ import com.intellectualcrafters.plot.util.block.GlobalBlockQueue; import com.intellectualcrafters.plot.util.block.QueueProvider; import com.plotsquared.listener.WEManager; import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; import java.util.HashSet; import java.util.UUID; @@ -123,21 +127,28 @@ public class PlotSquaredFeature extends FaweMaskManager { final BlockVector pos1 = new BlockVector(region.minX, min, region.minZ); final BlockVector pos2 = new BlockVector(region.maxX, max, region.maxZ); final Plot finalPlot = plot; - if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot)) { + if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot) || regions.isEmpty()) { return null; } - return new FaweMask(pos1, pos2) { - @Override - public String getName() { - return "PLOT^2"; - } + Region maskedRegion; + if (regions.size() == 1) { + maskedRegion = new CuboidRegion(pos1, pos2); + } else { + maskedRegion = new SimpleRegion(FaweAPI.getWorld(area.worldname), pos1, pos2) { + @Override + public boolean contains(int x, int y, int z) { + return WEManager.maskContains(regions, x, y, z); + } - @Override - public boolean contains(BlockVector loc) { - return WEManager.maskContains(regions, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); - } + @Override + public boolean contains(int x, int z) { + return WEManager.maskContains(regions, x, z); + } + }; + } + return new FaweMask(maskedRegion, "PLOT^2") { @Override public boolean isValid(FawePlayer player, MaskType type) { if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot)) { @@ -145,11 +156,6 @@ public class PlotSquaredFeature extends FaweMaskManager { } return isAllowed(player, finalPlot, type); } - - @Override - public HashSet getRegions() { - return faweRegions; - } }; } diff --git a/core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java b/core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java index ddeb1226..39418c8b 100644 --- a/core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java +++ b/core/src/main/java/com/boydti/fawe/util/EditSessionBuilder.java @@ -4,17 +4,14 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweAPI; import com.boydti.fawe.config.Settings; import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; -import com.boydti.fawe.object.FaweLimit; -import com.boydti.fawe.object.FawePlayer; -import com.boydti.fawe.object.FaweQueue; -import com.boydti.fawe.object.NullChangeSet; -import com.boydti.fawe.object.RegionWrapper; +import com.boydti.fawe.object.*; import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.MemoryOptimizedHistory; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.event.extent.EditSessionEvent; import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.world.World; import java.util.UUID; @@ -31,7 +28,7 @@ public class EditSessionBuilder { private FawePlayer player; private FaweLimit limit; private FaweChangeSet changeSet; - private RegionWrapper[] allowedRegions; + private Region[] allowedRegions; private Boolean autoQueue; private Boolean fastmode; private Boolean checkMemory; @@ -134,6 +131,12 @@ public class EditSessionBuilder { return this; } + public EditSessionBuilder allowedRegions(@Nullable Region[] allowedRegions) { + this.allowedRegions = allowedRegions; + return this; + } + + @Deprecated public EditSessionBuilder allowedRegions(@Nullable RegionWrapper[] allowedRegions) { this.allowedRegions = allowedRegions; return this; diff --git a/core/src/main/java/com/boydti/fawe/util/MathMan.java b/core/src/main/java/com/boydti/fawe/util/MathMan.java index c47b197a..bec54ee9 100644 --- a/core/src/main/java/com/boydti/fawe/util/MathMan.java +++ b/core/src/main/java/com/boydti/fawe/util/MathMan.java @@ -50,11 +50,8 @@ public class MathMan { return ANGLES[(int) (paramFloat * 10430.378F + 16384.0F) & 0xFFFF]; } - public static int log2nlz( int bits ) - { - if( bits == 0 ) - return 0; // or throw exception - return 31 - Integer.numberOfLeadingZeros( bits ); + public static int log2nlz( int bits ) { + return Integer.SIZE - Integer.numberOfLeadingZeros(bits); } public static int floorZero(double d0) { diff --git a/core/src/main/java/com/boydti/fawe/util/WEManager.java b/core/src/main/java/com/boydti/fawe/util/WEManager.java index 8ac722d6..07a14490 100644 --- a/core/src/main/java/com/boydti/fawe/util/WEManager.java +++ b/core/src/main/java/com/boydti/fawe/util/WEManager.java @@ -9,12 +9,13 @@ import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.regions.FaweMask; import com.boydti.fawe.regions.FaweMaskManager; +import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.regions.Region; import java.lang.reflect.Field; import java.util.ArrayDeque; -import java.util.Collection; import java.util.HashSet; import java.util.Set; @@ -68,15 +69,13 @@ public class WEManager { } @Deprecated - public RegionWrapper[] getMask(final FawePlayer player) { + public Region[] getMask(final FawePlayer player) { return getMask(player, FaweMaskManager.MaskType.MEMBER); } - public boolean isIn(int x, int y, int z, Collection regions) { - for (RegionWrapper region : regions) { - if (region.isIn(x, y, z)) { - return true; - } + public boolean isIn(int x, int y, int z, Region region) { + if (region.contains(x, y, z)) { + return true; } return false; } @@ -87,9 +86,9 @@ public class WEManager { * @param player * @return */ - public RegionWrapper[] getMask(final FawePlayer player, FaweMaskManager.MaskType type) { + public Region[] getMask(final FawePlayer player, FaweMaskManager.MaskType type) { if (!Settings.IMP.REGION_RESTRICTIONS || player.hasPermission("fawe.bypass") || player.hasPermission("fawe.bypass.regions")) { - return new RegionWrapper[]{RegionWrapper.GLOBAL()}; + return new Region[]{RegionWrapper.GLOBAL()}; } FaweLocation loc = player.getLocation(); String world = loc.world; @@ -99,7 +98,7 @@ public class WEManager { } player.setMeta("lastMaskWorld", world); Set masks = player.getMeta("lastMask"); - HashSet regions = new HashSet<>(); + HashSet regions = new HashSet<>(); if (masks == null) { masks = new HashSet<>(); } else { @@ -108,18 +107,15 @@ public class WEManager { removed = true; } else { for (FaweMask mask : masks) { - HashSet curRegions = mask.getRegions(); - for (RegionWrapper region : curRegions) { - if (!isIn(loc.x, loc.y, loc.z, curRegions)) { - removed = true; - break; - } + Region region = mask.getRegion(); + if (!region.contains(loc.x, loc.y, loc.z)) { + removed = true; } if (!mask.isValid(player, type)) { removed = true; break; } - regions.addAll(curRegions); + regions.add(region); } } if (removed) { @@ -132,11 +128,10 @@ public class WEManager { for (final FaweMaskManager manager : managers) { if (player.hasPermission("fawe." + manager.getKey())) { try { - final FaweMask fm = manager.getMask(player); - if (fm != null) { - HashSet cur = fm.getRegions(); - regions.addAll(cur); - masks.add(fm); + final FaweMask mask = manager.getMask(player, FaweMaskManager.MaskType.MEMBER); + if (mask != null) { + regions.add(mask.getRegion()); + masks.add(mask); } } catch (Throwable e) { e.printStackTrace(); @@ -152,12 +147,17 @@ public class WEManager { } - public boolean intersects(final RegionWrapper region1, final RegionWrapper region2) { - return (region1.minX <= region2.maxX) && (region1.maxX >= region2.minX) && (region1.minZ <= region2.maxZ) && (region1.maxZ >= region2.minZ); + public boolean intersects(final Region region1, final Region region2) { + Vector rg1P1 = region1.getMinimumPoint(); + Vector rg1P2 = region1.getMaximumPoint(); + Vector rg2P1 = region2.getMinimumPoint(); + Vector rg2P2 = region2.getMaximumPoint(); + + return (rg1P1.getBlockX() <= rg2P2.getBlockX()) && (rg1P2.getBlockX() >= rg2P1.getBlockX()) && (rg1P1.getBlockZ() <= rg2P2.getBlockZ()) && (rg1P2.getBlockZ() >= rg2P1.getBlockZ()); } - public boolean regionContains(final RegionWrapper selection, final HashSet mask) { - for (final RegionWrapper region : mask) { + public boolean regionContains(final Region selection, final HashSet mask) { + for (final Region region : mask) { if (this.intersects(region, selection)) { return true; } diff --git a/core/src/main/java/com/boydti/fawe/util/metrics/BStats.java b/core/src/main/java/com/boydti/fawe/util/metrics/BStats.java index fd926031..b9c4f4fc 100644 --- a/core/src/main/java/com/boydti/fawe/util/metrics/BStats.java +++ b/core/src/main/java/com/boydti/fawe/util/metrics/BStats.java @@ -52,7 +52,7 @@ public class BStats implements Closeable { private Gson gson = new Gson(); // Is bStats enabled on this server? - private boolean enabled; + private volatile boolean enabled; // The uuid of the server private UUID serverUUID; diff --git a/core/src/main/java/com/sk89q/jnbt/Tag.java b/core/src/main/java/com/sk89q/jnbt/Tag.java index ff19d3c6..f4ad574f 100644 --- a/core/src/main/java/com/sk89q/jnbt/Tag.java +++ b/core/src/main/java/com/sk89q/jnbt/Tag.java @@ -38,4 +38,6 @@ public abstract class Tag { public static Class inject() { return Tag.class; } + + } \ No newline at end of file diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 6f968b1e..a4ff4b36 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -30,44 +30,18 @@ import com.boydti.fawe.jnbt.anvil.MCAQueue; import com.boydti.fawe.jnbt.anvil.MCAWorld; import com.boydti.fawe.logging.LoggingChangeSet; import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; -import com.boydti.fawe.object.FaweLimit; -import com.boydti.fawe.object.FawePlayer; -import com.boydti.fawe.object.FaweQueue; -import com.boydti.fawe.object.HasFaweQueue; -import com.boydti.fawe.object.HistoryExtent; -import com.boydti.fawe.object.NullChangeSet; -import com.boydti.fawe.object.RegionWrapper; -import com.boydti.fawe.object.RunnableVal; -import com.boydti.fawe.object.changeset.BlockBagChangeSet; -import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet; -import com.boydti.fawe.object.changeset.DiskStorageHistory; -import com.boydti.fawe.object.changeset.FaweChangeSet; -import com.boydti.fawe.object.changeset.MemoryOptimizedHistory; +import com.boydti.fawe.object.*; +import com.boydti.fawe.object.changeset.*; import com.boydti.fawe.object.clipboard.WorldCopyClipboard; import com.boydti.fawe.object.collection.LocalBlockVectorSet; import com.boydti.fawe.object.exception.FaweException; -import com.boydti.fawe.object.extent.FastWorldEditExtent; -import com.boydti.fawe.object.extent.FaweRegionExtent; -import com.boydti.fawe.object.extent.HeightBoundExtent; -import com.boydti.fawe.object.extent.MultiRegionExtent; -import com.boydti.fawe.object.extent.NullExtent; -import com.boydti.fawe.object.extent.ProcessedWEExtent; -import com.boydti.fawe.object.extent.ResettableExtent; -import com.boydti.fawe.object.extent.SingleRegionExtent; -import com.boydti.fawe.object.extent.SlowExtent; -import com.boydti.fawe.object.extent.SourceMaskExtent; +import com.boydti.fawe.object.extent.*; import com.boydti.fawe.object.function.SurfaceRegionFunction; import com.boydti.fawe.object.mask.ResettableMask; import com.boydti.fawe.object.pattern.ExistingPattern; import com.boydti.fawe.object.progress.ChatProgressTracker; import com.boydti.fawe.object.progress.DefaultProgressTracker; -import com.boydti.fawe.util.ExtentTraverser; -import com.boydti.fawe.util.MaskTraverser; -import com.boydti.fawe.util.MathMan; -import com.boydti.fawe.util.MemUtil; -import com.boydti.fawe.util.Perm; -import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; +import com.boydti.fawe.util.*; import com.boydti.fawe.wrappers.WorldWrapper; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.blocks.BaseBlock; @@ -91,27 +65,13 @@ import com.sk89q.worldedit.function.RegionMaskingFilter; import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.Naturalizer; import com.sk89q.worldedit.function.generator.GardenPatchGenerator; -import com.sk89q.worldedit.function.mask.BlockMask; -import com.sk89q.worldedit.function.mask.BoundedHeightMask; -import com.sk89q.worldedit.function.mask.ExistingBlockMask; -import com.sk89q.worldedit.function.mask.FuzzyBlockMask; -import com.sk89q.worldedit.function.mask.Mask; -import com.sk89q.worldedit.function.mask.MaskIntersection; -import com.sk89q.worldedit.function.mask.Masks; -import com.sk89q.worldedit.function.mask.NoiseFilter2D; -import com.sk89q.worldedit.function.mask.RegionMask; +import com.sk89q.worldedit.function.mask.*; import com.sk89q.worldedit.function.operation.ChangeSetExecutor; import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.util.RegionOffset; -import com.sk89q.worldedit.function.visitor.DirectionalVisitor; -import com.sk89q.worldedit.function.visitor.DownwardVisitor; -import com.sk89q.worldedit.function.visitor.FlatRegionVisitor; -import com.sk89q.worldedit.function.visitor.LayerVisitor; -import com.sk89q.worldedit.function.visitor.NonRisingVisitor; -import com.sk89q.worldedit.function.visitor.RecursiveVisitor; -import com.sk89q.worldedit.function.visitor.RegionVisitor; +import com.sk89q.worldedit.function.visitor.*; import com.sk89q.worldedit.history.UndoContext; import com.sk89q.worldedit.history.change.BlockChange; import com.sk89q.worldedit.history.changeset.ChangeSet; @@ -124,11 +84,7 @@ import com.sk89q.worldedit.math.interpolation.Node; import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.EllipsoidRegion; -import com.sk89q.worldedit.regions.FlatRegion; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.regions.Regions; +import com.sk89q.worldedit.regions.*; import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape; import com.sk89q.worldedit.regions.shape.ArbitraryShape; import com.sk89q.worldedit.regions.shape.RegionShape; @@ -140,15 +96,7 @@ import com.sk89q.worldedit.world.SimpleWorld; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.WorldData; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -213,7 +161,12 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, this(null, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, bus, event); } + @Deprecated public EditSession(@Nullable String worldName, @Nullable World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) { + this(worldName, world, queue, player, limit, changeSet, (Region[]) allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, bus, event); + } + + public EditSession(@Nullable String worldName, @Nullable World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable Region[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) { super(world); this.worldName = worldName == null ? world == null ? queue == null ? "" : queue.getWorldName() : Fawe.imp().getWorldName(world) : worldName; if (world == null && this.worldName != null) world = FaweAPI.getWorld(this.worldName); @@ -355,7 +308,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, } else { this.extent = new ProcessedWEExtent(this.extent, this.limit); if (allowedRegions.length == 1) { - RegionWrapper region = allowedRegions[0]; + Region region = allowedRegions[0]; this.extent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]); } else { this.extent = new MultiRegionExtent(this.extent, this.limit, allowedRegions); @@ -1080,50 +1033,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, return bypassAll.getLazyBlock(position); } - /** - * Returns the highest solid 'terrain' block which can occur naturally. - * - * @param x the X coordinate - * @param z the Z cooridnate - * @param minY minimal height - * @param maxY maximal height - * @return height of highest block found or 'minY' - */ - public int getHighestTerrainBlock(final int x, final int z, final int minY, final int maxY) { - return this.getHighestTerrainBlock(x, z, minY, maxY, false); - } - - /** - * Returns the highest solid 'terrain' block which can occur naturally. - * - * @param x the X coordinate - * @param z the Z coordinate - * @param minY minimal height - * @param maxY maximal height - * @param naturalOnly look at natural blocks or all blocks - * @return height of highest block found or 'minY' - */ - public int getHighestTerrainBlock(final int x, final int z, int minY, int maxY, final boolean naturalOnly) { - maxY = Math.min(maxY, Math.max(0, maxY)); - minY = Math.max(0, minY); - if (naturalOnly) { - for (int y = maxY; y >= minY; --y) { - BaseBlock block = getLazyBlock(x, y, z); - if (BlockType.isNaturalTerrainBlock(block.getId(), block.getData())) { - return y; - } - } - } else { - for (int y = maxY; y >= minY; --y) { - BaseBlock block = getLazyBlock(x, y, z); - if (!FaweCache.canPassThrough(block.getId(), block.getData())) { - return y; - } - } - } - return minY; - } - /** * Set a block, bypassing both history and block re-ordering. * @@ -1667,8 +1576,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, Vector pos1 = region.getMinimumPoint(); Vector pos2 = region.getMaximumPoint(); boolean contains = false; - for (RegionWrapper current : regionExtent.getRegions()) { - if (current.isIn((int) pos1.getX(), pos1.getBlockY(), pos1.getBlockZ()) && current.isIn(pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ())) { + for (Region current : regionExtent.getRegions()) { + if (current.contains((int) pos1.getX(), pos1.getBlockY(), pos1.getBlockZ()) && current.contains(pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ())) { contains = true; break; } diff --git a/core/src/main/java/com/sk89q/worldedit/MutableBlockVector2D.java b/core/src/main/java/com/sk89q/worldedit/MutableBlockVector2D.java index ff41f82d..8b10c4dc 100644 --- a/core/src/main/java/com/sk89q/worldedit/MutableBlockVector2D.java +++ b/core/src/main/java/com/sk89q/worldedit/MutableBlockVector2D.java @@ -3,7 +3,7 @@ package com.sk89q.worldedit; import java.io.IOException; import java.io.Serializable; -public final class MutableBlockVector2D extends Vector2D implements Serializable { +public final class MutableBlockVector2D extends BlockVector2D implements Serializable { private static ThreadLocal MUTABLE_CACHE = new ThreadLocal() { @Override protected MutableBlockVector2D initialValue() { @@ -18,6 +18,7 @@ public final class MutableBlockVector2D extends Vector2D implements Serializable private transient int x, z; public MutableBlockVector2D() { + super(0, 0); this.x = 0; this.z = 0; } diff --git a/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java b/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java index 400b7648..fb4f0c82 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java @@ -37,13 +37,9 @@ import com.boydti.fawe.util.MathMan; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.*; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.world.World; @@ -181,7 +177,7 @@ public class HistoryCommands { final FawePlayer fp = FawePlayer.wrap(player); final FaweQueue finalQueue; - RegionWrapper[] allowedRegions = fp.getCurrentRegions(FaweMaskManager.MaskType.OWNER); + Region[] allowedRegions = fp.getCurrentRegions(FaweMaskManager.MaskType.OWNER); if (allowedRegions == null) { BBC.NO_REGION.send(fp); return; diff --git a/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java b/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java index 07a229ff..40d551b5 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java @@ -1,25 +1,7 @@ package com.sk89q.worldedit.command; -import com.boydti.fawe.object.mask.AdjacentAnyMask; -import com.boydti.fawe.object.mask.AdjacentMask; -import com.boydti.fawe.object.mask.AngleMask; -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.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.RadiusMask; -import com.boydti.fawe.object.mask.RandomMask; -import com.boydti.fawe.object.mask.SimplexMask; -import com.boydti.fawe.object.mask.SkyLightMask; -import com.boydti.fawe.object.mask.SurfaceMask; -import com.boydti.fawe.object.mask.WallMask; -import com.boydti.fawe.object.mask.XAxisMask; -import com.boydti.fawe.object.mask.YAxisMask; -import com.boydti.fawe.object.mask.ZAxisMask; +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.mask.*; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.LocalSession; @@ -28,16 +10,7 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.function.mask.BlockMask; -import com.sk89q.worldedit.function.mask.ExistingBlockMask; -import com.sk89q.worldedit.function.mask.ExpressionMask; -import com.sk89q.worldedit.function.mask.Mask; -import com.sk89q.worldedit.function.mask.MaskIntersection; -import com.sk89q.worldedit.function.mask.MaskUnion; -import com.sk89q.worldedit.function.mask.Masks; -import com.sk89q.worldedit.function.mask.OffsetMask; -import com.sk89q.worldedit.function.mask.RegionMask; -import com.sk89q.worldedit.function.mask.SolidBlockMask; +import com.sk89q.worldedit.function.mask.*; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment; @@ -188,6 +161,19 @@ public class MaskCommands extends MethodCommands { return new SolidBlockMask(extent); } + @Command( + aliases = {"#liquid"}, + desc = "If there is a solid block" + ) + public Mask liquid(Extent extent) { + return new ConditionalMask(extent) { + @Override + public boolean applies(BaseBlock block) { + return FaweCache.isLiquid(block.getId()); + } + }; + } + @Command( aliases = {"#dregion", "#dselection", "#dsel"}, desc = "inside the player's selection" diff --git a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 59821d37..7772fdb3 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -157,7 +157,7 @@ public class UtilityCommands extends MethodCommands { @Command( aliases = {"/fill"}, - usage = " [depth]", + usage = " [depth] [direction]", desc = "Fill a hole", min = 2, max = 4 diff --git a/core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/core/src/main/java/com/sk89q/worldedit/extent/Extent.java index a80e7b8b..2483a5d1 100644 --- a/core/src/main/java/com/sk89q/worldedit/extent/Extent.java +++ b/core/src/main/java/com/sk89q/worldedit/extent/Extent.java @@ -1,15 +1,12 @@ package com.sk89q.worldedit.extent; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.jnbt.anvil.generator.CavesGen; -import com.boydti.fawe.jnbt.anvil.generator.GenBase; -import com.boydti.fawe.jnbt.anvil.generator.OreGen; -import com.boydti.fawe.jnbt.anvil.generator.Resource; -import com.boydti.fawe.jnbt.anvil.generator.SchemGen; +import com.boydti.fawe.jnbt.anvil.generator.*; import com.boydti.fawe.object.PseudoRandom; import com.sk89q.worldedit.*; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.function.mask.Mask; @@ -71,6 +68,50 @@ public interface Extent extends InputExtent, OutputExtent { return setBiome(MutableBlockVector2D.get(x, z), biome); } + /** + * Returns the highest solid 'terrain' block which can occur naturally. + * + * @param x the X coordinate + * @param z the Z cooridnate + * @param minY minimal height + * @param maxY maximal height + * @return height of highest block found or 'minY' + */ + default int getHighestTerrainBlock(final int x, final int z, final int minY, final int maxY) { + return this.getHighestTerrainBlock(x, z, minY, maxY, false); + } + + /** + * Returns the highest solid 'terrain' block which can occur naturally. + * + * @param x the X coordinate + * @param z the Z coordinate + * @param minY minimal height + * @param maxY maximal height + * @param naturalOnly look at natural blocks or all blocks + * @return height of highest block found or 'minY' + */ + default int getHighestTerrainBlock(final int x, final int z, int minY, int maxY, final boolean naturalOnly) { + maxY = Math.min(maxY, Math.max(0, maxY)); + minY = Math.max(0, minY); + if (naturalOnly) { + for (int y = maxY; y >= minY; --y) { + BaseBlock block = getLazyBlock(x, y, z); + if (BlockType.isNaturalTerrainBlock(block.getId(), block.getData())) { + return y; + } + } + } else { + for (int y = maxY; y >= minY; --y) { + BaseBlock block = getLazyBlock(x, y, z); + if (!FaweCache.canPassThrough(block.getId(), block.getData())) { + return y; + } + } + } + return minY; + } + default public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) { int clearanceAbove = maxY - y; int clearanceBelow = y - minY; diff --git a/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/WavefrontReader.java b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/WavefrontReader.java new file mode 100644 index 00000000..b62a2fa8 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/WavefrontReader.java @@ -0,0 +1,553 @@ +package com.sk89q.worldedit.extent.clipboard.io; + +import com.boydti.fawe.Fawe; +import com.boydti.fawe.object.collection.SoftHashMap; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.world.registry.WorldData; +import java.awt.image.BufferedImage; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import javax.imageio.ImageIO; + +public class WavefrontReader implements ClipboardReader { + private final InputStream inputStream; + private final File root; + + private final Map textures = new SoftHashMap<>(); + private final Map> materialFiles = new HashMap<>(); + private final Map materials = new HashMap<>(); + + public WavefrontReader(File file) throws FileNotFoundException { + this.inputStream = new BufferedInputStream(new FileInputStream(file)); + File parent = file.getParentFile(); + this.root = parent == null ? new File(".") : parent; + } + + private final static double parse(String s) { + int len = s.length(); + int index; + int numIndex = 1; + + double neg; + + if (s.charAt(0) == '-') { + neg = -1; + index = 1; + } else { + index = 0; + neg = 1; + } + double val = 0; + outer: + for (; index < len; index++) { + char c = s.charAt(index); + switch (c) { + case ' ': break outer; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + val = val * 10 + (c - 48); + continue; + case '.': { + double factor = 0.1; + for (; index < len; index++) { + c = s.charAt(index); + switch (c) { + case ' ': break outer; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + val += ((c - 48) * factor); + factor *= 0.1; + } + } + } + break; + } + } + return val * neg; + } + + @Override + public Clipboard read(WorldData data) throws IOException { + try (InputStream finalStream = inputStream) { + load(finalStream); + } + return null; + } + + private final BufferedImage getTexture(String file) throws IOException { + BufferedImage texture = textures.get(file); + if (texture == null) { + texture = ImageIO.read(new File(root, file)); + textures.put(file, texture); + } + return texture; + } + + private void readLines(InputStream stream, Consumer onEachLine, boolean nullTerminate) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (line.isEmpty() || line.charAt(0) == '#') continue; + onEachLine.accept(line); + } + if (nullTerminate) onEachLine.accept(null); + } + } + + private final int toIntColor(float color) { + return (int) (color * 256 + 0.5); + } + + private String getFileName(String arg) { + String[] pathSplit = arg.split("[/|\\\\]"); + return pathSplit[pathSplit.length - 1]; + } + + private class Material { + private double dissolve = 1; + private int color = Integer.MIN_VALUE; + private String texture; + } + + private final void loadMaterials(String fileName) throws IOException { + File file = new File(root, fileName); + if (!file.exists()) { + Fawe.debug(".mtl not found: " + fileName); + return; + } + Map mtl = materialFiles.get(fileName); + if (mtl == null) { + final Map tmp = mtl = new HashMap<>(); + materialFiles.put(fileName, tmp); + readLines(new FileInputStream(file), new Consumer() { + + private String name; + private Material material; + private int index; + + private void add() { + if (material != null) { + if (material.color == Integer.MIN_VALUE) { + material.color = -1; + } + tmp.put(name, material); + material = null; + name = null; + } + } + + @Override + public void accept(String s) { + if (s == null) { + add(); + return; + } + String[] args = s.split("[ ]+"); + switch (args[0]) { + // Name + case "newmtl": { + add(); + material = new Material(); + name = args[1]; + break; + } + // Color + case "Ka": + if (material.color != Integer.MIN_VALUE) break; + case "Kd": { + float r = Float.parseFloat(args[1]); + float g = Float.parseFloat(args[2]); + float b = Float.parseFloat(args[3]); + material.color = (toIntColor(r) << 16) + (toIntColor(g) << 8) + toIntColor(b); + break; + } + // Density + case "d": { + material.dissolve = Double.parseDouble(args[1]); + break; + } + case "Tr": { + material.dissolve = 1.0 - Double.parseDouble(args[1]); + break; + } + case "map_Ka": + if (material.texture != null) break; + case "map_Kd": { + material.texture = getFileName(args[1]); + break; + } + + } + } + }, true); + } + materials.putAll(mtl); + } + + private final Material getMaterial(String name) { + Material mtl = materials.get(name); + return mtl != null ? mtl : new Material(); + } + + private void load(InputStream in) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (line.isEmpty()) continue; + char char0 = line.charAt(0); + switch (char0) { + case '#': continue; + case 'v': + switch (line.charAt(1)) { + case ' ': + case 'n': { + Double.parseDouble(""); + break; + } + case 't': { + + } + } + break; + case 'f': { + + break; + } + case 'l': + case 's': + case 'o': + case 'g': + // Ignore + break; + default: + String[] args = line.split(" "); + switch (args[0]) { + case "mtllib": { + String[] pathSplit = args[1].split("[/|\\\\]"); + String fileName = pathSplit[pathSplit.length - 1]; + loadMaterials(fileName); + break; + } + } + } + } + } + +// +// final File directory = file.getParentFile(); +// final Map materials = new HashMap(); +// final Map textures = new HashMap(); +// final Map colors = new HashMap(); +// final List v = new LinkedList(); +// final List vt = new LinkedList(); +// final List vn = new LinkedList(); +// final List f = new LinkedList(); +// final List obj = new LinkedList(); +// for (final String[] entry : obj) { +// if (entry[0].equals("v") || entry[0].equals("vn")) { +// if (entry.length == 1) { +// VLogger.log("[ERROR] Invalid vertex or vertex normal entry found (no data)"); +// return null; +// } +// double x; +// double y; +// double z; +// try { +// x = Double.parseDouble(entry[1]); +// y = Double.parseDouble(entry[2]); +// z = Double.parseDouble(entry[3]); +// } +// catch (NumberFormatException | ArrayIndexOutOfBoundsException ex8) { +// final RuntimeException ex5; +// final RuntimeException ex = ex5; +// VLogger.log("[ERROR] Invalid vertex or vertex normal entry found (not parseable data)"); +// return null; +// } +// if (entry[0].equals("v")) { +// if (entry.length >= 6) { +// try { +// final float r = Float.parseFloat(entry[4]); +// final float g = Float.parseFloat(entry[5]); +// final float b = Float.parseFloat(entry[6]); +// final Color c = new Color(r, g, b); +// v.add(new Vertex(x, y, z, v.size() + 1, c)); +// continue; +// } +// catch (NumberFormatException | ArrayIndexOutOfBoundsException ex9) { +// final RuntimeException ex6; +// final RuntimeException ex = ex6; +// VLogger.log("[ERROR] Invalid vertex color (not parseable data)"); +// return null; +// } +// } +// v.add(new Vertex(x, y, z, v.size() + 1)); +// } +// else { +// vn.add(new Vertex(x, y, z, vn.size() + 1)); +// } +// } +// else { +// if (!entry[0].equals("vt")) { +// continue; +// } +// if (entry.length == 1) { +// VLogger.log("[ERROR] Invalid vertex texture entry found (no data)"); +// return null; +// } +// double vt_u; +// double vt_v; +// try { +// vt_u = Double.parseDouble(entry[1]); +// vt_v = Double.parseDouble(entry[2]); +// if (vt_u < 0.0 || vt_v < 0.0 || vt_u > 1.0 || vt_v > 1.0) { +// VLogger.log("[ERROR] UV of vertex texture out of bounds"); +// return null; +// } +// } +// catch (NumberFormatException | ArrayIndexOutOfBoundsException ex10) { +// final RuntimeException ex7; +// final RuntimeException ex2 = ex7; +// VLogger.log("[ERROR] Invalid vertex texture entry found (not parseable data)"); +// return null; +// } +// vt.add(new VertexTexture(vt_u, vt_v, vn.size() + 1)); +// } +// } +// VLogger.log("[IMPORT] Loaded " + v.size() + " vertexes"); +// VLogger.log("[IMPORT] Loaded " + vt.size() + " vertex textures"); +// VLogger.log("[IMPORT] Loaded " + vn.size() + " vertex normals"); +// BufferedImage usemtl_texture = null; +// Color usemtl_color = null; +// for (final String[] entry2 : obj) { +// if (entry2[0].equals("usemtl")) { +// if (entry2.length == 1) { +// VLogger.log("[ERROR] Invalid usemtl entry"); +// return null; +// } +// SimpleMaterial material = (SimpleMaterial)materials.get(entry2[1]); +// if (material == null) { +// VLogger.log("[WARN] Material '" + entry2[1] + "' does not exist"); +// material = getFallbackMaterial(); +// VLogger.log("[WARN] Replacing with fallback material"); +// } +// usemtl_texture = material.texture; +// usemtl_color = material.color; +// VLogger.log("[IMPORT] Now using material '" + entry2[1] + "'"); +// } +// else { +// if (!entry2[0].equals("f")) { +// continue; +// } +// if (entry2.length == 1) { +// VLogger.log("[ERROR] Invalid face entry (no arguments)"); +// return null; +// } +// if (usemtl_texture == null && usemtl_color == null) { +// VLogger.log("[WARN] Current Material has neither a texture nor a color"); +// usemtl_color = Colors.getGray(1.0f); +// VLogger.log("[WARN] Using fallback color"); +// } +// final Collection points = new LinkedList(); +// for (int i = 1; i < entry2.length; ++i) { +// final String[] comp = entry2[i].split("/"); +// Integer comp_v; +// Integer comp_vt; +// Integer comp_vn; +// try { +// comp_v = Integer.parseInt(comp[0]); +// comp_vt = ((comp.length <= 1 || comp[1].isEmpty()) ? null : Integer.parseInt(comp[1])); +// comp_vn = ((comp.length <= 2 || comp[2].isEmpty()) ? null : Integer.parseInt(comp[2])); +// } +// catch (NumberFormatException ex3) { +// final StringBuilder debug = new StringBuilder(); +// String[] array; +// for (int length = (array = comp).length, j = 0; j < length; ++j) { +// final String segment = array[j]; +// debug.append(segment); +// debug.append("/"); +// } +// VLogger.log("[ERROR] Face point failed to load (" + (Object)debug + ")"); +// return null; +// } +// try { +// final FacePoint point = new FacePoint(); +// point.v = v.get((int)comp_v - 1); +// point.vt = ((comp_vt == null) ? null : ((VertexTexture)vt.get((int)comp_vt - 1))); +// point.vn = ((comp_vn == null) ? null : ((Vertex)vn.get((int)comp_vn - 1))); +// points.add(point); +// } +// catch (IndexOutOfBoundsException ex4) { +// VLogger.log("[ERROR] Face point reference to missing vertex"); +// return null; +// } +// } +// final Face face = new Face(points); +// f.add(face); +// if (usemtl_texture != null) { +// textures.put(face, usemtl_texture); +// } +// if (usemtl_color == null) { +// continue; +// } +// colors.put(face, usemtl_color); +// } +// } +// double minX = Double.MAX_VALUE; +// double minY = Double.MAX_VALUE; +// double minZ = Double.MAX_VALUE; +// double maxX = -1.7976931348623157E308; +// double maxY = -1.7976931348623157E308; +// double maxZ = -1.7976931348623157E308; +// for (final Face face2 : f) { +// for (final FacePoint point2 : face2.points) { +// final double x2 = point2.v.getX(); +// final double y2 = point2.v.getY(); +// final double z2 = point2.v.getZ(); +// if (x2 < minX) { +// minX = x2; +// } +// else if (x2 > maxX) { +// maxX = x2; +// } +// if (y2 < minY) { +// minY = y2; +// } +// else if (y2 > maxY) { +// maxY = y2; +// } +// if (z2 < minZ) { +// minZ = z2; +// } +// else { +// if (z2 <= maxZ) { +// continue; +// } +// maxZ = z2; +// } +// } +// } +// final double size = Math.max(maxX - minX, Math.max(maxY - minY, maxZ - minZ)); +// final double scale = size / (resolution - 1.0); +// final List polygons = new LinkedList(); +// for (final Face face3 : f) { +// polygons.addAll(shatterFace(face3, colors, textures)); +// } +// VLogger.log("[IMPORT] " + f.size() + " faces -> " + polygons.size() + " polygons"); +// final Map colormap = new HashMap(); +// for (final Face poly : polygons) { +// final FacePoint a = (FacePoint)poly.points.get(0); +// final FacePoint b2 = (FacePoint)poly.points.get(1); +// final FacePoint c2 = (FacePoint)poly.points.get(2); +// final Vector3D vAB = new Vector3D((Point3D)a.v, (Point3D)b2.v); +// final Vector3D vAC = new Vector3D((Point3D)a.v, (Point3D)c2.v); +// final float lAB = (float)vAB.length(); +// final float lAC = (float)vAC.length(); +// double[] array3; +// if (a.vt == null || b2.vt == null) { +// final double[] array2 = array3 = new double[2]; +// array2[1] = (array2[0] = 0.0); +// } +// else { +// final double[] array4 = array3 = new double[2]; +// array4[0] = b2.vt.u - a.vt.u; +// array4[1] = b2.vt.v - a.vt.v; +// } +// final double[] uvAB = array3; +// double[] array6; +// if (a.vt == null || c2.vt == null) { +// final double[] array5 = array6 = new double[2]; +// array5[1] = (array5[0] = 0.0); +// } +// else { +// final double[] array7 = array6 = new double[2]; +// array7[0] = c2.vt.u - a.vt.u; +// array7[1] = c2.vt.v - a.vt.v; +// } +// final double[] uvAC = array6; +// double[] array9; +// if (a.vt == null) { +// final double[] array8 = array9 = new double[2]; +// array8[1] = (array8[0] = 0.0); +// } +// else { +// final double[] array10 = array9 = new double[2]; +// array10[0] = a.vt.u; +// array10[1] = a.vt.v; +// } +// final double[] uvA = array9; +// final Vector3D i2 = vAB.clone(); +// i2.normalize(); +// i2.multiply(scale); +// final Vector3D i3 = vAC.clone(); +// i3.normalize(); +// i3.multiply(scale); +// final BufferedImage texture = (BufferedImage)textures.get(poly); +// final Color poly_color = (Color)colors.get(poly); +// final int maxW = (texture == null) ? 0 : (texture.getWidth() - 1); +// final int maxH = (texture == null) ? 0 : (texture.getHeight() - 1); +// final double l = scale / 2.0; +// for (float aloop = 0.0f; aloop < lAB; aloop += l) { +// for (float bloop = 0.0f; bloop < lAC; bloop += l) { +// final float ratio1 = aloop / lAB; +// final float ratio2 = bloop / lAC; +// if (ratio1 + ratio2 > 1.0f) { +// break; +// } +// final Point3D point3 = a.v.clone(); +// point3.add(vAB.clone().multiply((double)ratio1)); +// point3.add(vAC.clone().multiply((double)ratio2)); +// final double colorU = uvA[0] + uvAB[0] * ratio1 + uvAC[0] * ratio2; +// final double colorV = uvA[1] + uvAB[1] * ratio1 + uvAC[1] * ratio2; +// Color pointcolor = null; +// if (texture == null) { +// if (poly.hasVertexColors()) { +// final WeightedColor cA = new WeightedColor(a.v.getColor().getRGB(), 1.0f - ratio1 - ratio2); +// final WeightedColor cB = new WeightedColor(b2.v.getColor().getRGB(), ratio1); +// final WeightedColor cC = new WeightedColor(c2.v.getColor().getRGB(), ratio2); +// pointcolor = Colors.blendColors(new WeightedColor[] { cA, cB, cC }); +// } +// else { +// pointcolor = poly_color; +// } +// } +// else { +// pointcolor = new Color(texture.getRGB((int)Math.floor((double)maxW * colorU), (int)Math.floor((double)maxH - maxH * colorV)), true); +// } +// if (pointcolor.getAlpha() != 0) { +// point3.divide(scale); +// colormap.put(point3.toPositionRound(), pointcolor); +// colormap.put(point3.toPositionFloor(), pointcolor); +// } +// } +// } +// } +// VLogger.log("[IMPORT] Import complete, loaded " + f.size() + " faces"); +// VLogger.log("[IMPORT] Import complete, created " + colormap.size() + " voxels"); +// return new VoxelBox(colormap); + } + + +} diff --git a/core/src/main/java/com/sk89q/worldedit/function/mask/ConditionalMask.java b/core/src/main/java/com/sk89q/worldedit/function/mask/ConditionalMask.java new file mode 100644 index 00000000..e90711d1 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/function/mask/ConditionalMask.java @@ -0,0 +1,18 @@ +package com.sk89q.worldedit.function.mask; + +import com.boydti.fawe.FaweCache; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.Extent; + +public abstract class ConditionalMask extends BlockMask { + public ConditionalMask(Extent extent) { + super(extent); + for (BaseBlock block : FaweCache.CACHE_BLOCK) { + if (applies(block)) { + add(block); + } + } + } + + public abstract boolean applies(BaseBlock block); +} diff --git a/core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index 8ef51af3..53bc393a 100644 --- a/core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -133,7 +133,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { /** * Clamps the cuboid according to boundaries of the world. */ - private void recalculate() { + protected void recalculate() { if (pos1 == null || pos2 == null) { return; } @@ -413,6 +413,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { // private int lz = Integer.MIN_VALUE; // private boolean lr, lry, lrz; + @Override public boolean contains(int x, int y, int z) { return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ && y >= this.minY && y <= this.maxY; // if (z != lz) { @@ -431,6 +432,11 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { // return lr && (x >= this.minX && x <= this.maxX); } + @Override + public boolean contains(int x, int z) { + return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ; + } + @Override public Iterator iterator() { if (Settings.IMP.HISTORY.COMPRESSION_LEVEL >= 9 || useOldIterator) { diff --git a/core/src/main/java/com/sk89q/worldedit/regions/IDelegateRegion.java b/core/src/main/java/com/sk89q/worldedit/regions/IDelegateRegion.java new file mode 100644 index 00000000..d40af97f --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/regions/IDelegateRegion.java @@ -0,0 +1,110 @@ +package com.sk89q.worldedit.regions; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.world.World; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; + +public interface IDelegateRegion extends Region { + + public Region getRegion(); + + @Override + default Iterator iterator() { + return getRegion().iterator(); + } + + @Override + default Vector getMinimumPoint() { + return getRegion().getMinimumPoint(); + } + + @Override + default Vector getMaximumPoint() { + return getRegion().getMaximumPoint(); + } + + @Override + default Vector getCenter() { + return getRegion().getCenter(); + } + + @Override + default int getArea() { + return getRegion().getArea(); + } + + @Override + default int getWidth() { + return getRegion().getWidth(); + } + + @Override + default int getHeight() { + return getRegion().getHeight(); + } + + @Override + default int getLength() { + return getRegion().getLength(); + } + + @Override + default void expand(Vector... changes) throws RegionOperationException { + getRegion().expand(changes); + } + + @Override + default void contract(Vector... changes) throws RegionOperationException { + getRegion().contract(changes); + } + + @Override + default void shift(Vector change) throws RegionOperationException { + getRegion().shift(change); + } + + @Override + default boolean contains(Vector position) { + return getRegion().contains(position); + } + + @Override + default Set getChunks() { + return getRegion().getChunks(); + } + + @Override + default Set getChunkCubes() { + return getRegion().getChunkCubes(); + } + + @Override + @Nullable + default World getWorld() { + return getRegion().getWorld(); + } + + @Override + default void setWorld(@Nullable World world) { + getRegion().setWorld(world); + } + + @Override + @Deprecated + default void setWorld(@Nullable LocalWorld world) { + getRegion().setWorld(world); + } + + @Override + default Region clone() { + return getRegion().clone(); + } + + @Override + default List polygonize(int maxPoints) { + return getRegion().polygonize(maxPoints); + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/regions/Region.java b/core/src/main/java/com/sk89q/worldedit/regions/Region.java new file mode 100644 index 00000000..22f7c070 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -0,0 +1,182 @@ +/* + * 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.regions; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.world.World; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Set; + +/** + * Represents a physical shape. + */ +public interface Region extends Iterable, Cloneable { + + /** + * Get the lower point of a region. + * + * @return min. point + */ + public Vector getMinimumPoint(); + + /** + * Get the upper point of a region. + * + * @return max. point + */ + public Vector getMaximumPoint(); + + /** + * Get the center point of a region. + * Note: Coordinates will not be integers + * if the corresponding lengths are even. + * + * @return center point + */ + public Vector getCenter(); + + /** + * Get the number of blocks in the region. + * + * @return number of blocks + */ + public int getArea(); + + /** + * Get X-size. + * + * @return width + */ + public int getWidth(); + + /** + * Get Y-size. + * + * @return height + */ + public int getHeight(); + + /** + * Get Z-size. + * + * @return length + */ + public int getLength(); + + /** + * Expand the region. + * + * @param changes array/arguments with multiple related changes + * @throws RegionOperationException + */ + public void expand(Vector... changes) throws RegionOperationException; + + /** + * Contract the region. + * + * @param changes array/arguments with multiple related changes + * @throws RegionOperationException + */ + public void contract(Vector... changes) throws RegionOperationException; + + /** + * Shift the region. + * + * @param change the change + * @throws RegionOperationException + */ + public void shift(Vector change) throws RegionOperationException; + + /** + * Returns true based on whether the region contains the point. + * + * @param position the position + * @return true if contained + */ + public boolean contains(Vector position); + + default boolean contains(int x, int y, int z) { + return contains(MutableBlockVector.get(x, y, z)); + } + + default boolean contains(int x, int z) { + return contains(MutableBlockVector.get(x, 0, z)); + } + + default boolean isGlobal() { + Vector pos1 = getMinimumPoint(); + Vector pos2 = getMaximumPoint(); + return pos1.getBlockX() == Integer.MIN_VALUE && pos1.getBlockZ() == Integer.MIN_VALUE && pos2.getBlockX() == Integer.MAX_VALUE && pos2.getBlockZ() == Integer.MAX_VALUE && pos1.getBlockY() <= 0 && pos2.getBlockY() >= 255; + } + + /** + * Get a list of chunks. + * + * @return a list of chunk coordinates + */ + public Set getChunks(); + + /** + * Return a list of 16*16*16 chunks in a region + * + * @return the chunk cubes this region overlaps with + */ + public Set getChunkCubes(); + + /** + * Sets the world that the selection is in. + * + * @return the world, or null + */ + @Nullable + public World getWorld(); + + /** + * Sets the world that the selection is in. + * + * @param world the world, which may be null + */ + public void setWorld(@Nullable World world); + + /** + * Sets the world that the selection is in. + * + * @param world the world, which may be null + */ + @Deprecated + public void setWorld(@Nullable LocalWorld world); + + /** + * Make a clone of the region. + * + * @return a cloned version + */ + public Region clone(); + + /** + * Polygonizes a cross-section or a 2D projection of the region orthogonal to the Y axis. + * + * @param maxPoints maximum number of points to generate. -1 for no limit. + * @return the points. + */ + public List polygonize(int maxPoints); +} diff --git a/core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java b/core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java index dfb9021b..cf514e44 100644 --- a/core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java +++ b/core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java @@ -70,6 +70,11 @@ public class ConvexPolyhedralRegionSelector extends com.sk89q.worldedit.regions. region = new ConvexPolyhedralRegion(world); } + public ConvexPolyhedralRegionSelector(ConvexPolyhedralRegion region) { + checkNotNull(region); + this.region = region; + } + /** * Create a new selector. * diff --git a/core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java b/core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java index 906c11a0..34e9e11f 100644 --- a/core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java +++ b/core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java @@ -63,6 +63,11 @@ public class CylinderRegionSelector extends com.sk89q.worldedit.regions.Cylinder this((World) null); } + public CylinderRegionSelector(CylinderRegion region) { + checkNotNull(region); + this.region = region; + } + /** * Create a new region selector. * diff --git a/core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java b/core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java index 8c2de10e..eb5943d4 100644 --- a/core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java +++ b/core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java @@ -68,6 +68,11 @@ public class Polygonal2DRegionSelector extends com.sk89q.worldedit.regions.Polyg region = new Polygonal2DRegion(world); } + + public Polygonal2DRegionSelector(Polygonal2DRegion region) { + this.region = region; + } + /** * Create a new selector from another one. * diff --git a/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java b/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java index 05ed606f..c841b693 100644 --- a/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java +++ b/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java @@ -30,12 +30,7 @@ import com.boydti.fawe.bukkit.wrapper.AsyncWorld; import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.Settings; import com.boydti.fawe.logging.LoggingChangeSet; -import com.boydti.fawe.object.ChangeSetFaweQueue; -import com.boydti.fawe.object.FawePlayer; -import com.boydti.fawe.object.FaweQueue; -import com.boydti.fawe.object.MaskedFaweQueue; -import com.boydti.fawe.object.RegionWrapper; -import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.object.*; import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.extent.ResettableExtent; import com.boydti.fawe.object.extent.SourceMaskExtent; @@ -45,11 +40,7 @@ import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.WEManager; import com.google.common.base.Preconditions; -import com.google.common.collect.BiMap; -import com.google.common.collect.ClassToInstanceMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.MutableClassToInstanceMap; +import com.google.common.collect.*; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.extent.MaskingExtent; @@ -83,6 +74,8 @@ public class Sniper { private Map tools = new HashMap<>(); public Sniper(VoxelSniper plugin, Player player) { + Preconditions.checkNotNull(plugin); + Preconditions.checkNotNull(player); this.plugin = plugin; this.player = player.getUniqueId(); SniperTool sniperTool = new SniperTool(this); @@ -554,6 +547,8 @@ public class Sniper { } private SniperTool(Class currentBrush, SnipeData snipeData) { + Preconditions.checkNotNull(currentBrush); + Preconditions.checkNotNull(snipeData); this.snipeData = snipeData; messageHelper = new Message(snipeData); snipeData.setVoxelMessage(messageHelper); diff --git a/nukkit/build.gradle b/nukkit/build.gradle index 6b50ce60..cab7cb9f 100644 --- a/nukkit/build.gradle +++ b/nukkit/build.gradle @@ -1,9 +1,10 @@ repositories { flatDir {dirs 'lib'} + maven {url "https://repo.potestas.xyz/main/"} } dependencies { compile project(':core') - compile name: 'nukkit-1.0-SNAPSHOT' + compile 'cn.nukkit:nukkit:1.0-SNAPSHOT' compile name: 'worldedit-core-6.1.4-SNAPSHOT-dist' }