From de08ef85d704abff73a3eede0b8c58513a690612 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Thu, 21 Apr 2016 04:22:47 +1000 Subject: [PATCH] Fix limits / add cancellation messages --- .../com/boydti/fawe/bukkit/FaweBukkit.java | 5 + core/src/main/java/com/boydti/fawe/Fawe.java | 40 ++- core/src/main/java/com/boydti/fawe/IFawe.java | 2 + .../main/java/com/boydti/fawe/config/BBC.java | 10 + .../java/com/boydti/fawe/config/Settings.java | 7 + .../com/boydti/fawe/object/FaweLimit.java | 5 + .../fawe/object/exception/FaweException.java | 27 ++ .../fawe/object/extent/ProcessedWEExtent.java | 15 +- .../fawe/object/extent/SafeExtentWrapper.java | 2 +- .../java/com/boydti/fawe/util/WEManager.java | 5 +- .../java/com/sk89q/worldedit/EditSession.java | 339 +++++++----------- .../extension/platform/CommandManager.java | 14 +- .../function/operation/Operations.java | 35 +- .../com/boydti/fawe/forge/FaweSponge.java | 5 + 14 files changed, 268 insertions(+), 243 deletions(-) create mode 100644 core/src/main/java/com/boydti/fawe/object/exception/FaweException.java diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java index fee20de6..15b1c2dc 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -310,4 +310,9 @@ public class FaweBukkit extends JavaPlugin implements IFawe, Listener { fp.loadSessionFromDisk(fp.getWorld()); } } + + @Override + public String getPlatform() { + return "bukkit"; + } } diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index c6af93c2..f391ee83 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -240,14 +240,52 @@ public class Fawe { try { CommandManager.inject(); } catch (Throwable e) { + debug("====== UPDATE WORLDEDIT TO 6.1.1 ======"); e.printStackTrace(); - IMP.debug("Incompatible version of WorldEdit, please update the plugin or contact the Author!"); + debug("======================================="); + debug("Update the plugin, or contact the Author!"); + if (IMP.getPlatform().equals("bukkit")) { + debug(" - http://builds.enginehub.org/job/worldedit?branch=master"); + } else { + debug(" - http://builds.enginehub.org/job/worldedit?branch=forge-archive%2F1.8.9 (FORGE)"); + debug(" - https://ci.minecrell.net/job/worldedit-spongevanilla/ (SV)"); + } + debug("======================================="); } try { Native.load(); + String arch = System.getenv("PROCESSOR_ARCHITECTURE"); + String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432"); + boolean x86OS = arch.endsWith("64") || wow64Arch != null && wow64Arch.endsWith("64") ? false : true; + boolean x86JVM = System.getProperty("sun.arch.data.model").equals("32"); + if (x86OS != x86JVM) { + debug("====== UPGRADE TO 64-BIT JAVA ======"); + debug("You are running 32-bit Java on a 64-bit machine"); + debug(" - This is a recommendation"); + debug("===================================="); + } } catch (Throwable e) { + debug("====== LZ4 COMPRESSION BINDING NOT FOUND ======"); e.printStackTrace(); + debug("==============================================="); + debug("FAWE will still work, but some things may be slower"); + debug(" - Try updating your JVM / OS"); + debug(" - Report this issue if you cannot resolve it"); + debug("==============================================="); } + if (getJavaVersion() < 1.8) { + debug("====== UPGRADE TO JAVA 8 ======"); + debug("You are running " + System.getProperty("java.version")); + debug(" - This is a recommendation"); + debug("===================================="); + } + } + + static double getJavaVersion () { + String version = System.getProperty("java.version"); + int pos = version.indexOf('.'); + pos = version.indexOf('.', pos+1); + return Double.parseDouble (version.substring (0, pos)); } private void setupMemoryListener() { diff --git a/core/src/main/java/com/boydti/fawe/IFawe.java b/core/src/main/java/com/boydti/fawe/IFawe.java index 18043c68..6675e262 100644 --- a/core/src/main/java/com/boydti/fawe/IFawe.java +++ b/core/src/main/java/com/boydti/fawe/IFawe.java @@ -37,4 +37,6 @@ public interface IFawe { public void startMetrics(); public Set getPlayers(); + + public String getPlatform(); } diff --git a/core/src/main/java/com/boydti/fawe/config/BBC.java b/core/src/main/java/com/boydti/fawe/config/BBC.java index 89fd07f8..f594bbbf 100644 --- a/core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/core/src/main/java/com/boydti/fawe/config/BBC.java @@ -40,6 +40,16 @@ public enum BBC { WORLDEDIT_UNMASKED("&6Your WorldEdit is now unrestricted.", "Info"), WORLDEDIT_RESTRICTED("&6Your WorldEdit is now restricted.", "Info"), WORLDEDIT_OOM("&cYour WorldEdit action was cancelled due to low memory.", "Info"), + + WORLDEDIT_CANCEL_REASON("&cYour WorldEdit action was cancelled:&7 %s0&c.", "Cancel"), + WORLDEDIT_CANCEL_REASON_LOW_MEMORY("Low memory", "Cancel"), + WORLDEDIT_CANCEL_REASON_MAX_CHANGES("Too many blocks changed", "Cancel"), + WORLDEDIT_CANCEL_REASON_MAX_CHECKS("Too many block checks", "Cancel"), + WORLDEDIT_CANCEL_REASON_MAX_TILES("Too many blockstates", "Cancel"), + WORLDEDIT_CANCEL_REASON_MAX_ENTITIES("Too many entities", "Cancel"), + WORLDEDIT_CANCEL_REASON_MAX_ITERATIONS("Max iterations", "Cancel"), + WORLDEDIT_CANCEL_REASON_MAX_FAILS("Outside allowed region", "Cancel"), + WORLDEDIT_OOM_ADMIN("&cPossible options:\n&8 - &7//fast\n&8 - &7Do smaller edits\n&8 - &7Allocate more memory\n&8 - &7Disable this safeguard", "Info"), NOT_PLAYER("&cYou must be a player to perform this action!", "Error"), COMPRESSED("History compressed. Saved ~ %s0b (%s1x smaller)", "Info"), diff --git a/core/src/main/java/com/boydti/fawe/config/Settings.java b/core/src/main/java/com/boydti/fawe/config/Settings.java index 570d9bf4..f7417cbb 100644 --- a/core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/core/src/main/java/com/boydti/fawe/config/Settings.java @@ -40,6 +40,12 @@ public class Settings { public static FaweLimit getLimit(FawePlayer player) { FaweLimit limit = new FaweLimit(); + limit.MAX_CHANGES = 0; + limit.MAX_FAILS = 0; + limit.MAX_CHECKS = 0; + limit.MAX_ENTITIES = 0; + limit.MAX_BLOCKSTATES = 0; + limit.MAX_ITERATIONS = 0; for (Entry entry : limits.entrySet()) { String key = entry.getKey(); if (key.equals("default") || player.hasPermission("fawe.limit." + key)) { @@ -98,6 +104,7 @@ public class Settings { for (String key : config.getConfigurationSection("limits").getKeys(false)) { FaweLimit limit = new FaweLimit(); limit.load(config.getConfigurationSection("limits." + key), defaultLimit, false); + limits.put(key, limit); } for (final Entry node : options.entrySet()) { if (!config.contains(node.getKey())) { diff --git a/core/src/main/java/com/boydti/fawe/object/FaweLimit.java b/core/src/main/java/com/boydti/fawe/object/FaweLimit.java index e285e500..5efe587e 100644 --- a/core/src/main/java/com/boydti/fawe/object/FaweLimit.java +++ b/core/src/main/java/com/boydti/fawe/object/FaweLimit.java @@ -51,4 +51,9 @@ public class FaweLimit { } return changed; } + + @Override + public String toString() { + return MAX_CHANGES + ""; + } } diff --git a/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java b/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java new file mode 100644 index 00000000..dd318011 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java @@ -0,0 +1,27 @@ +package com.boydti.fawe.object.exception; + +import com.boydti.fawe.config.BBC; + +public class FaweException extends RuntimeException { + private final String message; + + public FaweException(BBC reason) { + this.message = reason.format(); + } + + @Override + public String getMessage() { + return message; + } + + public static FaweException get(Throwable e) { + Throwable cause = e.getCause(); + if (cause instanceof FaweException) { + return (FaweException) cause; + } + if (cause == null) { + return null; + } + return get(cause); + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java index 0a53fd05..5b71555e 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java @@ -1,6 +1,7 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.RegionWrapper; @@ -151,6 +152,10 @@ public class ProcessedWEExtent extends FaweExtent { case 151: case 178: { if (limit.MAX_BLOCKSTATES-- < 0) { + if (this.parent != null) { + WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_TILES); + this.parent = null; + } return false; } final int x = location.getBlockX(); @@ -158,7 +163,7 @@ public class ProcessedWEExtent extends FaweExtent { if (WEManager.IMP.maskContains(this.mask, x, z)) { if (limit.MAX_CHANGES-- < 0) { if (this.parent != null) { - WEManager.IMP.cancelEdit(this.parent); + WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES); this.parent = null; } return false; @@ -181,7 +186,7 @@ public class ProcessedWEExtent extends FaweExtent { return true; } else if (limit.MAX_FAILS-- < 0) { if (this.parent != null) { - WEManager.IMP.cancelEdit(this.parent); + WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); this.parent = null; } } @@ -192,8 +197,8 @@ public class ProcessedWEExtent extends FaweExtent { final int y = location.getBlockY(); final int z = location.getBlockZ(); if (WEManager.IMP.maskContains(this.mask, location.getBlockX(), location.getBlockZ())) { - if (limit.MAX_CHANGES--<0) { - WEManager.IMP.cancelEdit(this.parent); + if (limit.MAX_CHANGES -- <0) { + WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES); this.parent = null; return false; } @@ -288,7 +293,7 @@ public class ProcessedWEExtent extends FaweExtent { } } else if (limit.MAX_FAILS-- < 0) { if (this.parent != null) { - WEManager.IMP.cancelEdit(this.parent); + WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); this.parent = null; } } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java b/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java index 9e413f69..86e74a66 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java @@ -29,7 +29,7 @@ public class SafeExtentWrapper extends AbstractDelegateExtent { BBC.WORLDEDIT_OOM_ADMIN.send(this.player); } } - WEManager.IMP.cancelEdit(this); + WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_LOW_MEMORY); return false; } return true; 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 a1279f0a..a8b4e762 100644 --- a/core/src/main/java/com/boydti/fawe/util/WEManager.java +++ b/core/src/main/java/com/boydti/fawe/util/WEManager.java @@ -5,9 +5,11 @@ import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweLocation; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.RegionWrapper; +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.WorldEditException; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; import java.lang.reflect.Field; @@ -20,7 +22,7 @@ public class WEManager { public final ArrayDeque managers = new ArrayDeque<>(); - public void cancelEdit(Extent parent) { + public void cancelEdit(Extent parent, BBC reason) throws WorldEditException { try { final Field field = AbstractDelegateExtent.class.getDeclaredField("extent"); field.setAccessible(true); @@ -28,6 +30,7 @@ public class WEManager { } catch (final Exception e) { e.printStackTrace(); } + throw new FaweException(reason); } public boolean maskContains(final HashSet mask, final int x, final int z) { diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 7daeed79..1e7e74cd 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -32,6 +32,7 @@ import com.boydti.fawe.object.RunnableVal; 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.exception.FaweException; import com.boydti.fawe.object.extent.FastWorldEditExtent; import com.boydti.fawe.object.extent.FaweExtent; import com.boydti.fawe.object.extent.NullExtent; @@ -566,7 +567,7 @@ public class EditSession implements Extent { public BaseBlock getLazyBlock(int x, int y, int z) { if (limit != null && limit.MAX_CHECKS-- < 0) { - return nullBlock; + throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } int combinedId4Data = queue.getCombinedId4Data(x, y, z); if (!FaweCache.hasNBT(combinedId4Data >> 4)) { @@ -594,7 +595,7 @@ public class EditSession implements Extent { @Deprecated public int getBlockType(final Vector position) { if (limit != null && limit.MAX_CHECKS-- < 0) { - return 0; + throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } int combinedId4Data = queue.getCombinedId4Data(position.getBlockX(), position.getBlockY(), position.getBlockZ()); return combinedId4Data >> 4; @@ -610,7 +611,7 @@ public class EditSession implements Extent { @Deprecated public int getBlockData(final Vector position) { if (limit != null && limit.MAX_CHECKS-- < 0) { - return 0; + throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } int combinedId4Data = queue.getCombinedId4Data(position.getBlockX(), position.getBlockY(), position.getBlockZ()); return combinedId4Data & 0xF; @@ -866,15 +867,10 @@ public class EditSession implements Extent { * Finish off the queue. */ public void flushQueue() { - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - Operations.completeBlindly(EditSession.this.commit()); - if (queue != null) { - queue.enqueue(); - } - } - }); + Operations.completeBlindly(EditSession.this.commit()); + if (queue != null) { + queue.enqueue(); + } } @Override @@ -962,35 +958,30 @@ public class EditSession implements Extent { checkArgument(radius >= 0, "radius >= 0"); checkArgument(depth >= 1, "depth >= 1"); - TaskManager.IMP.async(new Runnable() { + final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), new BoundedHeightMask(Math.max( + (origin.getBlockY() - depth) + 1, 0), Math.min(EditSession.this.getWorld().getMaxY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this))); + + // Want to replace blocks + final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); + + // Pick how we're going to visit blocks + RecursiveVisitor visitor; + if (recursive) { + visitor = new RecursiveVisitor(mask, replace); + } else { + visitor = new DownwardVisitor(mask, replace, origin.getBlockY()); + } + + // Start at the origin + visitor.visit(origin); + + // Execute + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), new BoundedHeightMask(Math.max( - (origin.getBlockY() - depth) + 1, 0), Math.min(EditSession.this.getWorld().getMaxY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this))); - - // Want to replace blocks - final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); - - // Pick how we're going to visit blocks - RecursiveVisitor visitor; - if (recursive) { - visitor = new RecursiveVisitor(mask, replace); - } else { - visitor = new DownwardVisitor(mask, replace, origin.getBlockY()); - } - - // Start at the origin - visitor.visit(origin); - - // Execute - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1083,20 +1074,14 @@ public class EditSession implements Extent { public int setBlocks(final Region region, final Pattern pattern) throws MaxChangedBlocksException { checkNotNull(region); checkNotNull(pattern); - - TaskManager.IMP.async(new Runnable() { + final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); + final RegionVisitor visitor = new RegionVisitor(region, replace); + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); - final RegionVisitor visitor = new RegionVisitor(region, replace); - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1146,21 +1131,15 @@ public class EditSession implements Extent { checkNotNull(region); checkNotNull(mask); checkNotNull(pattern); - - TaskManager.IMP.async(new Runnable() { + final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); + final RegionMaskingFilter filter = new RegionMaskingFilter(mask, replace); + final RegionVisitor visitor = new RegionVisitor(region, filter); + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); - final RegionMaskingFilter filter = new RegionMaskingFilter(mask, replace); - final RegionVisitor visitor = new RegionVisitor(region, filter); - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1335,22 +1314,16 @@ public class EditSession implements Extent { public int overlayCuboidBlocks(final Region region, final Pattern pattern) throws MaxChangedBlocksException { checkNotNull(region); checkNotNull(pattern); - - TaskManager.IMP.async(new Runnable() { + final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); + final RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace); + final GroundFunction ground = new GroundFunction(new ExistingBlockMask(EditSession.this), offset); + final LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground); + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern)); - final RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace); - final GroundFunction ground = new GroundFunction(new ExistingBlockMask(EditSession.this), offset); - final LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground); - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1364,22 +1337,15 @@ public class EditSession implements Extent { */ public int naturalizeCuboidBlocks(final Region region) throws MaxChangedBlocksException { checkNotNull(region); - - TaskManager.IMP.async(new Runnable() { - + final Naturalizer naturalizer = new Naturalizer(EditSession.this); + final FlatRegion flatRegion = Regions.asFlatRegion(region); + final LayerVisitor visitor = new LayerVisitor(flatRegion, minimumBlockY(region), maximumBlockY(region), naturalizer); + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - final Naturalizer naturalizer = new Naturalizer(EditSession.this); - final FlatRegion flatRegion = Regions.asFlatRegion(region); - final LayerVisitor visitor = new LayerVisitor(flatRegion, minimumBlockY(region), maximumBlockY(region), naturalizer); - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1397,26 +1363,20 @@ public class EditSession implements Extent { checkNotNull(region); checkNotNull(dir); checkArgument(count >= 1, "count >= 1 required"); - - TaskManager.IMP.async(new Runnable() { + final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1); + final Vector to = region.getMinimumPoint(); + final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, EditSession.this, to); + copy.setRepetitions(count); + copy.setTransform(new AffineTransform().translate(dir.multiply(size))); + if (!copyAir) { + copy.setSourceMask(new ExistingBlockMask(EditSession.this)); + } + Operations.completeSmart(copy, new Runnable() { @Override public void run() { - final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1); - final Vector to = region.getMinimumPoint(); - final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, EditSession.this, to); - copy.setRepetitions(count); - copy.setTransform(new AffineTransform().translate(dir.multiply(size))); - if (!copyAir) { - copy.setSourceMask(new ExistingBlockMask(EditSession.this)); - } - Operations.completeSmart(copy, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1435,39 +1395,33 @@ public class EditSession implements Extent { checkNotNull(region); checkNotNull(dir); checkArgument(distance >= 1, "distance >= 1 required"); + final Vector to = region.getMinimumPoint(); - TaskManager.IMP.async(new Runnable() { + // Remove the original blocks + final com.sk89q.worldedit.function.pattern.Pattern pattern = replacement != null ? new BlockPattern(replacement) : new BlockPattern(new BaseBlock(BlockID.AIR)); + final BlockReplace remove = new BlockReplace(EditSession.this, pattern); + + // Copy to a buffer so we don't destroy our original before we can copy all the blocks from it + final ForgetfulExtentBuffer buffer = new ForgetfulExtentBuffer(EditSession.this, new RegionMask(region)); + final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, buffer, to); + copy.setTransform(new AffineTransform().translate(dir.multiply(distance))); + copy.setSourceFunction(remove); // Remove + copy.setRemovingEntities(true); + if (!copyAir) { + copy.setSourceMask(new ExistingBlockMask(EditSession.this)); + } + + // Then we need to copy the buffer to the world + final BlockReplace replace = new BlockReplace(EditSession.this, buffer); + final RegionVisitor visitor = new RegionVisitor(buffer.asRegion(), replace); + + final OperationQueue operation = new OperationQueue(copy, visitor); + Operations.completeSmart(operation, new Runnable() { @Override public void run() { - final Vector to = region.getMinimumPoint(); - - // Remove the original blocks - final com.sk89q.worldedit.function.pattern.Pattern pattern = replacement != null ? new BlockPattern(replacement) : new BlockPattern(new BaseBlock(BlockID.AIR)); - final BlockReplace remove = new BlockReplace(EditSession.this, pattern); - - // Copy to a buffer so we don't destroy our original before we can copy all the blocks from it - final ForgetfulExtentBuffer buffer = new ForgetfulExtentBuffer(EditSession.this, new RegionMask(region)); - final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, buffer, to); - copy.setTransform(new AffineTransform().translate(dir.multiply(distance))); - copy.setSourceFunction(remove); // Remove - copy.setRemovingEntities(true); - if (!copyAir) { - copy.setSourceMask(new ExistingBlockMask(EditSession.this)); - } - - // Then we need to copy the buffer to the world - final BlockReplace replace = new BlockReplace(EditSession.this, buffer); - final RegionVisitor visitor = new RegionVisitor(buffer.asRegion(), replace); - - final OperationQueue operation = new OperationQueue(copy, visitor); - Operations.completeSmart(operation, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1497,31 +1451,25 @@ public class EditSession implements Extent { public int drainArea(final Vector origin, final double radius) throws MaxChangedBlocksException { checkNotNull(origin); checkArgument(radius >= 0, "radius >= 0 required"); + final MaskIntersection mask = new MaskIntersection(new BoundedHeightMask(0, EditSession.this.getWorld().getMaxY()), new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, + radius, radius))), EditSession.this.getWorld().createLiquidMask()); - TaskManager.IMP.async(new Runnable() { + final BlockReplace replace = new BlockReplace(EditSession.this, new BlockPattern(new BaseBlock(BlockID.AIR))); + final RecursiveVisitor visitor = new RecursiveVisitor(mask, replace); + + // Around the origin in a 3x3 block + for (final BlockVector position : CuboidRegion.fromCenter(origin, 1)) { + if (mask.test(position)) { + visitor.visit(position); + } + } + + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - final MaskIntersection mask = new MaskIntersection(new BoundedHeightMask(0, EditSession.this.getWorld().getMaxY()), new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, - radius, radius))), EditSession.this.getWorld().createLiquidMask()); - - final BlockReplace replace = new BlockReplace(EditSession.this, new BlockPattern(new BaseBlock(BlockID.AIR))); - final RecursiveVisitor visitor = new RecursiveVisitor(mask, replace); - - // Around the origin in a 3x3 block - for (final BlockVector position : CuboidRegion.fromCenter(origin, 1)) { - if (mask.test(position)) { - visitor.visit(position); - } - } - - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -1538,39 +1486,32 @@ public class EditSession implements Extent { public int fixLiquid(final Vector origin, final double radius, final int moving, final int stationary) throws MaxChangedBlocksException { checkNotNull(origin); checkArgument(radius >= 0, "radius >= 0 required"); + // Our origins can only be liquids + final BlockMask liquidMask = new BlockMask(EditSession.this, new BaseBlock(moving, -1), new BaseBlock(stationary, -1)); - TaskManager.IMP.async(new Runnable() { + // But we will also visit air blocks + final MaskIntersection blockMask = new MaskUnion(liquidMask, new BlockMask(EditSession.this, new BaseBlock(BlockID.AIR))); + // There are boundaries that the routine needs to stay in + final MaskIntersection mask = new MaskIntersection(new BoundedHeightMask(0, Math.min(origin.getBlockY(), EditSession.this.getWorld().getMaxY())), new RegionMask(new EllipsoidRegion( + null, origin, new Vector(radius, radius, radius))), blockMask); + + final BlockReplace replace = new BlockReplace(EditSession.this, new BlockPattern(new BaseBlock(stationary))); + final NonRisingVisitor visitor = new NonRisingVisitor(mask, replace); + + // Around the origin in a 3x3 block + for (final BlockVector position : CuboidRegion.fromCenter(origin, 1)) { + if (liquidMask.test(position)) { + visitor.visit(position); + } + } + + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - // Our origins can only be liquids - final BlockMask liquidMask = new BlockMask(EditSession.this, new BaseBlock(moving, -1), new BaseBlock(stationary, -1)); - - // But we will also visit air blocks - final MaskIntersection blockMask = new MaskUnion(liquidMask, new BlockMask(EditSession.this, new BaseBlock(BlockID.AIR))); - - // There are boundaries that the routine needs to stay in - final MaskIntersection mask = new MaskIntersection(new BoundedHeightMask(0, Math.min(origin.getBlockY(), EditSession.this.getWorld().getMaxY())), new RegionMask(new EllipsoidRegion( - null, origin, new Vector(radius, radius, radius))), blockMask); - - final BlockReplace replace = new BlockReplace(EditSession.this, new BlockPattern(new BaseBlock(stationary))); - final NonRisingVisitor visitor = new NonRisingVisitor(mask, replace); - - // Around the origin in a 3x3 block - for (final BlockVector position : CuboidRegion.fromCenter(origin, 1)) { - if (liquidMask.test(position)) { - visitor.visit(position); - } - } - - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } @@ -2020,30 +1961,24 @@ public class EditSession implements Extent { * @throws MaxChangedBlocksException thrown if too many blocks are changed */ public int makePumpkinPatches(final Vector position, final int apothem) throws MaxChangedBlocksException { + // We want to generate pumpkins + final GardenPatchGenerator generator = new GardenPatchGenerator(EditSession.this); + generator.setPlant(GardenPatchGenerator.getPumpkinPattern()); - TaskManager.IMP.async(new Runnable() { + // In a region of the given radius + final FlatRegion region = new CuboidRegion(EditSession.this.getWorld(), // Causes clamping of Y range + position.add(-apothem, -5, -apothem), position.add(apothem, 10, apothem)); + final double density = 0.02; + + final GroundFunction ground = new GroundFunction(new ExistingBlockMask(EditSession.this), generator); + final LayerVisitor visitor = new LayerVisitor(region, minimumBlockY(region), maximumBlockY(region), ground); + visitor.setMask(new NoiseFilter2D(new RandomNoise(), density)); + Operations.completeSmart(visitor, new Runnable() { @Override public void run() { - // We want to generate pumpkins - final GardenPatchGenerator generator = new GardenPatchGenerator(EditSession.this); - generator.setPlant(GardenPatchGenerator.getPumpkinPattern()); - - // In a region of the given radius - final FlatRegion region = new CuboidRegion(EditSession.this.getWorld(), // Causes clamping of Y range - position.add(-apothem, -5, -apothem), position.add(apothem, 10, apothem)); - final double density = 0.02; - - final GroundFunction ground = new GroundFunction(new ExistingBlockMask(EditSession.this), generator); - final LayerVisitor visitor = new LayerVisitor(region, minimumBlockY(region), maximumBlockY(region), ground); - visitor.setMask(new NoiseFilter2D(new RandomNoise(), density)); - Operations.completeSmart(visitor, new Runnable() { - @Override - public void run() { - EditSession.this.flushQueue(); - } - }, true); + EditSession.this.flushQueue(); } - }); + }, true); return this.changes = -1; } diff --git a/core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index 5f8f10ca..f77ba2e7 100644 --- a/core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.extension.platform; import com.boydti.fawe.Fawe; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.wrappers.PlayerWrapper; @@ -279,10 +280,15 @@ public final class CommandManager { actor.printError("Usage: " + e.getSimpleUsageString("/")); } } catch (WrappedCommandException e) { - Throwable t = e.getCause(); - actor.printError("Please report this error: [See console]"); - actor.printRaw(t.getClass().getName() + ": " + t.getMessage()); - log.log(Level.SEVERE, "An unexpected error while handling a WorldEdit command", t); + FaweException faweException = FaweException.get(e); + if (faweException != null) { + actor.printError(BBC.PREFIX.s() + " " + BBC.WORLDEDIT_CANCEL_REASON.format(faweException.getMessage())); + } else { + Throwable t = e.getCause(); + actor.printError("Please report this error: [See console]"); + actor.printRaw(t.getClass().getName() + ": " + t.getMessage()); + log.log(Level.SEVERE, "An unexpected error while handling a WorldEdit command", t); + } } catch (CommandException e) { String message = e.getMessage(); if (message != null) { diff --git a/core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java b/core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java index 1d91303b..33d374d0 100644 --- a/core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java +++ b/core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java @@ -19,8 +19,6 @@ package com.sk89q.worldedit.function.operation; -import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.WorldEditException; @@ -72,38 +70,17 @@ public final class Operations { while (operation != null) { operation = operation.resume(new RunContext()); } - } catch (final Exception e) { - e.printStackTrace(); + } catch (WorldEditException e) { + throw new RuntimeException(e); } } public static void completeSmart(final Operation op, final Runnable whenDone, final boolean threadsafe) { - if (!threadsafe) { - completeBlindly(op); - if (whenDone != null) { - whenDone.run(); - } - return; + completeBlindly(op); + if (whenDone != null) { + whenDone.run(); } - SetQueue.IMP.addTask(new Runnable() { - @Override - public void run() { - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - Operation operation = op; - while (operation != null) { - try { - operation = operation.resume(new RunContext()); - } catch (final Exception e) { - e.printStackTrace(); - } - } - TaskManager.IMP.task(whenDone); - } - }); - }; - }); + return; } public static Class inject() { diff --git a/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java b/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java index c2c1e22a..5408484e 100644 --- a/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java +++ b/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java @@ -144,4 +144,9 @@ public class FaweSponge implements IFawe { } return players; } + + @Override + public String getPlatform() { + return "sponge"; + } }