diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitEditSessionWrapper_0.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitEditSessionWrapper_0.java index 4a98c616..d3d31093 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitEditSessionWrapper_0.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitEditSessionWrapper_0.java @@ -22,12 +22,12 @@ public class BukkitEditSessionWrapper_0 extends EditSessionWrapper { } @Override - public Extent getHistoryExtent(String world, FaweLimit limit, Extent parent, FaweChangeSet set, FaweQueue queue, FawePlayer player) { + public Extent getHistoryExtent(EditSession session, FaweLimit limit, Extent parent, FaweChangeSet set, FaweQueue queue, FawePlayer player) { if (this.hook != null) { // If we are doing logging, return a custom logging extent return this.hook.getLoggingExtent(parent, set, player); } // Otherwise return the normal history extent - return super.getHistoryExtent(world, limit, parent, set, queue, player); + return super.getHistoryExtent(session, limit, parent, set, queue, player); } } diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java index 88dab5f5..0015a4eb 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java @@ -7,6 +7,7 @@ import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.IntegerPair; +import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.ReflectionUtils.RefClass; import com.boydti.fawe.util.ReflectionUtils.RefConstructor; @@ -120,7 +121,7 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 { private LinkedBlockingDeque loadQueue = new LinkedBlockingDeque<>(); @Override - public int getCombinedId4Data(int x, int y, int z) { + public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException { if (y < 0 || y > 255) { return 0; } @@ -147,7 +148,7 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 { } } if (!bukkitWorld.isChunkLoaded(cx, cz)) { - return 0; + throw new FaweException.FaweChunkLoadException(); } } else { return 0; diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java index dbb26611..96d40e28 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java @@ -8,6 +8,7 @@ import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.IntegerPair; import com.boydti.fawe.object.PseudoRandom; +import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.ReflectionUtils.RefClass; import com.boydti.fawe.util.ReflectionUtils.RefConstructor; @@ -110,52 +111,46 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { private LinkedBlockingDeque loadQueue = new LinkedBlockingDeque<>(); @Override - public int getCombinedId4Data(int x, int y, int z) { + public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException { if (y < 0 || y > 255) { return 0; } - try { - int cx = x >> 4; - int cz = z >> 4; - int cy = y >> 4; - if (cx != lcx || cz != lcz) { - if (bukkitWorld == null) { - bukkitWorld = Bukkit.getServer().getWorld(world); - } - lcx = cx; - lcz = cz; - if (!bukkitWorld.isChunkLoaded(cx, cz)) { - boolean sync = Thread.currentThread() == Fawe.get().getMainThread(); - if (sync) { - bukkitWorld.loadChunk(cx, cz, true); - } else if (Settings.CHUNK_WAIT > 0) { - synchronized (loadQueue) { - loadQueue.add(new IntegerPair(cx, cz)); - try { - loadQueue.wait(Settings.CHUNK_WAIT); - } catch (InterruptedException e) { - e.printStackTrace(); - } + int cx = x >> 4; + int cz = z >> 4; + int cy = y >> 4; + if (cx != lcx || cz != lcz) { + if (bukkitWorld == null) { + bukkitWorld = Bukkit.getServer().getWorld(world); + } + lcx = cx; + lcz = cz; + if (!bukkitWorld.isChunkLoaded(cx, cz)) { + boolean sync = Thread.currentThread() == Fawe.get().getMainThread(); + if (sync) { + bukkitWorld.loadChunk(cx, cz, true); + } else if (Settings.CHUNK_WAIT > 0) { + synchronized (loadQueue) { + loadQueue.add(new IntegerPair(cx, cz)); + try { + loadQueue.wait(Settings.CHUNK_WAIT); + } catch (InterruptedException e) { + e.printStackTrace(); } - if (!bukkitWorld.isChunkLoaded(cx, cz)) { - return 0; - } - } else { - return 0; } + if (!bukkitWorld.isChunkLoaded(cx, cz)) { + throw new FaweException.FaweChunkLoadException(); + } + } else { + return 0; } - lc = methodGetType.of(methodGetHandleChunk.of(bukkitWorld.getChunkAt(cx, cz)).call()); } - if (lc == null) { - return 0; - } - int combined = (int) methodGetCombinedId.call(lc.call(x & 15, y, z & 15)); - return ((combined & 4095) << 4) + (combined >> 12); + lc = methodGetType.of(methodGetHandleChunk.of(bukkitWorld.getChunkAt(cx, cz)).call()); } - catch (Throwable e) { - e.printStackTrace(); + if (lc == null) { + return 0; } - return 0; + int combined = (int) methodGetCombinedId.call(lc.call(x & 15, y, z & 15)); + return ((combined & 4095) << 4) + (combined >> 12); } @Override diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java index 23315807..0b731c1a 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java @@ -9,6 +9,7 @@ import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.IntegerPair; import com.boydti.fawe.object.PseudoRandom; +import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.TaskManager; import com.sk89q.worldedit.LocalSession; @@ -78,67 +79,61 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0 { private DataPaletteBlock lastSection; @Override - public int getCombinedId4Data(int x, int y, int z) { + public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException { if (y < 0 || y > 255) { return 0; } - try { - int cx = x >> 4; - int cz = z >> 4; - int cy = y >> 4; - if (cx != lcx || cz != lcz) { - if (bukkitWorld == null) { - bukkitWorld = Bukkit.getServer().getWorld(world); - } - lcx = cx; - lcz = cz; - if (!bukkitWorld.isChunkLoaded(cx, cz)) { - boolean sync = Thread.currentThread() == Fawe.get().getMainThread(); - if (sync) { - bukkitWorld.loadChunk(cx, cz, true); - } else if (Settings.CHUNK_WAIT > 0) { - synchronized (loadQueue) { - loadQueue.add(new IntegerPair(cx, cz)); - try { - loadQueue.wait(Settings.CHUNK_WAIT); - } catch (InterruptedException e) { - e.printStackTrace(); - } + int cx = x >> 4; + int cz = z >> 4; + int cy = y >> 4; + if (cx != lcx || cz != lcz) { + if (bukkitWorld == null) { + bukkitWorld = Bukkit.getServer().getWorld(world); + } + lcx = cx; + lcz = cz; + if (!bukkitWorld.isChunkLoaded(cx, cz)) { + boolean sync = Thread.currentThread() == Fawe.get().getMainThread(); + if (sync) { + bukkitWorld.loadChunk(cx, cz, true); + } else if (Settings.CHUNK_WAIT > 0) { + synchronized (loadQueue) { + loadQueue.add(new IntegerPair(cx, cz)); + try { + loadQueue.wait(Settings.CHUNK_WAIT); + } catch (InterruptedException e) { + e.printStackTrace(); } - if (!bukkitWorld.isChunkLoaded(cx, cz)) { - return 0; - } - } else { - return 0; } - } - CraftChunk chunk = (CraftChunk) bukkitWorld.getChunkAt(cx, cz); - chunkSections = chunk.getHandle().getSections(); - ChunkSection nibble = chunkSections[cy]; - lastSection = nibble != null ? nibble.getBlocks() : null; - } else if (cy != lcy) { - if (chunkSections == null) { + if (!bukkitWorld.isChunkLoaded(cx, cz)) { + throw new FaweException.FaweChunkLoadException(); + } + } else { return 0; } - ChunkSection nibble = chunkSections[cy]; - lastSection = nibble != null ? nibble.getBlocks() : null; } - if (lastSection == null) { + CraftChunk chunk = (CraftChunk) bukkitWorld.getChunkAt(cx, cz); + chunkSections = chunk.getHandle().getSections(); + ChunkSection nibble = chunkSections[cy]; + lastSection = nibble != null ? nibble.getBlocks() : null; + } else if (cy != lcy) { + if (chunkSections == null) { return 0; } - IBlockData ibd = lastSection.a(x & 15, y & 15, z & 15); - Block block = ibd.getBlock(); - int id = Block.getId(block); - if (FaweCache.hasData(id)) { - return (id << 4) + block.toLegacyData(ibd); - } else { - return id << 4; - } + ChunkSection nibble = chunkSections[cy]; + lastSection = nibble != null ? nibble.getBlocks() : null; } - catch (Throwable e) { - e.printStackTrace(); + if (lastSection == null) { + return 0; + } + IBlockData ibd = lastSection.a(x & 15, y & 15, z & 15); + Block block = ibd.getBlock(); + int id = Block.getId(block); + if (FaweCache.hasData(id)) { + return (id << 4) + block.toLegacyData(ibd); + } else { + return id << 4; } - return 0; } @Override 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 f594bbbf..9f275ff6 100644 --- a/core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/core/src/main/java/com/boydti/fawe/config/BBC.java @@ -49,6 +49,7 @@ public enum BBC { 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_FAILED_LOAD_CHUNK("&cFailed to load chunk: &7%s0;%s1&c. Try increasing chunk-wait.", "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"), diff --git a/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java b/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java index 900e6e7e..20fbdcce 100644 --- a/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java +++ b/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java @@ -27,7 +27,7 @@ public class EditSessionWrapper { return minY; } - public Extent getHistoryExtent(String world, FaweLimit limit, Extent parent, FaweChangeSet set, FaweQueue queue, FawePlayer player) { - return new HistoryExtent(world, limit, parent, set, queue); + public Extent getHistoryExtent(EditSession session, FaweLimit limit, Extent parent, FaweChangeSet set, FaweQueue queue, FawePlayer player) { + return new HistoryExtent(session, limit, parent, set, queue); } } diff --git a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java index dc0ba86c..2371336b 100644 --- a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java @@ -3,6 +3,7 @@ package com.boydti.fawe.object; import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.util.FaweQueue; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; @@ -30,6 +31,7 @@ public class HistoryExtent extends AbstractDelegateExtent { private final com.boydti.fawe.object.changeset.FaweChangeSet changeSet; private final FaweQueue queue; private final FaweLimit limit; + private final EditSession session; /** * Create a new instance. @@ -37,12 +39,13 @@ public class HistoryExtent extends AbstractDelegateExtent { * @param extent the extent * @param changeSet the change set */ - public HistoryExtent(final String world, FaweLimit limit, final Extent extent, final FaweChangeSet changeSet, FaweQueue queue) { + public HistoryExtent(final EditSession session, FaweLimit limit, final Extent extent, final FaweChangeSet changeSet, FaweQueue queue) { super(extent); this.limit = limit; this.queue = queue; checkNotNull(changeSet); this.changeSet = changeSet; + this.session = session; } @Override @@ -51,7 +54,7 @@ public class HistoryExtent extends AbstractDelegateExtent { int x = location.getBlockX(); int y = location.getBlockY(); int z = location.getBlockZ(); - int combined = queue.getCombinedId4Data(x, y, z); + int combined = queue.getCombinedId4DataDebug(x, y, z, 0, session); int id = (combined >> 4); if (id == block.getId()) { if (!FaweCache.hasData(id)) { 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 index dd318011..81b0badf 100644 --- a/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java +++ b/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java @@ -24,4 +24,10 @@ public class FaweException extends RuntimeException { } return get(cause); } + + public static class FaweChunkLoadException extends FaweException { + public FaweChunkLoadException() { + super(BBC.WORLDEDIT_FAILED_LOAD_CHUNK); + } + } } diff --git a/core/src/main/java/com/boydti/fawe/util/FaweQueue.java b/core/src/main/java/com/boydti/fawe/util/FaweQueue.java index 9e3e62b4..270003d7 100644 --- a/core/src/main/java/com/boydti/fawe/util/FaweQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/FaweQueue.java @@ -3,6 +3,8 @@ package com.boydti.fawe.util; import com.boydti.fawe.Fawe; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.object.exception.FaweException; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.world.biome.BaseBiome; public abstract class FaweQueue { @@ -53,7 +55,24 @@ public abstract class FaweQueue { public abstract void addTask(int x, int z, Runnable runnable); - public abstract int getCombinedId4Data(int x, int y, int z); + public abstract int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException; + + public int getCombinedId4Data(int x, int y, int z, int def) { + try { + return getCombinedId4Data(x, y, z); + } catch (FaweException ignore) { + return def; + } + } + + public int getCombinedId4DataDebug(int x, int y, int z, int def, EditSession session) { + try { + return getCombinedId4Data(x, y, z); + } catch (FaweException ignore) { + session.debug(BBC.WORLDEDIT_FAILED_LOAD_CHUNK.format(x >> 4, z >> 4)); + return def; + } + } public abstract int size(); diff --git a/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java b/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java index 40791b42..b0fb0a7d 100644 --- a/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java +++ b/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java @@ -178,7 +178,7 @@ public class WorldWrapper extends AbstractWorld { } @Override - public boolean regenerate(final Region region, EditSession session) { + public boolean regenerate(final Region region, final EditSession session) { final FaweQueue queue = session.getQueue(); final FaweChangeSet fcs = (FaweChangeSet) session.getChangeSet(); final FaweExtent fe = session.getFaweExtent(); @@ -208,7 +208,7 @@ public class WorldWrapper extends AbstractWorld { for (int z = 0; z < 16; z++) { int zz = z + bz; for (int y = 0; y < getMaxY() + 1; y++) { - int from = queue.getCombinedId4Data(xx, y, zz); + int from = queue.getCombinedId4DataDebug(xx, y, zz, 0, session); if (!FaweCache.hasNBT(from >> 4)) { fcs.add(xx, y, zz, from, 0); } else { diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 1e7e74cd..13e58aa5 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -159,6 +159,7 @@ public class EditSession implements Extent { } private World world; + private Actor actor; private FaweChangeSet changeSet; private final EditSessionWrapper wrapper; private FaweExtent faweExtent; @@ -231,8 +232,7 @@ public class EditSession implements Extent { this.wrapper = Fawe.imp().getEditSessionWrapper(this); return; } - final Actor actor = event.getActor(); - + this.actor = event.getActor(); this.queue = SetQueue.IMP.getNewQueue(world.getName(), true); this.world = (world = new WorldWrapper((AbstractWorld) world)); this.wrapper = Fawe.imp().getEditSessionWrapper(this); @@ -316,7 +316,7 @@ public class EditSession implements Extent { Extent wrapped; extent = wrapped = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE); extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_REORDER); - extent = this.wrapper.getHistoryExtent(world.getName(), limit, extent, this.changeSet, queue, fp); + extent = this.wrapper.getHistoryExtent(this, limit, extent, this.changeSet, queue, fp); final Player skp = (Player) actor; final int item = skp.getItemInHand(); boolean hasMask = session.getMask() != null; @@ -340,6 +340,12 @@ public class EditSession implements Extent { return; } + public void debug(String message) { + if (actor != null && message != null && message.length() > 0) { + actor.print(BBC.PREFIX.s() + " " + message); + } + } + public FaweQueue getQueue() { return queue; } @@ -569,7 +575,7 @@ public class EditSession implements Extent { if (limit != null && limit.MAX_CHECKS-- < 0) { throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } - int combinedId4Data = queue.getCombinedId4Data(x, y, z); + int combinedId4Data = queue.getCombinedId4DataDebug(x, y, z, 0, this); if (!FaweCache.hasNBT(combinedId4Data >> 4)) { return FaweCache.CACHE_BLOCK[combinedId4Data]; } @@ -597,7 +603,7 @@ public class EditSession implements Extent { if (limit != null && limit.MAX_CHECKS-- < 0) { throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } - int combinedId4Data = queue.getCombinedId4Data(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + int combinedId4Data = queue.getCombinedId4DataDebug(position.getBlockX(), position.getBlockY(), position.getBlockZ(), 0, this); return combinedId4Data >> 4; } @@ -613,7 +619,7 @@ public class EditSession implements Extent { if (limit != null && limit.MAX_CHECKS-- < 0) { throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } - int combinedId4Data = queue.getCombinedId4Data(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + int combinedId4Data = queue.getCombinedId4DataDebug(position.getBlockX(), position.getBlockY(), position.getBlockZ(), 0, this); return combinedId4Data & 0xF; } @@ -2203,7 +2209,7 @@ public class EditSession implements Extent { expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ()); final BlockVector sourcePosition = environment.toWorld(x.getValue(), y.getValue(), z.getValue()); // read block from world - BaseBlock material = FaweCache.CACHE_BLOCK[this.queue.getCombinedId4Data(sourcePosition.getBlockX(), sourcePosition.getBlockY(), sourcePosition.getBlockZ())]; + BaseBlock material = FaweCache.CACHE_BLOCK[this.queue.getCombinedId4DataDebug(sourcePosition.getBlockX(), sourcePosition.getBlockY(), sourcePosition.getBlockZ(), 0, this)]; // queue operation if (this.setBlock(position, material)) { ++affected; diff --git a/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java b/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java index 0bfada11..33f1f399 100644 --- a/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java +++ b/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java @@ -8,6 +8,7 @@ import com.boydti.fawe.forge.v0.SpongeQueue_0; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.IntegerPair; import com.boydti.fawe.object.PseudoRandom; +import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.util.TaskManager; import com.flowpowered.math.vector.Vector3i; import java.lang.reflect.Field; @@ -63,7 +64,7 @@ public class SpongeQueue_1_8 extends SpongeQueue_0 { private LinkedBlockingDeque loadQueue = new LinkedBlockingDeque<>(); @Override - public int getCombinedId4Data(int x, int y, int z) { + public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException { if (y < 0 || y > 255) { return 0; } @@ -92,7 +93,7 @@ public class SpongeQueue_1_8 extends SpongeQueue_0 { } chunk = spongeWorld.getChunk(cx, 0, cz).orElse(null); if (chunk == null || !chunk.isLoaded()) { - return 0; + throw new FaweException.FaweChunkLoadException(); } } else { return 0;