wip history changes

This commit is contained in:
Jesse Boyd 2020-01-06 08:36:16 +00:00
parent b173c85c78
commit 195c4a7647
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
32 changed files with 442 additions and 287 deletions

View File

@ -0,0 +1,59 @@
import com.sk89q.worldedit.history.changeset.ChangeSetSummary;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import java.util.HashMap;
import java.util.Map;
public class SimpleChangeSetSummary implements ChangeSetSummary {
public int[] blocks;
public int minX;
public int minZ;
public int maxX;
public int maxZ;
public SimpleChangeSetSummary(int x, int z) {
blocks = new int[BlockTypesCache.states.length];
minX = x;
maxX = x;
minZ = z;
maxZ = z;
}
public void add(int x, int z, int id) {
blocks[id]++;
if (x < minX) {
minX = x;
} else if (x > maxX) {
maxX = x;
}
if (z < minZ) {
minZ = z;
} else if (z > maxZ) {
maxZ = z;
}
}
@Override
public Map<BlockState, Integer> getBlocks() {
HashMap<BlockState, Integer> map = new HashMap<>();
for (int i = 0; i < blocks.length; i++) {
if (blocks[i] != 0) {
BlockState state = BlockTypesCache.states[i];
map.put(state, blocks[i]);
}
}
return map;
}
@Override
public int getSize() {
int count = 0;
for (int block : blocks) {
count += block;
}
return count;
}
}

View File

@ -343,7 +343,7 @@ public class FaweAPI {
for (File file : files) { for (File file : files) {
UUID uuid = UUID.fromString(file.getParentFile().getName()); UUID uuid = UUID.fromString(file.getParentFile().getName());
DiskStorageHistory dsh = new DiskStorageHistory(world, uuid, Integer.parseInt(file.getName().split("\\.")[0])); DiskStorageHistory dsh = new DiskStorageHistory(world, uuid, Integer.parseInt(file.getName().split("\\.")[0]));
DiskStorageHistory.DiskStorageSummary summary = dsh.summarize(boundsPlus, shallow); SimpleChangeSetSummary summary = dsh.summarize(boundsPlus, shallow);
RegionWrapper region = new RegionWrapper(summary.minX, summary.maxX, summary.minZ, summary.maxZ); RegionWrapper region = new RegionWrapper(summary.minX, summary.maxX, summary.minZ, summary.maxZ);
boolean encompassed = false; boolean encompassed = false;
boolean isIn = false; boolean isIn = false;

View File

@ -1,7 +1,7 @@
package com.boydti.fawe.beta.implementation.processors; package com.boydti.fawe.beta.implementation.processors;
import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.beta.IBatchProcessor;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
public abstract class ExtentBatchProcessorHolder extends BatchProcessorHolder implements Extent { public abstract class ExtentBatchProcessorHolder extends BatchProcessorHolder implements Extent {
@ -12,13 +12,13 @@ public abstract class ExtentBatchProcessorHolder extends BatchProcessorHolder im
} }
@Override @Override
public Extent enableHistory(FaweChangeSet changeSet) { public Extent enableHistory(AbstractChangeSet changeSet) {
return this.addProcessor(changeSet); return this.addProcessor(changeSet);
} }
@Override @Override
public Extent disableHistory() { public Extent disableHistory() {
this.remove(FaweChangeSet.class); this.remove(AbstractChangeSet.class);
return this; return this;
} }
} }

View File

@ -2,10 +2,8 @@ package com.boydti.fawe.beta.implementation.processors;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IBatchProcessor;
import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock; import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock;
import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
@ -14,11 +12,9 @@ import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.PassthroughExtent; import com.sk89q.worldedit.extent.PassthroughExtent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.function.generator.GenBase; import com.sk89q.worldedit.function.generator.GenBase;
import com.sk89q.worldedit.function.generator.Resource; import com.sk89q.worldedit.function.generator.Resource;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;

View File

@ -9,13 +9,12 @@ import com.boydti.fawe.beta.implementation.filter.CountFilter;
import com.boydti.fawe.beta.implementation.filter.DistrFilter; import com.boydti.fawe.beta.implementation.filter.DistrFilter;
import com.boydti.fawe.beta.implementation.processors.BatchProcessorHolder; import com.boydti.fawe.beta.implementation.processors.BatchProcessorHolder;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.boydti.fawe.object.clipboard.WorldCopyClipboard; import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.object.extent.NullExtent;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.PassthroughExtent; import com.sk89q.worldedit.extent.PassthroughExtent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask;
@ -79,7 +78,7 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
} }
@Override @Override
public Extent enableHistory(FaweChangeSet changeSet) { public Extent enableHistory(AbstractChangeSet changeSet) {
return super.enableHistory(changeSet); return super.enableHistory(changeSet);
} }

View File

