mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-11-16 17:16:11 +00:00
Allow "post processing" of chunks (#658)
* begin allowing "post processing" of chunks - restores legacy capability to continue saving edits in the background after sending the chunks - speeds up the edit clientside - nail in the coffin of the terrible and staticly coded coreedit - We should totally make IronGolem work so Core* is no longer used by anyone * begin allowing background history saving * Handle post processors in queues properly * Use futures for postprocessing so we're not waiting for them needlessly * better use of closed boolean * Reword
This commit is contained in:
parent
2aef0ee27e
commit
82bcc0e9a5
@ -14,6 +14,8 @@ import com.sk89q.worldedit.world.block.BlockState;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import net.jpountz.util.UnsafeUtils;
|
import net.jpountz.util.UnsafeUtils;
|
||||||
|
import net.minecraft.server.v1_15_R1.BiomeBase;
|
||||||
|
import net.minecraft.server.v1_15_R1.BiomeStorage;
|
||||||
import net.minecraft.server.v1_15_R1.Block;
|
import net.minecraft.server.v1_15_R1.Block;
|
||||||
import net.minecraft.server.v1_15_R1.Chunk;
|
import net.minecraft.server.v1_15_R1.Chunk;
|
||||||
import net.minecraft.server.v1_15_R1.ChunkCoordIntPair;
|
import net.minecraft.server.v1_15_R1.ChunkCoordIntPair;
|
||||||
@ -61,6 +63,8 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
|||||||
private final static Field fieldDirtyCount;
|
private final static Field fieldDirtyCount;
|
||||||
private final static Field fieldDirtyBits;
|
private final static Field fieldDirtyBits;
|
||||||
|
|
||||||
|
private static final Field fieldBiomeArray;
|
||||||
|
|
||||||
private final static MethodHandle methodGetVisibleChunk;
|
private final static MethodHandle methodGetVisibleChunk;
|
||||||
|
|
||||||
public final static MethodHandle methodSetLightNibbleArray;
|
public final static MethodHandle methodSetLightNibbleArray;
|
||||||
@ -91,6 +95,9 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
|||||||
fieldDirtyBits = PlayerChunk.class.getDeclaredField("r");
|
fieldDirtyBits = PlayerChunk.class.getDeclaredField("r");
|
||||||
fieldDirtyBits.setAccessible(true);
|
fieldDirtyBits.setAccessible(true);
|
||||||
|
|
||||||
|
fieldBiomeArray = BiomeStorage.class.getDeclaredField("h");
|
||||||
|
fieldBiomeArray.setAccessible(true);
|
||||||
|
|
||||||
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
||||||
declaredGetVisibleChunk.setAccessible(true);
|
declaredGetVisibleChunk.setAccessible(true);
|
||||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
||||||
@ -307,4 +314,13 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
|||||||
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
||||||
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BiomeBase[] getBiomeArray(BiomeStorage storage) {
|
||||||
|
try {
|
||||||
|
return (BiomeBase[]) fieldBiomeArray.get(storage);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_15_2;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
@ -86,6 +87,8 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
public int X, Z;
|
public int X, Z;
|
||||||
public NibbleArray[] blockLight = new NibbleArray[16];
|
public NibbleArray[] blockLight = new NibbleArray[16];
|
||||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||||
|
private boolean createCopy = false;
|
||||||
|
private BukkitGetBlocks_1_15_2_Copy copy = null;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_15_2(World world, int X, int Z) {
|
public BukkitGetBlocks_1_15_2(World world, int X, int Z) {
|
||||||
this(((CraftWorld) world).getHandle(), X, Z);
|
this(((CraftWorld) world).getHandle(), X, Z);
|
||||||
@ -97,6 +100,21 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
this.Z = Z;
|
this.Z = Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
this.createCopy = createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkGet getCopy() {
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
@ -292,6 +310,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||||
|
copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world, getX(), getZ()) : null;
|
||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
||||||
@ -316,6 +335,9 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
if (ordinal != 0) {
|
if (ordinal != 0) {
|
||||||
TileEntity tile = entry.getValue();
|
TileEntity tile = entry.getValue();
|
||||||
nmsChunk.removeTileEntity(tile.getPosition());
|
nmsChunk.removeTileEntity(tile.getPosition());
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeTile(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,6 +351,9 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
if (!set.hasSection(layer)){
|
if (!set.hasSection(layer)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeSection(layer);
|
||||||
|
}
|
||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
@ -384,6 +409,9 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
// set biomes
|
// set biomes
|
||||||
BiomeStorage currentBiomes = nmsChunk.getBiomeIndex();
|
BiomeStorage currentBiomes = nmsChunk.getBiomeIndex();
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeBiomes(currentBiomes);
|
||||||
|
}
|
||||||
for (int z = 0, i = 0; z < 16; z++) {
|
for (int z = 0, i = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
for (int x = 0; x < 16; x++, i++) {
|
||||||
final BiomeType biome = biomes[i];
|
final BiomeType biome = biomes[i];
|
||||||
@ -446,6 +474,9 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
final Entity entity = iter.next();
|
final Entity entity = iter.next();
|
||||||
if (entityRemoves.contains(entity.getUniqueID())) {
|
if (entityRemoves.contains(entity.getUniqueID())) {
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeEntity(entity);
|
||||||
|
}
|
||||||
iter.remove();
|
iter.remove();
|
||||||
removeEntity(entity);
|
removeEntity(entity);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
package com.boydti.fawe.bukkit.adapter.mc1_15_2;
|
||||||
|
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
import net.minecraft.server.v1_15_R1.BiomeBase;
|
||||||
|
import net.minecraft.server.v1_15_R1.BiomeStorage;
|
||||||
|
import net.minecraft.server.v1_15_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_15_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_15_R1.TileEntity;
|
||||||
|
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 {
|
||||||
|
|
||||||
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
|
private BiomeStorage biomeStorage;
|
||||||
|
private final char[][] blocks = new char[16][4096];
|
||||||
|
|
||||||
|
protected BukkitGetBlocks_1_15_2_Copy(WorldServer world, int X, int Z) {
|
||||||
|
super(world, X, Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeTile(TileEntity tile) {
|
||||||
|
tiles.put(BlockVector3.at(tile.getPosition().getX(), tile.getPosition().getY(), tile.getPosition().getZ()),
|
||||||
|
new LazyCompoundTag_1_15_2(Suppliers.memoize(() -> tile.save(new NBTTagCompound()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
|
return tiles.get(BlockVector3.at(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeEntity(Entity entity) {
|
||||||
|
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
entities.add((CompoundTag) adapter.toNative(entity.save(tag)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CompoundTag> getEntities() {
|
||||||
|
return this.entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag getEntity(UUID uuid) {
|
||||||
|
for (CompoundTag tag : entities) {
|
||||||
|
UUID tagUUID;
|
||||||
|
if (tag.containsKey("UUID")) {
|
||||||
|
int[] arr = tag.getIntArray("UUID");
|
||||||
|
tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL));
|
||||||
|
} else if (tag.containsKey("UUIDMost")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast"));
|
||||||
|
} else if (tag.containsKey("PersistentIDMSB")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB"));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (uuid.equals(tagUUID)) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
|
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_15_2.getBiomeArray(biomeStorage).clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiomeType(int x, int y, int z) {
|
||||||
|
BiomeBase base = null;
|
||||||
|
if (y == -1) {
|
||||||
|
for (y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) {
|
||||||
|
base = biomeStorage.getBiome(x >> 2, y >> 2, z >> 2);
|
||||||
|
if (base != null) break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base = biomeStorage.getBiome(x >> 2, y >> 2, z >> 2);
|
||||||
|
}
|
||||||
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer) {
|
||||||
|
update(layer, blocks[layer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||||
|
BlockState state = BlockTypesCache.states[get(x, y, z)];
|
||||||
|
return state.toBaseBlock(this, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char get(int x, int y, int z) {
|
||||||
|
final int layer = y >> 4;
|
||||||
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
|
return blocks[layer][index];
|
||||||
|
}
|
||||||
|
}
|
@ -47,6 +47,8 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
|
|||||||
private final static Field fieldDirtyCount;
|
private final static Field fieldDirtyCount;
|
||||||
private final static Field fieldDirtyBits;
|
private final static Field fieldDirtyBits;
|
||||||
|
|
||||||
|
private static final Field fieldBiomeArray;
|
||||||
|
|
||||||
private final static MethodHandle methodGetVisibleChunk;
|
private final static MethodHandle methodGetVisibleChunk;
|
||||||
|
|
||||||
private static final int CHUNKSECTION_BASE;
|
private static final int CHUNKSECTION_BASE;
|
||||||
@ -78,6 +80,9 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
|
|||||||
fieldDirtyBits = PlayerChunk.class.getDeclaredField("r");
|
fieldDirtyBits = PlayerChunk.class.getDeclaredField("r");
|
||||||
fieldDirtyBits.setAccessible(true);
|
fieldDirtyBits.setAccessible(true);
|
||||||
|
|
||||||
|
fieldBiomeArray = BiomeStorage.class.getDeclaredField("h");
|
||||||
|
fieldBiomeArray.setAccessible(true);
|
||||||
|
|
||||||
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
||||||
declaredGetVisibleChunk.setAccessible(true);
|
declaredGetVisibleChunk.setAccessible(true);
|
||||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
||||||
@ -291,4 +296,13 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
|
|||||||
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
||||||
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BiomeBase[] getBiomeArray(BiomeStorage storage) {
|
||||||
|
try {
|
||||||
|
return (BiomeBase[]) fieldBiomeArray.get(storage);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_1;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
@ -11,7 +12,6 @@ import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
|||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.AdaptedMap;
|
import com.boydti.fawe.object.collection.AdaptedMap;
|
||||||
import com.boydti.fawe.object.collection.BitArray;
|
|
||||||
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
@ -55,6 +55,8 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
public int X, Z;
|
public int X, Z;
|
||||||
public NibbleArray[] blockLight = new NibbleArray[16];
|
public NibbleArray[] blockLight = new NibbleArray[16];
|
||||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||||
|
private boolean createCopy = false;
|
||||||
|
private BukkitGetBlocks_1_16_1_Copy copy = null;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_1(World world, int X, int Z) {
|
public BukkitGetBlocks_1_16_1(World world, int X, int Z) {
|
||||||
this(((CraftWorld) world).getHandle(), X, Z);
|
this(((CraftWorld) world).getHandle(), X, Z);
|
||||||
@ -66,6 +68,21 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
this.Z = Z;
|
this.Z = Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
this.createCopy = createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkGet getCopy() {
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
@ -259,6 +276,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||||
|
copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world, getX(), getZ()) : null;
|
||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
||||||
@ -283,6 +301,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
if (ordinal != 0) {
|
if (ordinal != 0) {
|
||||||
TileEntity tile = entry.getValue();
|
TileEntity tile = entry.getValue();
|
||||||
nmsChunk.removeTileEntity(tile.getPosition());
|
nmsChunk.removeTileEntity(tile.getPosition());
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeTile(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,6 +317,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
if (!set.hasSection(layer)){
|
if (!set.hasSection(layer)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeSection(layer);
|
||||||
|
}
|
||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
@ -353,6 +377,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
// set biomes
|
// set biomes
|
||||||
BiomeStorage currentBiomes = nmsChunk.getBiomeIndex();
|
BiomeStorage currentBiomes = nmsChunk.getBiomeIndex();
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeBiomes(currentBiomes);
|
||||||
|
}
|
||||||
for (int z = 0, i = 0; z < 16; z++) {
|
for (int z = 0, i = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
for (int x = 0; x < 16; x++, i++) {
|
||||||
final BiomeType biome = biomes[i];
|
final BiomeType biome = biomes[i];
|
||||||
@ -415,6 +442,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
final Entity entity = iter.next();
|
final Entity entity = iter.next();
|
||||||
if (entityRemoves.contains(entity.getUniqueID())) {
|
if (entityRemoves.contains(entity.getUniqueID())) {
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeEntity(entity);
|
||||||
|
}
|
||||||
iter.remove();
|
iter.remove();
|
||||||
removeEntity(entity);
|
removeEntity(entity);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.boydti.fawe.bukkit.adapter.mc1_16_1;
|
||||||
|
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
import net.minecraft.server.v1_16_R1.BiomeBase;
|
||||||
|
import net.minecraft.server.v1_16_R1.BiomeStorage;
|
||||||
|
import net.minecraft.server.v1_16_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_16_R1.IRegistry;
|
||||||
|
import net.minecraft.server.v1_16_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_16_R1.TileEntity;
|
||||||
|
import net.minecraft.server.v1_16_R1.WorldServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 {
|
||||||
|
|
||||||
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
|
private BiomeStorage biomeStorage;
|
||||||
|
private final char[][] blocks = new char[16][4096];
|
||||||
|
|
||||||
|
protected BukkitGetBlocks_1_16_1_Copy(WorldServer world, int X, int Z) {
|
||||||
|
super(world, X, Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeTile(TileEntity tile) {
|
||||||
|
tiles.put(BlockVector3.at(tile.getPosition().getX(), tile.getPosition().getY(), tile.getPosition().getZ()),
|
||||||
|
new LazyCompoundTag_1_16_1(Suppliers.memoize(() -> tile.save(new NBTTagCompound()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
|
return tiles.get(BlockVector3.at(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeEntity(Entity entity) {
|
||||||
|
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
entities.add((CompoundTag) adapter.toNative(entity.save(tag)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CompoundTag> getEntities() {
|
||||||
|
return this.entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag getEntity(UUID uuid) {
|
||||||
|
for (CompoundTag tag : entities) {
|
||||||
|
UUID tagUUID;
|
||||||
|
if (tag.containsKey("UUID")) {
|
||||||
|
int[] arr = tag.getIntArray("UUID");
|
||||||
|
tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL));
|
||||||
|
} else if (tag.containsKey("UUIDMost")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast"));
|
||||||
|
} else if (tag.containsKey("PersistentIDMSB")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB"));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (uuid.equals(tagUUID)) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
|
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_16_1.getBiomeArray(biomeStorage).clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiomeType(int x, int y, int z) {
|
||||||
|
BiomeBase base = null;
|
||||||
|
if (y == -1) {
|
||||||
|
for (y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) {
|
||||||
|
base = biomeStorage.getBiome(x >> 2, y >> 2, z >> 2);
|
||||||
|
if (base != null) break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base = biomeStorage.getBiome(x >> 2, y >> 2, z >> 2);
|
||||||
|
}
|
||||||
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer) {
|
||||||
|
update(layer, blocks[layer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||||
|
BlockState state = BlockTypesCache.states[get(x, y, z)];
|
||||||
|
return state.toBaseBlock(this, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char get(int x, int y, int z) {
|
||||||
|
final int layer = y >> 4;
|
||||||
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
|
return blocks[layer][index];
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,8 @@ import com.sk89q.worldedit.world.block.BlockState;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import net.jpountz.util.UnsafeUtils;
|
import net.jpountz.util.UnsafeUtils;
|
||||||
|
import net.minecraft.server.v1_16_R2.BiomeBase;
|
||||||
|
import net.minecraft.server.v1_16_R2.BiomeStorage;
|
||||||
import net.minecraft.server.v1_16_R2.Block;
|
import net.minecraft.server.v1_16_R2.Block;
|
||||||
import net.minecraft.server.v1_16_R2.Chunk;
|
import net.minecraft.server.v1_16_R2.Chunk;
|
||||||
import net.minecraft.server.v1_16_R2.ChunkCoordIntPair;
|
import net.minecraft.server.v1_16_R2.ChunkCoordIntPair;
|
||||||
@ -64,6 +66,8 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
|
|||||||
private static final Field fieldDirty;
|
private static final Field fieldDirty;
|
||||||
private static final Field fieldDirtyBlocks;
|
private static final Field fieldDirtyBlocks;
|
||||||
|
|
||||||
|
private static final Field fieldBiomeArray;
|
||||||
|
|
||||||
private static final MethodHandle methodGetVisibleChunk;
|
private static final MethodHandle methodGetVisibleChunk;
|
||||||
|
|
||||||
private static final int CHUNKSECTION_BASE;
|
private static final int CHUNKSECTION_BASE;
|
||||||
@ -95,6 +99,9 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
|
|||||||
fieldDirtyBlocks = PlayerChunk.class.getDeclaredField("dirtyBlocks");
|
fieldDirtyBlocks = PlayerChunk.class.getDeclaredField("dirtyBlocks");
|
||||||
fieldDirtyBlocks.setAccessible(true);
|
fieldDirtyBlocks.setAccessible(true);
|
||||||
|
|
||||||
|
fieldBiomeArray = BiomeStorage.class.getDeclaredField("h");
|
||||||
|
fieldBiomeArray.setAccessible(true);
|
||||||
|
|
||||||
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
||||||
declaredGetVisibleChunk.setAccessible(true);
|
declaredGetVisibleChunk.setAccessible(true);
|
||||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
||||||
@ -286,7 +293,7 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
|
|||||||
.setType(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(),
|
.setType(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(),
|
||||||
Block.getByCombinedId(ordinal)));
|
Block.getByCombinedId(ordinal)));
|
||||||
}
|
}
|
||||||
} catch (final IllegalAccessException | NoSuchFieldException e) {
|
} catch (final IllegalAccessException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,9 +308,18 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
|
|||||||
return new ChunkSection(layer << 4);
|
return new ChunkSection(layer << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setCount(final int tickingBlockCount, final int nonEmptyBlockCount, final ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
public static void setCount(final int tickingBlockCount, final int nonEmptyBlockCount, final ChunkSection section) throws IllegalAccessException {
|
||||||
fieldFluidCount.setShort(section, (short) 0); // TODO FIXME
|
fieldFluidCount.setShort(section, (short) 0); // TODO FIXME
|
||||||
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
||||||
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BiomeBase[] getBiomeArray(BiomeStorage storage) {
|
||||||
|
try {
|
||||||
|
return (BiomeBase[]) fieldBiomeArray.get(storage);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_2;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
@ -11,7 +12,6 @@ import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
|||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.AdaptedMap;
|
import com.boydti.fawe.object.collection.AdaptedMap;
|
||||||
import com.boydti.fawe.object.collection.BitArray;
|
|
||||||
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
@ -55,6 +55,8 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
public int X, Z;
|
public int X, Z;
|
||||||
public NibbleArray[] blockLight = new NibbleArray[16];
|
public NibbleArray[] blockLight = new NibbleArray[16];
|
||||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||||
|
private boolean createCopy = false;
|
||||||
|
private BukkitGetBlocks_1_16_2_Copy copy = null;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_2(World world, int X, int Z) {
|
public BukkitGetBlocks_1_16_2(World world, int X, int Z) {
|
||||||
this(((CraftWorld) world).getHandle(), X, Z);
|
this(((CraftWorld) world).getHandle(), X, Z);
|
||||||
@ -66,6 +68,21 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
this.Z = Z;
|
this.Z = Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
this.createCopy = createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkGet getCopy() {
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
@ -107,7 +124,8 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We);
|
return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getSkyLight(int x, int y, int z) {
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
int layer = y >> 4;
|
int layer = y >> 4;
|
||||||
if (skyLight[layer] == null) {
|
if (skyLight[layer] == null) {
|
||||||
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
@ -126,7 +144,8 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
return skyLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
return skyLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getEmmittedLight(int x, int y, int z) {
|
@Override
|
||||||
|
public int getEmmittedLight(int x, int y, int z) {
|
||||||
int layer = y >> 4;
|
int layer = y >> 4;
|
||||||
if (blockLight[layer] == null) {
|
if (blockLight[layer] == null) {
|
||||||
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer);
|
||||||
@ -145,7 +164,8 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int[] getHeightMap(HeightMapType type) {
|
@Override
|
||||||
|
public int[] getHeightMap(HeightMapType type) {
|
||||||
long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a();
|
long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a();
|
||||||
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray);
|
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray);
|
||||||
return bitArray.toRaw(new int[256]);
|
return bitArray.toRaw(new int[256]);
|
||||||
@ -259,6 +279,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||||
|
copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world, getX(), getZ()) : null;
|
||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
||||||
@ -283,6 +304,9 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
if (ordinal != 0) {
|
if (ordinal != 0) {
|
||||||
TileEntity tile = entry.getValue();
|
TileEntity tile = entry.getValue();
|
||||||
nmsChunk.removeTileEntity(tile.getPosition());
|
nmsChunk.removeTileEntity(tile.getPosition());
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeTile(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,6 +320,9 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
if (!set.hasSection(layer)){
|
if (!set.hasSection(layer)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeSection(layer);
|
||||||
|
}
|
||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
@ -353,6 +380,9 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
// set biomes
|
// set biomes
|
||||||
BiomeStorage currentBiomes = nmsChunk.getBiomeIndex();
|
BiomeStorage currentBiomes = nmsChunk.getBiomeIndex();
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeBiomes(currentBiomes);
|
||||||
|
}
|
||||||
for (int z = 0, i = 0; z < 16; z++) {
|
for (int z = 0, i = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
for (int x = 0; x < 16; x++, i++) {
|
||||||
final BiomeType biome = biomes[i];
|
final BiomeType biome = biomes[i];
|
||||||
@ -415,6 +445,9 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
final Entity entity = iter.next();
|
final Entity entity = iter.next();
|
||||||
if (entityRemoves.contains(entity.getUniqueID())) {
|
if (entityRemoves.contains(entity.getUniqueID())) {
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeEntity(entity);
|
||||||
|
}
|
||||||
iter.remove();
|
iter.remove();
|
||||||
removeEntity(entity);
|
removeEntity(entity);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.boydti.fawe.bukkit.adapter.mc1_16_2;
|
||||||
|
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
import net.minecraft.server.v1_16_R2.BiomeBase;
|
||||||
|
import net.minecraft.server.v1_16_R2.BiomeStorage;
|
||||||
|
import net.minecraft.server.v1_16_R2.Entity;
|
||||||
|
import net.minecraft.server.v1_16_R2.IRegistry;
|
||||||
|
import net.minecraft.server.v1_16_R2.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_16_R2.TileEntity;
|
||||||
|
import net.minecraft.server.v1_16_R2.WorldServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 {
|
||||||
|
|
||||||
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
|
private BiomeStorage biomeStorage;
|
||||||
|
private final char[][] blocks = new char[16][4096];
|
||||||
|
|
||||||
|
protected BukkitGetBlocks_1_16_2_Copy(WorldServer world, int X, int Z) {
|
||||||
|
super(world, X, Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeTile(TileEntity tile) {
|
||||||
|
tiles.put(BlockVector3.at(tile.getPosition().getX(), tile.getPosition().getY(), tile.getPosition().getZ()),
|
||||||
|
new LazyCompoundTag_1_16_2(Suppliers.memoize(() -> tile.save(new NBTTagCompound()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
|
return tiles.get(BlockVector3.at(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeEntity(Entity entity) {
|
||||||
|
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
entities.add((CompoundTag) adapter.toNative(entity.save(tag)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CompoundTag> getEntities() {
|
||||||
|
return this.entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag getEntity(UUID uuid) {
|
||||||
|
for (CompoundTag tag : entities) {
|
||||||
|
UUID tagUUID;
|
||||||
|
if (tag.containsKey("UUID")) {
|
||||||
|
int[] arr = tag.getIntArray("UUID");
|
||||||
|
tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL));
|
||||||
|
} else if (tag.containsKey("UUIDMost")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast"));
|
||||||
|
} else if (tag.containsKey("PersistentIDMSB")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB"));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (uuid.equals(tagUUID)) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
|
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_2.getBiomeArray(biomeStorage).clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiomeType(int x, int y, int z) {
|
||||||
|
BiomeBase base = null;
|
||||||
|
if (y == -1) {
|
||||||
|
for (y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) {
|
||||||
|
base = biomeStorage.getBiome(x >> 2, y >> 2, z >> 2);
|
||||||
|
if (base != null) break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base = biomeStorage.getBiome(x >> 2, y >> 2, z >> 2);
|
||||||
|
}
|
||||||
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer) {
|
||||||
|
update(layer, blocks[layer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||||
|
BlockState state = BlockTypesCache.states[get(x, y, z)];
|
||||||
|
return state.toBaseBlock(this, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char get(int x, int y, int z) {
|
||||||
|
final int layer = y >> 4;
|
||||||
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
|
return blocks[layer][index];
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface IBatchProcessor {
|
public interface IBatchProcessor {
|
||||||
@ -23,6 +24,8 @@ public interface IBatchProcessor {
|
|||||||
*/
|
*/
|
||||||
IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set);
|
IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set);
|
||||||
|
|
||||||
|
Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set);
|
||||||
|
|
||||||
default boolean processGet(int chunkX, int chunkZ) {
|
default boolean processGet(int chunkX, int chunkZ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -115,6 +118,10 @@ public interface IBatchProcessor {
|
|||||||
return MultiBatchProcessor.of(this, other);
|
return MultiBatchProcessor.of(this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default IBatchProcessor joinPost(IBatchProcessor other) {
|
||||||
|
return MultiBatchProcessor.of(this, other);
|
||||||
|
}
|
||||||
|
|
||||||
default void flush() {}
|
default void flush() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
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 com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@ -46,4 +47,13 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent, ITileInput {
|
|||||||
<T extends Future<T>> T call(IChunkSet set, Runnable finalize);
|
<T extends Future<T>> T call(IChunkSet set, Runnable finalize);
|
||||||
|
|
||||||
CompoundTag getEntity(UUID uuid);
|
CompoundTag getEntity(UUID uuid);
|
||||||
|
|
||||||
|
void setCreateCopy(boolean createCopy);
|
||||||
|
|
||||||
|
boolean isCreateCopy();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
default IChunkGet getCopy() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,12 @@ public class FallbackChunkGet implements IChunkGet {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void setCreateCopy(boolean createCopy) {}
|
||||||
|
|
||||||
|
@Override public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -63,6 +63,12 @@ public final class NullChunkGet implements IChunkGet {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void setCreateCopy(boolean createCopy) {}
|
||||||
|
|
||||||
|
@Override public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import com.boydti.fawe.beta.IQueueChunk;
|
|||||||
import com.boydti.fawe.beta.IQueueExtent;
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
|
import com.boydti.fawe.beta.implementation.processors.EmptyBatchProcessor;
|
||||||
import com.boydti.fawe.beta.implementation.queue.Pool;
|
import com.boydti.fawe.beta.implementation.queue.Pool;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -20,11 +21,11 @@ import com.sk89q.worldedit.world.block.BlockState;
|
|||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import org.jetbrains.annotations.Range;
|
import org.jetbrains.annotations.Range;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract {@link IChunk} class that implements basic get/set blocks
|
* An abstract {@link IChunk} class that implements basic get/set blocks
|
||||||
@ -47,6 +48,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
private boolean fastmode;
|
private boolean fastmode;
|
||||||
private int bitMask = -1; // Allow forceful setting of bitmask (for lighting)
|
private int bitMask = -1; // Allow forceful setting of bitmask (for lighting)
|
||||||
private boolean isInit = false; // Lighting handles queue differently. It relies on the chunk cache and not doing init.
|
private boolean isInit = false; // Lighting handles queue differently. It relies on the chunk cache and not doing init.
|
||||||
|
private boolean createCopy = false;
|
||||||
|
|
||||||
private ChunkHolder() {
|
private ChunkHolder() {
|
||||||
this.delegate = NULL;
|
this.delegate = NULL;
|
||||||
@ -140,6 +142,14 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
return delegate.get(this).getEntity(uuid);
|
return delegate.get(this).getEntity(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void setCreateCopy(boolean createCopy) {
|
||||||
|
this.createCopy = createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isCreateCopy() {
|
||||||
|
return createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
private static final IBlockDelegate BOTH = new IBlockDelegate() {
|
private static final IBlockDelegate BOTH = new IBlockDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public IChunkGet get(ChunkHolder chunk) {
|
public IChunkGet get(ChunkHolder chunk) {
|
||||||
@ -778,9 +788,15 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
if (set != null) {
|
if (set != null) {
|
||||||
IChunkGet get = getOrCreateGet();
|
IChunkGet get = getOrCreateGet();
|
||||||
get.trim(false);
|
get.trim(false);
|
||||||
|
boolean postProcess = !(getExtent().getPostProcessor() instanceof EmptyBatchProcessor);
|
||||||
|
get.setCreateCopy(postProcess);
|
||||||
set = getExtent().processSet(this, get, set);
|
set = getExtent().processSet(this, get, set);
|
||||||
if (set != null) {
|
try {
|
||||||
return get.call(set, finalize);
|
return get.call(set, finalize);
|
||||||
|
} finally {
|
||||||
|
if (postProcess) {
|
||||||
|
getExtent().postProcessSet(this, get.getCopy(), set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -171,6 +171,12 @@ public final class NullChunk implements IQueueChunk {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void setCreateCopy(boolean createCopy) {}
|
||||||
|
|
||||||
|
@Override public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends Future<T>> T call(@Nullable IChunkSet set, @Nullable Runnable finalize) {
|
public <T extends Future<T>> T call(@Nullable IChunkSet set, @Nullable Runnable finalize) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -5,19 +5,32 @@ 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;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class BatchProcessorHolder implements IBatchProcessorHolder {
|
public class BatchProcessorHolder implements IBatchProcessorHolder {
|
||||||
private IBatchProcessor processor = EmptyBatchProcessor.getInstance();
|
private IBatchProcessor processor = EmptyBatchProcessor.getInstance();
|
||||||
|
private IBatchProcessor postProcessor = EmptyBatchProcessor.getInstance();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBatchProcessor getProcessor() {
|
public IBatchProcessor getProcessor() {
|
||||||
return processor;
|
return processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBatchProcessor getPostProcessor() {
|
||||||
|
return postProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
return getProcessor().processSet(chunk, get, set);
|
return getProcessor().processSet(chunk, get, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
return getPostProcessor().postProcessSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
getProcessor().flush();
|
getProcessor().flush();
|
||||||
@ -28,6 +41,11 @@ public class BatchProcessorHolder implements IBatchProcessorHolder {
|
|||||||
this.processor = set;
|
this.processor = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPostProcessor(IBatchProcessor set) {
|
||||||
|
this.postProcessor = set;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
IBatchProcessor tmp = getProcessor();
|
IBatchProcessor tmp = getProcessor();
|
||||||
|
@ -12,6 +12,8 @@ import com.sk89q.worldedit.extent.Extent;
|
|||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ChunkSendProcessor implements IBatchProcessor {
|
public class ChunkSendProcessor implements IBatchProcessor {
|
||||||
@ -65,6 +67,12 @@ public class ChunkSendProcessor implements IBatchProcessor {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
// Doesn't need to do anything
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
}
|
||||||
|
|
||||||
public IBlocks combine(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IBlocks combine(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
return new CombinedBlocks(get, set, 0);
|
return new CombinedBlocks(get, set, 0);
|
||||||
}
|
}
|
||||||
@ -73,4 +81,4 @@ public class ChunkSendProcessor implements IBatchProcessor {
|
|||||||
public Extent construct(Extent child) {
|
public Extent construct(Extent child) {
|
||||||
throw new UnsupportedOperationException("Processing only");
|
throw new UnsupportedOperationException("Processing only");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,9 @@ import com.sk89q.worldedit.extent.Extent;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public final class EmptyBatchProcessor implements IBatchProcessor {
|
public final class EmptyBatchProcessor implements IBatchProcessor {
|
||||||
private static final EmptyBatchProcessor instance = new EmptyBatchProcessor();
|
private static final EmptyBatchProcessor instance = new EmptyBatchProcessor();
|
||||||
|
|
||||||
@ -26,11 +29,23 @@ public final class EmptyBatchProcessor implements IBatchProcessor {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public Future<IChunkSet> postProcessSet(@Nullable IChunk chunk, @Nullable IChunkGet get, @Nullable IChunkSet set) {
|
||||||
|
// Doesn't need to do anything
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public IBatchProcessor join(@Nullable IBatchProcessor other) {
|
public IBatchProcessor join(@Nullable IBatchProcessor other) {
|
||||||
return other;
|
return other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public IBatchProcessor joinPost(@Nullable IBatchProcessor other) {
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
|
||||||
private EmptyBatchProcessor() {
|
private EmptyBatchProcessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +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.config.Settings;
|
||||||
import com.boydti.fawe.object.changeset.AbstractChangeSet;
|
import com.boydti.fawe.object.changeset.AbstractChangeSet;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
|
||||||
@ -11,9 +12,19 @@ public abstract class ExtentBatchProcessorHolder extends BatchProcessorHolder im
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Extent addPostProcessor(IBatchProcessor processor) {
|
||||||
|
joinPost(processor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Extent enableHistory(AbstractChangeSet changeSet) {
|
public Extent enableHistory(AbstractChangeSet changeSet) {
|
||||||
return this.addProcessor(changeSet);
|
if (Settings.IMP.EXPERIMENTAL.SEND_BEFORE_HISTORY) {
|
||||||
|
return this.addPostProcessor(changeSet);
|
||||||
|
} else {
|
||||||
|
return this.addProcessor(changeSet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,6 +6,8 @@ import com.boydti.fawe.beta.IChunkGet;
|
|||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds a batch processor
|
* Holds a batch processor
|
||||||
* (Join and remove operations affect the held processor)
|
* (Join and remove operations affect the held processor)
|
||||||
@ -13,17 +15,26 @@ import com.sk89q.worldedit.extent.Extent;
|
|||||||
public interface IBatchProcessorHolder extends IBatchProcessor {
|
public interface IBatchProcessorHolder extends IBatchProcessor {
|
||||||
IBatchProcessor getProcessor();
|
IBatchProcessor getProcessor();
|
||||||
|
|
||||||
|
IBatchProcessor getPostProcessor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the held processor
|
* set the held processor
|
||||||
* @param set
|
* @param set
|
||||||
*/
|
*/
|
||||||
void setProcessor(IBatchProcessor set);
|
void setProcessor(IBatchProcessor set);
|
||||||
|
|
||||||
|
void setPostProcessor(IBatchProcessor set);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
return getProcessor().processSet(chunk, get, set);
|
return getProcessor().processSet(chunk, get, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
return getPostProcessor().postProcessSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default boolean processGet(int chunkX, int chunkZ) {
|
default boolean processGet(int chunkX, int chunkZ) {
|
||||||
return getProcessor().processGet(chunkX, chunkZ);
|
return getProcessor().processGet(chunkX, chunkZ);
|
||||||
@ -40,6 +51,12 @@ public interface IBatchProcessorHolder extends IBatchProcessor {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default IBatchProcessor joinPost(IBatchProcessor other) {
|
||||||
|
setPostProcessor(getPostProcessor().joinPost(other));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default <T extends IBatchProcessor> IBatchProcessor remove(Class<T> clazz) {
|
default <T extends IBatchProcessor> IBatchProcessor remove(Class<T> clazz) {
|
||||||
setProcessor(getProcessor().remove(clazz));
|
setProcessor(getProcessor().remove(clazz));
|
||||||
|
@ -14,6 +14,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@ -84,6 +86,23 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
try {
|
||||||
|
for (int i = processors.length - 1 ; i >= 0; i--) {
|
||||||
|
IBatchProcessor processor = processors[i];
|
||||||
|
set = processor.postProcessSet(chunk, get, set).get();
|
||||||
|
if (set == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processGet(int chunkX, int chunkZ) {
|
public boolean processGet(int chunkX, int chunkZ) {
|
||||||
for (IBatchProcessor processor : this.processors) {
|
for (IBatchProcessor processor : this.processors) {
|
||||||
@ -121,6 +140,18 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBatchProcessor joinPost(IBatchProcessor other) {
|
||||||
|
if (other instanceof MultiBatchProcessor) {
|
||||||
|
for (IBatchProcessor processor : ((MultiBatchProcessor) other).processors) {
|
||||||
|
addBatchProcessor(processor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addBatchProcessor(other);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
for (IBatchProcessor processor : this.processors) processor.flush();
|
for (IBatchProcessor processor : this.processors) processor.flush();
|
||||||
|
@ -9,6 +9,8 @@ import com.sk89q.worldedit.extent.NullExtent;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public final class NullProcessor implements IBatchProcessor {
|
public final class NullProcessor implements IBatchProcessor {
|
||||||
private static final NullProcessor instance = new NullProcessor();
|
private static final NullProcessor instance = new NullProcessor();
|
||||||
|
|
||||||
@ -21,6 +23,11 @@ public final class NullProcessor implements IBatchProcessor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Future<IChunkSet> postProcessSet(@NotNull IChunk chunk, @NotNull IChunkGet get, @NotNull IChunkSet set) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Extent construct(@NotNull Extent child) {
|
public Extent construct(@NotNull Extent child) {
|
||||||
return new NullExtent();
|
return new NullExtent();
|
||||||
|
@ -43,14 +43,16 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
|
|||||||
private final World world;
|
private final World world;
|
||||||
private final QueueHandler handler;
|
private final QueueHandler handler;
|
||||||
private final BatchProcessorHolder processor;
|
private final BatchProcessorHolder processor;
|
||||||
|
private final BatchProcessorHolder postProcessor;
|
||||||
private int changes;
|
private int changes;
|
||||||
private final boolean fastmode;
|
private final boolean fastmode;
|
||||||
|
|
||||||
public ParallelQueueExtent(QueueHandler handler, World world, boolean fastmode) {
|
public ParallelQueueExtent(QueueHandler handler, World world, boolean fastmode) {
|
||||||
super(handler.getQueue(world, new BatchProcessorHolder()));
|
super(handler.getQueue(world, new BatchProcessorHolder(), new BatchProcessorHolder()));
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.processor = (BatchProcessorHolder) getExtent().getProcessor();
|
this.processor = (BatchProcessorHolder) getExtent().getProcessor();
|
||||||
|
this.postProcessor = (BatchProcessorHolder) getExtent().getPostProcessor();
|
||||||
this.fastmode = fastmode;
|
this.fastmode = fastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,19 +65,21 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
|
|||||||
public boolean cancel() {
|
public boolean cancel() {
|
||||||
if (super.cancel()) {
|
if (super.cancel()) {
|
||||||
processor.setProcessor(new NullExtent(this, FaweCache.MANUAL));
|
processor.setProcessor(new NullExtent(this, FaweCache.MANUAL));
|
||||||
|
postProcessor.setPostProcessor(new NullExtent(this, FaweCache.MANUAL));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IQueueExtent<IQueueChunk> getNewQueue() {
|
private IQueueExtent<IQueueChunk> getNewQueue() {
|
||||||
return wrapQueue(handler.getQueue(this.world, this.processor));
|
return wrapQueue(handler.getQueue(this.world, this.processor, this.postProcessor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IQueueExtent<IQueueChunk> wrapQueue(IQueueExtent<IQueueChunk> queue) {
|
public IQueueExtent<IQueueChunk> wrapQueue(IQueueExtent<IQueueChunk> queue) {
|
||||||
// TODO wrap
|
// TODO wrap
|
||||||
queue.setProcessor(this.processor);
|
queue.setProcessor(this.processor);
|
||||||
|
queue.setPostProcessor(this.postProcessor);
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,10 +280,10 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
public abstract void endSet(boolean parallel);
|
public abstract void endSet(boolean parallel);
|
||||||
|
|
||||||
public IQueueExtent<IQueueChunk> getQueue(World world) {
|
public IQueueExtent<IQueueChunk> getQueue(World world) {
|
||||||
return getQueue(world, null);
|
return getQueue(world, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueueExtent<IQueueChunk> getQueue(World world, IBatchProcessor processor) {
|
public IQueueExtent<IQueueChunk> getQueue(World world, IBatchProcessor processor, IBatchProcessor postProcessor) {
|
||||||
final IQueueExtent<IQueueChunk> queue = pool();
|
final IQueueExtent<IQueueChunk> queue = pool();
|
||||||
IChunkCache<IChunkGet> cacheGet = getOrCreateWorldCache(world);
|
IChunkCache<IChunkGet> cacheGet = getOrCreateWorldCache(world);
|
||||||
IChunkCache<IChunkSet> set = null; // TODO cache?
|
IChunkCache<IChunkSet> set = null; // TODO cache?
|
||||||
@ -291,6 +291,9 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
if (processor != null) {
|
if (processor != null) {
|
||||||
queue.setProcessor(processor);
|
queue.setProcessor(processor);
|
||||||
}
|
}
|
||||||
|
if (postProcessor != null) {
|
||||||
|
queue.setPostProcessor(postProcessor);
|
||||||
|
}
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
this.currentThread = null;
|
this.currentThread = null;
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
this.setProcessor(EmptyBatchProcessor.getInstance());
|
this.setProcessor(EmptyBatchProcessor.getInstance());
|
||||||
|
this.setPostProcessor(EmptyBatchProcessor.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,6 +133,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
this.cacheGet = get;
|
this.cacheGet = get;
|
||||||
this.cacheSet = set;
|
this.cacheSet = set;
|
||||||
this.setProcessor(EmptyBatchProcessor.getInstance());
|
this.setProcessor(EmptyBatchProcessor.getInstance());
|
||||||
|
this.setPostProcessor(EmptyBatchProcessor.getInstance());
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,6 +393,12 @@ public class Settings extends Config {
|
|||||||
"This will increase time taken slightly."
|
"This will increase time taken slightly."
|
||||||
})
|
})
|
||||||
public boolean ALLOW_TICK_EXISTING = true;
|
public boolean ALLOW_TICK_EXISTING = true;
|
||||||
|
@Comment({
|
||||||
|
"Do not wait for a chunk's history to save before sending it",
|
||||||
|
" - Undo/redo commands will wait until the history has been written to disk before executing",
|
||||||
|
" - Requires combine_stages = true"
|
||||||
|
})
|
||||||
|
public boolean SEND_BEFORE_HISTORY = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PLOTSQUARED_INTEGRATION {
|
public static class PLOTSQUARED_INTEGRATION {
|
||||||
|
@ -62,6 +62,8 @@ public class MCAChunk implements IChunk {
|
|||||||
public int chunkX;
|
public int chunkX;
|
||||||
public int chunkZ;
|
public int chunkZ;
|
||||||
|
|
||||||
|
private boolean createCopy = false;
|
||||||
|
|
||||||
public MCAChunk() {}
|
public MCAChunk() {}
|
||||||
|
|
||||||
private boolean readLayer(Section section) {
|
private boolean readLayer(Section section) {
|
||||||
@ -602,6 +604,14 @@ public class MCAChunk implements IChunk {
|
|||||||
return this.entities.get(uuid);
|
return this.entities.get(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void setCreateCopy(boolean createCopy) {
|
||||||
|
this.createCopy = createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isCreateCopy() {
|
||||||
|
return createCopy;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future call(IChunkSet set, Runnable finalize) {
|
public Future call(IChunkSet set, Runnable finalize) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -59,7 +59,6 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
if (closed) {
|
if (closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
closed = true;
|
|
||||||
waitingAsync.incrementAndGet();
|
waitingAsync.incrementAndGet();
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.IMP.async(() -> {
|
||||||
waitingAsync.decrementAndGet();
|
waitingAsync.decrementAndGet();
|
||||||
@ -97,8 +96,8 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
closed = true;
|
|
||||||
flush();
|
flush();
|
||||||
|
closed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +203,11 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(final IChunk chunk, final IChunkGet get,final IChunkSet set) {
|
||||||
|
return (Future<IChunkSet>) addWriteTask(() -> processSet(chunk, get, set));
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void addTileCreate(CompoundTag tag);
|
public abstract void addTileCreate(CompoundTag tag);
|
||||||
|
|
||||||
public abstract void addTileRemove(CompoundTag tag);
|
public abstract void addTileRemove(CompoundTag tag);
|
||||||
|
@ -10,6 +10,8 @@ import com.sk89q.worldedit.regions.Region;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class HeightBoundExtent extends FaweRegionExtent {
|
public class HeightBoundExtent extends FaweRegionExtent {
|
||||||
|
|
||||||
@ -51,4 +53,9 @@ public class HeightBoundExtent extends FaweRegionExtent {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import com.sk89q.worldedit.regions.RegionIntersection;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class MultiRegionExtent extends FaweRegionExtent {
|
public class MultiRegionExtent extends FaweRegionExtent {
|
||||||
|
|
||||||
@ -86,4 +87,9 @@ public class MultiRegionExtent extends FaweRegionExtent {
|
|||||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
return intersection.processSet(chunk, get, set);
|
return intersection.processSet(chunk, get, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
return intersection.postProcessSet(chunk, get, set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
//todo This should be removed in favor of com.sk89q.worldedit.extent.NullExtent
|
//todo This should be removed in favor of com.sk89q.worldedit.extent.NullExtent
|
||||||
@ -340,6 +341,11 @@ public class NullExtent extends FaweRegionExtent implements IBatchProcessor {
|
|||||||
throw reason;
|
throw reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
throw reason;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processGet(int chunkX, int chunkZ) {
|
public boolean processGet(int chunkX, int chunkZ) {
|
||||||
throw reason;
|
throw reason;
|
||||||
|
@ -9,6 +9,7 @@ import com.sk89q.worldedit.regions.Region;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class SingleRegionExtent extends FaweRegionExtent {
|
public class SingleRegionExtent extends FaweRegionExtent {
|
||||||
|
|
||||||
@ -44,6 +45,11 @@ public class SingleRegionExtent extends FaweRegionExtent {
|
|||||||
return region.processSet(chunk, get, set);
|
return region.processSet(chunk, get, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
return region.postProcessSet(chunk, get, set);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processGet(int chunkX, int chunkZ) {
|
public boolean processGet(int chunkX, int chunkZ) {
|
||||||
return region.containsChunk(chunkX, chunkZ);
|
return region.containsChunk(chunkX, chunkZ);
|
||||||
|
@ -317,6 +317,24 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Extent addPostProcessor(IBatchProcessor processor) {
|
||||||
|
if (Settings.IMP.EXPERIMENTAL.OTHER) {
|
||||||
|
logger.info("addPostProcessor Info: \t " + processor.getClass().getName());
|
||||||
|
logger.info("The following is not an error or a crash:");
|
||||||
|
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
||||||
|
for (StackTraceElement stackTraceElement : stackTrace) {
|
||||||
|
logger.info(stackTraceElement.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Extent result = this.extent.addPostProcessor(processor);
|
||||||
|
if (result != this.extent) {
|
||||||
|
new ExtentTraverser<Extent>(this).setNext(result);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Extent disableHistory() {
|
public Extent disableHistory() {
|
||||||
Extent result = this.extent.disableHistory();
|
Extent result = this.extent.disableHistory();
|
||||||
|
@ -23,6 +23,7 @@ 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.IBatchProcessor;
|
||||||
import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock;
|
import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.changeset.AbstractChangeSet;
|
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;
|
||||||
@ -671,8 +672,16 @@ public interface Extent extends InputExtent, OutputExtent {
|
|||||||
return processor.construct(this);
|
return processor.construct(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Extent addPostProcessor(IBatchProcessor processor) {
|
||||||
|
return processor.construct(this);
|
||||||
|
}
|
||||||
|
|
||||||
default Extent enableHistory(AbstractChangeSet changeSet) {
|
default Extent enableHistory(AbstractChangeSet changeSet) {
|
||||||
return addProcessor(changeSet);
|
if (Settings.IMP.EXPERIMENTAL.SEND_BEFORE_HISTORY) {
|
||||||
|
return addPostProcessor(changeSet);
|
||||||
|
} else {
|
||||||
|
return addProcessor(changeSet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default Extent disableHistory() {
|
default Extent disableHistory() {
|
||||||
|
@ -36,6 +36,9 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
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.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,6 +109,12 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce
|
|||||||
return filter.filter(chunk, get, set, MaskingExtent.this);
|
return filter.filter(chunk, get, set, MaskingExtent.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
// This should not do anything otherwise dangerous...
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyBlock(final FilterBlock block) {
|
public void applyBlock(final FilterBlock block) {
|
||||||
if (!this.mask.test(block)) {
|
if (!this.mask.test(block)) {
|
||||||
|
@ -37,6 +37,8 @@ import com.sk89q.worldedit.world.World;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -350,6 +352,12 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
// Doesn't need to do anything
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default Extent construct(Extent child) {
|
default Extent construct(Extent child) {
|
||||||
if (isGlobal()) {
|
if (isGlobal()) {
|
||||||
|
@ -34,6 +34,8 @@ import java.util.Collections;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -170,6 +172,12 @@ public class RegionIntersection extends AbstractRegion {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IChunkSet> postProcessSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
|
// Doesn't need to do anything
|
||||||
|
return CompletableFuture.completedFuture(set);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Region> getRegions() {
|
public List<Region> getRegions() {
|
||||||
return regions;
|
return regions;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user