From b168d1b3363acfe1cb1e97f2331f8987ebb53156 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Thu, 26 May 2016 05:29:55 +1000 Subject: [PATCH] Various Fix entity y value not within chunk Fix combined stages CPUOptimizedHistory not restoring air in existing sections on undo Change EditSession to wait for completion on flush (you should be flushing it async) Added setting for edit session history with no session --- .../fawe/bukkit/v1_8/BukkitQueue18R3.java | 3 +- .../fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java | 3 +- .../java/com/boydti/fawe/config/Settings.java | 3 + .../changeset/CPUOptimizedChangeSet.java | 22 ++++++- .../java/com/boydti/fawe/util/MainUtil.java | 28 ++++----- .../com/boydti/fawe/util/TaskManager.java | 19 ++++++ .../java/com/sk89q/worldedit/EditSession.java | 60 +++++++++++++++---- .../com/sk89q/worldedit/LocalSession.java | 41 ------------- .../extension/platform/CommandManager.java | 31 ++++------ .../boydti/fawe/forge/v0/ForgeQueue_All.java | 3 +- .../boydti/fawe/forge/v0/ForgeQueue_All.java | 3 +- .../fawe/sponge/v1_8/SpongeQueue_1_8.java | 3 +- 12 files changed, 122 insertions(+), 97 deletions(-) diff --git a/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java b/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java index 338f88f7..9a20d908 100644 --- a/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java +++ b/bukkit18/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue18R3.java @@ -227,8 +227,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) { nmsWorld.removeEntity(entity); } } diff --git a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java index 13399247..3ebfad15 100644 --- a/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java +++ b/bukkit19/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java @@ -505,8 +505,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0 255) { continue; } - int j = FaweCache.CACHE_J[y][x][z]; - if (array[j] != 0) { + if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) { nmsWorld.removeEntity(entity); } } 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 27f5d697..3956e6aa 100644 --- a/core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/core/src/main/java/com/boydti/fawe/config/Settings.java @@ -19,6 +19,7 @@ public class Settings { public static boolean ENABLE_HARD_LIMIT = true; public static boolean STORE_HISTORY_ON_DISK = false; public static boolean STORE_CLIPBOARD_ON_DISK = false; + public static boolean CONSOLE_HISTORY = true; public static int DELETE_HISTORY_AFTER_DAYS = 7; public static boolean CLEAN_HISTORY_ON_LOGOUT = true; public static int DELETE_CLIPBOARD_AFTER_DAYS = 1; @@ -98,6 +99,7 @@ public class Settings { options.put("history.chunk-wait-ms", CHUNK_WAIT); options.put("history.delete-after-days", DELETE_HISTORY_AFTER_DAYS); options.put("history.delete-on-logout", CLEAN_HISTORY_ON_LOGOUT); + options.put("history.enable-for-console", CONSOLE_HISTORY); options.put("region-restrictions", REGION_RESTRICTIONS); options.put("queue.extra-time-ms", ALLOCATE); options.put("queue.progress.display", DISPLAY_PROGRESS); @@ -144,6 +146,7 @@ public class Settings { DELETE_HISTORY_AFTER_DAYS = config.getInt("history.delete-after-days"); CLEAN_HISTORY_ON_LOGOUT = config.getBoolean("history.delete-on-logout"); CHUNK_WAIT = config.getInt("history.chunk-wait-ms"); + CONSOLE_HISTORY = config.getBoolean("history.enable-for-console"); ALLOCATE = config.getInt("queue.extra-time-ms"); QUEUE_SIZE = config.getInt("queue.target-size"); QUEUE_MAX_WAIT = config.getInt("queue.max-wait-ms"); diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/CPUOptimizedChangeSet.java b/core/src/main/java/com/boydti/fawe/object/changeset/CPUOptimizedChangeSet.java index f7186546..711a7562 100644 --- a/core/src/main/java/com/boydti/fawe/object/changeset/CPUOptimizedChangeSet.java +++ b/core/src/main/java/com/boydti/fawe/object/changeset/CPUOptimizedChangeSet.java @@ -1,9 +1,9 @@ package com.boydti.fawe.object.changeset; import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.RunnableVal2; import com.boydti.fawe.object.change.MutableChunkChange; -import com.boydti.fawe.object.FaweQueue; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.history.change.Change; import com.sk89q.worldedit.world.World; @@ -25,8 +25,24 @@ public class CPUOptimizedChangeSet extends FaweChangeSet { char[][] previousIds = previous.getCombinedIdArrays(); char[][] nextIds = next.getCombinedIdArrays(); for (int i = 0; i < nextIds.length; i++) { - if (nextIds[i] != null && previousIds[i] == null) { - previous.fillCuboid(0, 15, i << 4, (i << 4) + 15, 0, 15, 0, (byte) 0); + char[] nextArray = nextIds[i]; + if (nextArray != null) { + char[] previousArray = previousIds[i]; + if (previousArray == null) { + previous.fillCuboid(0, 15, i << 4, (i << 4) + 15, 0, 15, 0, (byte) 0); + continue; + } + for (int k = 0; k < nextArray.length; k++) { + int combinedNext = nextArray[k]; + if (combinedNext > 0) { + int combinedPrevious = previousArray[k]; + if (combinedPrevious == 0) { + previousArray[k] = 1; + } + } else { + previousArray[k] = 0; + } + } } } changes.add(new MutableChunkChange(previous, next)); diff --git a/core/src/main/java/com/boydti/fawe/util/MainUtil.java b/core/src/main/java/com/boydti/fawe/util/MainUtil.java index 969fc565..8f99fceb 100644 --- a/core/src/main/java/com/boydti/fawe/util/MainUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/MainUtil.java @@ -185,22 +185,22 @@ public class MainUtil { if (e == null) { return; } - if (!debug) { +// if (!debug) { e.printStackTrace(); return; - } - String header = "====== FAWE: " + e.getLocalizedMessage() + " ======"; - Fawe.debug(header); - String[] trace = getTrace(e); - for (int i = 0; i < trace.length && i < 8; i++) { - Fawe.debug(" - " + trace[i]); - } - String[] cause = getTrace(e.getCause()); - Fawe.debug("Cause: " + (cause.length == 0 ? "N/A" : "")); - for (int i = 0; i < cause.length && i < 8; i++) { - Fawe.debug(" - " + cause[i]); - } - Fawe.debug(StringMan.repeat("=", header.length())); +// } +// String header = "====== FAWE: " + e.getLocalizedMessage() + " ======"; +// Fawe.debug(header); +// String[] trace = getTrace(e); +// for (int i = 0; i < trace.length && i < 8; i++) { +// Fawe.debug(" - " + trace[i]); +// } +// String[] cause = getTrace(e.getCause()); +// Fawe.debug("Cause: " + (cause.length == 0 ? "N/A" : "")); +// for (int i = 0; i < cause.length && i < 8; i++) { +// Fawe.debug(" - " + cause[i]); +// } +// Fawe.debug(StringMan.repeat("=", header.length())); } public static String[] getTrace(Throwable e) { diff --git a/core/src/main/java/com/boydti/fawe/util/TaskManager.java b/core/src/main/java/com/boydti/fawe/util/TaskManager.java index 6607d58a..f0c88b69 100644 --- a/core/src/main/java/com/boydti/fawe/util/TaskManager.java +++ b/core/src/main/java/com/boydti/fawe/util/TaskManager.java @@ -141,6 +141,25 @@ public abstract class TaskManager { return sync(function, Integer.MAX_VALUE); } + public void wait(AtomicBoolean running, int timout) { + try { + synchronized (running) { + while (running.get()) { + running.wait(timout); + } + } + } catch (InterruptedException e) { + MainUtil.handleError(e); + } + } + + public void notify(AtomicBoolean running) { + running.set(false); + synchronized (running) { + running.notifyAll(); + } + } + /** * Quickly run a task on the main thread, and wait for execution to finish:
* - Useful if you need to access something from the Bukkit API from another thread
diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index b9b1769f..e156ea63 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -26,6 +26,7 @@ import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.EditSessionWrapper; import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.HistoryExtent; import com.boydti.fawe.object.NullChangeSet; import com.boydti.fawe.object.RegionWrapper; @@ -41,7 +42,6 @@ import com.boydti.fawe.object.extent.MemoryCheckingExtent; import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.object.extent.ProcessedWEExtent; import com.boydti.fawe.object.progress.DefaultProgressTracker; -import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.Perm; @@ -131,6 +131,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -178,8 +180,9 @@ public class EditSession implements Extent { private FaweLimit limit = FaweLimit.MAX.copy(); private FaweQueue queue; - public static BaseBiome nullBiome = new BaseBiome(0); - public static BaseBlock nullBlock = FaweCache.CACHE_BLOCK[0]; + public static final UUID CONSOLE = UUID.fromString("1-1-3-3-7"); + public static final BaseBiome nullBiome = new BaseBiome(0); + public static final BaseBlock nullBlock = FaweCache.CACHE_BLOCK[0]; /** * Create a new instance. @@ -252,9 +255,18 @@ public class EditSession implements Extent { // Everything bypasses extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE); extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_REORDER); + // History + if (Settings.CONSOLE_HISTORY) { + this.changeSet = Settings.STORE_HISTORY_ON_DISK ? new DiskStorageHistory(world, CONSOLE) : (Settings.COMBINE_HISTORY_STAGE && Settings.COMPRESSION_LEVEL == 0) ? new CPUOptimizedChangeSet(world) : new MemoryOptimizedHistory(world); + if (Settings.COMBINE_HISTORY_STAGE) { + changeSet.addChangeTask(queue); + } else { + extent = new HistoryExtent(this, limit, extent, changeSet, queue); + } + } extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_HISTORY); - this.bypassReorderHistory = extent; - this.bypassHistory = extent; + this.bypassReorderHistory = primaryExtent; + this.bypassHistory = primaryExtent; this.bypassNone = extent; this.changeSet = new NullChangeSet(world); return; @@ -384,11 +396,16 @@ public class EditSession implements Extent { public boolean cancel() { // Cancel this if (primaryExtent != null && queue != null) { + System.out.println("CANCEL"); try { WEManager.IMP.cancelEdit(primaryExtent, BBC.WORLDEDIT_CANCEL_REASON_MANUAL); } catch (Throwable ignore) {} NullExtent nullExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MANUAL); primaryExtent = nullExtent; + regionExtent = nullExtent; + bypassReorderHistory = nullExtent; + bypassHistory = nullExtent; + bypassNone = nullExtent; dequeue(); queue.clear(); return true; @@ -883,7 +900,8 @@ public class EditSession implements Extent { */ public void undo(final EditSession editSession) { final UndoContext context = new UndoContext(); - context.setExtent(editSession.bypassHistory); + context.setExtent(editSession.primaryExtent); + editSession.getQueue().setChangeTask(null); Operations.completeSmart(ChangeSetExecutor.createUndo(this.changeSet, context), new Runnable() { @Override public void run() { @@ -900,7 +918,8 @@ public class EditSession implements Extent { */ public void redo(final EditSession editSession) { final UndoContext context = new UndoContext(); - context.setExtent(editSession.bypassHistory); + context.setExtent(editSession.primaryExtent); + editSession.getQueue().setChangeTask(null); Operations.completeSmart(ChangeSetExecutor.createRedo(this.changeSet, context), new Runnable() { @Override public void run() { @@ -943,9 +962,30 @@ public class EditSession implements Extent { * Finish off the queue. */ public void flushQueue() { - Operations.completeBlindly(EditSession.this.commit()); - if (queue != null) { - queue.enqueue(); + Operations.completeBlindly(commit()); + // Enqueue it + if (queue != null && queue.size() > 0) { + SetQueue.IMP.enqueue(queue); + } + if (changeSet != null) { + if (Settings.COMBINE_HISTORY_STAGE && queue.size() > 0) { + final AtomicBoolean running = new AtomicBoolean(true); + queue.addNotifyTask(new Runnable() { + @Override + public void run() { + TaskManager.IMP.async(new Runnable() { + @Override + public void run() { + changeSet.flush(); + TaskManager.IMP.notify(running); + } + }); + } + }); + TaskManager.IMP.wait(running, Settings.QUEUE_DISCARD_AFTER); + } else { + changeSet.flush(); + } } } diff --git a/core/src/main/java/com/sk89q/worldedit/LocalSession.java b/core/src/main/java/com/sk89q/worldedit/LocalSession.java index 492c2df2..a418a340 100644 --- a/core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -20,13 +20,7 @@ package com.sk89q.worldedit; import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.changeset.FaweChangeSet; -import com.boydti.fawe.object.changeset.FaweStreamChangeSet; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; -import com.boydti.fawe.object.FaweQueue; -import com.boydti.fawe.util.MainUtil; -import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; import com.sk89q.jchronic.Chronic; import com.sk89q.jchronic.Options; import com.sk89q.jchronic.utils.Span; @@ -43,7 +37,6 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Masks; -import com.sk89q.worldedit.history.changeset.ChangeSet; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.internal.cui.CUIRegion; import com.sk89q.worldedit.internal.cui.SelectionShapeEvent; @@ -210,14 +203,6 @@ public class LocalSession { if (Settings.STORE_HISTORY_ON_DISK) { MAX_HISTORY_SIZE = Integer.MAX_VALUE; } - // Enqueue it - if (editSession.getQueue() != null) { - FaweQueue queue = editSession.getQueue(); - if (queue.size() > 0) { - SetQueue.IMP.enqueue(editSession.getQueue()); - } - } - // Don't store anything if no changes were made if (editSession.size() == 0 || editSession.hasFastMode()) return; @@ -227,32 +212,6 @@ public class LocalSession { history.remove(historyPointer); } } - ChangeSet set = editSession.getChangeSet(); - if (set instanceof FaweStreamChangeSet) { - final FaweStreamChangeSet fcs = (FaweStreamChangeSet) set; - if (Settings.COMBINE_HISTORY_STAGE) { - editSession.getQueue().addNotifyTask(new Runnable() { - @Override - public void run() { - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - if (fcs.flush() && append && sendMessage) { - MainUtil.sendCompressedMessage(fcs, editSession.getActor()); - } - } - }); - } - }); - } else { - if (fcs.flush() && append && sendMessage) { - MainUtil.sendCompressedMessage(fcs, editSession.getActor()); - } - } - - } else if (set instanceof FaweChangeSet) { - ((FaweChangeSet) set).flush(); - } if (append) { history.add(editSession); historyPointer = history.size(); 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 90e6d958..f7ee1f23 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 @@ -21,7 +21,9 @@ package com.sk89q.worldedit.extension.platform; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.changeset.FaweStreamChangeSet; import com.boydti.fawe.object.exception.FaweException; +import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.wrappers.PlayerWrapper; import com.google.common.base.Joiner; @@ -64,6 +66,7 @@ import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; import com.sk89q.worldedit.function.factory.Deform; import com.sk89q.worldedit.function.factory.Deform.Mode; +import com.sk89q.worldedit.history.changeset.ChangeSet; import com.sk89q.worldedit.internal.command.ActorAuthorizer; import com.sk89q.worldedit.internal.command.CommandLoggingHandler; import com.sk89q.worldedit.internal.command.UserCommandCompleter; @@ -288,29 +291,19 @@ public final class CommandManager { if (editSession != null) { editSession.flushQueue(); worldEdit.flushBlockBag(actor, editSession); + session.remember(editSession, true, true); } if (fp != null) { - if (editSession != null && editSession.size() > 0 && editSession.getQueue() != null) { - delayed = true; - editSession.getQueue().addNotifyTask(new Runnable() { - @Override - public void run() { - session.remember(editSession, true, true); - fp.deleteMeta("fawe_action"); - final long time = System.currentTimeMillis() - start; - if (time > 5) { - BBC.ACTION_COMPLETE.send(actor, (time / 1000d)); - } - } - }); + fp.deleteMeta("fawe_action"); + final long time = System.currentTimeMillis() - start; + if (time > 0) { + BBC.ACTION_COMPLETE.send(actor, (time / 50d)); + ChangeSet fcs = editSession.getChangeSet(); + if (fcs != null && fcs instanceof FaweStreamChangeSet) { + MainUtil.sendCompressedMessage((FaweStreamChangeSet) fcs, editSession.getActor()); + } } } - if (!delayed) { - if (fp != null) { - fp.deleteMeta("fawe_action"); - } - session.remember(editSession, true, true); - } } } }); diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java index 1d36eb38..db85f870 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java @@ -332,8 +332,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) { nmsWorld.removeEntity(entity); } } diff --git a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java index 96b2103e..6e7af89a 100644 --- a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java +++ b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java @@ -385,8 +385,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) { nmsWorld.removeEntity(entity); } } diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java b/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java index 0d9b3b4e..07f9a301 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java @@ -334,8 +334,7 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) { nmsWorld.removeEntity(entity); } }