Fix limits / add cancellation messages
This commit is contained in:
parent
c1acacc208
commit
de08ef85d7
@ -310,4 +310,9 @@ public class FaweBukkit extends JavaPlugin implements IFawe, Listener {
|
||||
fp.loadSessionFromDisk(fp.getWorld());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatform() {
|
||||
return "bukkit";
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -37,4 +37,6 @@ public interface IFawe {
|
||||
public void startMetrics();
|
||||
|
||||
public Set<FawePlayer> getPlayers();
|
||||
|
||||
public String getPlatform();
|
||||
}
|
||||
|
@ -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"),
|
||||
|
@ -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<String, FaweLimit> 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<String, Object> node : options.entrySet()) {
|
||||
if (!config.contains(node.getKey())) {
|
||||
|
@ -51,4 +51,9 @@ public class FaweLimit {
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MAX_CHANGES + "";
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<FaweMaskManager> 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<RegionWrapper> mask, final int x, final int z) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -144,4 +144,9 @@ public class FaweSponge implements IFawe {
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatform() {
|
||||
return "sponge";
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user