WIP VisualExtent

This commit is contained in:
Jesse Boyd 2019-11-16 00:20:14 +00:00
parent 49baebeaa3
commit 0b1a36bb7d
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
23 changed files with 339 additions and 95 deletions

View File

@ -22,7 +22,10 @@ package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket; import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.boydti.fawe.bukkit.FaweBukkit; import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14; import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14;
@ -55,6 +58,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;

View File

@ -0,0 +1,135 @@
package com.boydti.fawe.beta;
import com.boydti.fawe.FaweCache;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CombinedBlocks implements IBlocks {
private final IBlocks secondary;
private final IBlocks primary;
private final int addMask;
/**
* @param secondary
* @param primary
* @param addMask - bitMask for force sending sections, else 0 to send the primary ones
*/
public CombinedBlocks(IBlocks secondary, IBlocks primary, int addMask) {
this.secondary = secondary;
this.primary = primary;
this.addMask = addMask;
}
@Override
public int getBitMask() {
int bitMask = addMask;
for (int layer = 0; layer < FaweCache.IMP.CHUNK_LAYERS; layer++) {
if (primary.hasSection(layer)) {
bitMask |= (1 << layer);
}
}
return bitMask;
}
@Override
public boolean hasSection(int layer) {
return primary.hasSection(layer) || secondary.hasSection(layer);
}
@Override
public char[] load(int layer) {
if (primary.hasSection(layer)) {
char[] blocks = primary.load(layer);
if (secondary.hasSection(layer)) {
int i = 0;
for (; i < 4096; i++) {
if (blocks[i] == 0) {
break;
}
}
if (i != 4096) {
char[] fallback = secondary.load(layer);
for (; i < 4096; i++) {
if (blocks[i] == 0) {
blocks[i] = fallback[i];
}
}
}
}
return blocks;
}
return secondary.load(layer);
}
@Override
public BlockState getBlock(int x, int y, int z) {
BlockState block = primary.getBlock(x, y, z);
if (block == null) {
return secondary.getBlock(x, y, z);
}
return BlockTypes.__RESERVED__.getDefaultState();
}
@Override
public Map<BlockVector3, CompoundTag> getTiles() {
Map<BlockVector3, CompoundTag> tiles = primary.getTiles();
if (tiles.isEmpty()) {
return secondary.getTiles();
}
Map<BlockVector3, CompoundTag> otherTiles = secondary.getTiles();
if (!otherTiles.isEmpty()) {
HashMap<BlockVector3, CompoundTag> copy = null;
for (Map.Entry<BlockVector3, CompoundTag> entry : otherTiles.entrySet()) {
BlockVector3 pos = entry.getKey();
BlockState block = primary.getBlock(pos.getX(), pos.getY(), pos.getZ());
if (block.getBlockType() == BlockTypes.__RESERVED__) {
if (copy == null) copy = new HashMap<>(tiles);
copy.put(pos, entry.getValue());
}
}
if (copy != null) return copy;
}
return tiles;
}
@Override
public Set<CompoundTag> getEntities() {
Set<CompoundTag> ents1 = primary.getEntities();
Set<CompoundTag> ents2 = secondary.getEntities();
if (ents1.isEmpty()) return ents2;
if (ents2.isEmpty()) return ents1;
HashSet<CompoundTag> joined = new HashSet<>(ents1);
joined.addAll(ents2);
return joined;
}
@Override
public BiomeType getBiomeType(int x, int z) {
BiomeType biome = primary.getBiomeType(x, z);
if (biome == null) {
return secondary.getBiomeType(x, z);
}
return biome;
}
@Override
public IBlocks reset() {
return null;
}
@Override
public boolean trim(boolean aggressive) {
return false;
}
}

View File

