mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-24 19:46:34 +01:00
parent
ea6840535a
commit
9f0602f2ec
@ -1,8 +1,11 @@
|
||||
package com.boydti.fawe.bukkit.logging;
|
||||
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
import org.PrimeSoft.blocksHub.BlocksHub;
|
||||
import org.PrimeSoft.blocksHub.IBlocksHubApi;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -17,7 +20,7 @@ public class BlocksHubHook {
|
||||
this.api = this.hub.getApi();
|
||||
}
|
||||
|
||||
public Extent getLoggingExtent(final Extent parent, final ChangeSet set, final FawePlayer<?> player) {
|
||||
return new LoggingExtent(parent, set, (FawePlayer<Player>) player, this.api);
|
||||
public FaweChangeSet getLoggingChangeSet(EditSession session, FaweLimit limit, Extent parent, FaweChangeSet set, FaweQueue queue, FawePlayer<?> player) {
|
||||
return new LoggingChangeSet((FawePlayer<Player>) player, set, api);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
package com.boydti.fawe.bukkit.logging;
|
||||
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import java.util.Iterator;
|
||||
import org.PrimeSoft.blocksHub.IBlocksHubApi;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class LoggingChangeSet implements FaweChangeSet {
|
||||
|
||||
private final FaweChangeSet parent;
|
||||
private final IBlocksHubApi api;
|
||||
private final World world;
|
||||
private final Location loc;
|
||||
private final String name;
|
||||
|
||||
public LoggingChangeSet(FawePlayer<Player> player, FaweChangeSet parent, IBlocksHubApi api) {
|
||||
this.parent = parent;
|
||||
this.name = player.getName();
|
||||
this.api = api;
|
||||
this.world = player.parent.getWorld();
|
||||
this.loc = new Location(world, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean flush() {
|
||||
return parent.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompressedSize() {
|
||||
return parent.getCompressedSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Vector location, BaseBlock from, BaseBlock to) {
|
||||
loc.setX(location.getX());
|
||||
loc.setY(location.getY());
|
||||
loc.setZ(location.getZ());
|
||||
api.logBlock(name, world, loc, from.getId(), (byte) from.getData(), to.getId(), (byte) to.getData());
|
||||
parent.add(location, from, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) {
|
||||
loc.setX(x);
|
||||
loc.setY(y);
|
||||
loc.setZ(z);
|
||||
api.logBlock(name, world, loc, combinedId4DataFrom >> 4, (byte) (combinedId4DataFrom & 0xF), to.getId(), (byte) to.getData());
|
||||
parent.add(x, y, z, combinedId4DataFrom, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {
|
||||
loc.setX(x);
|
||||
loc.setY(y);
|
||||
loc.setZ(z);
|
||||
api.logBlock(name, world, loc, combinedId4DataFrom >> 4, (byte) (combinedId4DataFrom & 0xF), combinedId4DataTo >> 4, (byte) (combinedId4DataTo & 0xF));
|
||||
parent.add(x, y, z, combinedId4DataFrom, combinedId4DataTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Change change) {
|
||||
parent.add(change);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> backwardIterator() {
|
||||
return parent.backwardIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> forwardIterator() {
|
||||
return parent.forwardIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return parent.size();
|
||||
}
|
||||
}
|
@ -24,10 +24,10 @@ public class BukkitEditSessionWrapper_0 extends EditSessionWrapper {
|
||||
@Override
|
||||
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);
|
||||
// If we are doing logging, use a custom logging ChangeSet
|
||||
set = hook.getLoggingChangeSet(session, limit, parent, set, queue, player);
|
||||
}
|
||||
// Otherwise return the normal history extent
|
||||
// Now return the normal history extent
|
||||
return super.getHistoryExtent(session, limit, parent, set, queue, player);
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
ChunkListener.physicsFreeze = false;
|
||||
if (parallel) {
|
||||
try {Field fieldEnabled = Class.forName("co.aikar.timings.Timings").getDeclaredField("timingsEnabled");fieldEnabled.setAccessible(true);fieldEnabled.set(null, timingsEnabled);
|
||||
} catch (Throwable ignore) {ignore.printStackTrace();}
|
||||
} catch (Throwable ignore) {}
|
||||
try { Class.forName("org.spigotmc.AsyncCatcher").getField("enabled").set(null, true); } catch (Throwable ignore) {}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.v1_9;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import net.minecraft.server.v1_9_R1.Block;
|
||||
import net.minecraft.server.v1_9_R1.DataBits;
|
||||
@ -96,7 +97,17 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk> {
|
||||
if (sectionPalettes == null) {
|
||||
sectionPalettes = new DataPaletteBlock[16];
|
||||
}
|
||||
DataPaletteBlock palette = sectionPalettes[layer] = new DataPaletteBlock();
|
||||
DataPaletteBlock palette;
|
||||
try {
|
||||
palette = sectionPalettes[layer] = new DataPaletteBlock();
|
||||
} catch (Throwable e) {
|
||||
try {
|
||||
Constructor<DataPaletteBlock> constructor = DataPaletteBlock.class.getDeclaredConstructor(IBlockData[].class);
|
||||
palette = sectionPalettes[layer] = constructor.newInstance(null);
|
||||
} catch (Throwable e2) {
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
char[] blocks = getIdArray(layer);
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
|
@ -10,6 +10,7 @@ import com.boydti.fawe.object.IntegerPair;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayDeque;
|
||||
@ -224,6 +225,28 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
|
||||
fieldSection.set(section, palette);
|
||||
}
|
||||
|
||||
public ChunkSection newChunkSection(int y2, boolean flag, char[] array) {
|
||||
try {
|
||||
if (array == null) {
|
||||
return new ChunkSection(y2, flag);
|
||||
} else {
|
||||
return new ChunkSection(y2, flag, array);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
try {
|
||||
if (array == null) {
|
||||
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, IBlockData[].class);
|
||||
return constructor.newInstance(y2, flag, null);
|
||||
} else {
|
||||
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, char[].class, IBlockData[].class);
|
||||
return constructor.newInstance(y2, flag, array, null);
|
||||
}
|
||||
} catch (Throwable e2) {
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComponents(final FaweChunk pc) {
|
||||
final BukkitChunk_1_9 fs = (BukkitChunk_1_9) pc;
|
||||
@ -268,9 +291,6 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removed) {
|
||||
w.tileEntityListTick.clear();
|
||||
}
|
||||
|
||||
// Trim entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
|
@ -336,6 +336,9 @@ public class Fawe {
|
||||
}
|
||||
|
||||
private void setupMemoryListener() {
|
||||
if (Settings.MEM_FREE < 1) {
|
||||
return;
|
||||
}
|
||||
final MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
|
||||
final NotificationEmitter ne = (NotificationEmitter) memBean;
|
||||
|
||||
|
@ -3,14 +3,10 @@ package com.boydti.fawe.command;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.extent.FaweExtent;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@ -37,21 +33,8 @@ public class Cancel extends FaweCommand {
|
||||
continue;
|
||||
}
|
||||
if (uuid.equals(actor.getUniqueId())) {
|
||||
// Cancel this
|
||||
FaweExtent fe = session.getFaweExtent();
|
||||
if (fe != null) {
|
||||
if (session.cancel()) {
|
||||
cancelled++;
|
||||
try {
|
||||
WEManager.IMP.cancelEdit(fe, BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
|
||||
} catch (Throwable ignore) {}
|
||||
World world = session.getWorld();
|
||||
NullExtent nullExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
|
||||
session.bypassHistory = nullExtent;
|
||||
session.bypassNone = nullExtent;
|
||||
session.bypassReorderHistory = nullExtent;
|
||||
session.faweExtent = nullExtent;
|
||||
queue.clear();
|
||||
SetQueue.IMP.dequeue(queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,14 +92,14 @@ public class Settings {
|
||||
options.put("history.use-disk", STORE_HISTORY_ON_DISK);
|
||||
options.put("history.compress", false);
|
||||
options.put("history.chunk-wait-ms", CHUNK_WAIT);
|
||||
options.put("history.buffer-size", BUFFER_SIZE);
|
||||
// options.put("history.buffer-size", BUFFER_SIZE);
|
||||
options.put("history.delete-after-days", DELETE_HISTORY_AFTER_DAYS);
|
||||
options.put("region-restrictions", REGION_RESTRICTIONS);
|
||||
options.put("queue.parallel-threads", UNSAFE_PARALLEL_THREADS);
|
||||
options.put("queue.extra-time-ms", ALLOCATE);
|
||||
options.put("queue.target-size", QUEUE_SIZE);
|
||||
options.put("queue.max-wait-ms", QUEUE_MAX_WAIT);
|
||||
options.put("queue.discard-after-ms", QUEUE_DISCARD_AFTER);
|
||||
// options.put("queue.discard-after-ms", QUEUE_DISCARD_AFTER);
|
||||
options.put("extent.allowed-plugins", new ArrayList<String>());
|
||||
options.put("extent.debug", EXTENT_DEBUG);
|
||||
options.put("metrics", METRICS);
|
||||
@ -140,7 +140,7 @@ public class Settings {
|
||||
QUEUE_SIZE = config.getInt("queue.target-size");
|
||||
QUEUE_MAX_WAIT = config.getInt("queue.max-wait-ms");
|
||||
UNSAFE_PARALLEL_THREADS = config.getInt("queue.parallel-threads");
|
||||
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms");
|
||||
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms", QUEUE_DISCARD_AFTER);
|
||||
ALLOWED_3RDPARTY_EXTENTS = config.getStringList("extent.allowed-plugins");
|
||||
EXTENT_DEBUG = config.getBoolean("extent.debug");
|
||||
STORE_CLIPBOARD_ON_DISK = config.getBoolean("clipboard.use-disk");
|
||||
|
@ -50,37 +50,34 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
|
||||
@Override
|
||||
public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException {
|
||||
if (super.setBlock(location, block)) {
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
int combined = queue.getCombinedId4DataDebug(x, y, z, 0, session);
|
||||
int id = (combined >> 4);
|
||||
if (id == block.getId()) {
|
||||
if (!FaweCache.hasData(id)) {
|
||||
return false;
|
||||
}
|
||||
int data = id & 0xF;
|
||||
if (data == block.getData()) {
|
||||
return false;
|
||||
}
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
int combined = queue.getCombinedId4DataDebug(x, y, z, 0, session);
|
||||
int id = (combined >> 4);
|
||||
if (id == block.getId()) {
|
||||
if (!FaweCache.hasData(id)) {
|
||||
return false;
|
||||
}
|
||||
if (!FaweCache.hasNBT(id)) {
|
||||
if (FaweCache.hasNBT(block.getId())) {
|
||||
this.changeSet.add(x, y, z, combined, block);
|
||||
} else {
|
||||
this.changeSet.add(x, y, z, combined, (block.getId() << 4) + block.getData());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
this.changeSet.add(location, getBlock(location), block);
|
||||
} catch (Throwable e) {
|
||||
this.changeSet.add(x, y, z, combined, block);
|
||||
}
|
||||
int data = id & 0xF;
|
||||
if (data == block.getData()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (!FaweCache.hasNBT(id)) {
|
||||
if (FaweCache.hasNBT(block.getId())) {
|
||||
this.changeSet.add(x, y, z, combined, block);
|
||||
} else {
|
||||
this.changeSet.add(x, y, z, combined, (block.getId() << 4) + block.getData());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
this.changeSet.add(location, getBlock(location), block);
|
||||
} catch (Throwable e) {
|
||||
this.changeSet.add(x, y, z, combined, block);
|
||||
}
|
||||
}
|
||||
return super.setBlock(location, block);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -8,8 +8,12 @@ import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.io.File;
|
||||
@ -21,12 +25,33 @@ public class HeightBrush implements Brush {
|
||||
public final HeightMap heightMap;
|
||||
private final int rotation;
|
||||
double yscale = 1;
|
||||
private final BrushTool tool;
|
||||
|
||||
public HeightBrush(File file, int rotation, double yscale) {
|
||||
public HeightBrush(File file, int rotation, double yscale, BrushTool tool, EditSession session, CuboidRegion selection) {
|
||||
this.tool = tool;
|
||||
this.rotation = (rotation / 90) % 4;
|
||||
this.yscale = yscale;
|
||||
if (file == null || !file.exists()) {
|
||||
heightMap = new HeightMap();
|
||||
if (file.getName().equalsIgnoreCase("#selection.png") && selection != null) {
|
||||
byte[][] heightArray = new byte[selection.getWidth()][selection.getLength()];
|
||||
int minX = selection.getMinimumPoint().getBlockX();
|
||||
int minZ = selection.getMinimumPoint().getBlockZ();
|
||||
int minY = selection.getMinimumY() - 1;
|
||||
int maxY = selection.getMaximumY() + 1;
|
||||
int selHeight = selection.getHeight();
|
||||
for (Vector pos : selection) {
|
||||
int xx = pos.getBlockX();
|
||||
int zz = pos.getBlockZ();
|
||||
int worldPointHeight = session.getHighestTerrainBlock(xx, zz, minY, maxY);
|
||||
int pointHeight = (256 * (worldPointHeight - minY)) / selHeight;
|
||||
int x = xx - minX;
|
||||
int z = zz - minZ;
|
||||
heightArray[x][z] = (byte) pointHeight;
|
||||
}
|
||||
heightMap = new ArrayHeightMap(heightArray);
|
||||
} else {
|
||||
heightMap = new HeightMap();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
BufferedImage heightFile = ImageIO.read(file);
|
||||
@ -53,10 +78,12 @@ public class HeightBrush implements Brush {
|
||||
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
|
||||
Mask mask = tool.getMask();
|
||||
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
||||
mask = null;
|
||||
}
|
||||
int size = (int) sizeDouble;
|
||||
heightMap.setSize(size);
|
||||
|
||||
int size2 = size * size;
|
||||
int startY = position.getBlockY() + size;
|
||||
int endY = position.getBlockY() - size;
|
||||
@ -65,6 +92,7 @@ public class HeightBrush implements Brush {
|
||||
Vector mutablePos = new Vector(0, 0, 0);
|
||||
for (int x = -size; x <= size; x++) {
|
||||
int xx = cx + x;
|
||||
mutablePos.x = xx;
|
||||
for (int z = -size; z <= size; z++) {
|
||||
int zz = cz + z;
|
||||
int raise;
|
||||
@ -86,11 +114,18 @@ public class HeightBrush implements Brush {
|
||||
if (raise == 0) {
|
||||
continue;
|
||||
}
|
||||
mutablePos.z = zz;
|
||||
int foundHeight = Integer.MAX_VALUE;
|
||||
BaseBlock block = null;
|
||||
for (int y = startY; y >= endY; y--) {
|
||||
block = editSession.getLazyBlock(xx, y, zz);
|
||||
if (block != EditSession.nullBlock) {
|
||||
if (mask != null) {
|
||||
mutablePos.y = y;
|
||||
if (!mask.test(mutablePos)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foundHeight = y;
|
||||
break;
|
||||
}
|
||||
@ -98,10 +133,17 @@ public class HeightBrush implements Brush {
|
||||
if (foundHeight == Integer.MAX_VALUE) {
|
||||
continue;
|
||||
}
|
||||
for (int y = foundHeight + 1; y <= foundHeight + raise; y++) {
|
||||
mutablePos.x = xx;
|
||||
mutablePos.y = y;
|
||||
mutablePos.z = zz;
|
||||
if (raise > 0) {
|
||||
for (int y = foundHeight + 1; y <= foundHeight + raise; y++) {
|
||||
mutablePos.y = y;
|
||||
editSession.setBlock(mutablePos, block);
|
||||
}
|
||||
} else {
|
||||
for (int y = foundHeight; y > foundHeight + raise; y--) {
|
||||
mutablePos.y = y;
|
||||
editSession.setBlock(mutablePos, EditSession.nullBlock);
|
||||
}
|
||||
mutablePos.y = foundHeight + raise;
|
||||
editSession.setBlock(mutablePos, block);
|
||||
}
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
||||
EditSessionFactory factory = WorldEdit.getInstance().getEditSessionFactory();
|
||||
EditSession edit = factory.getEditSession(world, -1, null, player);
|
||||
edit.setChangeSet(this);
|
||||
edit.dequeue();
|
||||
return edit;
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,14 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.List;
|
||||
|
||||
public class FastWorldEditExtent extends FaweExtent {
|
||||
public class FastWorldEditExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final FaweQueue queue;
|
||||
|
||||
@ -228,9 +229,4 @@ public class FastWorldEditExtent extends FaweExtent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int x, int y, int z) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,13 @@ package com.boydti.fawe.object.extent;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
public abstract class FaweExtent extends AbstractDelegateExtent {
|
||||
|
||||
public abstract class FaweRegionExtent extends AbstractDelegateExtent {
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
*/
|
||||
protected FaweExtent(Extent extent) {
|
||||
public FaweRegionExtent(Extent extent) {
|
||||
super(extent);
|
||||
}
|
||||
|
@ -11,10 +11,10 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
public class SafeExtentWrapper extends AbstractDelegateExtent {
|
||||
public class MemoryCheckingExtent extends AbstractDelegateExtent {
|
||||
private final FawePlayer<?> player;
|
||||
|
||||
public SafeExtentWrapper(final FawePlayer<?> player, final Extent extent) {
|
||||
public MemoryCheckingExtent(final FawePlayer<?> player, final Extent extent) {
|
||||
super(extent);
|
||||
this.player = player;
|
||||
}
|
@ -15,18 +15,16 @@ import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class NullExtent extends FaweExtent {
|
||||
public class NullExtent implements Extent {
|
||||
|
||||
private final BBC reason;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
*/
|
||||
public NullExtent(Extent extent, BBC failReason) {
|
||||
super(extent);
|
||||
public NullExtent(BBC failReason) {
|
||||
this.reason = failReason;
|
||||
}
|
||||
|
||||
@ -50,6 +48,12 @@ public class NullExtent extends FaweExtent {
|
||||
throw new FaweException(reason);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Operation commit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(final Vector arg0, final BaseBlock arg1) throws WorldEditException {
|
||||
throw new FaweException(reason);
|
||||
@ -79,17 +83,4 @@ public class NullExtent extends FaweExtent {
|
||||
public Vector getMinimumPoint() {
|
||||
return new Vector(0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int x, int y, int z) { return false; }
|
||||
|
||||
@Override
|
||||
protected Operation commitBefore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extent getExtent() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,9 @@ package com.boydti.fawe.object.extent;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -20,52 +15,30 @@ import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class ProcessedWEExtent extends FaweExtent {
|
||||
private final FaweQueue queue;
|
||||
public class ProcessedWEExtent extends FaweRegionExtent {
|
||||
private final FaweLimit limit;
|
||||
private Extent parent;
|
||||
private final RegionWrapper[] mask;
|
||||
|
||||
private final FawePlayer<?> user;
|
||||
private final HashSet<RegionWrapper> mask;
|
||||
|
||||
public ProcessedWEExtent(final World world, final FawePlayer<?> player, final HashSet<RegionWrapper> mask, FaweLimit limit, FaweQueue queue) {
|
||||
super(world);
|
||||
this.user = player;
|
||||
this.queue = queue;
|
||||
this.mask = mask;
|
||||
public ProcessedWEExtent(final Extent parent, final HashSet<RegionWrapper> mask, FaweLimit limit) {
|
||||
super(parent);
|
||||
this.mask = mask.toArray(new RegionWrapper[mask.size()]);
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public void setParent(final Extent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity createEntity(final Location location, final BaseEntity entity) {
|
||||
if (limit.MAX_ENTITIES-- < 0 || entity == null) {
|
||||
return null;
|
||||
}
|
||||
if (WEManager.IMP.maskContains(this.mask, location.getBlockX(), location.getBlockZ())) {
|
||||
TaskManager.IMP.task(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProcessedWEExtent.super.createEntity(location, entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
return super.createEntity(location, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBiome getBiome(final Vector2D position) {
|
||||
if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) {
|
||||
return EditSession.nullBiome;
|
||||
}
|
||||
return super.getBiome(position);
|
||||
}
|
||||
|
||||
@ -74,21 +47,6 @@ public class ProcessedWEExtent extends FaweExtent {
|
||||
|
||||
@Override
|
||||
public BaseBlock getLazyBlock(final Vector position) {
|
||||
// TODO get fast!
|
||||
// TODO caches base blocks
|
||||
|
||||
if ((this.lastBlock != null) && this.lastVector.equals(position.toBlockVector())) {
|
||||
return this.lastBlock;
|
||||
}
|
||||
if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) {
|
||||
try {
|
||||
this.lastVector = position.toBlockVector();
|
||||
return this.lastBlock = super.getBlock(position);
|
||||
} catch (final Throwable e) {
|
||||
return EditSession.nullBlock;
|
||||
}
|
||||
}
|
||||
this.lastVector = position.toBlockVector();
|
||||
return super.getLazyBlock(position);
|
||||
}
|
||||
|
||||
@ -109,200 +67,27 @@ public class ProcessedWEExtent extends FaweExtent {
|
||||
|
||||
@Override
|
||||
public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException {
|
||||
final short id = (short) block.getType();
|
||||
boolean nbt = true;
|
||||
switch (id) {
|
||||
case 63:
|
||||
case 68:
|
||||
if (block.hasNbtData() && !MainUtil.isValidSign(block.getNbtData())) {
|
||||
nbt = false;
|
||||
}
|
||||
case 54:
|
||||
case 130:
|
||||
case 142:
|
||||
case 27:
|
||||
case 137:
|
||||
case 52:
|
||||
case 154:
|
||||
case 84:
|
||||
case 25:
|
||||
case 144:
|
||||
case 138:
|
||||
case 176:
|
||||
case 177:
|
||||
case 119:
|
||||
case 323:
|
||||
case 117:
|
||||
case 116:
|
||||
case 28:
|
||||
case 66:
|
||||
case 157:
|
||||
case 61:
|
||||
case 62:
|
||||
case 140:
|
||||
case 146:
|
||||
case 149:
|
||||
case 150:
|
||||
case 158:
|
||||
case 23:
|
||||
case 123:
|
||||
case 124:
|
||||
case 29:
|
||||
case 33:
|
||||
case 151:
|
||||
case 178: {
|
||||
if (limit.MAX_BLOCKSTATES-- < 0) {
|
||||
if (this.parent != null) {
|
||||
WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_TILES);
|
||||
this.parent = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final int x = location.getBlockX();
|
||||
final int z = location.getBlockZ();
|
||||
if (WEManager.IMP.maskContains(this.mask, x, z)) {
|
||||
if (limit.MAX_CHANGES-- < 0) {
|
||||
if (this.parent != null) {
|
||||
WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
||||
this.parent = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (block.hasNbtData() && nbt) {
|
||||
final Vector loc = new Vector(location.x, location.y, location.z);
|
||||
queue.addTask(x >> 4, z >> 4, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ProcessedWEExtent.super.setBlock(loc, block);
|
||||
} catch (WorldEditException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
queue.setBlock(x, location.getBlockY(), z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0);
|
||||
return true;
|
||||
} else if (limit.MAX_FAILS-- < 0) {
|
||||
if (this.parent != null) {
|
||||
WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
this.parent = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default: {
|
||||
final int x = location.getBlockX();
|
||||
final int y = location.getBlockY();
|
||||
final int z = location.getBlockZ();
|
||||
if (WEManager.IMP.maskContains(this.mask, location.getBlockX(), location.getBlockZ())) {
|
||||
if (limit.MAX_CHANGES -- <0) {
|
||||
WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
||||
this.parent = null;
|
||||
return false;
|
||||
}
|
||||
switch (id) {
|
||||
case 0:
|
||||
case 2:
|
||||
case 4:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 25:
|
||||
case 30:
|
||||
case 32:
|
||||
case 37:
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 51:
|
||||
case 52:
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 60:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 73:
|
||||
case 74:
|
||||
case 78:
|
||||
case 79:
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
case 83:
|
||||
case 84:
|
||||
case 85:
|
||||
case 87:
|
||||
case 88:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 110:
|
||||
case 112:
|
||||
case 113:
|
||||
case 117:
|
||||
case 121:
|
||||
case 122:
|
||||
case 123:
|
||||
case 124:
|
||||
case 129:
|
||||
case 133:
|
||||
case 138:
|
||||
case 137:
|
||||
case 140:
|
||||
case 165:
|
||||
case 166:
|
||||
case 169:
|
||||
case 170:
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 181:
|
||||
case 182:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192: {
|
||||
queue.setBlock(x, y, z, id, (byte) 0);
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
queue.setBlock(x, y, z, id, (byte) block.getData());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (limit.MAX_FAILS-- < 0) {
|
||||
if (this.parent != null) {
|
||||
WEManager.IMP.cancelEdit(this.parent, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
this.parent = null;
|
||||
}
|
||||
}
|
||||
if (block.hasNbtData() && FaweCache.hasNBT(block.getType())) {
|
||||
if (limit.MAX_BLOCKSTATES-- < 0) {
|
||||
WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_TILES);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (WEManager.IMP.maskContains(this.mask, (int) location.x, (int) location.z)) {
|
||||
if (limit.MAX_CHANGES-- < 0) {
|
||||
WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_TILES);
|
||||
return false;
|
||||
}
|
||||
return super.setBlock(location, block);
|
||||
} else if (limit.MAX_FAILS-- < 0) {
|
||||
WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_TILES);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(final Vector2D position, final BaseBiome biome) {
|
||||
if (WEManager.IMP.maskContains(this.mask, position.getBlockX(), position.getBlockZ())) {
|
||||
queue.setBiome(position.getBlockX(), position.getBlockZ(), biome);
|
||||
}
|
||||
return false;
|
||||
return super.setBiome(position, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,6 +54,16 @@ public abstract class FaweQueue {
|
||||
|
||||
public void endSet(boolean parallel) {}
|
||||
|
||||
public int cancel() {
|
||||
int count = 0;
|
||||
for (EditSession session : sessions) {
|
||||
if (session.cancel()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FaweChunk and sets the requested blocks
|
||||
* @return
|
||||
|
@ -79,26 +79,34 @@ public class SetQueue {
|
||||
if (SET_TASK.value2 == null) {
|
||||
return;
|
||||
}
|
||||
if (Settings.UNSAFE_PARALLEL_THREADS <= 1) {
|
||||
SET_TASK.value2.startSet(false);
|
||||
SET_TASK.run();
|
||||
SET_TASK.value2.endSet(false);
|
||||
} else {
|
||||
SET_TASK.value2.startSet(true);
|
||||
ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
for (int i = 0; i < Settings.UNSAFE_PARALLEL_THREADS; i++) {
|
||||
threads.add(new Thread(SET_TASK));
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
thread.start();
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
if (Thread.currentThread() != Fawe.get().getMainThread()) {
|
||||
throw new IllegalStateException("This shouldn't be possible for placement to occur off the main thread");
|
||||
}
|
||||
// Disable the async catcher as it can't discern async vs parallel
|
||||
SET_TASK.value2.startSet(true);
|
||||
try {
|
||||
if (Settings.UNSAFE_PARALLEL_THREADS <= 1) {
|
||||
SET_TASK.run();
|
||||
} else {
|
||||
ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
for (int i = 0; i < Settings.UNSAFE_PARALLEL_THREADS; i++) {
|
||||
threads.add(new Thread(SET_TASK));
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
thread.start();
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// Enable it again (note that we are still on the main thread)
|
||||
SET_TASK.value2.endSet(true);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class WEManager {
|
||||
try {
|
||||
final Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
|
||||
field.setAccessible(true);
|
||||
field.set(parent, new NullExtent((Extent) field.get(parent), reason));
|
||||
field.set(parent, new NullExtent(reason));
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -42,6 +42,22 @@ public class WEManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean maskContains(RegionWrapper[] mask, final int x, final int z) {
|
||||
switch (mask.length) {
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
return mask[0].isIn(x, z);
|
||||
default:
|
||||
for (final RegionWrapper region : mask) {
|
||||
if (region.isIn(x, z)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public HashSet<RegionWrapper> getMask(final FawePlayer<?> player) {
|
||||
final HashSet<RegionWrapper> regions = new HashSet<>();
|
||||
if (player.hasPermission("fawe.bypass") || !Settings.REGION_RESTRICTIONS) {
|
||||
|
@ -3,7 +3,7 @@ package com.boydti.fawe.wrappers;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.extent.FaweExtent;
|
||||
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
@ -230,7 +230,7 @@ public class WorldWrapper extends AbstractWorld {
|
||||
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();
|
||||
final FaweRegionExtent fe = session.getRegionExtent();
|
||||
session.setChangeSet(fcs);
|
||||
final boolean cuboid = region instanceof CuboidRegion;
|
||||
Set<Vector2D> chunks = region.getChunks();
|
||||
|
@ -34,11 +34,10 @@ import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
||||
import com.boydti.fawe.object.extent.FaweExtent;
|
||||
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
||||
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.extent.SafeExtentWrapper;
|
||||
import com.boydti.fawe.util.ExtentWrapper;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.Perm;
|
||||
@ -118,7 +117,6 @@ import com.sk89q.worldedit.util.eventbus.EventBus;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -164,8 +162,9 @@ public class EditSession implements Extent {
|
||||
public Actor actor;
|
||||
public FaweChangeSet changeSet;
|
||||
public EditSessionWrapper wrapper;
|
||||
public FaweExtent faweExtent;
|
||||
public MaskingExtent maskingExtent;
|
||||
public FaweRegionExtent regionExtent;
|
||||
public Extent primaryExtent;
|
||||
public Extent bypassReorderHistory;
|
||||
public Extent bypassHistory;
|
||||
public Extent bypassNone;
|
||||
@ -204,7 +203,6 @@ public class EditSession implements Extent {
|
||||
}
|
||||
|
||||
private int changes = 0;
|
||||
private int maxBlocks;
|
||||
private BlockBag blockBag;
|
||||
|
||||
/**
|
||||
@ -220,13 +218,14 @@ public class EditSession implements Extent {
|
||||
checkNotNull(eventBus);
|
||||
checkArgument(maxBlocks >= -1, "maxBlocks >= -1 required");
|
||||
checkNotNull(event);
|
||||
|
||||
this.actor = event.getActor();
|
||||
// Wrap world
|
||||
// TODO block bag
|
||||
this.blockBag = blockBag;
|
||||
this.maxBlocks = maxBlocks;
|
||||
// Invalid; return null extent
|
||||
|
||||
// Invalid world: return null extent
|
||||
if (world == null) {
|
||||
FaweExtent extent = faweExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
NullExtent extent = new NullExtent(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
this.bypassReorderHistory = extent;
|
||||
this.bypassHistory = extent;
|
||||
this.bypassNone = extent;
|
||||
@ -234,26 +233,18 @@ public class EditSession implements Extent {
|
||||
this.wrapper = Fawe.imp().getEditSessionWrapper(this);
|
||||
return;
|
||||
}
|
||||
// Set the world of the event to the actual world (workaround for CoreProtect)
|
||||
try {
|
||||
Class<? extends EditSessionEvent> eventClass = event.getClass();
|
||||
Field fieldWorld = eventClass.getDeclaredField("world");
|
||||
fieldWorld.setAccessible(true);
|
||||
if (world instanceof WorldWrapper) {
|
||||
fieldWorld.set(event, ((WorldWrapper) world).getParent());
|
||||
} else {
|
||||
fieldWorld.set(event, world);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Wrap the world
|
||||
this.world = (world = new WorldWrapper((AbstractWorld) world));
|
||||
|
||||
// Delegate some methods to an implementation specific class
|
||||
this.wrapper = Fawe.imp().getEditSessionWrapper(this);
|
||||
|
||||
// Not a player; bypass history
|
||||
if ((actor == null) || !actor.isPlayer()) {
|
||||
this.queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), true, true);
|
||||
queue.addEditSession(this);
|
||||
Extent extent = (this.faweExtent = new FastWorldEditExtent(world, queue));
|
||||
Extent extent = primaryExtent = new FastWorldEditExtent(world, queue);
|
||||
// Everything bypasses
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE);
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_REORDER);
|
||||
@ -264,8 +255,9 @@ public class EditSession implements Extent {
|
||||
this.changeSet = new NullChangeSet();
|
||||
return;
|
||||
}
|
||||
this.changeSet = Settings.STORE_HISTORY_ON_DISK ? new DiskStorageHistory(world, actor.getUniqueId()) : new MemoryOptimizedHistory(actor);
|
||||
|
||||
Extent extent;
|
||||
HashSet<RegionWrapper> mask;
|
||||
final FawePlayer fp = FawePlayer.wrap(actor);
|
||||
final LocalSession session = fp.getSession();
|
||||
this.fastmode = session.hasFastMode();
|
||||
@ -273,7 +265,7 @@ public class EditSession implements Extent {
|
||||
this.queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), true, true);
|
||||
queue.addEditSession(this);
|
||||
// Bypass skips processing and area restrictions
|
||||
extent = (this.faweExtent = new FastWorldEditExtent(world, queue));
|
||||
extent = primaryExtent = new FastWorldEditExtent(world, queue);
|
||||
if (this.hasFastMode()) {
|
||||
// Fastmode skips history and memory checks
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE);
|
||||
@ -284,30 +276,28 @@ public class EditSession implements Extent {
|
||||
this.bypassNone = extent;
|
||||
return;
|
||||
}
|
||||
mask = null;
|
||||
} else {
|
||||
this.queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), false, true);
|
||||
queue.addEditSession(this);
|
||||
this.limit = fp.getLimit();
|
||||
final HashSet<RegionWrapper> mask = WEManager.IMP.getMask(fp);
|
||||
mask = WEManager.IMP.getMask(fp);
|
||||
if (mask.size() == 0) {
|
||||
// No allowed area; return null extent
|
||||
extent = faweExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
extent = new NullExtent(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
this.bypassReorderHistory = extent;
|
||||
this.bypassHistory = extent;
|
||||
this.bypassNone = extent;
|
||||
return;
|
||||
}
|
||||
// Process the WorldEdit action
|
||||
ProcessedWEExtent processed = (ProcessedWEExtent) (this.faweExtent = new ProcessedWEExtent(world, fp, mask, limit, queue));
|
||||
extent = processed;
|
||||
extent = primaryExtent = new FastWorldEditExtent(world, queue);
|
||||
if (this.hasFastMode()) {
|
||||
// Fastmode skips history, masking, and memory checks
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE);
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_REORDER);
|
||||
// Restrictions
|
||||
extent = new ProcessedWEExtent(extent, mask, limit);
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_HISTORY);
|
||||
extent = new ExtentWrapper(extent);
|
||||
// Set the parent. This allows efficient cancelling
|
||||
processed.setParent(extent);
|
||||
this.bypassReorderHistory = extent;
|
||||
this.bypassHistory = extent;
|
||||
this.bypassNone = extent;
|
||||
@ -318,9 +308,8 @@ public class EditSession implements Extent {
|
||||
if (Perm.hasPermission(fp, "worldedit.fast")) {
|
||||
BBC.WORLDEDIT_OOM_ADMIN.send(fp);
|
||||
}
|
||||
|
||||
// Memory limit reached; return null extent
|
||||
extent = faweExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
extent = new NullExtent(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
|
||||
this.bypassReorderHistory = extent;
|
||||
this.bypassHistory = extent;
|
||||
this.bypassNone = extent;
|
||||
@ -328,14 +317,24 @@ public class EditSession implements Extent {
|
||||
}
|
||||
}
|
||||
// Perform memory checks after reorder
|
||||
extent = new SafeExtentWrapper(fp, extent);
|
||||
processed.setParent(extent);
|
||||
extent = new MemoryCheckingExtent(fp, extent);
|
||||
}
|
||||
// Include history, masking and memory checking.
|
||||
Extent wrapped;
|
||||
// First two events
|
||||
extent = wrapped = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE);
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_REORDER);
|
||||
|
||||
// History
|
||||
this.changeSet = Settings.STORE_HISTORY_ON_DISK ? new DiskStorageHistory(world, actor.getUniqueId()) : new MemoryOptimizedHistory(actor);
|
||||
extent = this.wrapper.getHistoryExtent(this, limit, extent, this.changeSet, queue, fp);
|
||||
|
||||
// Region restrictions if mask is not null
|
||||
if (mask != null) {
|
||||
extent = this.regionExtent = new ProcessedWEExtent(extent, mask, limit);
|
||||
}
|
||||
|
||||
// Masking
|
||||
final Player skp = (Player) actor;
|
||||
final int item = skp.getItemInHand();
|
||||
boolean hasMask = session.getMask() != null;
|
||||
@ -351,14 +350,44 @@ public class EditSession implements Extent {
|
||||
extent = this.maskingExtent = new MaskingExtent(extent, Masks.alwaysTrue());
|
||||
}
|
||||
|
||||
// Before history event
|
||||
extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_HISTORY);
|
||||
extent = new SafeExtentWrapper(fp, extent);
|
||||
|
||||
this.bypassReorderHistory = wrapped;
|
||||
this.bypassHistory = wrapped;
|
||||
this.bypassNone = extent;
|
||||
return;
|
||||
}
|
||||
|
||||
public FaweRegionExtent getRegionExtent() {
|
||||
return regionExtent;
|
||||
}
|
||||
|
||||
public boolean cancel() {
|
||||
// Cancel this
|
||||
if (primaryExtent != null && queue != null) {
|
||||
try {
|
||||
WEManager.IMP.cancelEdit(primaryExtent, BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
|
||||
} catch (Throwable ignore) {}
|
||||
NullExtent nullExtent = new NullExtent(BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
|
||||
primaryExtent = nullExtent;
|
||||
dequeue();
|
||||
queue.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dequeue() {
|
||||
if (queue != null) {
|
||||
SetQueue.IMP.dequeue(queue);
|
||||
}
|
||||
}
|
||||
|
||||
public FastWorldEditExtent getPrimaryExtent() {
|
||||
return (FastWorldEditExtent) primaryExtent;
|
||||
}
|
||||
|
||||
public void debug(BBC message, Object... args) {
|
||||
message.send(actor, args);
|
||||
}
|
||||
@ -427,7 +456,7 @@ public class EditSession implements Extent {
|
||||
* @return the limit (>= 0) or -1 for no limit
|
||||
*/
|
||||
public int getBlockChangeLimit() {
|
||||
return this.maxBlocks;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,10 +518,6 @@ public class EditSession implements Extent {
|
||||
}
|
||||
}
|
||||
|
||||
public FaweExtent getFaweExtent() {
|
||||
return this.faweExtent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mask.
|
||||
*
|
||||
|
@ -29,6 +29,7 @@ import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
@ -51,6 +52,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
@ -226,13 +228,13 @@ public class BrushCommands {
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new GravityBrush(fromMaxY), "worldedit.brush.gravity");
|
||||
tool.setBrush(new GravityBrush(fromMaxY, tool), "worldedit.brush.gravity");
|
||||
BBC.BRUSH_GRAVITY.send(player, radius);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "height", "high" },
|
||||
usage = "[radius] [file] [rotation] [yscale]",
|
||||
aliases = { "height", "heightmap" },
|
||||
usage = "[radius] [file|#selection|null] [rotation] [yscale]",
|
||||
flags = "h",
|
||||
desc = "Height brush",
|
||||
help =
|
||||
@ -246,7 +248,12 @@ public class BrushCommands {
|
||||
File file = new File(Fawe.imp().getDirectory(), "heightmap" + File.separator + (filename.endsWith(".png") ? filename : filename + ".png"));
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new HeightBrush(file, rotation, yscale), "worldedit.brush.height");
|
||||
try {
|
||||
tool.setBrush(new HeightBrush(file, rotation, yscale, tool, editSession, (CuboidRegion) session.getSelection(player.getWorld())), "worldedit.brush.height");
|
||||
} catch (IncompleteRegionException ignore) {
|
||||
ignore.printStackTrace();
|
||||
tool.setBrush(new HeightBrush(file, rotation, yscale, tool, editSession, null), "worldedit.brush.height");
|
||||
}
|
||||
BBC.BRUSH_HEIGHT.send(player, radius);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.annotation.Direction;
|
||||
import com.sk89q.worldedit.internal.annotation.Selection;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
@ -278,7 +279,7 @@ public class ClipboardCommands {
|
||||
final Vector origin = clipboard.getOrigin();
|
||||
final Vector to = atOrigin ? origin : session.getPlacementPosition(player);
|
||||
// Optimize for BlockArrayClipboard
|
||||
if (clipboard instanceof BlockArrayClipboard) {
|
||||
if (clipboard instanceof BlockArrayClipboard && region instanceof CuboidRegion) {
|
||||
// To is relative to the world origin (player loc + small clipboard offset) (As the positions supplied are relative to the clipboard min)
|
||||
final int relx = to.getBlockX() + bot.getBlockX() - origin.getBlockX();
|
||||
final int rely = to.getBlockY() + bot.getBlockY() - origin.getBlockY();
|
||||
|
@ -23,18 +23,27 @@ import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class GravityBrush implements Brush {
|
||||
|
||||
private final boolean fullHeight;
|
||||
private final BrushTool tool;
|
||||
|
||||
public GravityBrush(boolean fullHeight) {
|
||||
public GravityBrush(boolean fullHeight, BrushTool tool) {
|
||||
this.fullHeight = fullHeight;
|
||||
this.tool = tool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
Mask mask = tool.getMask();
|
||||
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
||||
mask = null;
|
||||
}
|
||||
int size = (int) sizeDouble;
|
||||
int endY = position.getBlockY() + size;
|
||||
int startPerformY = Math.max(0, position.getBlockY() - size);
|
||||
@ -51,11 +60,12 @@ public class GravityBrush implements Brush {
|
||||
continue;
|
||||
}
|
||||
BaseBlock block = editSession.getLazyBlock(x, y, z);
|
||||
if (block != EditSession.nullBlock) {
|
||||
mutablePos.x = x;
|
||||
mutablePos.y = y;
|
||||
mutablePos.z = z;
|
||||
if (block != EditSession.nullBlock && (mask == null || mask.test(mutablePos))) {
|
||||
if (freeSpot != y) {
|
||||
mutablePos.x = x;
|
||||
mutablePos.y = freeSpot;
|
||||
mutablePos.z = z;
|
||||
editSession.setBlock(mutablePos, block);
|
||||
mutablePos.y = y;
|
||||
editSession.setBlock(mutablePos, EditSession.nullBlock);
|
||||
|
Loading…
Reference in New Issue
Block a user