Proper support for WorldEdit inventory
- Per player inventory mode (0, 1, 2) - Use mode 2 for survival (setting air doesn't give you the blocks) - Fixes several duplications glitches - Adds speed and placement type option per player -
This commit is contained in:
parent
7886947061
commit
47cbc2bc8c
@ -204,42 +204,46 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
* - When a block change is requested, the SetQueue will first check if the chunk exists in the queue, or it will create and add it<br>
|
||||
*/
|
||||
@Override
|
||||
public FaweQueue getNewQueue(World world, boolean dontCareIfFast) {
|
||||
if (playerChunk != (playerChunk = true)) {
|
||||
public FaweQueue getNewQueue(World world, boolean fast) {
|
||||
if (fast) {
|
||||
if (playerChunk != (playerChunk = true)) {
|
||||
try {
|
||||
Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
||||
fieldDirtyCount.setAccessible(true);
|
||||
int mod = fieldDirtyCount.getModifiers();
|
||||
if ((mod & Modifier.VOLATILE) == 0) {
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(fieldDirtyCount, mod + Modifier.VOLATILE);
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
||||
fieldDirtyCount.setAccessible(true);
|
||||
int mod = fieldDirtyCount.getModifiers();
|
||||
if ((mod & Modifier.VOLATILE) == 0) {
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(fieldDirtyCount, mod + Modifier.VOLATILE);
|
||||
}
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
try {
|
||||
return plugin.getQueue(world);
|
||||
} catch (Throwable ignore) {}
|
||||
// Disable incompatible settings
|
||||
Settings.QUEUE.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
|
||||
Settings.HISTORY.COMBINE_STAGES = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
|
||||
if (hasNMS) {
|
||||
debug("====== NO NMS BLOCK PLACER FOUND ======");
|
||||
debug("FAWE couldn't find a fast block placer");
|
||||
debug("Bukkit version: " + Bukkit.getVersion());
|
||||
debug("NMS label: " + plugin.getClass().getSimpleName().split("_")[1]);
|
||||
debug("Fallback placer: " + BukkitQueue_All.class);
|
||||
debug("=======================================");
|
||||
debug("Download the version of FAWE for your platform");
|
||||
debug(" - http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target");
|
||||
debug("=======================================");
|
||||
TaskManager.IMP.laterAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MainUtil.sendAdmin("&cNo NMS placer found, see console!");
|
||||
}
|
||||
}, 1);
|
||||
hasNMS = false;
|
||||
return plugin.getQueue(world);
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
// Disable incompatible settings
|
||||
Settings.QUEUE.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
|
||||
Settings.HISTORY.COMBINE_STAGES = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
|
||||
if (hasNMS) {
|
||||
debug("====== NO NMS BLOCK PLACER FOUND ======");
|
||||
debug("FAWE couldn't find a fast block placer");
|
||||
debug("Bukkit version: " + Bukkit.getVersion());
|
||||
debug("NMS label: " + plugin.getClass().getSimpleName().split("_")[1]);
|
||||
debug("Fallback placer: " + BukkitQueue_All.class);
|
||||
debug("=======================================");
|
||||
debug("Download the version of FAWE for your platform");
|
||||
debug(" - http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target");
|
||||
debug("=======================================");
|
||||
TaskManager.IMP.laterAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MainUtil.sendAdmin("&cNo NMS placer found, see console!");
|
||||
}
|
||||
}, 1);
|
||||
hasNMS = false;
|
||||
}
|
||||
}
|
||||
return new BukkitQueue_All(world);
|
||||
}
|
||||
|
@ -82,6 +82,19 @@ public class Settings extends Config {
|
||||
" - History on disk or memory will be deleted",
|
||||
})
|
||||
public int MAX_HISTORY_MB = -1;
|
||||
@Comment("Needlessly make WorldEdit slower for this player (ms/block)")
|
||||
public int SPEED_REDUCTION = 0;
|
||||
@Comment({
|
||||
"Should WorldEdit use inventory?",
|
||||
"0 = No inventory usage (creative)",
|
||||
"1 = Inventory for removing and placing (freebuild)",
|
||||
"2 = Inventory for placing (survival)",
|
||||
})
|
||||
public static int INVENTORY_MODE = 0;
|
||||
@Comment({
|
||||
"Place chunks instead of individual blocks"
|
||||
})
|
||||
public static boolean FAST_PLACEMENT = true;
|
||||
}
|
||||
|
||||
public static class HISTORY {
|
||||
@ -297,6 +310,9 @@ public class Settings extends Config {
|
||||
limit.MAX_FAILS = Math.max(limit.MAX_FAILS, newLimit.MAX_FAILS != -1 ? newLimit.MAX_FAILS : Integer.MAX_VALUE);
|
||||
limit.MAX_ITERATIONS = Math.max(limit.MAX_ITERATIONS, newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE);
|
||||
limit.MAX_HISTORY = Math.max(limit.MAX_HISTORY, newLimit.MAX_HISTORY_MB != -1 ? newLimit.MAX_HISTORY_MB : Integer.MAX_VALUE);
|
||||
limit.INVENTORY_MODE = Math.min(limit.INVENTORY_MODE, newLimit.INVENTORY_MODE);
|
||||
limit.SPEED_REDUCTION = Math.min(limit.SPEED_REDUCTION, newLimit.SPEED_REDUCTION);
|
||||
limit.FAST_PLACEMENT |= newLimit.FAST_PLACEMENT;
|
||||
}
|
||||
}
|
||||
return limit;
|
||||
|
@ -5,6 +5,7 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import java.util.Iterator;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -87,6 +88,11 @@ public class LoggingChangeSet extends FaweChangeSet {
|
||||
parent.addEntityCreate(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo) {
|
||||
return parent.getIterator(blockBag, mode, redo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> getIterator(boolean undo) {
|
||||
return parent.getIterator(undo);
|
||||
|
@ -12,6 +12,9 @@ public class FaweLimit {
|
||||
public int MAX_BLOCKSTATES = 0;
|
||||
public int MAX_ENTITIES = 0;
|
||||
public int MAX_HISTORY = 0;
|
||||
public int INVENTORY_MODE = Integer.MAX_VALUE;
|
||||
public int SPEED_REDUCTION = Integer.MAX_VALUE;
|
||||
public boolean FAST_PLACEMENT = false;
|
||||
|
||||
|
||||
public static FaweLimit MAX;
|
||||
@ -42,6 +45,8 @@ public class FaweLimit {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
MAX.SPEED_REDUCTION = 0;
|
||||
MAX.INVENTORY_MODE = 0;
|
||||
MAX.MAX_ACTIONS = 1;
|
||||
MAX.MAX_CHANGES = Integer.MAX_VALUE;
|
||||
MAX.MAX_FAILS = Integer.MAX_VALUE;
|
||||
@ -50,6 +55,7 @@ public class FaweLimit {
|
||||
MAX.MAX_BLOCKSTATES = Integer.MAX_VALUE;
|
||||
MAX.MAX_ENTITIES = Integer.MAX_VALUE;
|
||||
MAX.MAX_HISTORY = Integer.MAX_VALUE;
|
||||
MAX.FAST_PLACEMENT = true;
|
||||
}
|
||||
|
||||
public boolean MAX_CHANGES() {
|
||||
@ -83,7 +89,10 @@ public class FaweLimit {
|
||||
MAX_ITERATIONS == Integer.MAX_VALUE &&
|
||||
MAX_BLOCKSTATES == Integer.MAX_VALUE &&
|
||||
MAX_ENTITIES == Integer.MAX_VALUE &&
|
||||
MAX_HISTORY == Integer.MAX_VALUE;
|
||||
MAX_HISTORY == Integer.MAX_VALUE &&
|
||||
INVENTORY_MODE == 0 &&
|
||||
SPEED_REDUCTION == 0 &&
|
||||
FAST_PLACEMENT == true;
|
||||
}
|
||||
|
||||
public void set(FaweLimit limit) {
|
||||
@ -95,10 +104,15 @@ public class FaweLimit {
|
||||
MAX_FAILS = limit.MAX_FAILS;
|
||||
MAX_ITERATIONS = limit.MAX_ITERATIONS;
|
||||
MAX_HISTORY = limit.MAX_HISTORY;
|
||||
INVENTORY_MODE = limit.INVENTORY_MODE;
|
||||
SPEED_REDUCTION = limit.SPEED_REDUCTION;
|
||||
FAST_PLACEMENT = limit.FAST_PLACEMENT;
|
||||
}
|
||||
|
||||
public FaweLimit copy() {
|
||||
FaweLimit limit = new FaweLimit();
|
||||
limit.INVENTORY_MODE = INVENTORY_MODE;
|
||||
limit.SPEED_REDUCTION = SPEED_REDUCTION;
|
||||
limit.MAX_ACTIONS = MAX_ACTIONS;
|
||||
limit.MAX_CHANGES = MAX_CHANGES;
|
||||
limit.MAX_BLOCKSTATES = MAX_BLOCKSTATES;
|
||||
@ -107,6 +121,7 @@ public class FaweLimit {
|
||||
limit.MAX_FAILS = MAX_FAILS;
|
||||
limit.MAX_ITERATIONS = MAX_ITERATIONS;
|
||||
limit.MAX_HISTORY = MAX_HISTORY;
|
||||
limit.FAST_PLACEMENT = FAST_PLACEMENT;
|
||||
return limit;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.util.ArrayList;
|
||||
@ -42,6 +43,11 @@ public class NullChangeSet extends FaweChangeSet {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo) {
|
||||
return getIterator(redo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Iterator<Change> getIterator(boolean undo) {
|
||||
return new ArrayList<Change>().iterator();
|
||||
|
@ -79,7 +79,7 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
|
||||
@Override
|
||||
public void run(DiskStorageHistory value) {
|
||||
try {
|
||||
Iterator<MutableFullBlockChange> iter = value.getFullBlockIterator(false);
|
||||
Iterator<MutableFullBlockChange> iter = value.getFullBlockIterator(null, 0, false);
|
||||
while (iter.hasNext()) {
|
||||
MutableFullBlockChange change = iter.next();
|
||||
if (change.x != x || change.y != y || change.z != z) {
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.change;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.history.UndoContext;
|
||||
@ -45,10 +46,11 @@ public class MutableBlockChange implements Change {
|
||||
if (!checkedQueue) {
|
||||
checkedQueue = true;
|
||||
Extent extent = context.getExtent();
|
||||
if (extent instanceof HasFaweQueue) {
|
||||
(queue = ((HasFaweQueue) extent).getQueue()).setBlock(x, y, z, id, data);
|
||||
ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
|
||||
if (found != null) {
|
||||
(queue = ((HasFaweQueue) found.get()).getQueue()).setBlock(x, y, z, id, data);
|
||||
} else {
|
||||
Fawe.debug("FAWE doesn't support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
Fawe.debug("FAWE does not support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.history.UndoContext;
|
||||
@ -39,10 +40,11 @@ public class MutableChunkChange implements Change {
|
||||
if (!checkedQueue) {
|
||||
checkedQueue = true;
|
||||
Extent extent = context.getExtent();
|
||||
if (extent instanceof HasFaweQueue) {
|
||||
perform(queue = ((HasFaweQueue) extent).getQueue(), undo);
|
||||
ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
|
||||
if (found != null) {
|
||||
perform(queue = ((HasFaweQueue) found.get()).getQueue(), undo);
|
||||
} else {
|
||||
Fawe.debug("FAWE doesn't support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
Fawe.debug("FAWE does not support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,10 +84,11 @@ public class MutableEntityChange implements Change {
|
||||
if (!checkedQueue) {
|
||||
checkedQueue = true;
|
||||
Extent extent = context.getExtent();
|
||||
if (extent instanceof HasFaweQueue) {
|
||||
perform(queue = ((HasFaweQueue) extent).getQueue());
|
||||
ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
|
||||
if (found != null) {
|
||||
perform(queue = ((HasFaweQueue) found.get()).getQueue());
|
||||
} else {
|
||||
Fawe.debug("FAWE doesn't support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
Fawe.debug("FAWE does not support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,11 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBagException;
|
||||
import com.sk89q.worldedit.history.UndoContext;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
|
||||
@ -16,14 +19,14 @@ public class MutableFullBlockChange implements Change {
|
||||
public int x;
|
||||
public int from;
|
||||
public int to;
|
||||
public BlockBag blockBag;
|
||||
public boolean allowFetch;
|
||||
public boolean allowStore;
|
||||
|
||||
|
||||
public MutableFullBlockChange(int x, int y, int z, int combinedFrom, int combinedTo) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.from = combinedFrom;
|
||||
this.to = combinedTo;
|
||||
public MutableFullBlockChange(BlockBag blockBag, int mode, boolean redo) {
|
||||
this.blockBag = blockBag;
|
||||
allowFetch = redo || mode == 1;
|
||||
allowStore = !redo || mode == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -46,15 +49,35 @@ public class MutableFullBlockChange implements Change {
|
||||
if (!checkedQueue) {
|
||||
checkedQueue = true;
|
||||
Extent extent = context.getExtent();
|
||||
if (extent instanceof HasFaweQueue) {
|
||||
perform(queue = ((HasFaweQueue) extent).getQueue());
|
||||
ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
|
||||
if (found != null) {
|
||||
perform(queue = ((HasFaweQueue) found.get()).getQueue());
|
||||
} else {
|
||||
Fawe.debug("FAWE doesn't support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
Fawe.debug("FAWE does not support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void perform(FaweQueue queue) {
|
||||
queue.setBlock(x, y, z, FaweCache.getId(from), FaweCache.getData(from));
|
||||
int idFrom = FaweCache.getId(from);
|
||||
int dataFrom = FaweCache.getData(from);
|
||||
if (blockBag != null) {
|
||||
if (allowFetch && idFrom != 0) {
|
||||
try {
|
||||
blockBag.fetchPlacedBlock(idFrom, dataFrom);
|
||||
} catch (BlockBagException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int idTo = FaweCache.getId(to);
|
||||
int dataTo = FaweCache.getData(to);
|
||||
if (allowStore && idTo != 0) {
|
||||
try {
|
||||
blockBag.storeDroppedBlock(idTo, dataTo);
|
||||
} catch (BlockBagException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
queue.setBlock(x, y, z, idFrom, dataFrom);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.change;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
@ -46,10 +47,11 @@ public class MutableTileChange implements Change {
|
||||
if (!checkedQueue) {
|
||||
checkedQueue = true;
|
||||
Extent extent = context.getExtent();
|
||||
if (extent instanceof HasFaweQueue) {
|
||||
perform(queue = ((HasFaweQueue) extent).getQueue());
|
||||
ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
|
||||
if (found != null) {
|
||||
perform(queue = ((HasFaweQueue) found.get()).getQueue());
|
||||
} else {
|
||||
Fawe.debug("FAWE doesn't support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
Fawe.debug("FAWE does not support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.change.MutableChunkChange;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.util.ArrayList;
|
||||
@ -76,6 +77,11 @@ public class CPUOptimizedChangeSet extends FaweChangeSet {
|
||||
throw new UnsupportedOperationException("Invalid mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo) {
|
||||
return getIterator(redo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> getIterator(boolean redo) {
|
||||
return changes.iterator();
|
||||
|
@ -17,6 +17,7 @@ import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.BlockChange;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.history.change.EntityCreate;
|
||||
@ -93,6 +94,7 @@ public abstract class FaweChangeSet implements ChangeSet {
|
||||
public abstract void addTileRemove(CompoundTag tag);
|
||||
public abstract void addEntityRemove(CompoundTag tag);
|
||||
public abstract void addEntityCreate(CompoundTag tag);
|
||||
public abstract Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo);
|
||||
public abstract Iterator<Change> getIterator(boolean redo);
|
||||
|
||||
public void delete() {};
|
||||
|
@ -12,6 +12,7 @@ import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.io.EOFException;
|
||||
@ -382,12 +383,24 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
};
|
||||
}
|
||||
|
||||
public Iterator<MutableFullBlockChange> getFullBlockIterator(final boolean dir) throws IOException {
|
||||
@Override
|
||||
public Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo) {
|
||||
if (blockBag != null && mode > 0) {
|
||||
try {
|
||||
return (Iterator<Change>) (Iterator<?>) getFullBlockIterator(blockBag, mode, redo);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return getIterator(redo);
|
||||
}
|
||||
|
||||
public Iterator<MutableFullBlockChange> getFullBlockIterator(BlockBag blockBag, int inventory, final boolean dir) throws IOException {
|
||||
final FaweInputStream is = new FaweInputStream(getBlockIS());
|
||||
if (is == null) {
|
||||
return new ArrayList<MutableFullBlockChange>().iterator();
|
||||
}
|
||||
final MutableFullBlockChange change = new MutableFullBlockChange(0, 0, 0, 0, 0);
|
||||
final MutableFullBlockChange change = new MutableFullBlockChange(blockBag, inventory, dir);
|
||||
return new Iterator<MutableFullBlockChange>() {
|
||||
private MutableFullBlockChange last = read();
|
||||
public MutableFullBlockChange read() {
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
public class SlowExtent extends AbstractDelegateExtent {
|
||||
private final long sleep;
|
||||
|
||||
public SlowExtent(Extent extent, long sleep) {
|
||||
super(extent);
|
||||
this.sleep = sleep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
|
||||
if (!Fawe.get().isMainThread()) try {
|
||||
Thread.sleep(sleep);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return super.setBlock(location, block);
|
||||
}
|
||||
}
|
@ -88,7 +88,6 @@ public class PlotTrim implements Listener {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("Run!");
|
||||
Bukkit.getPluginManager().registerEvents(this, (Plugin) PS.get().IMP);
|
||||
final Set<ChunkLoc> mcas = new HashSet<>();
|
||||
if (deleteUnowned && area != null) {
|
||||
|
@ -34,8 +34,8 @@ public class EditSessionBuilder {
|
||||
private Boolean fastmode;
|
||||
private Boolean checkMemory;
|
||||
private Boolean combineStages;
|
||||
private BlockBag blockBag;
|
||||
private EventBus eventBus;
|
||||
private BlockBag blockBag;
|
||||
private EditSessionEvent event;
|
||||
|
||||
/**
|
||||
@ -77,6 +77,15 @@ public class EditSessionBuilder {
|
||||
return limit(FaweLimit.MAX.copy());
|
||||
}
|
||||
|
||||
public EditSessionBuilder limitUnprocessed(@Nonnull FawePlayer fp) {
|
||||
checkNotNull(fp);
|
||||
limitUnlimited();
|
||||
FaweLimit tmp = fp.getLimit();
|
||||
limit.INVENTORY_MODE = tmp.INVENTORY_MODE;
|
||||
limit.FAST_PLACEMENT = tmp.FAST_PLACEMENT;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EditSessionBuilder changeSet(@Nullable FaweChangeSet changeSet) {
|
||||
this.changeSet = changeSet;
|
||||
return this;
|
||||
|
@ -45,6 +45,7 @@ import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
||||
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.boydti.fawe.object.extent.ProcessedWEExtent;
|
||||
import com.boydti.fawe.object.extent.SlowExtent;
|
||||
import com.boydti.fawe.object.extent.TransformExtent;
|
||||
import com.boydti.fawe.object.mask.ResettableMask;
|
||||
import com.boydti.fawe.object.progress.DefaultProgressTracker;
|
||||
@ -69,6 +70,7 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.MaskingExtent;
|
||||
import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
|
||||
import com.sk89q.worldedit.extent.world.SurvivalModeExtent;
|
||||
import com.sk89q.worldedit.function.GroundFunction;
|
||||
import com.sk89q.worldedit.function.RegionMaskingFilter;
|
||||
@ -262,14 +264,14 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_LOW_MEMORY);
|
||||
}
|
||||
}
|
||||
this.blockBag = blockBag;
|
||||
this.originalLimit = limit;
|
||||
this.blockBag = limit.INVENTORY_MODE != 0 ? blockBag : null;
|
||||
this.limit = limit.copy();
|
||||
if (queue == null) {
|
||||
if (world instanceof MCAWorld) {
|
||||
queue = ((MCAWorld) world).getQueue();
|
||||
} else {
|
||||
queue = SetQueue.IMP.getNewQueue(this, fastmode, autoQueue);
|
||||
queue = SetQueue.IMP.getNewQueue(this, fastmode || limit.FAST_PLACEMENT, autoQueue);
|
||||
}
|
||||
}
|
||||
if (Settings.EXPERIMENTAL.ANVIL_QUEUE_MODE && !(queue instanceof MCAQueue)) {
|
||||
@ -282,15 +284,23 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
||||
}
|
||||
this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), bus, event, Stage.BEFORE_CHANGE);
|
||||
this.bypassHistory = (this.extent = wrapExtent(bypassAll, bus, event, Stage.BEFORE_REORDER));
|
||||
if (!fastmode && !(changeSet instanceof NullChangeSet)) {
|
||||
if (player != null && Fawe.imp().getBlocksHubApi() != null) {
|
||||
changeSet = LoggingChangeSet.wrap(player, changeSet);
|
||||
if (!fastmode) {
|
||||
if (this.blockBag != null && limit.INVENTORY_MODE > 0) {
|
||||
this.bypassHistory = new BlockBagExtent(this.bypassHistory, this.blockBag, limit.INVENTORY_MODE == 1);
|
||||
}
|
||||
if (combineStages) {
|
||||
changeTask = changeSet;
|
||||
changeSet.addChangeTask(queue);
|
||||
} else {
|
||||
this.extent = (history = new HistoryExtent(this, bypassHistory, changeSet, queue));
|
||||
if (limit.SPEED_REDUCTION > 0) {
|
||||
this.bypassHistory = new SlowExtent(this.bypassHistory, limit.SPEED_REDUCTION);
|
||||
}
|
||||
if (!(changeSet instanceof NullChangeSet)) {
|
||||
if (player != null && Fawe.imp().getBlocksHubApi() != null) {
|
||||
changeSet = LoggingChangeSet.wrap(player, changeSet);
|
||||
}
|
||||
if (combineStages) {
|
||||
changeTask = changeSet;
|
||||
changeSet.addChangeTask(queue);
|
||||
} else {
|
||||
this.extent = (history = new HistoryExtent(this, bypassHistory, changeSet, queue));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allowedRegions != null) {
|
||||
@ -1102,7 +1112,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
||||
context.setExtent(editSession.bypassAll);
|
||||
ChangeSet changeSet = getChangeSet();
|
||||
editSession.getQueue().setChangeTask(null);
|
||||
Operations.completeSmart(ChangeSetExecutor.createUndo(changeSet, context), new Runnable() {
|
||||
Operations.completeSmart(ChangeSetExecutor.create(changeSet, context, ChangeSetExecutor.Type.UNDO, editSession.getBlockBag(), editSession.getLimit().INVENTORY_MODE), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
editSession.flushQueue();
|
||||
@ -1121,7 +1131,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
||||
context.setExtent(editSession.bypassAll);
|
||||
ChangeSet changeSet = getChangeSet();
|
||||
editSession.getQueue().setChangeTask(null);
|
||||
Operations.completeSmart(ChangeSetExecutor.createRedo(changeSet, context), new Runnable() {
|
||||
Operations.completeSmart(ChangeSetExecutor.create(changeSet, context, ChangeSetExecutor.Type.REDO, editSession.getBlockBag(), editSession.getLimit().INVENTORY_MODE), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
editSession.flushQueue();
|
||||
|
@ -514,13 +514,15 @@ public class LocalSession {
|
||||
loadSessionHistoryFromDisk(player.getUniqueId(), player.getWorld());
|
||||
if (getHistoryNegativeIndex() < history.size()) {
|
||||
FaweChangeSet changeSet = (FaweChangeSet) history.get(getHistoryIndex());
|
||||
final FawePlayer fp = FawePlayer.wrap(player);
|
||||
EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld())
|
||||
.allowedRegionsEverywhere()
|
||||
.checkMemory(false)
|
||||
.changeSet(changeSet)
|
||||
.fastmode(false)
|
||||
.limitUnlimited()
|
||||
.player(FawePlayer.wrap(player))
|
||||
.limitUnprocessed(fp)
|
||||
.player(fp)
|
||||
.blockBag(getBlockBag(player))
|
||||
.build();
|
||||
newEditSession.undo(newEditSession);
|
||||
setDirty();
|
||||
@ -561,13 +563,15 @@ public class LocalSession {
|
||||
setDirty();
|
||||
historyNegativeIndex--;
|
||||
FaweChangeSet changeSet = (FaweChangeSet) history.get(getHistoryIndex());
|
||||
final FawePlayer fp = FawePlayer.wrap(player);
|
||||
EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld())
|
||||
.allowedRegionsEverywhere()
|
||||
.checkMemory(false)
|
||||
.changeSet(changeSet)
|
||||
.fastmode(false)
|
||||
.limitUnlimited()
|
||||
.player(FawePlayer.wrap(player))
|
||||
.limitUnprocessed(fp)
|
||||
.player(fp)
|
||||
.blockBag(getBlockBag(player))
|
||||
.build();
|
||||
newEditSession.redo(newEditSession);
|
||||
return newEditSession;
|
||||
|
@ -0,0 +1,111 @@
|
||||
package com.sk89q.worldedit.extent.inventory;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Applies a {@link BlockBag} to operations.
|
||||
*/
|
||||
public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final boolean mine;
|
||||
private int[] missingBlocks = new int[4096];
|
||||
private BlockBag blockBag;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param blockBag the block bag
|
||||
*/
|
||||
public BlockBagExtent(Extent extent, @Nonnull BlockBag blockBag) {
|
||||
this(extent, blockBag, false);
|
||||
}
|
||||
|
||||
public BlockBagExtent(Extent extent, @Nonnull BlockBag blockBag, boolean mine) {
|
||||
super(extent);
|
||||
checkNotNull(blockBag);
|
||||
this.blockBag = blockBag;
|
||||
this.mine = mine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block bag.
|
||||
*
|
||||
* @return a block bag, which may be null if none is used
|
||||
*/
|
||||
public @Nullable BlockBag getBlockBag() {
|
||||
return blockBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block bag.
|
||||
*
|
||||
* @param blockBag a block bag, which may be null if none is used
|
||||
*/
|
||||
public void setBlockBag(@Nullable BlockBag blockBag) {
|
||||
this.blockBag = blockBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of missing blocks and clears the list for the next
|
||||
* operation.
|
||||
*
|
||||
* @return a map of missing blocks
|
||||
*/
|
||||
public Map<Integer, Integer> popMissing() {
|
||||
HashMap<Integer, Integer> map = new HashMap<>();
|
||||
for (int i = 0; i < missingBlocks.length; i++) {
|
||||
int count = missingBlocks[i];
|
||||
if (count > 0) {
|
||||
map.put(i, count);
|
||||
}
|
||||
}
|
||||
Arrays.fill(missingBlocks, 0);
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
|
||||
CompoundTag nbt = block.getNbtData();
|
||||
final int type = block.getType();
|
||||
if (type != 0) {
|
||||
try {
|
||||
blockBag.fetchPlacedBlock(block.getId(), block.getData());
|
||||
if (nbt != null) {
|
||||
// Remove items (to avoid duplication)
|
||||
if (nbt.containsKey("items")) {
|
||||
block.setNbtData(null);
|
||||
}
|
||||
}
|
||||
} catch (UnplaceableBlockException e) {
|
||||
return false;
|
||||
} catch (BlockBagException e) {
|
||||
missingBlocks[type]++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (mine) {
|
||||
BaseBlock lazyBlock = getExtent().getLazyBlock(position);
|
||||
int existing = lazyBlock.getType();
|
||||
if (existing != 0) {
|
||||
try {
|
||||
blockBag.storeDroppedBlock(existing, lazyBlock.getData());
|
||||
} catch (BlockBagException ignored) {}
|
||||
}
|
||||
}
|
||||
return super.setBlock(position, block);
|
||||
}
|
||||
}
|
@ -19,7 +19,9 @@
|
||||
|
||||
package com.sk89q.worldedit.function.operation;
|
||||
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.UndoContext;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
@ -47,13 +49,16 @@ public class ChangeSetExecutor implements Operation {
|
||||
* @param type type of change
|
||||
* @param context the undo context
|
||||
*/
|
||||
private ChangeSetExecutor(ChangeSet changeSet, Type type, UndoContext context) {
|
||||
private ChangeSetExecutor(ChangeSet changeSet, Type type, UndoContext context, BlockBag blockBag, int inventory) {
|
||||
checkNotNull(changeSet);
|
||||
checkNotNull(type);
|
||||
checkNotNull(context);
|
||||
this.type = type;
|
||||
this.context = context;
|
||||
if (type == Type.UNDO) {
|
||||
if (changeSet instanceof FaweChangeSet) {
|
||||
iterator = ((FaweChangeSet) changeSet).getIterator(blockBag, inventory, type == Type.REDO);
|
||||
}
|
||||
else if (type == Type.UNDO) {
|
||||
iterator = changeSet.backwardIterator();
|
||||
} else {
|
||||
iterator = changeSet.forwardIterator();
|
||||
@ -82,6 +87,10 @@ public class ChangeSetExecutor implements Operation {
|
||||
public void addStatusMessages(List<String> messages) {
|
||||
}
|
||||
|
||||
public static ChangeSetExecutor create(ChangeSet changeSet, UndoContext context, Type type, BlockBag blockBag, int inventory) {
|
||||
return new ChangeSetExecutor(changeSet, type, context, blockBag, inventory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new undo operation.
|
||||
*
|
||||
@ -89,8 +98,9 @@ public class ChangeSetExecutor implements Operation {
|
||||
* @param context an undo context
|
||||
* @return an operation
|
||||
*/
|
||||
@Deprecated
|
||||
public static ChangeSetExecutor createUndo(ChangeSet changeSet, UndoContext context) {
|
||||
return new ChangeSetExecutor(changeSet, Type.UNDO, context);
|
||||
return new ChangeSetExecutor(changeSet, Type.UNDO, context, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,8 +110,9 @@ public class ChangeSetExecutor implements Operation {
|
||||
* @param context an undo context
|
||||
* @return an operation
|
||||
*/
|
||||
@Deprecated
|
||||
public static ChangeSetExecutor createRedo(ChangeSet changeSet, UndoContext context) {
|
||||
return new ChangeSetExecutor(changeSet, Type.REDO, context);
|
||||
return new ChangeSetExecutor(changeSet, Type.REDO, context, null, 0);
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
Loading…
Reference in New Issue
Block a user