mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-01 02:46:41 +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:
@ -47,6 +47,8 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
|
||||
private final static Field fieldDirtyCount;
|
||||
private final static Field fieldDirtyBits;
|
||||
|
||||
private static final Field fieldBiomeArray;
|
||||
|
||||
private final static MethodHandle methodGetVisibleChunk;
|
||||
|
||||
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.setAccessible(true);
|
||||
|
||||
fieldBiomeArray = BiomeStorage.class.getDeclaredField("h");
|
||||
fieldBiomeArray.setAccessible(true);
|
||||
|
||||
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
||||
declaredGetVisibleChunk.setAccessible(true);
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
||||
@ -291,4 +296,13 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
|
||||
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
||||
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.FaweCache;
|
||||
import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||
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.config.Settings;
|
||||
import com.boydti.fawe.object.collection.AdaptedMap;
|
||||
import com.boydti.fawe.object.collection.BitArray;
|
||||
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Iterables;
|
||||
@ -55,6 +55,8 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
||||
public int X, Z;
|
||||
public NibbleArray[] blockLight = 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) {
|
||||
this(((CraftWorld) world).getHandle(), X, Z);
|
||||
@ -66,6 +68,21 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
||||
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() {
|
||||
return X;
|
||||
}
|
||||
@ -259,6 +276,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
||||
|
||||
@Override
|
||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world, getX(), getZ()) : null;
|
||||
try {
|
||||
WorldServer nmsWorld = world;
|
||||
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
||||
@ -283,6 +301,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
||||
if (ordinal != 0) {
|
||||
TileEntity tile = entry.getValue();
|
||||
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)){
|
||||
continue;
|
||||
}
|
||||
if (createCopy) {
|
||||
copy.storeSection(layer);
|
||||
}
|
||||
|
||||
bitMask |= 1 << layer;
|
||||
|
||||
@ -353,6 +377,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
||||
if (biomes != null) {
|
||||
// set biomes
|
||||
BiomeStorage currentBiomes = nmsChunk.getBiomeIndex();
|
||||
if (createCopy) {
|
||||
copy.storeBiomes(currentBiomes);
|
||||
}
|
||||
for (int z = 0, i = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++, i++) {
|
||||
final BiomeType biome = biomes[i];
|
||||
@ -415,6 +442,9 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
||||
while (iter.hasNext()) {
|
||||
final Entity entity = iter.next();
|
||||
if (entityRemoves.contains(entity.getUniqueID())) {
|
||||
if (createCopy) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
iter.remove();
|
||||
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];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user