Minor tweaks

Fix tile add/remove for anvil commands
Add MCAWorld
This commit is contained in:
Jesse Boyd 2016-08-25 16:36:58 +10:00
parent b34c534bb0
commit b261a5c8b8
15 changed files with 243 additions and 54 deletions

View File

@ -1,5 +1,7 @@
package com.boydti.fawe.database;
import com.boydti.fawe.Fawe;
import com.sk89q.worldedit.world.World;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -8,6 +10,22 @@ public class DBHandler {
private Map<String, RollbackDatabase> databases = new ConcurrentHashMap<>(8, 0.9f, 1);
public RollbackDatabase getDatabase(World world) {
String worldName = Fawe.imp().getWorldName(world);
RollbackDatabase database = databases.get(worldName);
if (database != null) {
return database;
}
try {
database = new RollbackDatabase(world);
databases.put(worldName, database);
return database;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
public RollbackDatabase getDatabase(String world) {
RollbackDatabase database = databases.get(world);
if (database != null) {

View File

@ -26,7 +26,8 @@ public class RollbackDatabase {
private final String prefix;
private final File dbLocation;
private final String world;
private final String worldName;
private final World world;
private Connection connection;
private String INSERT_EDIT;
@ -41,8 +42,13 @@ public class RollbackDatabase {
private ConcurrentLinkedQueue<RollbackOptimizedHistory> historyChanges = new ConcurrentLinkedQueue<>();
private ConcurrentLinkedQueue<Runnable> notify = new ConcurrentLinkedQueue<>();
public RollbackDatabase(final String world) throws SQLException, ClassNotFoundException {
public RollbackDatabase(String world) throws SQLException, ClassNotFoundException {
this(FaweAPI.getWorld(world));
}
public RollbackDatabase(final World world) throws SQLException, ClassNotFoundException {
this.prefix = "";
this.worldName = Fawe.imp().getWorldName(world);
this.world = world;
this.dbLocation = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.PATHS.HISTORY + File.separator + world + File.separator + "summary.db");
connection = openConnection();
@ -124,7 +130,7 @@ public class RollbackDatabase {
}
public void getPotentialEdits(final UUID uuid, final long minTime, final Vector pos1, final Vector pos2, final RunnableVal<DiskStorageHistory> onEach, final Runnable whenDone, final boolean delete) {
final World world = FaweAPI.getWorld(this.world);
final World world = FaweAPI.getWorld(this.worldName);
addTask(new Runnable() {
@Override
public void run() {

View File

@ -0,0 +1,120 @@
package com.boydti.fawe.jnbt.anvil;
import com.boydti.fawe.object.extent.FastWorldEditExtent;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.WorldData;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
public class MCAWorld extends LocalWorld {
private final String name;
private final MCAQueue queue;
private final FastWorldEditExtent extent;
public MCAWorld(String name, File saveFolder, boolean hasSky) {
this.name = name;
this.queue = new MCAQueue(name, saveFolder, hasSky);
this.extent = new FastWorldEditExtent(this, queue);
}
public MCAQueue getQueue() {
return queue;
}
@Override
public String getName() {
return name;
}
@Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException {
return extent.setBlock(position, block);
}
@Override
public int getBlockLightLevel(Vector position) {
return queue.getEmmittedLight((int) position.x, (int) position.y, (int) position.z);
}
@Override
public boolean clearContainerBlockContents(Vector position) {
BaseBlock block = extent.getLazyBlock(position);
if (block.hasNbtData()) {
Map<String, Tag> nbt = ReflectionUtils.getMap(block.getNbtData().getValue());
if (nbt.containsKey("Items")) {
nbt.put("Items", new ListTag(CompoundTag.class, new ArrayList<CompoundTag>()));
try {
extent.setBlock(position, block);
} catch (WorldEditException e) {
e.printStackTrace();
}
}
}
return true;
}
@Override
public void dropItem(Vector position, BaseItemStack item) {
}
@Override
public boolean regenerate(Region region, EditSession editSession) {
return false;
}
@Override
public WorldData getWorldData() {
return null;
}
@Override
public List<? extends Entity> getEntities(Region region) {
return new ArrayList<>();
}
@Override
public List<? extends Entity> getEntities() {
return new ArrayList<>();
}
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {
return extent.createEntity(location, entity);
}
@Override
public BaseBlock getBlock(Vector position) {
return extent.getLazyBlock(position);
}
@Override
public BaseBiome getBiome(Vector2D position) {
return extent.getBiome(position);
}
@Override
public boolean setBiome(Vector2D position, BaseBiome biome) {
return extent.setBiome(position, biome);
}
}

View File

@ -82,7 +82,7 @@ public class MutableMCABackedBaseBlock extends BaseBlock {
@Override
public void setNbtData(@Nullable CompoundTag nbtData) {
chunk.setTile(x, y, z, null);
chunk.setTile(x, y, z, nbtData);
chunk.setModified();
}
}

View File

@ -1,6 +1,5 @@
package com.boydti.fawe.logging.rollback;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.database.DBHandler;
import com.boydti.fawe.database.RollbackDatabase;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
@ -74,7 +73,7 @@ public class RollbackOptimizedHistory extends DiskStorageHistory {
public boolean flush() {
if (super.flush()) {
// Save to DB
RollbackDatabase db = DBHandler.IMP.getDatabase(Fawe.imp().getWorldName(getWorld()));
RollbackDatabase db = DBHandler.IMP.getDatabase(getWorld());
db.logEdit(this);
return true;
}

View File

@ -1,41 +1,42 @@
package com.boydti.fawe.object;
import com.boydti.fawe.util.MathMan;
public class BytePair {
public byte[] pair;
public short pair;
public BytePair(final byte x, final byte z) {
this.pair = new byte[] { x, z};
this.pair = MathMan.pairByte(x, z);
}
int hash;
public byte get0() {
return pair[0];
public int get0x() {
return MathMan.unpair16x((byte) get0());
}
public byte get1() {
return pair[1];
public int get0y() {
return MathMan.unpair16y((byte) get0());
}
public int get0() {
return MathMan.unpairShortX(pair);
}
public int get1() {
return MathMan.unpairShortY(pair);
}
@Override
public int hashCode() {
return pair[0] + (pair[1] << 8);
return pair;
}
@Override
public String toString() {
return pair[0] + "," + pair[1];
return pair + "";
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if ((obj == null) || (this.hashCode() != obj.hashCode()) || (this.getClass() != obj.getClass())) {
return false;
}
final BytePair other = (BytePair) obj;
return pair[0] == other.pair[0] && pair[1] == other.pair[1];
return obj.hashCode() == pair;
}
}

View File

@ -1,6 +1,5 @@
package com.boydti.fawe.object.brush;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
import com.boydti.fawe.wrappers.PlayerWrapper;
@ -34,7 +33,7 @@ public class CommandBrush implements Brush {
String replaced = command.replace("{x}", position.getBlockX() + "")
.replace("{y}", position.getBlockY() + "")
.replace("{z}", position.getBlockZ() + "")
.replace("{world}", Fawe.imp().getWorldName(editSession.getWorld()) + "")
.replace("{world}", editSession.getQueue().getWorldName())
.replace("{size}", radius + "");
WorldVectorFace face = player.getBlockTraceFace(256, true);

View File

@ -73,8 +73,7 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
World world = player.getWorld();
final FawePlayer fp = FawePlayer.wrap(player);
EditSessionBuilder editSession = new EditSessionBuilder(world).player(fp);
String worldName = Fawe.imp().getWorldName(world);
RollbackDatabase db = DBHandler.IMP.getDatabase(worldName);
RollbackDatabase db = DBHandler.IMP.getDatabase(world);
final AtomicInteger count = new AtomicInteger();
db.getPotentialEdits(null, 0, target, target, new RunnableVal<DiskStorageHistory>() {
@Override

View File

@ -107,7 +107,7 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
Fawe.debug("Deleting history: " + Fawe.imp().getWorldName(getWorld()) + "/" + uuid + "/" + index);
deleteFiles();
if (Settings.HISTORY.USE_DATABASE) {
RollbackDatabase db = DBHandler.IMP.getDatabase(Fawe.imp().getWorldName(getWorld()));
RollbackDatabase db = DBHandler.IMP.getDatabase(getWorld());
db.delete(uuid, index);
}
}

View File

@ -34,7 +34,7 @@ public abstract class FaweBlockMatcher {
if (FaweCache.hasData(currentId)) {
oldBlock.setData(0);
}
if (FaweCache.hasNBT(id) && oldBlock.hasNbtData()) {
if (FaweCache.hasNBT(currentId)) {
oldBlock.setNbtData(null);
}
return true;
@ -47,7 +47,7 @@ public abstract class FaweBlockMatcher {
int currentId = oldBlock.getId();
oldBlock.setId(id);
oldBlock.setData(data);
if (FaweCache.hasNBT(id) && oldBlock.hasNbtData()) {
if (FaweCache.hasNBT(currentId)) {
oldBlock.setNbtData(null);
}
return true;

View File

@ -5,6 +5,7 @@ import com.boydti.fawe.config.Settings;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.NullChangeSet;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
@ -19,11 +20,11 @@ import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class EditSessionBuilder {
private World world;
private FaweQueue queue;
private FawePlayer player;
private FaweLimit limit;
private FaweChangeSet changeSet;
@ -83,6 +84,12 @@ public class EditSessionBuilder {
return changeSet(new NullChangeSet(world));
}
public EditSessionBuilder world(@Nonnull World world) {
checkNotNull(world);
this.world = world;
return this;
}
/**
* @param disk If it should be stored on disk
* @param uuid The uuid to store it under (if on disk)
@ -136,6 +143,11 @@ public class EditSessionBuilder {
return this;
}
public EditSessionBuilder queue(@Nullable FaweQueue queue) {
this.queue = queue;
return this;
}
public EditSessionBuilder blockBag(@Nullable BlockBag blockBag) {
this.blockBag = blockBag;
return this;
@ -152,6 +164,6 @@ public class EditSessionBuilder {
}
public EditSession build() {
return new EditSession(world, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event);
return new EditSession(world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event);
}
}

View File

@ -39,6 +39,9 @@ public class WorldWrapper extends LocalWorld {
private final AbstractWorld parent;
public static WorldWrapper wrap(AbstractWorld world) {
if (world == null) {
return null;
}
if (world instanceof WorldWrapper) {
return (WorldWrapper) world;
}

View File

@ -24,6 +24,7 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.jnbt.anvil.MCAWorld;
import com.boydti.fawe.logging.LoggingChangeSet;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.FaweLimit;
@ -114,6 +115,7 @@ 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 com.sk89q.worldedit.world.registry.WorldData;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -178,8 +180,7 @@ public class EditSession implements Extent {
PlayerDirection.UP.vector(),
PlayerDirection.DOWN.vector(), };
public EditSession(@Nonnull World world, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
checkNotNull(world);
public EditSession(@Nonnull World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
this.world = world = WorldWrapper.wrap((AbstractWorld) world);
if (bus == null) {
bus = WorldEdit.getInstance().getEventBus();
@ -200,7 +201,7 @@ public class EditSession implements Extent {
} else {
changeSet = new DiskStorageHistory(world, uuid);
}
} else if (Settings.HISTORY.COMBINE_STAGES && Settings.HISTORY.COMPRESSION_LEVEL == 0) {
} else if (Settings.HISTORY.COMBINE_STAGES && Settings.HISTORY.COMPRESSION_LEVEL == 0 && !(queue instanceof MCAQueue)) {
changeSet = new CPUOptimizedChangeSet(world);
} else {
changeSet = new MemoryOptimizedHistory(world);
@ -235,7 +236,7 @@ public class EditSession implements Extent {
checkMemory = player != null && !fastmode;
}
if (combineStages == null) {
combineStages = Settings.HISTORY.COMBINE_STAGES;
combineStages = Settings.HISTORY.COMBINE_STAGES && !(queue instanceof MCAQueue);
}
if (checkMemory) {
if (MemUtil.isMemoryLimitedSlow()) {
@ -248,10 +249,16 @@ public class EditSession implements Extent {
this.blockBag = blockBag;
this.originalLimit = limit;
this.limit = limit.copy();
this.queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), fastmode, autoQueue);
if (Settings.EXPERIMENTAL.ANVIL_QUEUE_MODE) {
this.queue = new MCAQueue(queue);
if (queue == null) {
if (world instanceof MCAWorld) {
queue = ((MCAWorld) world).getQueue();
} else {
queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), fastmode, autoQueue);
}
} else if (Settings.EXPERIMENTAL.ANVIL_QUEUE_MODE && !(queue instanceof MCAQueue)) {
queue = new MCAQueue(queue);
}
this.queue = queue;
queue.addEditSession(this);
this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), bus, event, Stage.BEFORE_CHANGE);
this.bypassHistory = (this.extent = wrapExtent(bypassAll, bus, event, Stage.BEFORE_REORDER));
@ -311,7 +318,7 @@ public class EditSession implements Extent {
* @param event the event to call with the extent
*/
public EditSession(final EventBus eventBus, World world, final int maxBlocks, @Nullable final BlockBag blockBag, EditSessionEvent event) {
this(world, null, null, null, null, true, null, null, null, blockBag, eventBus, event);
this(world, null, null, null, null, null, true, null, null, null, blockBag, eventBus, event);
}
/**
@ -462,6 +469,10 @@ public class EditSession implements Extent {
return this.world;
}
public WorldData getWorldData() {
return getWorld() != null ? getWorld().getWorldData() : null;
}
/**
* Get the underlying {@link ChangeSet}.
*
@ -1078,12 +1089,20 @@ public class EditSession implements Extent {
@Override
public Vector getMinimumPoint() {
return this.getWorld().getMinimumPoint();
if (getWorld() != null) {
return this.getWorld().getMinimumPoint();
} else {
return new Vector(-30000000, 0, -30000000);
}
}
@Override
public Vector getMaximumPoint() {
return this.getWorld().getMaximumPoint();
if (getWorld() != null) {
return this.getWorld().getMaximumPoint();
} else {
return new Vector(30000000, 255, 30000000);
}
}
@Override
@ -1202,7 +1221,7 @@ public class EditSession implements Extent {
checkArgument(depth >= 1, "depth >= 1");
final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), new BoundedHeightMask(Math.max(
(origin.getBlockY() - depth) + 1, 0), Math.min(EditSession.this.getWorld().getMaxY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));
(origin.getBlockY() - depth) + 1, 0), Math.min(EditSession.this.getMaximumPoint().getBlockY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));
// Want to replace blocks
final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern));
@ -1717,8 +1736,21 @@ public class EditSession implements Extent {
public int drainArea(final Vector origin, final double radius) throws MaxChangedBlocksException {
checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required");
final MaskIntersection mask = new MaskIntersection(new BoundedHeightMask(0, EditSession.this.getWorld().getMaxY()), new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius,
radius, radius))), EditSession.this.getWorld().createLiquidMask());
Mask liquidMask;
if (getWorld() != null) {
liquidMask = getWorld().createLiquidMask();
} else {
liquidMask = new BlockMask(this,
new BaseBlock(BlockID.STATIONARY_LAVA, -1),
new BaseBlock(BlockID.LAVA, -1),
new BaseBlock(BlockID.STATIONARY_WATER, -1),
new BaseBlock(BlockID.WATER, -1));
}
final MaskIntersection mask = new MaskIntersection(
new BoundedHeightMask(0, EditSession.this.getMaximumPoint().getBlockY()),
new RegionMask(
new EllipsoidRegion(null, origin,
new Vector(radius,radius, radius))), liquidMask);
final BlockReplace replace = new BlockReplace(EditSession.this, new BlockPattern(new BaseBlock(BlockID.AIR)));
final RecursiveVisitor visitor = new RecursiveVisitor(mask, replace);
@ -1780,7 +1812,7 @@ public class EditSession implements Extent {
// There are boundaries that the routine needs to stay in
MaskIntersection mask = new MaskIntersection(
new BoundedHeightMask(0, Math.min(origin.getBlockY(), getWorld().getMaxY())),
new BoundedHeightMask(0, Math.min(origin.getBlockY(), getMaximumPoint().getBlockY())),
new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))),
blockMask);

View File

@ -145,7 +145,7 @@ public class ClipboardCommands {
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
clipboard.setOrigin(session.getPlacementPosition(player));
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorld().getWorldData()));
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData()));
BBC.COMMAND_COPY.send(player, region.getArea());
}
@ -176,7 +176,7 @@ public class ClipboardCommands {
copy.setSourceMask(mask);
}
Operations.completeLegacy(copy);
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorld().getWorldData()));
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData()));
BBC.COMMAND_COPY.send(player, region.getArea());
}
@ -208,7 +208,7 @@ public class ClipboardCommands {
copy.setSourceMask(mask);
}
Operations.completeLegacy(copy);
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorld().getWorldData()));
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData()));
BBC.COMMAND_CUT.send(player, region.getArea());
}
@ -286,7 +286,7 @@ public class ClipboardCommands {
Region region = clipboard.getRegion();
Vector to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(player);
Operation operation = holder
.createPaste(editSession, editSession.getWorld().getWorldData())
.createPaste(editSession, editSession.getWorldData())
.to(to)
.ignoreAirBlocks(ignoreAirBlocks)
.build();

View File

@ -111,7 +111,7 @@ public class HistoryCommands {
if (summary != null) {
rollback.setDimensions(new Vector(summary.minX, 0, summary.minZ), new Vector(summary.maxX, 255, summary.maxZ));
rollback.setTime(historyFile.lastModified());
RollbackDatabase db = DBHandler.IMP.getDatabase(worldName);
RollbackDatabase db = DBHandler.IMP.getDatabase(world);
db.logEdit(rollback);
player.print("Logging: " + historyFile);
}
@ -140,7 +140,7 @@ public class HistoryCommands {
WorldVector origin = player.getPosition();
Vector bot = origin.subtract(radius, radius, radius);
Vector top = origin.add(radius, radius, radius);
RollbackDatabase database = DBHandler.IMP.getDatabase(Fawe.imp().getWorldName(world));
RollbackDatabase database = DBHandler.IMP.getDatabase(world);
final AtomicInteger count = new AtomicInteger();
database.getPotentialEdits(other, System.currentTimeMillis() - timeDiff, bot, top, new RunnableVal<DiskStorageHistory>() {
@Override