diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
index dd1ab796..cb01fd96 100644
--- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
+++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
@@ -191,7 +191,9 @@ public class FaweBukkit implements IFawe, Listener {
} catch (Throwable ignore) {}
try {
return plugin.getQueue(world);
- } catch (Throwable ignore) {}
+ } catch (Throwable ignore) {
+ ignore.printStackTrace();
+ }
// Disable incompatible settings
Settings.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
Settings.COMBINE_HISTORY_STAGE = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java
index 26fec2ac..b987c755 100644
--- a/core/src/main/java/com/boydti/fawe/Fawe.java
+++ b/core/src/main/java/com/boydti/fawe/Fawe.java
@@ -30,6 +30,7 @@ import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.composition.SelectionCommand;
import com.sk89q.worldedit.command.tool.brush.GravityBrush;
+import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
@@ -244,6 +245,7 @@ public class Fawe {
*/
try {
EditSession.inject(); // Custom block placer + optimizations
+ EditSessionEvent.inject(); // Add EditSession to event
LocalSession.inject(); // Add remember order / queue flushing
// Commands
BrushCommands.inject(); // Translations + heightmap
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 afee1fc5..b6847010 100644
--- a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java
+++ b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java
@@ -26,7 +26,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class HistoryExtent extends AbstractDelegateExtent {
- private final com.boydti.fawe.object.changeset.FaweChangeSet changeSet;
+ private com.boydti.fawe.object.changeset.FaweChangeSet changeSet;
private final FaweQueue queue;
private final FaweLimit limit;
private final EditSession session;
@@ -46,6 +46,10 @@ public class HistoryExtent extends AbstractDelegateExtent {
this.session = session;
}
+ public void setChangeSet(FaweChangeSet fcs) {
+ this.changeSet = fcs;
+ }
+
@Override
public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException {
int x = location.getBlockX();
diff --git a/core/src/main/java/com/boydti/fawe/util/MathMan.java b/core/src/main/java/com/boydti/fawe/util/MathMan.java
index 494c47aa..72b60541 100644
--- a/core/src/main/java/com/boydti/fawe/util/MathMan.java
+++ b/core/src/main/java/com/boydti/fawe/util/MathMan.java
@@ -43,6 +43,18 @@ public class MathMan {
253, 254, 254, 255
};
+ public static long pairInt(int x, int y) {
+ return (((long)x) << 32) | (y & 0xffffffffL);
+ }
+
+ public static int unpairIntX(long pair) {
+ return (int)(pair >> 32);
+ }
+
+ public static int unpairIntY(long pair) {
+ return (int)pair;
+ }
+
public static byte pair16(byte x, byte y) {
return (byte) (x + (y << 4));
}
diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java
index e0aba620..1ed33661 100644
--- a/core/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -171,6 +171,7 @@ public class EditSession implements Extent {
private MaskingExtent maskingExtent;
private FaweRegionExtent regionExtent;
private Extent primaryExtent;
+ private HistoryExtent history;
private Extent bypassReorderHistory;
private Extent bypassHistory;
private Extent bypassNone;
@@ -221,10 +222,11 @@ public class EditSession implements Extent {
* @param blockBag an optional {@link BlockBag} to use, otherwise null
* @param event the event to call with the extent
*/
- public EditSession(final EventBus eventBus, World world, final int maxBlocks, @Nullable final BlockBag blockBag, final EditSessionEvent event) {
+ public EditSession(final EventBus eventBus, World world, final int maxBlocks, @Nullable final BlockBag blockBag, EditSessionEvent event) {
checkNotNull(eventBus);
checkArgument(maxBlocks >= -1, "maxBlocks >= -1 required");
checkNotNull(event);
+ event.setEditSession(this);
this.actor = event.getActor();
// TODO block bag
@@ -261,7 +263,7 @@ public class EditSession implements Extent {
if (Settings.COMBINE_HISTORY_STAGE) {
changeSet.addChangeTask(queue);
} else {
- extent = new HistoryExtent(this, limit, extent, changeSet, queue);
+ extent = history = new HistoryExtent(this, limit, extent, changeSet, queue);
}
}
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_HISTORY);
@@ -348,7 +350,7 @@ public class EditSession implements Extent {
if (Settings.COMBINE_HISTORY_STAGE) {
changeSet.addChangeTask(queue);
} else {
- extent = new HistoryExtent(this, limit, extent, changeSet, queue);
+ extent = history = new HistoryExtent(this, limit, extent, changeSet, queue);
}
// Region restrictions if mask is not null
if (mask != null) {
@@ -476,6 +478,9 @@ public class EditSession implements Extent {
}
public void setChangeSet(FaweChangeSet set) {
+ if (history != null) {
+ history.setChangeSet(set);
+ }
changes++;
this.changeSet = set;
}
diff --git a/core/src/main/java/com/sk89q/worldedit/event/extent/EditSessionEvent.java b/core/src/main/java/com/sk89q/worldedit/event/extent/EditSessionEvent.java
new file mode 100644
index 00000000..c0400e8d
--- /dev/null
+++ b/core/src/main/java/com/sk89q/worldedit/event/extent/EditSessionEvent.java
@@ -0,0 +1,166 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * event.setExtent(new MyExtent(event.getExtent()) + *+ * + * This event is fired several times during the creation of a single + * {@link EditSession}, but {@link #getStage()} will differ each time. + * The stage determines at which point {@link Extent}s added to this event + * will be called. For example, if you inject an extent when the stage + * is set to {@link Stage#BEFORE_HISTORY}, then you can drop (or log) changes + * before the change has reached the history, reordering, and actual change + * extents, but that means that any changes made with + * {@link EditSession#rawSetBlock(Vector, BaseBlock)} will skip your + * custom {@link Extent} because that method bypasses history (and reorder). + * It is thus recommended that loggers intercept at {@link Stage#BEFORE_CHANGE} + * and block interceptors intercept at BOTH {@link Stage#BEFORE_CHANGE} and + * {@link Stage#BEFORE_HISTORY}. + */ +public class EditSessionEvent extends Event { + + private final World world; + private final Actor actor; + private final int maxBlocks; + private final Stage stage; + private Extent extent; + private EditSession session; + + /** + * Create a new event. + * + * @param world the world + * @param actor the actor, or null if there is no actor specified + * @param maxBlocks the maximum number of block changes + * @param stage the stage + */ + public EditSessionEvent(@Nullable World world, Actor actor, int maxBlocks, Stage stage) { + this.world = world; + this.actor = actor; + this.maxBlocks = maxBlocks; + this.stage = stage; + } + + public void setEditSession(EditSession session) { + this.session = session; + } + + public EditSession getEditSession() { + return session; + } + + /** + * Get the actor for this event. + * + * @return the actor, which may be null if unavailable + */ + public @Nullable Actor getActor() { + return actor; + } + + /** + * Get the world. + * + * @return the world + */ + public @Nullable World getWorld() { + return world; + } + + /** + * Get the maximum number of blocks that may be set. + * + * @return the maximum number of blocks, which is -1 if unlimited + */ + public int getMaxBlocks() { + return maxBlocks; + } + + /** + * Get the {@link Extent} that can be wrapped. + * + * @return the extent + */ + public Extent getExtent() { + return extent; + } + + /** + * Get the stage that is being wrapped. + * + * @return the stage + */ + public Stage getStage() { + return stage; + } + + /** + * Set a new extent that should be used. It should wrap the extent + * returned from {@link #getExtent()}. + * + * @param extent the extent + */ + public void setExtent(Extent extent) { + checkNotNull(extent); + this.extent = extent; + } + + /** + * Create a clone of this event with the given stage. + * + * @param stage the stage + * @return a new event + */ + public EditSessionEvent clone(Stage stage) { + EditSessionEvent clone = new EditSessionEvent(world, actor, maxBlocks, stage); + clone.setEditSession(session); + return clone; + } + + public static Class> inject() { + return EditSessionEvent.class; + } + +}