@ -1,7 +1,7 @@
package com.boydti.fawe.logging; package com.boydti.fawe.logging;
import com.boydti.fawe.object.changeset.AbstractDelegateChangeSet; import com.boydti.fawe.object.changeset.AbstractDelegateChangeSet;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
//import org.primesoft.blockshub.IBlocksHubApi; //import org.primesoft.blockshub.IBlocksHubApi;
//import org.primesoft.blockshub.api.IPlayer; //import org.primesoft.blockshub.api.IPlayer;
@ -11,7 +11,7 @@ public class LoggingChangeSet extends AbstractDelegateChangeSet {
private static boolean initialized = false; private static boolean initialized = false;
public static FaweChangeSet wrap(Player player, FaweChangeSet parent) { public static AbstractChangeSet wrap(Player player, AbstractChangeSet parent) {
if (!initialized) { if (!initialized) {
initialized = true; initialized = true;
// api = (IBlocksHubApi) Fawe.imp().getBlocksHubApi(); // api = (IBlocksHubApi) Fawe.imp().getBlocksHubApi();
@ -30,7 +30,7 @@ public class LoggingChangeSet extends AbstractDelegateChangeSet {
// private final MutableBlockData oldBlock; // private final MutableBlockData oldBlock;
// private final MutableBlockData newBlock; // private final MutableBlockData newBlock;
private LoggingChangeSet(Player player, FaweChangeSet parent) { private LoggingChangeSet(Player player, AbstractChangeSet parent) {
super(parent); super(parent);
// String world = player.getLocation().world; // String world = player.getLocation().world;
// try { // try {

View File

@ -1,10 +1,8 @@
package com.boydti.fawe.logging.rollback; package com.boydti.fawe.logging.rollback;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.database.DBHandler; import com.boydti.fawe.database.DBHandler;
import com.boydti.fawe.database.RollbackDatabase; import com.boydti.fawe.database.RollbackDatabase;
import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
@ -55,6 +53,7 @@ public class RollbackOptimizedHistory extends DiskStorageHistory {
this.blockSize = (int) size; this.blockSize = (int) size;
this.command = command; this.command = command;
this.closed = true; this.closed = true;
System.out.println("Size " + size);
} }
public long getTime() { public long getTime() {
@ -62,8 +61,8 @@ public class RollbackOptimizedHistory extends DiskStorageHistory {
} }
@Override @Override
protected DiskStorageSummary summarizeShallow() { protected SimpleChangeSetSummary summarizeShallow() {
DiskStorageSummary summary = super.summarizeShallow(); SimpleChangeSetSummary summary = super.summarizeShallow();
summary.minX = this.minX; summary.minX = this.minX;
summary.minZ = this.minZ; summary.minZ = this.minZ;
summary.maxX = this.maxX; summary.maxX = this.maxX;

View File

@ -2,7 +2,7 @@ package com.boydti.fawe.object;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -25,7 +25,7 @@ import javax.annotation.Nullable;
*/ */
public class HistoryExtent extends AbstractDelegateExtent { public class HistoryExtent extends AbstractDelegateExtent {
private FaweChangeSet changeSet; private AbstractChangeSet changeSet;
/** /**
* Create a new instance. * Create a new instance.
@ -33,18 +33,18 @@ public class HistoryExtent extends AbstractDelegateExtent {
* @param extent the extent * @param extent the extent
* @param changeSet the change set * @param changeSet the change set
*/ */
public HistoryExtent(Extent extent, FaweChangeSet changeSet) { public HistoryExtent(Extent extent, AbstractChangeSet changeSet) {
super(extent); super(extent);
checkNotNull(changeSet); checkNotNull(changeSet);
this.changeSet = changeSet; this.changeSet = changeSet;
} }
public FaweChangeSet getChangeSet() { public AbstractChangeSet getChangeSet() {
return changeSet; return changeSet;
} }
@Override @Override
public void setChangeSet(FaweChangeSet fcs) { public void setChangeSet(AbstractChangeSet fcs) {
this.changeSet = fcs; this.changeSet = fcs;
} }

View File

@ -1,6 +1,6 @@
package com.boydti.fawe.object; package com.boydti.fawe.object;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.history.change.Change; import com.sk89q.worldedit.history.change.Change;
@ -9,7 +9,7 @@ import com.sk89q.worldedit.world.biome.BiomeType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
public class NullChangeSet extends FaweChangeSet { public class NullChangeSet extends AbstractChangeSet {
public NullChangeSet(World world) { public NullChangeSet(World world) {
super(world); super(world);
} }

View File

@ -63,10 +63,12 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
public boolean perform(final Player player, LocalSession session, boolean rightClick) { public boolean perform(final Player player, LocalSession session, boolean rightClick) {
if (!session.isToolControlEnabled() || !player.hasPermission("worldedit.tool.inspect")) { if (!session.isToolControlEnabled() || !player.hasPermission("worldedit.tool.inspect")) {
player.print(Caption.of("", "worldedit.tool.inspect")); player.print(Caption.of("", "worldedit.tool.inspect"));
System.out.println("No tool control");
return false; return false;
} }
if (!Settings.IMP.HISTORY.USE_DATABASE) { if (!Settings.IMP.HISTORY.USE_DATABASE) {
player.print(Caption.of("fawe.error.setting.disable", ("history.use-database (Import with /history import )"))); player.print(Caption.of("fawe.error.setting.disable", ("history.use-database (Import with /history import )")));
System.out.println("No db");
return false; return false;
} }
try { try {
@ -76,14 +78,17 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
final int z = target.getBlockZ(); final int z = target.getBlockZ();
World world = player.getWorld(); World world = player.getWorld();
RollbackDatabase db = DBHandler.IMP.getDatabase(world); RollbackDatabase db = DBHandler.IMP.getDatabase(world);
System.out.println("World " + world.getName());
int count = 0; int count = 0;
for (Supplier<RollbackOptimizedHistory> supplier : db.getEdits(target, false)) { for (Supplier<RollbackOptimizedHistory> supplier : db.getEdits(target, false)) {
System.out.println("History " + db);
count++; count++;
RollbackOptimizedHistory edit = supplier.get(); RollbackOptimizedHistory edit = supplier.get();
Iterator<MutableFullBlockChange> iter = edit.getFullBlockIterator(null, 0, false); Iterator<MutableFullBlockChange> iter = edit.getFullBlockIterator(null, 0, false);
while (iter.hasNext()) { while (iter.hasNext()) {
MutableFullBlockChange change = iter.next(); MutableFullBlockChange change = iter.next();
if (change.x != x || change.y != y || change.z != z) { if (change.x != x || change.y != y || change.z != z) {
System.out.println("Not pos " + change.x + "," + change.y + "," + change.z + " | " + x + "," + y + "," + z);
continue; continue;
} }
int from = change.from; int from = change.from;
@ -107,7 +112,10 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
} }
player.print(Caption.of("fawe.worldedit.tool.tool.inspect.info.footer" , count)); player.print(Caption.of("fawe.worldedit.tool.tool.inspect.info.footer" , count));
} catch (IOException e) { } catch (IOException e) {
System.out.println("IOE");
throw new RuntimeException(e); throw new RuntimeException(e);
} catch (Throwable e) {
System.out.println("E throw");
} }
return true; return true;
} }

View File

@ -16,13 +16,12 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.UUID;
import java.util.concurrent.Future; import java.util.concurrent.Future;
public class AbstractDelegateChangeSet extends FaweChangeSet { public class AbstractDelegateChangeSet extends AbstractChangeSet {
public final FaweChangeSet parent; public final AbstractChangeSet parent;
public AbstractDelegateChangeSet(FaweChangeSet parent) { public AbstractDelegateChangeSet(AbstractChangeSet parent) {
super(parent.getWorld()); super(parent.getWorld());
this.parent = parent; this.parent = parent;
this.waitingCombined = parent.waitingCombined; this.waitingCombined = parent.waitingCombined;
@ -44,7 +43,7 @@ public class AbstractDelegateChangeSet extends FaweChangeSet {
parent.close(); parent.close();
} }
public final FaweChangeSet getParent() { public final AbstractChangeSet getParent() {
return parent; return parent;
} }

View File

@ -1,7 +1,6 @@
package com.boydti.fawe.object.changeset; package com.boydti.fawe.object.changeset;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
@ -24,7 +23,7 @@ public class BlockBagChangeSet extends AbstractDelegateChangeSet {
private int[] missingBlocks = new int[BlockTypes.size()]; private int[] missingBlocks = new int[BlockTypes.size()];
private BlockBag blockBag; private BlockBag blockBag;
public BlockBagChangeSet(FaweChangeSet parent, BlockBag blockBag, boolean mine) { public BlockBagChangeSet(AbstractChangeSet parent, BlockBag blockBag, boolean mine) {
super(parent); super(parent);
this.blockBag = blockBag; this.blockBag = blockBag;
this.mine = mine; this.mine = mine;

View File

@ -14,7 +14,7 @@ import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.UUID; import java.util.UUID;
public class CFIChangeSet extends FaweChangeSet { public class CFIChangeSet extends AbstractChangeSet {
private final File file; private final File file;

View File

@ -7,30 +7,20 @@ import com.boydti.fawe.database.RollbackDatabase;
import com.boydti.fawe.object.FaweInputStream; import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.IntegerPair; import com.boydti.fawe.object.IntegerPair;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.change.MutableFullBlockChange; import com.boydti.fawe.object.change.MutableFullBlockChange;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
/** /**
@ -405,15 +395,15 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
return new NBTInputStream(MainUtil.getCompressedIS(new FileInputStream(nbtfFile))); return new NBTInputStream(MainUtil.getCompressedIS(new FileInputStream(nbtfFile)));
} }
protected DiskStorageSummary summarizeShallow() { protected SimpleChangeSetSummary summarizeShallow() {
return new DiskStorageSummary(getOriginX(), getOriginZ()); return new SimpleChangeSetSummary(getOriginX(), getOriginZ());
} }
public DiskStorageSummary summarize(Region region, boolean shallow) { public SimpleChangeSetSummary summarize(Region region, boolean shallow) {
if (bdFile.exists()) { if (bdFile.exists()) {
int ox = getOriginX(); int ox = getOriginX();
int oz = getOriginZ(); int oz = getOriginZ();
DiskStorageSummary summary = summarizeShallow(); SimpleChangeSetSummary summary = summarizeShallow();
if (region != null && !region.contains(ox, oz)) { if (region != null && !region.contains(ox, oz)) {
return summary; return summary;
} }
@ -459,79 +449,6 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
return new IntegerPair(ox, oz); return new IntegerPair(ox, oz);
} }
public static class DiskStorageSummary {
public int[] blocks;
public int minX;
public int minZ;
public int maxX;
public int maxZ;
public DiskStorageSummary(int x, int z) {
blocks = new int[BlockTypesCache.states.length];
minX = x;
maxX = x;
minZ = z;
maxZ = z;
}
public void add(int x, int z, int id) {
blocks[id]++;
if (x < minX) {
minX = x;
} else if (x > maxX) {
maxX = x;
}
if (z < minZ) {
minZ = z;
} else if (z > maxZ) {
maxZ = z;
}
}
public Map<BlockState, Integer> getBlocks() {
HashMap<BlockState, Integer> map = new HashMap<>();
for (int i = 0; i < blocks.length; i++) {
if (blocks[i] != 0) {
BlockState state = BlockTypesCache.states[i];
map.put(state, blocks[i]);
}
}
return map;
}
public List<Countable<BlockState>> getBlockDistributionWithData() {
ArrayList<Countable<BlockState>> list = new ArrayList<>();
for (Map.Entry<BlockState, Integer> entry : getBlocks().entrySet()) {
list.add(new Countable<>(entry.getKey(), entry.getValue()));
}
return list;
}
public Map<BlockState, Double> getPercents() {
Map<BlockState, Integer> map = getBlocks();
int count = getSize();
Map<BlockState, Double> newMap = new HashMap<>();
for (Map.Entry<BlockState, Integer> entry : map.entrySet()) {
BlockState id = entry.getKey();
int changes = entry.getValue();
double percent = (changes * 1000L / count) / 10d;
newMap.put(id, percent);
}
return newMap;
}
public int getSize() {
int count = 0;
for (int block : blocks) {
count += block;
}
return count;
}
}
@Override @Override
public boolean isRecordingChanges() { public boolean isRecordingChanges() {
// TODO Auto-generated method stub // TODO Auto-generated method stub

View File

@ -27,7 +27,7 @@ import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
public abstract class FaweStreamChangeSet extends FaweChangeSet { public abstract class FaweStreamChangeSet extends AbstractChangeSet {
public static final int HEADER_SIZE = 9; public static final int HEADER_SIZE = 9;
private int mode; private int mode;

View File

@ -40,11 +40,13 @@ public class YieldIterable<T> implements Iterable<T>, Consumer<T>, Closeable {
buffer = queue.poll(50, TimeUnit.MILLISECONDS); buffer = queue.poll(50, TimeUnit.MILLISECONDS);
if (buffer == END_MARKER) { if (buffer == END_MARKER) {
interrupted = true; interrupted = true;
buffer = null;
return false; return false;
} }
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
interrupted = true; interrupted = true;
buffer = null;
} }
return buffer != null; return buffer != null;
} }

View File

@ -21,7 +21,7 @@ import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.brush.visualization.VirtualWorld; import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.object.changeset.BlockBagChangeSet; import com.boydti.fawe.object.changeset.BlockBagChangeSet;
import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory; import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
import com.boydti.fawe.object.extent.FaweRegionExtent; import com.boydti.fawe.object.extent.FaweRegionExtent;
import com.boydti.fawe.object.extent.MultiRegionExtent; import com.boydti.fawe.object.extent.MultiRegionExtent;
@ -49,7 +49,7 @@ public class EditSessionBuilder {
private String worldName; private String worldName;
private Player player; private Player player;
private FaweLimit limit; private FaweLimit limit;
private FaweChangeSet changeSet; private AbstractChangeSet changeSet;
private Region[] allowedRegions; private Region[] allowedRegions;
private Boolean autoQueue; private Boolean autoQueue;
private Boolean fastmode; private Boolean fastmode;
@ -116,7 +116,7 @@ public class EditSessionBuilder {
return setDirty(); return setDirty();
} }
public EditSessionBuilder changeSet(@Nullable FaweChangeSet changeSet) { public EditSessionBuilder changeSet(@Nullable AbstractChangeSet changeSet) {
this.changeSet = changeSet; this.changeSet = changeSet;
return setDirty(); return setDirty();
} }
@ -265,7 +265,7 @@ public class EditSessionBuilder {
return extent; return extent;
} }
private FaweChangeSet changeTask; private AbstractChangeSet changeTask;
private int maxY; private int maxY;
private Extent bypassHistory; private Extent bypassHistory;
private Extent bypassAll; private Extent bypassAll;
@ -493,7 +493,7 @@ public class EditSessionBuilder {
return player; return player;
} }
public FaweChangeSet getChangeTask() { public AbstractChangeSet getChangeTask() {
return changeTask; return changeTask;
} }

View File

@ -58,6 +58,17 @@ public class StringMan {
return -1; return -1;
} }
public static String humanReadableByteCountBin(long bytes) {
long b = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
return b < 1024L ? bytes + " B"
: b <= 0xfffccccccccccccL >> 40 ? String.format("%.1f KiB", bytes / 0x1p10)
: b <= 0xfffccccccccccccL >> 30 ? String.format("%.1f MiB", bytes / 0x1p20)
: b <= 0xfffccccccccccccL >> 20 ? String.format("%.1f GiB", bytes / 0x1p30)
: b <= 0xfffccccccccccccL >> 10 ? String.format("%.1f TiB", bytes / 0x1p40)
: b <= 0xfffccccccccccccL ? String.format("%.1f PiB", (bytes >> 10) / 0x1p40)
: String.format("%.1f EiB", (bytes >> 20) / 0x1p40);
}
public static String prettyFormat(double d) { public static String prettyFormat(double d) {
if (d == Double.MIN_VALUE || d == Double.NEGATIVE_INFINITY) return "-∞"; if (d == Double.MIN_VALUE || d == Double.NEGATIVE_INFINITY) return "-∞";
if (d == Double.MAX_VALUE || d == Double.POSITIVE_INFINITY) return ""; if (d == Double.MAX_VALUE || d == Double.POSITIVE_INFINITY) return "";

View File

@ -32,7 +32,7 @@ import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.changeset.BlockBagChangeSet; import com.boydti.fawe.object.changeset.BlockBagChangeSet;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.boydti.fawe.object.collection.LocalBlockVectorSet; import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.boydti.fawe.object.extent.FaweRegionExtent; import com.boydti.fawe.object.extent.FaweRegionExtent;
import com.boydti.fawe.object.extent.ProcessedWEExtent; import com.boydti.fawe.object.extent.ProcessedWEExtent;
@ -198,7 +198,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
private final FaweLimit originalLimit; private final FaweLimit originalLimit;
private final FaweLimit limit; private final FaweLimit limit;
private final Player player; private final Player player;
private FaweChangeSet changeSet; private AbstractChangeSet changeSet;
private boolean history; private boolean history;
private final MutableBlockVector3 mutablebv = new MutableBlockVector3(); private final MutableBlockVector3 mutablebv = new MutableBlockVector3();
@ -212,11 +212,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
private final int maxY; private final int maxY;
@Deprecated @Deprecated
public EditSession(@NotNull World world, @Nullable Player 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) { public EditSession(@NotNull World world, @Nullable Player player, @Nullable FaweLimit limit, @Nullable AbstractChangeSet 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(null, world, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, bus, event); this(null, world, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, bus, event);
} }
public EditSession(@Nullable String worldName, @Nullable World world, @Nullable Player player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable Region[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) { public EditSession(@Nullable String worldName, @Nullable World world, @Nullable Player player, @Nullable FaweLimit limit, @Nullable AbstractChangeSet changeSet, @Nullable Region[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
this(new EditSessionBuilder(world, worldName).player(player).limit(limit).changeSet(changeSet).allowedRegions(allowedRegions).autoQueue(autoQueue).fastmode(fastmode).checkMemory(checkMemory).combineStages(combineStages).blockBag(blockBag).eventBus(bus).event(event)); this(new EditSessionBuilder(world, worldName).player(player).limit(limit).changeSet(changeSet).allowedRegions(allowedRegions).autoQueue(autoQueue).fastmode(fastmode).checkMemory(checkMemory).combineStages(combineStages).blockBag(blockBag).eventBus(bus).event(event));
} }
@ -393,7 +393,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* Used internally to set the ChangeSet during completion to record custom changes which aren't normally recorded * Used internally to set the ChangeSet during completion to record custom changes which aren't normally recorded
* @param set * @param set
*/ */
public void setRawChangeSet(@Nullable FaweChangeSet set) { public void setRawChangeSet(@Nullable AbstractChangeSet set) {
changeSet = set; changeSet = set;
changes++; changes++;
} }
@ -999,10 +999,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
// Enqueue it // Enqueue it
if (getChangeSet() != null) { if (getChangeSet() != null) {
if (Settings.IMP.HISTORY.COMBINE_STAGES) { if (Settings.IMP.HISTORY.COMBINE_STAGES) {
((FaweChangeSet) getChangeSet()).closeAsync(); ((AbstractChangeSet) getChangeSet()).closeAsync();
} else { } else {
try { try {
((FaweChangeSet) getChangeSet()).close(); ((AbstractChangeSet) getChangeSet()).close();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -2794,7 +2794,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
public boolean regenerate(Region region, BiomeType biome, Long seed) { public boolean regenerate(Region region, BiomeType biome, Long seed) {
//TODO Optimize - avoid Vector2D creation (make mutable) //TODO Optimize - avoid Vector2D creation (make mutable)
final FaweChangeSet fcs = (FaweChangeSet) this.getChangeSet(); final AbstractChangeSet fcs = (AbstractChangeSet) this.getChangeSet();
this.setChangeSet(null); this.setChangeSet(null);
final FaweRegionExtent fe = this.getRegionExtent(); final FaweRegionExtent fe = this.getRegionExtent();
final boolean cuboid = region instanceof CuboidRegion; final boolean cuboid = region instanceof CuboidRegion;

View File

@ -28,7 +28,6 @@ import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.brush.visualization.VirtualWorld; import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.clipboard.MultiClipboardHolder; import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
import com.boydti.fawe.object.collection.SparseBitSet; import com.boydti.fawe.object.collection.SparseBitSet;
import com.boydti.fawe.object.extent.ResettableExtent; import com.boydti.fawe.object.extent.ResettableExtent;
@ -39,6 +38,8 @@ import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.TextureHolder; import com.boydti.fawe.util.TextureHolder;
import com.boydti.fawe.util.TextureUtil; import com.boydti.fawe.util.TextureUtil;
import com.boydti.fawe.wrappers.WorldWrapper; import com.boydti.fawe.wrappers.WorldWrapper;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.sk89q.jchronic.Chronic; import com.sk89q.jchronic.Chronic;
import com.sk89q.jchronic.Options; import com.sk89q.jchronic.Options;
import com.sk89q.jchronic.utils.Span; import com.sk89q.jchronic.utils.Span;
@ -153,7 +154,7 @@ public class LocalSession implements TextureHolder {
private transient VirtualWorld virtual; private transient VirtualWorld virtual;
private transient BlockVector3 cuiTemporaryBlock; private transient BlockVector3 cuiTemporaryBlock;
private transient List<Countable<BlockState>> lastDistribution; private transient List<Countable> lastDistribution;
private transient World worldOverride; private transient World worldOverride;
private transient boolean tickingWatchdog = false; private transient boolean tickingWatchdog = false;
@ -331,6 +332,10 @@ public class LocalSession implements TextureHolder {
return (historyNegativeIndex == null ? historyNegativeIndex = 0 : historyNegativeIndex); return (historyNegativeIndex == null ? historyNegativeIndex = 0 : historyNegativeIndex);
} }
public List<ChangeSet> getHistory() {
return Lists.transform(history, this::getChangeSet);
}
public boolean save() { public boolean save() {
saveHistoryNegativeIndex(uuid, currentWorld); saveHistoryNegativeIndex(uuid, currentWorld);
if (defaultSelector == RegionSelectorType.CUBOID) { if (defaultSelector == RegionSelectorType.CUBOID) {
@ -395,9 +400,9 @@ public class LocalSession implements TextureHolder {
remember(editSession, true, limit); remember(editSession, true, limit);
} }
private FaweChangeSet getChangeSet(Object o) { private ChangeSet getChangeSet(Object o) {
if (o instanceof FaweChangeSet) { if (o instanceof ChangeSet) {
FaweChangeSet cs = (FaweChangeSet) o; ChangeSet cs = (ChangeSet) o;
try { try {
cs.close(); cs.close();
} catch (IOException e) { } catch (IOException e) {
@ -427,16 +432,16 @@ public class LocalSession implements TextureHolder {
return; return;
} }
loadSessionHistoryFromDisk(player.getUniqueId(), world); loadSessionHistoryFromDisk(player.getUniqueId(), world);
if (changeSet instanceof FaweChangeSet) { if (changeSet instanceof ChangeSet) {
ListIterator<Object> iter = history.listIterator(); ListIterator<Object> iter = history.listIterator();
int i = 0; int i = 0;
int cutoffIndex = history.size() - getHistoryNegativeIndex(); int cutoffIndex = history.size() - getHistoryNegativeIndex();
while (iter.hasNext()) { while (iter.hasNext()) {
Object item = iter.next(); Object item = iter.next();
if (++i > cutoffIndex) { if (++i > cutoffIndex) {
FaweChangeSet oldChangeSet; ChangeSet oldChangeSet;
if (item instanceof FaweChangeSet) { if (item instanceof ChangeSet) {
oldChangeSet = (FaweChangeSet) item; oldChangeSet = (ChangeSet) item;
} else { } else {
oldChangeSet = getChangeSet(item); oldChangeSet = getChangeSet(item);
} }
@ -454,7 +459,7 @@ public class LocalSession implements TextureHolder {
if (limit != null) { if (limit != null) {
int limitMb = limit.MAX_HISTORY; int limitMb = limit.MAX_HISTORY;
while (((!Settings.IMP.HISTORY.USE_DISK && history.size() > MAX_HISTORY_SIZE) || (historySize >> 20) > limitMb) && history.size() > 1) { while (((!Settings.IMP.HISTORY.USE_DISK && history.size() > MAX_HISTORY_SIZE) || (historySize >> 20) > limitMb) && history.size() > 1) {
FaweChangeSet item = (FaweChangeSet) history.remove(0); ChangeSet item = (ChangeSet) history.remove(0);
item.delete(); item.delete();
long size = MainUtil.getSize(item); long size = MainUtil.getSize(item);
historySize -= size; historySize -= size;
@ -478,7 +483,7 @@ public class LocalSession implements TextureHolder {
} }
*/ */
FaweChangeSet changeSet = (FaweChangeSet) editSession.getChangeSet(); ChangeSet changeSet = editSession.getChangeSet();
if (changeSet.isEmpty()) { if (changeSet.isEmpty()) {
return; return;
} }
@ -495,9 +500,9 @@ public class LocalSession implements TextureHolder {
while (iter.hasNext()) { while (iter.hasNext()) {
Object item = iter.next(); Object item = iter.next();
if (++i > cutoffIndex) { if (++i > cutoffIndex) {
FaweChangeSet oldChangeSet; ChangeSet oldChangeSet;
if (item instanceof FaweChangeSet) { if (item instanceof ChangeSet) {
oldChangeSet = (FaweChangeSet) item; oldChangeSet = (ChangeSet) item;
} else { } else {
oldChangeSet = getChangeSet(item); oldChangeSet = getChangeSet(item);
} }
@ -518,7 +523,7 @@ public class LocalSession implements TextureHolder {
history.add(0, changeSet); history.add(0, changeSet);
} }
while (((!Settings.IMP.HISTORY.USE_DISK && history.size() > MAX_HISTORY_SIZE) || (historySize >> 20) > limitMb) && history.size() > 1) { while (((!Settings.IMP.HISTORY.USE_DISK && history.size() > MAX_HISTORY_SIZE) || (historySize >> 20) > limitMb) && history.size() > 1) {
FaweChangeSet item = (FaweChangeSet) history.remove(0); ChangeSet item = (ChangeSet) history.remove(0);
item.delete(); item.delete();
long size = MainUtil.getSize(item); long size = MainUtil.getSize(item);
historySize -= size; historySize -= size;
@ -534,10 +539,11 @@ public class LocalSession implements TextureHolder {
*/ */
public EditSession undo(@Nullable BlockBag newBlockBag, Actor actor) { public EditSession undo(@Nullable BlockBag newBlockBag, Actor actor) {
checkNotNull(actor); checkNotNull(actor);
loadSessionHistoryFromDisk(actor.getUniqueId(), ((Player) actor).getWorldForEditing()); World world = ((Player) actor).getWorldForEditing();
loadSessionHistoryFromDisk(actor.getUniqueId(), world);
if (getHistoryNegativeIndex() < history.size()) { if (getHistoryNegativeIndex() < history.size()) {
FaweChangeSet changeSet = getChangeSet(history.get(getHistoryIndex())); ChangeSet changeSet = getChangeSet(history.get(getHistoryIndex()));
try (EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld()) try (EditSession newEditSession = new EditSessionBuilder(world)
.allowedRegionsEverywhere() .allowedRegionsEverywhere()
.checkMemory(false) .checkMemory(false)
.changeSetNull() .changeSetNull()
@ -570,12 +576,13 @@ public class LocalSession implements TextureHolder {
*/ */
public EditSession redo(@Nullable BlockBag newBlockBag, Actor actor) { public EditSession redo(@Nullable BlockBag newBlockBag, Actor actor) {
checkNotNull(actor); checkNotNull(actor);
loadSessionHistoryFromDisk(actor.getUniqueId(), ((Player)actor).getWorldForEditing()); World world = ((Player) actor).getWorldForEditing();
loadSessionHistoryFromDisk(actor.getUniqueId(), world);
if (getHistoryNegativeIndex() > 0) { if (getHistoryNegativeIndex() > 0) {
setDirty(); setDirty();
historyNegativeIndex--; historyNegativeIndex--;
FaweChangeSet changeSet = getChangeSet(history.get(getHistoryIndex())); ChangeSet changeSet = getChangeSet(history.get(getHistoryIndex()));
try (EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld()) try (EditSession newEditSession = new EditSessionBuilder(world)
.allowedRegionsEverywhere() .allowedRegionsEverywhere()
.checkMemory(false) .checkMemory(false)
.changeSetNull() .changeSetNull()
@ -1590,14 +1597,14 @@ public class LocalSession implements TextureHolder {
* *
* @return block distribution or {@code null} * @return block distribution or {@code null}
*/ */
public List<Countable<BlockState>> getLastDistribution() { public List<Countable> getLastDistribution() {
return lastDistribution == null ? null : Collections.unmodifiableList(lastDistribution); return lastDistribution == null ? null : Collections.unmodifiableList(lastDistribution);
} }
/** /**
* Store a block distribution in this session. * Store a block distribution in this session.
*/ */
public void setLastDistribution(List<Countable<BlockState>> dist) { public void setLastDistribution(List<Countable> dist) {
lastDistribution = dist; lastDistribution = dist;
} }

View File

@ -10,8 +10,8 @@ import com.boydti.fawe.database.DBHandler;
import com.boydti.fawe.database.RollbackDatabase; import com.boydti.fawe.database.RollbackDatabase;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.StringMan;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
@ -22,6 +22,7 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.annotation.Confirm; import com.sk89q.worldedit.command.util.annotation.Confirm;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.internal.annotation.AllowedRegion; import com.sk89q.worldedit.internal.annotation.AllowedRegion;
import com.sk89q.worldedit.internal.annotation.Time; import com.sk89q.worldedit.internal.annotation.Time;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
@ -32,6 +33,7 @@ import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Identifiable; import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.PaginationBox; import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
@ -46,7 +48,6 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.Command;
@ -168,7 +169,7 @@ public class HistorySubCommands {
world, uuid, world, uuid,
Integer.parseInt( Integer.parseInt(
name.substring(0, name.length() - 3))); name.substring(0, name.length() - 3)));
DiskStorageHistory.DiskStorageSummary summary = rollback SimpleChangeSetSummary summary = rollback
.summarize(RegionWrapper.GLOBAL(), false); .summarize(RegionWrapper.GLOBAL(), false);
if (summary != null) { if (summary != null) {
rollback.setDimensions( rollback.setDimensions(
@ -194,15 +195,14 @@ public class HistorySubCommands {
} }
@Command( @Command(
name = "summary", name = "info",
aliases = {"info", "summarize"}, aliases = {"summary", "summarize"},
desc = "Summarize an edit" desc = "Summarize an edit"
) )
@CommandPermissions("worldedit.history.find") @CommandPermissions("worldedit.history.info")
public synchronized void summary(Player player, RollbackDatabase database, Arguments arguments, public synchronized void summary(Player player, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name") UUID other, @Arg(desc = "Player uuid/name") UUID other,
@Arg(desc = "edit index") Integer index, @Arg(desc = "edit index") Integer index) throws WorldEditException, ExecutionException, InterruptedException {
@ArgFlag(name = 'p', desc = "Page to view.", def = "-1") int page) throws WorldEditException, ExecutionException, InterruptedException {
RollbackOptimizedHistory edit = database.getEdit(other, index).get(); RollbackOptimizedHistory edit = database.getEdit(other, index).get();
if (edit == null) { if (edit == null) {
player.print(TranslatableComponent.of("fawe.worldedit.schematic.schematic.none")); player.print(TranslatableComponent.of("fawe.worldedit.schematic.schematic.none"));
@ -226,47 +226,75 @@ public class HistorySubCommands {
String timeStr = MainUtil.secToTime(seconds); String timeStr = MainUtil.secToTime(seconds);
int size = edit.size(); int size = edit.size();
String pageCommand = "/" + arguments.get().replaceAll("-p [0-9]+", "").trim();
List<Countable<BlockState>> list = null;
Reference<List<Countable<BlockState>>> cached = player.getMeta(pageCommand);
if (cached != null) {
list = cached.get();
}
if (list == null) {
DiskStorageHistory.DiskStorageSummary summary = edit.summarize(null, false);
if (summary != null) {
list = summary.getBlockDistributionWithData();
player.setMeta(pageCommand, new SoftReference<>(list));
}
}
boolean biomes = edit.getBioFile().exists(); boolean biomes = edit.getBioFile().exists();
boolean createdEnts = edit.getEnttFile().exists(); boolean createdEnts = edit.getEnttFile().exists();
boolean removedEnts = edit.getEntfFile().exists(); boolean removedEnts = edit.getEntfFile().exists();
boolean createdTiles = edit.getNbttFile().exists(); boolean createdTiles = edit.getNbttFile().exists();
boolean removedTiles = edit.getNbtfFile().exists(); boolean removedTiles = edit.getNbtfFile().exists();
System.out.println("TODO FIXME move to translations");
if (page == -1) { TranslatableComponent header = Caption.of("fawe.worldedit.history.find.element", name, timeStr, distance, direction.name(), cmd);
player.print("name: " + name
+ ", cmd: " + edit.getCommand() String sizeStr = StringMan.humanReadableByteCountBin(edit.getSizeOnDisk());
+ ", dist: " + distance + "m " + direction.name() String extra = "";
+ ", time: " + timeStr + " ago" if (biomes) extra += "biomes, ";
+ ", size: " + size + " blocks" if (createdEnts) extra += "+entity, ";
+ ", biomes: " + biomes if (removedEnts) extra += "-entity, ";
+ ", +entity: " + createdEnts if (createdTiles) extra += "+tile, ";
+ ", -entity: " + removedEnts if (removedTiles) extra += "-tile, ";
+ ", +tile: " + createdTiles
+ ", -tile: " + removedTiles TranslatableComponent body = Caption.of("fawe.worldedit.history.find.element.more", size, edit.getMinimumPoint(), edit.getMaximumPoint(), extra.trim(), sizeStr);
+ ", disk: " + (edit.getSizeOnDisk() / 1000) + "mb" Component distr = TextComponent.of("/history distr").clickEvent(ClickEvent.suggestCommand("//history distr " + other + " " + index));
+ ", min " + edit.getMinimumPoint() TextComponentProducer content = new TextComponentProducer().append(header).newline().append(body).newline().append(distr);
+ ", max " + edit.getMaximumPoint() player.print(content.create());
); }
}
page = 1; private void list(RollbackDatabase database, String pageCommand, List<? extends ChangeSet> histories, BlockVector3 origin) {
if (list != null) { return PaginationBox.fromStrings("Edits:", pageCommand, histories, new Function<Supplier<? extends ChangeSet>, Component>() {
SelectionCommands.BlockDistributionResult pages = new SelectionCommands.BlockDistributionResult((List) list, true, pageCommand); @NotNull
player.print(pages.create(page)); @Override
} public Component apply(@Nullable Supplier<? extends ChangeSet> input) {
ChangeSet edit = input.get();
if (edit instanceof RollbackOptimizedHistory) {
RollbackOptimizedHistory rollback = (RollbackOptimizedHistory) edit;
UUID uuid = rollback.getUUID();
int index = rollback.getIndex();
String name = Fawe.imp().getName(rollback.getUUID());
String cmd = rollback.getCommand();
BlockVector3 pos1 = rollback.getMinimumPoint();
BlockVector3 pos2 = rollback.getMaximumPoint();
double distanceX = Math.min(Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX()));
double distanceZ = Math.min(Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ()));
int distance = (int) Math.sqrt(distanceX * distanceX + distanceZ * distanceZ);
BlockVector2 dirVec = BlockVector2.at(rollback.getOriginX() - origin.getX(), rollback.getOriginZ() - origin.getZ());
Direction direction = Direction.findClosest(dirVec.toVector3(), Direction.Flag.ALL);
long seconds = (System.currentTimeMillis() - rollback.getBDFile().lastModified()) / 1000;
String timeStr = MainUtil.secToTime(seconds);
int size = edit.size();
TranslatableComponent elem = Caption.of("fawe.worldedit.history.find.element", name, timeStr, distance, direction.name(), cmd);
String infoCmd = "//history summary " + uuid + " " + index;
TranslatableComponent hover = Caption.of("fawe.worldedit.history.find.hover", size);
elem = elem.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hover));
elem = elem.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, infoCmd));
return elem;
} else {
}
System.out.println(" - return elem");
return elem;
}
});
} }
@Command( @Command(
@ -276,28 +304,26 @@ public class HistorySubCommands {
) )
@CommandPermissions("worldedit.history.find") @CommandPermissions("worldedit.history.find")
public synchronized void find(Player player, World world, RollbackDatabase database, Arguments arguments, public synchronized void find(Player player, World world, RollbackDatabase database, Arguments arguments,
@ArgFlag(name = 'u', desc = "String user") UUID other, @ArgFlag(name = 'u', def="", desc = "String user") UUID other,
@ArgFlag(name = 'r', def = "0", desc = "radius") @ArgFlag(name = 'r', def = "0", desc = "radius")
@Range(from = 0, to = Integer.MAX_VALUE) int radius, @Range(from = 0, to = Integer.MAX_VALUE) Integer radius,
@ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0") @ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0")
@Time long timeDiff, @Time Long timeDiff,
@ArgFlag(name = 'p', desc = "Page to view.", def = "1") int page) throws WorldEditException { @ArgFlag(name = 'p', desc = "Page to view.", def = "") Integer page) throws WorldEditException {
if (!Settings.IMP.HISTORY.USE_DATABASE) { if (!Settings.IMP.HISTORY.USE_DATABASE) {
player.print(Caption.of("fawe.error.setting.disable" , "history.use-database (Import with //history import )")); player.print(Caption.of("fawe.error.setting.disable" , "history.use-database (Import with //history import )"));
return; return;
} }
if (other == null && radius == 0 && timeDiff == 0) throw new InsufficientArgumentsException("User must be provided");
checkCommandArgument(radius > 0, "Radius must be >= 0"); checkCommandArgument(radius > 0, "Radius must be >= 0");
checkCommandArgument(timeDiff > 0, "Time must be >= 0"); checkCommandArgument(timeDiff > 0, "Time must be >= 0");
Location origin = player.getLocation(); Location origin = player.getLocation();
String pageCommand = "/" + arguments.get().replaceAll("-p [0-9]+", "").trim(); String pageCommand = "/" + arguments.get().replaceAll("-p [0-9]+", "").trim();
Reference<List<Supplier<? extends ChangeSet>>> cached = player.getMeta(pageCommand);
List<Supplier<? extends ChangeSet>> history = cached == null ? null : cached.get();
List<Supplier<RollbackOptimizedHistory>> list = null; if (page == null || history == null) {
Reference<List<Supplier<RollbackOptimizedHistory>>> cached = player.getMeta(pageCommand);
if (cached != null) {
list = cached.get();
}
if (list == null) {
if (other == null) other = player.getUniqueId(); if (other == null) other = player.getUniqueId();
if (!other.equals(player.getUniqueId())) { if (!other.equals(player.getUniqueId())) {
player.checkPermission("worldedit.history.undo.other"); player.checkPermission("worldedit.history.undo.other");
@ -309,56 +335,59 @@ public class HistorySubCommands {
bot = bot.clampY(0, world.getMaxY()); bot = bot.clampY(0, world.getMaxY());
top = top.clampY(0, world.getMaxY()); top = top.clampY(0, world.getMaxY());
LongAdder total = new LongAdder();
long minTime = System.currentTimeMillis() - timeDiff; long minTime = System.currentTimeMillis() - timeDiff;
Iterable<Supplier<RollbackOptimizedHistory>> edits = database.getEdits(other, minTime, bot, top, false, false); Iterable<Supplier<RollbackOptimizedHistory>> edits = database.getEdits(other, minTime, bot, top, false, false);
list = Lists.newArrayList(edits); history = Lists.newArrayList(edits);
player.setMeta(pageCommand, new SoftReference<>(list)); player.setMeta(pageCommand, new SoftReference<>(history));
page = 1;
} }
PaginationBox pages = PaginationBox.fromStrings("Edits:", pageCommand, list, new Function<Supplier<RollbackOptimizedHistory>, Component>() {
@NotNull
@Override
public Component apply(@Nullable Supplier<RollbackOptimizedHistory> input) {
RollbackOptimizedHistory edit = input.get();
UUID uuid = edit.getUUID();
int index = edit.getIndex();
if (!edit.isEmpty()) {
database.delete(uuid, index);
return TextComponent.empty();
}
String name = Fawe.imp().getName(edit.getUUID());
String cmd = edit.getCommand();
BlockVector3 pos1 = edit.getMinimumPoint();
BlockVector3 pos2 = edit.getMaximumPoint();
double distanceX = Math.min(Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX()));
double distanceZ = Math.min(Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ()));
int distance = (int) Math.sqrt(distanceX * distanceX + distanceZ * distanceZ);
BlockVector2 dirVec = BlockVector2.at(edit.getOriginX() - origin.getX(), edit.getOriginZ() - origin.getZ());
Direction direction = Direction.findClosest(dirVec.toVector3(), Direction.Flag.ALL);
long seconds = (System.currentTimeMillis() - edit.getBDFile().lastModified()) / 1000;
String timeStr = MainUtil.secToTime(seconds);
int size = edit.size();
TranslatableComponent elem = Caption.of("fawe.worldedit.history.find.element", name, timeStr, distance, direction.name(), cmd);
String infoCmd = "//history summary " + uuid + " " + index;
TranslatableComponent hover = Caption.of("fawe.worldedit.history.find.hover", size);
elem = elem.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hover));
elem = elem.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, infoCmd));
return elem;
}
});
player.print(pages.create(page)); player.print(pages.create(page));
} }
@Command(
name = "distr",
aliases = {"distribution"},
desc = "View block distribution for an edit"
)
@CommandPermissions("worldedit.history.distr")
public void distr(Player player, LocalSession session, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name") UUID other,
@Arg(desc = "edit index") Integer index,
@ArgFlag(name = 'p', desc = "Page to view.", def = "") Integer page) throws ExecutionException, InterruptedException {
String pageCommand = "/" + arguments.get().replaceAll("-p [0-9]+", "").trim();
Reference<PaginationBox> cached = player.getMeta(pageCommand);
PaginationBox pages = cached == null ? null : cached.get();
if (page == null || pages == null) {
RollbackOptimizedHistory edit = database.getEdit(other, index).get();
SimpleChangeSetSummary summary = edit.summarize(null, false);
if (summary != null) {
List<Countable<BlockState>> distr = summary.getBlockDistributionWithData();
SelectionCommands.BlockDistributionResult distrPages = new SelectionCommands.BlockDistributionResult((List) distr, true, pageCommand);
pages = new PaginationBox.MergedPaginationBox("Block Distribution", pageCommand, pages, distrPages);
player.setMeta(pageCommand, new SoftReference<>(pages));
}
page = 1;
}
player.print(pages.create(page));
}
@Command(
name = "list",
desc = "List your history"
)
@CommandPermissions("worldedit.history.list")
public void list(Actor actor, LocalSession session,
@Arg(desc = "Player uuid/name") UUID other,
@ArgFlag(name = 'p', desc = "Page to view.", def = "") Integer page) {
int index = session.getHistoryIndex();
List<ChangeSet> history = session.getHistory();
// index
}
@Command( @Command(
name = "clear", name = "clear",
desc = "Clear your history" desc = "Clear your history"

View File

@ -25,6 +25,10 @@ import com.google.common.base.Strings;
import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION; import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION; import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.block.BlockDistributionCounter;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.boydti.fawe.object.clipboard.URIClipboardHolder; import com.boydti.fawe.object.clipboard.URIClipboardHolder;
import com.boydti.fawe.object.mask.IdMask; import com.boydti.fawe.object.mask.IdMask;
@ -530,25 +534,34 @@ public class SelectionCommands {
boolean clipboardDistr, boolean clipboardDistr,
@Switch(name = 'd', desc = "Separate blocks by state") @Switch(name = 'd', desc = "Separate blocks by state")
boolean separateStates, boolean separateStates,
@ArgFlag(name = 'p', desc = "Gets page from a previous distribution.", def = "1") @ArgFlag(name = 'p', desc = "Gets page from a previous distribution.", def = "")
Integer page) throws WorldEditException { Integer page) throws WorldEditException {
List<Countable> distribution; List<Countable> distribution;
Region region; Region region;
if (clipboardDistr) { if (page == null) {
// TODO multi clipboard distribution Extent extent;
Clipboard clipboard = session.getClipboard().getClipboard(); // throws if missing if (clipboardDistr) {
region = clipboard.getRegion(); Clipboard clipboard = session.getClipboard().getClipboard(); // throws if missing
new ExtentTraverser<AbstractDelegateExtent>(editSession).setNext(new AbstractDelegateExtent(clipboard)); extent = clipboard;
region = clipboard.getRegion();
} else {
extent = editSession;
region = session.getSelection(world);
}
if (separateStates)
distribution = (List) extent.getBlockDistributionWithData(region);
else
distribution = (List) extent.getBlockDistribution(region);
session.setLastDistribution(distribution);
page = 1;
} else { } else {
region = session.getSelection(world); distribution = (List) session.getLastDistribution();
if (distribution == null) {
actor.printError(TranslatableComponent.of("worldedit.distr.no-previous"));
return;
}
} }
if (separateStates)
distribution = (List) editSession.getBlockDistributionWithData(region);
else
distribution = (List) editSession.getBlockDistribution(region);
if (distribution.isEmpty()) { // *Should* always be false if (distribution.isEmpty()) { // *Should* always be false
actor.printError(TranslatableComponent.of("worldedit.distr.no-blocks")); actor.printError(TranslatableComponent.of("worldedit.distr.no-blocks"));
return; return;

View File

@ -24,11 +24,10 @@ import static org.slf4j.LoggerFactory.getLogger;
import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.beta.IBatchProcessor;
import com.boydti.fawe.object.HistoryExtent; import com.boydti.fawe.object.HistoryExtent;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.extent.LightingExtent; import com.boydti.fawe.object.extent.LightingExtent;
import com.boydti.fawe.util.ExtentTraverser; import com.boydti.fawe.util.ExtentTraverser;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
@ -116,7 +115,7 @@ public class AbstractDelegateExtent implements Extent, LightingExtent {
/* /*
History History
*/ */
public void setChangeSet(FaweChangeSet changeSet) { public void setChangeSet(AbstractChangeSet changeSet) {
if (extent instanceof HistoryExtent) { if (extent instanceof HistoryExtent) {
HistoryExtent history = ((HistoryExtent) extent); HistoryExtent history = ((HistoryExtent) extent);
if (changeSet == null) { if (changeSet == null) {

View File

@ -25,7 +25,7 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock; import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.beta.IBatchProcessor;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.boydti.fawe.object.clipboard.WorldCopyClipboard; import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.object.extent.NullExtent;
@ -34,7 +34,6 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.RegionMaskingFilter; import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.BlockReplace;
@ -659,7 +658,7 @@ public interface Extent extends InputExtent, OutputExtent {
return processor.construct(this); return processor.construct(this);
} }
default Extent enableHistory(FaweChangeSet changeSet) { default Extent enableHistory(AbstractChangeSet changeSet) {
return addProcessor(changeSet); return addProcessor(changeSet);
} }

View File

@ -2,11 +2,10 @@ package com.sk89q.worldedit.extent;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.beta.IBatchProcessor;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.generator.GenBase; import com.sk89q.worldedit.function.generator.GenBase;
import com.sk89q.worldedit.function.generator.Resource; import com.sk89q.worldedit.function.generator.Resource;
@ -221,7 +220,7 @@ public class PassthroughExtent extends AbstractDelegateExtent {
return super.addProcessor(processor); return super.addProcessor(processor);
} }
public Extent enableHistory(FaweChangeSet changeSet) { public Extent enableHistory(AbstractChangeSet changeSet) {
return super.enableHistory(changeSet); return super.enableHistory(changeSet);
} }

View File

@ -105,16 +105,27 @@ public class BlockTransformExtent extends ResettableExtent {
private static long combine(Direction... directions) { private static long combine(Direction... directions) {
return Arrays.stream(directions).mapToLong(dir -> (1L << dir.ordinal())) long mask = 0;
.reduce(0, (a, b) -> a | b); for (Direction dir : directions) {
mask = mask | (1L << dir.ordinal());
}
return mask;
} }
private static long[] adapt(Direction... dirs) { private static long[] adapt(Direction... dirs) {
return Arrays.stream(dirs).mapToLong(dir -> 1L << dir.ordinal()).toArray(); long[] arr = new long[dirs.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = 1L << dirs[i].ordinal();
}
return arr;
} }
private static long[] adapt(Long... dirs) { private static long[] adapt(Long... dirs) {
return Arrays.stream(dirs).mapToLong(dir -> dir).toArray(); long[] arr = new long[dirs.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = dirs[i];
}
return arr;
} }
private static long[] getDirections(AbstractProperty property) { private static long[] getDirections(AbstractProperty property) {
@ -228,7 +239,9 @@ public class BlockTransformExtent extends ResettableExtent {
} }
private static long notIndex(long mask, int... indexes) { private static long notIndex(long mask, int... indexes) {
mask |= Arrays.stream(indexes).mapToLong(index -> (1L << (index + values().length))).reduce(0, (a, b) -> a | b); for (int index : indexes) {
mask = mask | (1L << (index + values().length));
}
return mask; return mask;
} }

View File

@ -21,14 +21,13 @@ package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.AbstractChangeSet;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.history.UndoContext; import com.sk89q.worldedit.history.UndoContext;
import com.sk89q.worldedit.history.change.Change; import com.sk89q.worldedit.history.change.Change;
import com.sk89q.worldedit.history.changeset.ChangeSet; import com.sk89q.worldedit.history.changeset.ChangeSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
/** /**
* Performs an undo or redo from a given {@link ChangeSet}. * Performs an undo or redo from a given {@link ChangeSet}.
@ -71,8 +70,8 @@ public class ChangeSetExecutor implements Operation {
this.type = type; this.type = type;
this.context = context; this.context = context;
if (changeSet instanceof FaweChangeSet) { if (changeSet instanceof AbstractChangeSet) {
iterator = ((FaweChangeSet) changeSet).getIterator(blockBag, inventory, type == Type.REDO); iterator = ((AbstractChangeSet) changeSet).getIterator(blockBag, inventory, type == Type.REDO);
} else if (type == Type.UNDO) { } else if (type == Type.UNDO) {
iterator = changeSet.backwardIterator(); iterator = changeSet.backwardIterator();
} else { } else {

View File

@ -19,15 +19,22 @@
package com.sk89q.worldedit.history.changeset; package com.sk89q.worldedit.history.changeset;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.history.change.Change; import com.sk89q.worldedit.history.change.Change;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
import java.io.Closeable;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
/** /**
* Tracks a set of undoable operations and allows their undo and redo. The * Tracks a set of undoable operations and allows their undo and redo. The
* entirety of a change set should be undone and redone at once. * entirety of a change set should be undone and redone at once.
*/ */
public interface ChangeSet { public interface ChangeSet extends Closeable {
/** /**
* Add the given change to the history. * Add the given change to the history.
@ -77,4 +84,38 @@ public interface ChangeSet {
*/ */
int size(); int size();
/**
* Close the changeset
*/
@Override
default void close() throws IOException {
}
/**
* Delete the changeset (e.g. files on disk, or in a database)
*/
default void delete() {}
ChangeSetSummary summarize(Region region, boolean shallow) {
return new ChangeSetSummary() {
@Override
public Map<BlockState, Integer> getBlocks() {
return Collections.emptyMap();
}
@Override
public int getSize() {
return size();
}
};
}
/**
* Get if the changeset is empty (i.e. size == 0)
* @return is empty
*/
default boolean isEmpty() {
return size() == 0;
}
} }

View File

@ -0,0 +1,37 @@
package com.sk89q.worldedit.history.changeset;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface ChangeSetSummary {
Map<BlockState, Integer> getBlocks();
int getSize();
default List<Countable<BlockState>> getBlockDistributionWithData() {
ArrayList<Countable<BlockState>> list = new ArrayList<>();
for (Map.Entry<BlockState, Integer> entry : getBlocks().entrySet()) {
list.add(new Countable<>(entry.getKey(), entry.getValue()));
}
return list;
}
default Map<BlockState, Double> getPercents() {
Map<BlockState, Integer> map = getBlocks();
int count = getSize();
Map<BlockState, Double> newMap = new HashMap<>();
for (Map.Entry<BlockState, Integer> entry : map.entrySet()) {
BlockState id = entry.getKey();
int changes = entry.getValue();
double percent = (changes * 1000L / count) / 10d;
newMap.put(id, percent);
}
return newMap;
}
}

View File

@ -71,5 +71,4 @@ public class LazyReference<T> {
refInfo.lock.unlock(); refInfo.lock.unlock();
} }
} }
} }

View File

@ -196,4 +196,34 @@ public abstract class PaginationBox extends MessageBox {
return lines.size(); return lines.size();
} }
} }
public static class MergedPaginationBox extends PaginationBox {
private final PaginationBox[] values;
public MergedPaginationBox(String header, String pageCommand, PaginationBox... values) {
super(header, pageCommand);
this.values = values;
}
@Override
public Component getComponent(int number) {
for (PaginationBox box : values) {
int size = box.getComponentsSize();
if (size > number) {
return box.getComponent(number);
}
number -= size;
}
return null;
}
@Override
public int getComponentsSize() {
int size = 0;
for (PaginationBox box : values) {
size += box.getComponentsSize();
}
return size;
}
}
} }

View File

@ -4,7 +4,8 @@
"fawe.info": "&7{0}", "fawe.info": "&7{0}",
"fawe.debug": "&3{0}", "fawe.debug": "&3{0}",
"fawe.worldedit.history.find.element": "&8 - &2{0}: {1} &7ago &3{2}m &6{3} &c/{4}", "fawe.worldedit.history.find.element": "&2{0} {1} &7ago &3{2}m &6{3} &c/{4}",
"fawe.worldedit.history.find.element.more": " - Changes: {0}\n - Bounds: {1} -> {2}\n - Extra: {3}\n - Size on Disk: {4}",
"fawe.worldedit.history.find.hover": "{0} blocks changed, click for more info", "fawe.worldedit.history.find.hover": "{0} blocks changed, click for more info",
"fawe.info.lighting.propagate.selection": "Lighting has been propagated in {0} chunks. (Note: To remove light use //removelight)", "fawe.info.lighting.propagate.selection": "Lighting has been propagated in {0} chunks. (Note: To remove light use //removelight)",