@ -101,6 +101,8 @@ public interface IBatchProcessor {
return MultiBatchProcessor.of(this, other); return MultiBatchProcessor.of(this, other);
} }
default void flush() {}
/** /**
* Return a new processor after removing all are instances of a specified class * Return a new processor after removing all are instances of a specified class
* @param clazz * @param clazz

View File

@ -45,11 +45,11 @@ public interface IBlocks extends Trimable {
IBlocks reset(); IBlocks reset();
default byte[] toByteArray(boolean writeBiomes) { default byte[] toByteArray(int bitMask) {
return toByteArray(null, writeBiomes); return toByteArray(null, bitMask);
} }
default byte[] toByteArray(byte[] buffer, boolean writeBiomes) { default byte[] toByteArray(byte[] buffer, int bitMask) {
if (buffer == null) { if (buffer == null) {
buffer = new byte[1024]; buffer = new byte[1024];
} }
@ -138,7 +138,7 @@ public interface IBlocks extends Trimable {
// } // }
// } // }
// } // }
if (writeBiomes) { if (bitMask == Character.MAX_VALUE) {
for (int z = 0; z < 16; z++) { for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
BiomeType biome = getBiomeType(x, z); BiomeType biome = getBiomeType(x, z);

View File

@ -1,6 +1,8 @@
package com.boydti.fawe.beta.implementation.chunk; package com.boydti.fawe.beta.implementation.chunk;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.CombinedBlocks;
import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.IQueueChunk; import com.boydti.fawe.beta.IQueueChunk;
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;

View File

@ -62,7 +62,8 @@ public class ChunkPacket implements Function<byte[], byte[]>, Supplier<byte[]> {
if (tmp == null) { if (tmp == null) {
synchronized (this) { synchronized (this) {
if (sectionBytes == null) { if (sectionBytes == null) {
sectionBytes = getChunk().toByteArray(FaweCache.IMP.BYTE_BUFFER_8192.get(), this.full); IBlocks tmpChunk = getChunk();
sectionBytes = tmpChunk.toByteArray(FaweCache.IMP.BYTE_BUFFER_8192.get(), tmpChunk.getBitMask());
} }
tmp = sectionBytes; tmp = sectionBytes;
} }

View File

@ -19,6 +19,11 @@ public class BatchProcessorHolder implements IBatchProcessorHolder {
return getProcessor().processSet(chunk, get, set); return getProcessor().processSet(chunk, get, set);
} }
@Override
public void flush() {
getProcessor().flush();
}
@Override @Override
public void setProcessor(IBatchProcessor set) { public void setProcessor(IBatchProcessor set) {
this.processor = set; this.processor = set;

View File

@ -1,6 +1,8 @@
package com.boydti.fawe.beta.implementation.processors; package com.boydti.fawe.beta.implementation.processors;
import com.boydti.fawe.beta.CombinedBlocks;
import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.beta.IBatchProcessor;
import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
@ -16,18 +18,41 @@ import java.util.stream.Stream;
public class ChunkSendProcessor implements IBatchProcessor { public class ChunkSendProcessor implements IBatchProcessor {
private final Supplier<Stream<Player>> players; private final Supplier<Stream<Player>> players;
private final World world; private final World world;
private final boolean full;
public ChunkSendProcessor(World world, Supplier<Stream<Player>> players) { public ChunkSendProcessor(World world, Supplier<Stream<Player>> players) {
this(world, players, false);
}
public ChunkSendProcessor(World world, Supplier<Stream<Player>> players, boolean full) {
this.players = players; this.players = players;
this.world = world; this.world = world;
this.full = full;
}
public World getWorld() {
return world;
}
public Supplier<Stream<Player>> getPlayers() {
return players;
} }
@Override @Override
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
int chunkX = chunk.getX(); int chunkX = chunk.getX();
int chunkZ = chunk.getZ(); int chunkZ = chunk.getZ();
boolean replaceAll = set.hasBiomes(); IBlocks blocks;
ChunkPacket packet = new ChunkPacket(chunkX, chunkZ, () -> set, replaceAll); boolean full = this.full;
if (full) {
blocks = set;
} else {
blocks = combine(chunk, get, set);
if (set.hasBiomes()) {
full = true;
}
}
ChunkPacket packet = new ChunkPacket(chunkX, chunkZ, () -> blocks, full);
Stream<Player> stream = this.players.get(); Stream<Player> stream = this.players.get();
if (stream == null) { if (stream == null) {
world.sendFakeChunk(null, packet); world.sendFakeChunk(null, packet);
@ -38,8 +63,12 @@ public class ChunkSendProcessor implements IBatchProcessor {
return set; return set;
} }
public IBlocks combine(IChunk chunk, IChunkGet get, IChunkSet set) {
return new CombinedBlocks(get, set, 0);
}
@Override @Override
public Extent construct(Extent child) { public Extent construct(Extent child) {
return null; throw new UnsupportedOperationException("Processing only");
} }
} }

View File

@ -106,6 +106,11 @@ public class MultiBatchProcessor implements IBatchProcessor {
return this; return this;
} }
@Override
public void flush() {
for (IBatchProcessor processor : this.processors) processor.flush();
}
@Override @Override
public String toString() { public String toString() {
return super.toString() + "{" + StringMan.join(processors, ",") + "}"; return super.toString() + "{" + StringMan.join(processors, ",") + "}";

View File

@ -0,0 +1,61 @@
package com.boydti.fawe.beta.implementation.processors;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.CombinedBlocks;
import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.world.World;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class PersistentChunkSendProcessor extends ChunkSendProcessor {
private Long2ObjectLinkedOpenHashMap<Character> current;
private Long2ObjectLinkedOpenHashMap<Character> previous;
public PersistentChunkSendProcessor(World world, IQueueExtent queue, PersistentChunkSendProcessor previous, Supplier<Stream<Player>> players) {
super(world, players);
this.current = new Long2ObjectLinkedOpenHashMap<>();
this.previous = previous.current;
}
@Override
public IBlocks combine(IChunk chunk, IChunkGet get, IChunkSet set) {
int chunkX = chunk.getX();
int chunkZ = chunk.getZ();
long pair = MathMan.pairInt(chunkX, chunkZ);
Character bitMask = (char) (set.hasBiomes() ? Character.MAX_VALUE : set.getBitMask());
current.put(pair, bitMask);
Character lastValue = previous.remove(pair);
return new CombinedBlocks(get, set, lastValue == null ? 0 : lastValue);
}
public void flush(IQueueExtent extent) {
if (!previous.isEmpty()) {
Stream<Player> players = getPlayers().get();
for (Long2ObjectMap.Entry<Character> entry : previous.long2ObjectEntrySet()) {
long pair = entry.getLongKey();
int chunkX = MathMan.unpairIntX(pair);
int chunkZ = MathMan.unpairIntY(pair);
BlockVector2 pos = BlockVector2.at(chunkX, chunkZ);
Supplier<IBlocks> chunk = () -> extent.getOrCreateChunk(pos.getX(), pos.getZ());
ChunkPacket packet = new ChunkPacket(pos.getX(), pos.getZ(), chunk, true);
char bitMask = entry.getValue();
if (players == null) {
getWorld().sendFakeChunk(null, packet);
} else {
players.forEach(player -> getWorld().sendFakeChunk(player, packet));
}
}
}
}
}

View File

@ -82,16 +82,13 @@ public class RollbackOptimizedHistory extends DiskStorageHistory {
} }
@Override @Override
public boolean close() { public void close() throws IOException {
if (super.close()) { super.close();
// Save to DB // Save to DB
RollbackDatabase db = DBHandler.IMP.getDatabase(getWorld()); RollbackDatabase db = DBHandler.IMP.getDatabase(getWorld());
if (db != null) { if (db != null) {
db.logEdit(this); db.logEdit(this);
} }
return true;
}
return false;
} }
@Override @Override

View File

@ -19,9 +19,7 @@ public class NullChangeSet extends FaweChangeSet {
} }
@Override @Override
public final boolean close() { public final void close() {}
return false;
}
@Override @Override
public final void add(int x, int y, int z, int combinedFrom, int combinedTo) { public final void add(int x, int y, int z, int combinedFrom, int combinedTo) {

View File

@ -13,6 +13,8 @@ import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -32,18 +34,18 @@ public class AbstractDelegateChangeSet extends FaweChangeSet {
} }
@Override @Override
public boolean closeAsync() { public void closeAsync() {
return parent.closeAsync(); parent.closeAsync();
} }
@Override @Override
public boolean flush() { public void flush() {
return parent.flush(); parent.flush();
} }
@Override @Override
public boolean close() { public void close() throws IOException {
return super.close() && parent.close(); parent.close();
} }
public final FaweChangeSet getParent() { public final FaweChangeSet getParent() {
@ -60,12 +62,6 @@ public class AbstractDelegateChangeSet extends FaweChangeSet {
return parent.getWorld(); return parent.getWorld();
} }
@Override
@Deprecated
public boolean flushAsync() {
return parent.flushAsync();
}
@Override @Override
public void add(int x, int y, int z, int combinedFrom, int combinedTo) { public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
parent.add(x, y, z, combinedFrom, combinedTo); parent.add(x, y, z, combinedFrom, combinedTo);

View File

@ -30,14 +30,10 @@ public class CFIChangeSet extends FaweChangeSet {
} }
@Override @Override
public boolean close() { public void close() {}
return true;
}
@Override @Override
public boolean closeAsync() { public void closeAsync() {}
return true;
}
@Override @Override
public void add(int x, int y, int z, int combinedFrom, int combinedTo) { public void add(int x, int y, int z, int combinedFrom, int combinedTo) {

View File

@ -173,10 +173,9 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
} }
@Override @Override
public boolean flush() { public void flush() {
super.flush(); super.flush();
synchronized (this) { synchronized (this) {
boolean flushed = osBD != null || osBIO != null || osNBTF != null || osNBTT != null && osENTCF != null || osENTCT != null;
try { try {
if (osBD != null) osBD.flush(); if (osBD != null) osBD.flush();
if (osBIO != null) osBIO.flush(); if (osBIO != null) osBIO.flush();
@ -187,12 +186,11 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return flushed;
} }
} }
@Override @Override
public boolean close() { public void close() throws IOException {
super.close(); super.close();
synchronized (this) { synchronized (this) {
boolean flushed = osBD != null || osBIO != null || osNBTF != null || osNBTT != null && osENTCF != null || osENTCT != null; boolean flushed = osBD != null || osBIO != null || osNBTF != null || osNBTT != null && osENTCF != null || osENTCT != null;
@ -224,7 +222,9 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return flushed; if (!flushed) {
throw new IOException("Empty");
}
} }
} }

View File

@ -33,6 +33,8 @@ import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -40,7 +42,7 @@ import java.util.UUID;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor { public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor, Closeable {
private World world; private World world;
private final String worldName; private final String worldName;
@ -77,24 +79,23 @@ public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor {
return world; return world;
} }
@Deprecated public void closeAsync() {
public boolean flushAsync() {
return closeAsync();
}
public boolean closeAsync() {
waitingAsync.incrementAndGet(); waitingAsync.incrementAndGet();
TaskManager.IMP.async(() -> { TaskManager.IMP.async(() -> {
waitingAsync.decrementAndGet(); waitingAsync.decrementAndGet();
synchronized (waitingAsync) { synchronized (waitingAsync) {
waitingAsync.notifyAll(); waitingAsync.notifyAll();
} }
try {
close(); close();
} catch (IOException e) {
e.printStackTrace();
}
}); });
return true;
} }
public boolean flush() { @Override
public void flush() {
try { try {
if (!Fawe.isMainThread()) { if (!Fawe.isMainThread()) {
while (waitingAsync.get() > 0) { while (waitingAsync.get() > 0) {
@ -111,11 +112,11 @@ public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor {
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
return true;
} }
public boolean close() { @Override
return flush(); public void close() throws IOException {
flush();
} }
public abstract void add(int x, int y, int z, int combinedFrom, int combinedTo); public abstract void add(int x, int y, int z, int combinedFrom, int combinedTo);

View File

@ -667,8 +667,8 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
@Override @Override
public Iterator<Change> getIterator(final boolean dir) { public Iterator<Change> getIterator(final boolean dir) {
close();
try { try {
close();
final Iterator<MutableTileChange> tileCreate = getTileIterator(getTileCreateIS(), true); final Iterator<MutableTileChange> tileCreate = getTileIterator(getTileCreateIS(), true);
final Iterator<MutableTileChange> tileRemove = getTileIterator(getTileRemoveIS(), false); final Iterator<MutableTileChange> tileRemove = getTileIterator(getTileRemoveIS(), false);

View File

@ -52,7 +52,7 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
} }
@Override @Override
public boolean flush() { public void flush() {
super.flush(); super.flush();
synchronized (this) { synchronized (this) {
try { try {
@ -62,16 +62,14 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
if (entRStream != null) entRStreamZip.flush(); if (entRStream != null) entRStreamZip.flush();
if (tileCStream != null) tileCStreamZip.flush(); if (tileCStream != null) tileCStreamZip.flush();
if (tileRStream != null) tileRStreamZip.flush(); if (tileRStream != null) tileRStreamZip.flush();
return true;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
return false;
} }
@Override @Override
public boolean close() { public void close() throws IOException {
super.close(); super.close();
synchronized (this) { synchronized (this) {
try { try {
@ -111,12 +109,10 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
tileRStream = null; tileRStream = null;
tileRStreamZip = null; tileRStreamZip = null;
} }
return true;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
return false;
} }
@Override @Override

View File

@ -128,6 +128,8 @@ import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -1008,7 +1010,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
if (Settings.IMP.HISTORY.COMBINE_STAGES) { if (Settings.IMP.HISTORY.COMBINE_STAGES) {
((FaweChangeSet) getChangeSet()).closeAsync(); ((FaweChangeSet) getChangeSet()).closeAsync();
} else { } else {
try {
((FaweChangeSet) getChangeSet()).close(); ((FaweChangeSet) getChangeSet()).close();
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
} }
} }

View File

@ -399,7 +399,12 @@ public class LocalSession implements TextureHolder {
private FaweChangeSet getChangeSet(Object o) { private FaweChangeSet getChangeSet(Object o) {
if (o instanceof FaweChangeSet) { if (o instanceof FaweChangeSet) {
FaweChangeSet cs = (FaweChangeSet) o; FaweChangeSet cs = (FaweChangeSet) o;
try {
cs.close(); cs.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return cs; return cs;
} }
if (o instanceof Integer) { if (o instanceof Integer) {

View File

@ -207,7 +207,7 @@ public class BrushCommands {
) )
@CommandPermissions("worldedit.brush.sphere") @CommandPermissions("worldedit.brush.sphere")
public void circleBrush(Player player, InjectedValueAccess context, public void circleBrush(Player player, InjectedValueAccess context,
Pattern fill, @Arg(desc = "Pattern") Pattern fill,
@Arg(desc = "The radius to sample for blending", def = "5") @Arg(desc = "The radius to sample for blending", def = "5")
Expression radius) throws WorldEditException { Expression radius) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius); worldEdit.checkMaxBrushRadius(radius);
@ -223,7 +223,7 @@ public class BrushCommands {
) )
@CommandPermissions("worldedit.brush.recursive") @CommandPermissions("worldedit.brush.recursive")
public void recursiveBrush(InjectedValueAccess context, EditSession editSession, public void recursiveBrush(InjectedValueAccess context, EditSession editSession,
Pattern fill, @Arg(desc = "Pattern") Pattern fill,
@Arg(desc = "The radius to sample for blending", def = "5") @Arg(desc = "The radius to sample for blending", def = "5")
Expression radius, Expression radius,
@Switch(name = 'd', desc = "Apply in depth first order") @Switch(name = 'd', desc = "Apply in depth first order")
@ -264,7 +264,7 @@ public class BrushCommands {
) )
@CommandPermissions("worldedit.brush.spline") @CommandPermissions("worldedit.brush.spline")
public void splineBrush(Player player, InjectedValueAccess context, public void splineBrush(Player player, InjectedValueAccess context,
Pattern fill, @Arg(desc = "Pattern") Pattern fill,
@Arg(desc = "The radius to sample for blending", def = "25") @Arg(desc = "The radius to sample for blending", def = "25")
Expression radius) throws WorldEditException { Expression radius) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius); worldEdit.checkMaxBrushRadius(radius);
@ -407,7 +407,7 @@ public class BrushCommands {
) )
@CommandPermissions("worldedit.brush.shatter") @CommandPermissions("worldedit.brush.shatter")
public void shatterBrush(EditSession editSession, InjectedValueAccess context, public void shatterBrush(EditSession editSession, InjectedValueAccess context,
Pattern fill, @Arg(desc = "Pattern") Pattern fill,
@Arg(desc = "The radius to sample for blending", def = "10") @Arg(desc = "The radius to sample for blending", def = "10")
Expression radius, Expression radius,
@Arg(desc = "Lines", def = "10") int count) throws WorldEditException { @Arg(desc = "Lines", def = "10") int count) throws WorldEditException {

View File

@ -19,24 +19,12 @@
package com.sk89q.worldedit.command; package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.MethodCommands.getArguments;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.internal.command.CommandUtil.checkCommandArgument;
import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.implementation.processors.ChunkSendProcessor; import com.boydti.fawe.beta.implementation.processors.ChunkSendProcessor;
import com.boydti.fawe.beta.implementation.processors.NullProcessor; import com.boydti.fawe.beta.implementation.processors.NullProcessor;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.util.TextureUtil;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
@ -47,7 +35,9 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.command.util.Logging;
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.function.FlatRegionFunction;
import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.biome.BiomeReplace;
import com.sk89q.worldedit.function.generator.FloraGenerator; import com.sk89q.worldedit.function.generator.FloraGenerator;
import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
@ -55,6 +45,7 @@ import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.mask.SolidBlockMask; import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor; import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.internal.annotation.Direction; import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.Range; import com.sk89q.worldedit.internal.annotation.Range;
@ -74,21 +65,9 @@ import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.regions.Regions; import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.serializer.legacy.LegacyComponentSerializer;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.CommandContainer;
@ -97,6 +76,21 @@ import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch; import org.enginehub.piston.annotation.param.Switch;
import org.enginehub.piston.inject.InjectedValueAccess; import org.enginehub.piston.inject.InjectedValueAccess;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.MethodCommands.getArguments;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.internal.command.CommandUtil.checkCommandArgument;
import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
/** /**
* Commands that operate on regions. * Commands that operate on regions.
*/ */
@ -155,7 +149,14 @@ public class RegionCommands {
) )
@CommandPermissions("worldedit.region.test") @CommandPermissions("worldedit.region.test")
@Logging(REGION) @Logging(REGION)
public void test(Player player, @Arg(desc = "hello there")BlockType type) throws WorldEditException { public void test(Player player, EditSession editSession, @Selection Region region, @Arg(desc = "hello there") BiomeType biome) throws WorldEditException {
System.out.println("Test start");
editSession.addProcessor(new ChunkSendProcessor(editSession.getWorld(), () -> Stream.of(player)));
editSession.addProcessor(NullProcessor.INSTANCE);
FlatRegionFunction replace = new BiomeReplace(editSession, biome);
FlatRegionVisitor visitor = new FlatRegionVisitor(Regions.asFlatRegion(region), replace);
Operations.completeLegacy(visitor);
System.out.println("Test end");
} }
@Command( @Command(

View File

@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger; import static org.slf4j.LoggerFactory.getLogger;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.implementation.processors.PersistentChunkSendProcessor;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.brush.BrushSettings; import com.boydti.fawe.object.brush.BrushSettings;
@ -644,8 +645,11 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
.autoQueue(false) .autoQueue(false)
.blockBag(null) .blockBag(null)
.changeSetNull() .changeSetNull()
.combineStages(false); .fastmode(true)
.combineStages(true);
EditSession editSession = builder.build(); EditSession editSession = builder.build();
// processor = new PersistentChunkSendProcessor()
VisualExtent newVisualExtent = new VisualExtent(editSession, player); VisualExtent newVisualExtent = new VisualExtent(editSession, player);
BlockVector3 position = getPosition(editSession, player); BlockVector3 position = getPosition(editSession, player);
if (position != null) { if (position != null) {