geforkt von Mirrors/FastAsyncWorldEdit
Added events for each stage of EditSession Extent creation.
Dieser Commit ist enthalten in:
Ursprung
c8e455cd6f
Commit
2e904577b7
@ -90,13 +90,13 @@ import static com.sk89q.worldedit.regions.Regions.*;
|
||||
public class EditSession implements Extent {
|
||||
|
||||
/**
|
||||
* Used by {@link #setBlock(Vector, BaseBlock, Level)} to
|
||||
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to
|
||||
* determine which {@link Extent}s should be bypassed.
|
||||
*/
|
||||
public enum Level {
|
||||
NORMAL,
|
||||
NO_HISTORY_REORDER,
|
||||
NO_HISTORY
|
||||
public enum Stage {
|
||||
BEFORE_HISTORY,
|
||||
BEFORE_REORDER,
|
||||
BEFORE_CHANGE
|
||||
}
|
||||
|
||||
@SuppressWarnings("ProtectedField")
|
||||
@ -138,32 +138,37 @@ public class EditSession implements Extent {
|
||||
|
||||
this.world = world;
|
||||
|
||||
// This extents are ALWAYS used
|
||||
fastModeExtent = new FastModeExtent(world, false);
|
||||
chunkLoadingExtent = new ChunkLoadingExtent(fastModeExtent, world);
|
||||
cacheExtent = new LastAccessExtentCache(chunkLoadingExtent);
|
||||
|
||||
// Call the event a plugin can wrap the extent
|
||||
event.setExtent(cacheExtent);
|
||||
eventBus.post(event);
|
||||
Extent wrappedExtent = event.getExtent();
|
||||
Extent extent;
|
||||
|
||||
// This extents are ALWAYS used
|
||||
quirkExtent = new BlockQuirkExtent(wrappedExtent, world);
|
||||
validator = new DataValidatorExtent(quirkExtent, world);
|
||||
blockBagExtent = new BlockBagExtent(validator, world, blockBag);
|
||||
extent = fastModeExtent = new FastModeExtent(world, false);
|
||||
extent = chunkLoadingExtent = new ChunkLoadingExtent(extent, world);
|
||||
extent = cacheExtent = new LastAccessExtentCache(extent);
|
||||
extent = wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE);
|
||||
extent = quirkExtent = new BlockQuirkExtent(extent, world);
|
||||
extent = validator = new DataValidatorExtent(extent, world);
|
||||
extent = blockBagExtent = new BlockBagExtent(extent, world, blockBag);
|
||||
|
||||
// This extent can be skipped by calling rawSetBlock()
|
||||
reorderExtent = new MultiStageReorder(blockBagExtent, false);
|
||||
extent = reorderExtent = new MultiStageReorder(extent, false);
|
||||
extent = wrapExtent(extent, eventBus, event, Stage.BEFORE_REORDER);
|
||||
|
||||
// These extents can be skipped by calling smartSetBlock()
|
||||
changeSetExtent = new ChangeSetExtent(reorderExtent, changeSet);
|
||||
maskingExtent = new MaskingExtent(changeSetExtent, Masks.alwaysTrue());
|
||||
changeLimiter = new BlockChangeLimiter(maskingExtent, maxBlocks);
|
||||
extent = changeSetExtent = new ChangeSetExtent(extent, changeSet);
|
||||
extent = maskingExtent = new MaskingExtent(extent, Masks.alwaysTrue());
|
||||
extent = changeLimiter = new BlockChangeLimiter(extent, maxBlocks);
|
||||
extent = wrapExtent(extent, eventBus, event, Stage.BEFORE_HISTORY);
|
||||
|
||||
this.bypassReorderHistory = blockBagExtent;
|
||||
this.bypassHistory = reorderExtent;
|
||||
this.bypassNone = changeLimiter;
|
||||
this.bypassNone = extent;
|
||||
}
|
||||
|
||||
private Extent wrapExtent(Extent extent, EventBus eventBus, EditSessionEvent event, Stage stage) {
|
||||
event = event.clone(stage);
|
||||
event.setExtent(extent);
|
||||
eventBus.post(event);
|
||||
return event.getExtent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -402,16 +407,16 @@ public class EditSession implements Extent {
|
||||
*
|
||||
* @param position the position to set the block at
|
||||
* @param block the block
|
||||
* @param level the level
|
||||
* @param stage the level
|
||||
* @return whether the block changed
|
||||
*/
|
||||
public boolean setBlock(Vector position, BaseBlock block, Level level) throws WorldEditException {
|
||||
switch (level) {
|
||||
case NORMAL:
|
||||
public boolean setBlock(Vector position, BaseBlock block, Stage stage) throws WorldEditException {
|
||||
switch (stage) {
|
||||
case BEFORE_HISTORY:
|
||||
return bypassNone.setBlock(position, block);
|
||||
case NO_HISTORY_REORDER:
|
||||
case BEFORE_CHANGE:
|
||||
return bypassHistory.setBlock(position, block);
|
||||
case NO_HISTORY:
|
||||
case BEFORE_REORDER:
|
||||
return bypassReorderHistory.setBlock(position, block);
|
||||
}
|
||||
|
||||
@ -424,12 +429,10 @@ public class EditSession implements Extent {
|
||||
* @param position the position to set the block at
|
||||
* @param block the block
|
||||
* @return whether the block changed
|
||||
* @deprecated Use {@link #setBlock(Vector, BaseBlock, Level)}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean rawSetBlock(Vector position, BaseBlock block) {
|
||||
try {
|
||||
return setBlock(position, block, Level.NO_HISTORY_REORDER);
|
||||
return setBlock(position, block, Stage.BEFORE_CHANGE);
|
||||
} catch (WorldEditException e) {
|
||||
throw new RuntimeException("Unexpected exception", e);
|
||||
}
|
||||
@ -441,12 +444,10 @@ public class EditSession implements Extent {
|
||||
* @param position the position to set the block at
|
||||
* @param block the block
|
||||
* @return whether the block changed
|
||||
* @deprecated Use {@link #setBlock(Vector, BaseBlock, Level)}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean smartSetBlock(Vector position, BaseBlock block) {
|
||||
try {
|
||||
return setBlock(position, block, Level.NO_HISTORY);
|
||||
return setBlock(position, block, Stage.BEFORE_REORDER);
|
||||
} catch (WorldEditException e) {
|
||||
throw new RuntimeException("Unexpected exception", e);
|
||||
}
|
||||
@ -455,7 +456,7 @@ public class EditSession implements Extent {
|
||||
@Override
|
||||
public boolean setBlock(Vector position, BaseBlock block) throws MaxChangedBlocksException {
|
||||
try {
|
||||
return setBlock(position, block, Level.NORMAL);
|
||||
return setBlock(position, block, Stage.BEFORE_HISTORY);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
throw e;
|
||||
} catch (WorldEditException e) {
|
||||
|
@ -33,6 +33,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extension.registry.BlockRegistry;
|
||||
import com.sk89q.worldedit.extension.registry.MaskRegistry;
|
||||
import com.sk89q.worldedit.extension.registry.PatternRegistry;
|
||||
import com.sk89q.worldedit.extent.ExtentDelegate;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||
@ -46,6 +47,7 @@ import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.LogFormat;
|
||||
import com.sk89q.worldedit.util.eventbus.EventBus;
|
||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.*;
|
||||
|
@ -22,39 +22,63 @@ package com.sk89q.worldedit.event.extent;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.event.Event;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.sk89q.worldedit.EditSession.Stage;
|
||||
|
||||
/**
|
||||
* Raised when a new {@link EditSession} is being instantiated.
|
||||
* Raised (several times) when a new {@link EditSession} is being instantiated.
|
||||
* </p>
|
||||
* Block loggers, as well as block set interceptors, can use this event to wrap
|
||||
* the given {@link Extent} with their own, which would allow them to intercept
|
||||
* all changes made to the world.
|
||||
* all changes made to the world. For example, the code below would wrap the
|
||||
* existing extent with a custom one, and the custom extent would receive
|
||||
* all method calls <strong>before</strong> the extent fetched from
|
||||
* {@link #getExtent()} would.
|
||||
* <pre>
|
||||
* event.setExtent(new MyExtent(event.getExtent())
|
||||
* </pre>
|
||||
* 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, <em>but</em> 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 LocalWorld world;
|
||||
private final LocalPlayer player;
|
||||
private final int maxBlocks;
|
||||
private final Stage stage;
|
||||
private Extent extent;
|
||||
|
||||
/**
|
||||
* Create a new event.
|
||||
*
|
||||
* @param player the player, or null if not available
|
||||
* @param world the world
|
||||
* @param player the player, or null if not available
|
||||
* @param maxBlocks the maximum number of block changes
|
||||
* @param stage the stage
|
||||
*/
|
||||
public EditSessionEvent(LocalWorld world, LocalPlayer player, int maxBlocks) {
|
||||
public EditSessionEvent(LocalWorld world, LocalPlayer player, int maxBlocks, Stage stage) {
|
||||
checkNotNull(world);
|
||||
this.world = world;
|
||||
this.player = player;
|
||||
this.maxBlocks = maxBlocks;
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,6 +117,15 @@ public class EditSessionEvent extends Event {
|
||||
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()}.
|
||||
@ -103,4 +136,15 @@ public class EditSessionEvent extends Event {
|
||||
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) {
|
||||
return new EditSessionEvent(world, player, maxBlocks, stage);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,22 +49,22 @@ public final class InternalEditSessionFactory extends EditSessionFactory {
|
||||
|
||||
@Override
|
||||
public EditSession getEditSession(LocalWorld world, int maxBlocks) {
|
||||
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, null, maxBlocks));
|
||||
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, null, maxBlocks, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditSession getEditSession(LocalWorld world, int maxBlocks, LocalPlayer player) {
|
||||
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, player, maxBlocks));
|
||||
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, player, maxBlocks, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditSession getEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag) {
|
||||
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks));
|
||||
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditSession getEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player) {
|
||||
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks));
|
||||
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks, null));
|
||||
}
|
||||
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren