Many Much

- Add readregions to queues for when we're setting our own consumer (usually meaning the queue writes its own blocks, so it doesn't know which chunks to actually load)
 - Finish removing chunk/regionTasks
 - Allow the queue to not remove tickets from chunks (useful for swapping chunks so they don't unload needlessly)
 - Remove a lot of unused methods
 - Implement entities to queues
 - Remove chunk unloading (the server should really handle it)
This commit is contained in:
dordsor21
2020-07-23 17:30:23 +01:00
parent 207e56969b
commit 27498f68fb
21 changed files with 504 additions and 540 deletions

View File

@ -53,7 +53,6 @@ import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
import com.plotsquared.core.queue.ChunkCoordinator;
import com.plotsquared.core.queue.ChunkCoordinatorBuilder;
import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.queue.QueueProvider;
import com.plotsquared.core.util.ChunkManager;
@ -94,8 +93,8 @@ public class BukkitModule extends AbstractModule {
bind(InventoryUtil.class).to(BukkitInventoryUtil.class);
bind(SetupUtils.class).to(BukkitSetupUtils.class);
bind(WorldUtil.class).to(BukkitUtil.class);
bind(GlobalBlockQueue.class).toInstance(new GlobalBlockQueue(
QueueProvider.of(BukkitQueueCoordinator.class, BukkitQueueCoordinator.class)));
bind(GlobalBlockQueue.class)
.toInstance(new GlobalBlockQueue(QueueProvider.of(BukkitQueueCoordinator.class)));
bind(ChunkManager.class).to(BukkitChunkManager.class);
bind(RegionManager.class).to(BukkitRegionManager.class);
bind(SchematicHandler.class).to(BukkitSchematicHandler.class);

View File

@ -69,6 +69,7 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
private final org.bukkit.World bukkitWorld;
private final Runnable whenDone;
private final Consumer<Throwable> throwableConsumer;
private final boolean unloadAfter;
private final int totalSize;
private final AtomicInteger expectedSize;
@ -80,7 +81,8 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
@Assisted @Nonnull final World world,
@Assisted @Nonnull final Collection<BlockVector2> requestedChunks,
@Assisted @Nonnull final Runnable whenDone,
@Assisted @Nonnull final Consumer<Throwable> throwableConsumer) {
@Assisted @Nonnull final Consumer<Throwable> throwableConsumer,
@Assisted final boolean unloadAfter) {
this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks);
this.availableChunks = new LinkedBlockingQueue<>();
this.totalSize = requestedChunks.size();
@ -90,6 +92,7 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
this.maxIterationTime = maxIterationTime;
this.whenDone = whenDone;
this.throwableConsumer = throwableConsumer;
this.unloadAfter = unloadAfter;
this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class);
this.bukkitWorld = Bukkit.getWorld(world.getName());
}
@ -119,7 +122,9 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
} catch (final Throwable throwable) {
this.throwableConsumer.accept(throwable);
}
this.freeChunk(chunk);
if (unloadAfter) {
this.freeChunk(chunk);
}
processedChunks++;
final long end = System.currentTimeMillis();
// Update iteration time

View File

@ -52,17 +52,16 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Container;
import org.bukkit.block.data.BlockData;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class BukkitQueueCoordinator extends BasicQueueCoordinator {
private final World world;
private final SideEffectSet sideEffectSet;
private org.bukkit.World bukkitWorld;
@Inject private ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory;
@ -72,13 +71,12 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
@Inject public BukkitQueueCoordinator(World world) {
super(world);
this.world = world;
sideEffectSet = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF)
.with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
}
@Override public BlockState getBlock(int x, int y, int z) {
org.bukkit.World worldObj = BukkitAdapter.adapt(world);
org.bukkit.World worldObj = BukkitAdapter.adapt(getWorld());
if (worldObj != null) {
Block block = worldObj.getBlockAt(x, y, z);
return BukkitBlockUtil.get(block);
@ -103,7 +101,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
BlockVector3.at(getRegenStart()[0] << 4, 0, getRegenStart()[1] << 4),
BlockVector3.at((getRegenEnd()[0] << 4) + 15, 255, (getRegenEnd()[1] << 4) + 15));
regenClipboard = new BlockArrayClipboard(region);
world.regenerate(region, regenClipboard);
getWorld().regenerate(region, regenClipboard);
} else {
regenClipboard = null;
}
@ -164,40 +162,51 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
int x = sx + ChunkUtil.getX(j);
int y = ChunkUtil.getY(layer, j);
int z = sz + ChunkUtil.getZ(j);
world.setBiome(BlockVector3.at(x, y, z), biome);
getWorld().setBiome(BlockVector3.at(x, y, z), biome);
}
}
if (localChunk.getTiles().size() > 0) {
localChunk.getTiles().forEach(((blockVector3, tag) -> {
try {
BaseBlock block = world.getBlock(blockVector3).toBaseBlock(tag);
world.setBlock(blockVector3, block, sideEffectSet);
BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag);
getWorld().setBlock(blockVector3, block, sideEffectSet);
} catch (WorldEditException ignored) {
StateWrapper sw = new StateWrapper(tag);
sw.restoreTag(world.getName(), blockVector3.getX(), blockVector3.getY(),
blockVector3.getZ());
sw.restoreTag(getWorld().getName(), blockVector3.getX(),
blockVector3.getY(), blockVector3.getZ());
}
}));
}
if (localChunk.getEntities().size() > 0) {
localChunk.getEntities().forEach((location, entity) -> {
getWorld().createEntity(location, entity);
});
}
};
}
CuboidRegion region;
Collection<BlockVector2> read = new ArrayList<>();
if ((region = getReadRegion()) != null) {
read = region.getChunks();
}
chunkCoordinator =
chunkCoordinatorBuilderFactory.create(chunkCoordinatorFactory).inWorld(world)
.withChunks(getBlockChunks().keySet()).withInitialBatchSize(3)
chunkCoordinatorBuilderFactory.create(chunkCoordinatorFactory).inWorld(getWorld())
.withChunks(getBlockChunks().keySet()).withChunks(read).withInitialBatchSize(3)
.withMaxIterationTime(40).withThrowableConsumer(Throwable::printStackTrace)
.withFinalAction(whenDone).withConsumer(consumer).build();
.withFinalAction(whenDone).withConsumer(consumer).unloadAfter(isUnloadAfter())
.build();
return super.enqueue();
}
private void setWorldBlock(int x, int y, int z, BaseBlock block, BlockVector2 blockVector2) {
try {
world.setBlock(BlockVector3.at(x, y, z), block, sideEffectSet);
getWorld().setBlock(BlockVector3.at(x, y, z), block, sideEffectSet);
} catch (WorldEditException ignored) {
// Fallback to not so nice method
BlockData blockData = BukkitAdapter.adapt(block);
if (bukkitWorld == null) {
bukkitWorld = Bukkit.getWorld(world.getName());
bukkitWorld = Bukkit.getWorld(getWorld().getName());
}
Chunk chunk = bukkitWorld.getChunkAt(blockVector2.getX(), blockVector2.getZ());
@ -218,7 +227,8 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
CompoundTag tag = block.getNbtData();
StateWrapper sw = new StateWrapper(tag);
sw.restoreTag(world.getName(), existing.getX(), existing.getY(), existing.getZ());
sw.restoreTag(getWorld().getName(), existing.getX(), existing.getY(),
existing.getZ());
}
}
}
@ -227,13 +237,4 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
this.whenDone = whenDone;
}
private void setMaterial(@Nonnull final BlockState plotBlock, @Nonnull final Block block) {
Material material = BukkitAdapter.adapt(plotBlock.getBlockType());
block.setType(material, false);
}
private boolean equals(@Nonnull final BlockState plotBlock, @Nonnull final Block block) {
return plotBlock.equals(BukkitBlockUtil.get(block));
}
}

View File

@ -129,37 +129,4 @@ public class BukkitChunkManager extends ChunkManager {
.getChunkAtAsync(BukkitUtil.getWorld(world), chunkLoc.getX(), chunkLoc.getZ(), force);
}
@Override
public void unloadChunk(final String world, final BlockVector2 chunkLoc, final boolean save) {
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
TaskManager.runTask(() -> BukkitUtil.getWorld(world)
.unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save));
} else {
BukkitUtil.getWorld(world).unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save);
}
}
private void count(int[] count, Entity entity) {
final com.sk89q.worldedit.world.entity.EntityType entityType =
BukkitAdapter.adapt(entity.getType());
if (EntityCategories.PLAYER.contains(entityType)) {
return;
} else if (EntityCategories.PROJECTILE.contains(entityType) || EntityCategories.OTHER
.contains(entityType) || EntityCategories.HANGING.contains(entityType)) {
count[CAP_MISC]++;
} else if (EntityCategories.ANIMAL.contains(entityType) || EntityCategories.VILLAGER
.contains(entityType) || EntityCategories.TAMEABLE.contains(entityType)) {
count[CAP_MOB]++;
count[CAP_ANIMAL]++;
} else if (EntityCategories.VEHICLE.contains(entityType)) {
count[CAP_VEHICLE]++;
} else if (EntityCategories.HOSTILE.contains(entityType)) {
count[CAP_MOB]++;
count[CAP_MONSTER]++;
}
count[CAP_ENTITY]++;
}
}

View File

@ -28,15 +28,13 @@ package com.plotsquared.bukkit.util;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.generator.AugmentedUtils;
import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.location.PlotLoc;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotManager;
import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.queue.QueueCoordinator;
import com.plotsquared.core.queue.ScopedQueueCoordinator;
import com.plotsquared.core.util.ChunkManager;
@ -45,13 +43,11 @@ import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockTypes;
import io.papermc.lib.PaperLib;
@ -63,17 +59,13 @@ import org.bukkit.entity.Player;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Semaphore;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ANIMAL;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ENTITY;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MISC;
@ -86,19 +78,8 @@ public class BukkitRegionManager extends RegionManager {
private static final Logger logger =
LoggerFactory.getLogger("P2/" + BukkitRegionManager.class.getSimpleName());
private final WorldUtil worldUtil;
private final ChunkCoordinatorFactory chunkCoordinatorFactory;
private final ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory;
@Inject public BukkitRegionManager(@Nonnull final ChunkManager chunkManager,
@Nonnull final WorldUtil worldUtil,
@Nonnull ChunkCoordinatorFactory chunkCoordinatorFactory,
@Nonnull ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory) {
super(chunkManager, worldUtil, chunkCoordinatorBuilderFactory);
this.worldUtil = worldUtil;
this.chunkCoordinatorFactory = chunkCoordinatorFactory;
this.chunkCoordinatorBuilderFactory = chunkCoordinatorBuilderFactory;
}
@Inject private WorldUtil worldUtil;
@Inject private GlobalBlockQueue blockQueue;
@Override public Set<BlockVector2> getChunkChunks(String world) {
Set<BlockVector2> chunks = super.getChunkChunks(world);
@ -141,7 +122,6 @@ public class BukkitRegionManager extends RegionManager {
}
PlotArea area = plot.getArea();
World world = BukkitUtil.getWorld(area.getWorldName());
Location bot = plot.getBottomAbs();
Location top = plot.getTopAbs();
int bx = bot.getX() >> 4;
@ -209,53 +189,6 @@ public class BukkitRegionManager extends RegionManager {
return count;
}
@Override @Inject
public boolean copyRegion(final Location pos1, final Location pos2, final Location newPos,
final Runnable whenDone) {
final int relX = newPos.getX() - pos1.getX();
final int relZ = newPos.getZ() - pos1.getZ();
final com.sk89q.worldedit.world.World oldWorld = worldUtil.getWeWorld(pos1.getWorldName());
final BukkitWorld newWorld = new BukkitWorld((World) newPos.getWorld());
assert oldWorld.equals(newWorld);
final ContentMap map = new ContentMap();
final QueueCoordinator queue =
PlotSquared.platform().getGlobalBlockQueue().getNewQueue(newWorld);
chunkCoordinatorBuilderFactory.create(chunkCoordinatorFactory).inWorld(newWorld)
.withRegion(pos1, pos2).withThrowableConsumer(Throwable::printStackTrace)
.withRegion(pos1, pos2).withInitialBatchSize(4).withMaxIterationTime(45)
.withConsumer(chunk -> {
int cbx = chunk.getX();
int cbz = chunk.getZ();
int bx = Math.max(pos1.getX() & 15, 0);
int bz = Math.max(pos1.getZ() & 15, 0);
int tx = Math.min(pos2.getX() & 15, 15);
int tz = Math.min(pos2.getZ() & 15, 15);
for (int x = bx; x <= tx; x++) {
for (int z = bz; z <= tz; z++) {
map.saveBlocks(newWorld, 256, cbx + x, cbz + z, relX, relZ);
}
}
}).withFinalAction(() -> {
for (Entry<PlotLoc, BaseBlock[]> entry : map.allBlocks.entrySet()) {
PlotLoc loc = entry.getKey();
BaseBlock[] blocks = entry.getValue();
for (int y = 0; y < blocks.length; y++) {
if (blocks[y] != null) {
BaseBlock block = blocks[y];
queue.setBlock(loc.getX(), y, loc.getZ(), block);
}
}
}
queue.setCompleteTask(() -> {
//map.restoreBlocks(newWorld, 0, 0);
map.restoreEntities(Bukkit.getWorld(newPos.getWorldName()), relX, relZ);
TaskManager.runTask(whenDone);
});
queue.enqueue();
});
return true;
}
@Override @Inject public boolean regenerateRegion(final Location pos1, final Location pos2,
final boolean ignoreAugment, final Runnable whenDone) {
final BukkitWorld world = new BukkitWorld((World) pos1.getWorld());
@ -269,130 +202,120 @@ public class BukkitRegionManager extends RegionManager {
final int tcx = p2x >> 4;
final int tcz = p2z >> 4;
final List<BlockVector2> chunks = new ArrayList<>();
final QueueCoordinator queue = blockQueue.getNewQueue(world);
queue.setReadRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()));
queue.setChunkConsumer(chunk -> {
for (int x = bcx; x <= tcx; x++) {
for (int z = bcz; z <= tcz; z++) {
chunks.add(BlockVector2.at(x, z));
int x = chunk.getX();
int z = chunk.getZ();
int xxb = x << 4;
int zzb = z << 4;
int xxt = xxb + 15;
int zzt = zzb + 15;
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
AugmentedUtils
.bypass(ignoreAugment, () -> queue.regenChunk(chunk.getX(), chunk.getZ()));
return;
}
}
boolean checkX1 = false;
final QueueCoordinator queue =
PlotSquared.platform().getGlobalBlockQueue().getNewQueue(world);
chunkCoordinatorBuilderFactory.create(chunkCoordinatorFactory).inWorld(world)
.withRegion(pos1, pos2).withThrowableConsumer(Throwable::printStackTrace)
.withRegion(pos1, pos2).withInitialBatchSize(4).withMaxIterationTime(45)
.withConsumer(chunk -> {
int xxb2;
int x = chunk.getX();
int z = chunk.getZ();
int xxb = x << 4;
int zzb = z << 4;
int xxt = xxb + 15;
int zzt = zzb + 15;
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
AugmentedUtils.bypass(ignoreAugment,
() -> queue.regenChunk(chunk.getX(), chunk.getZ()));
return;
}
boolean checkX1 = false;
int xxb2;
if (x == bcx) {
xxb2 = p1x - 1;
checkX1 = true;
} else {
xxb2 = xxb;
}
boolean checkX2 = false;
int xxt2;
if (x == tcx) {
xxt2 = p2x + 1;
checkX2 = true;
} else {
xxt2 = xxt;
}
boolean checkZ1 = false;
int zzb2;
if (z == bcz) {
zzb2 = p1z - 1;
checkZ1 = true;
} else {
zzb2 = zzb;
}
boolean checkZ2 = false;
int zzt2;
if (z == tcz) {
zzt2 = p2z + 1;
checkZ2 = true;
} else {
zzt2 = zzt;
}
final ContentMap map = new ContentMap();
if (checkX1) {
map.saveRegion(world, xxb, xxb2, zzb2, zzt2); //
}
if (checkX2) {
map.saveRegion(world, xxt2, xxt, zzb2, zzt2); //
}
if (checkZ1) {
map.saveRegion(world, xxb2, xxt2, zzb, zzb2); //
}
if (checkZ2) {
map.saveRegion(world, xxb2, xxt2, zzt2, zzt); //
}
if (checkX1 && checkZ1) {
map.saveRegion(world, xxb, xxb2, zzb, zzb2); //
}
if (checkX2 && checkZ1) {
map.saveRegion(world, xxt2, xxt, zzb, zzb2); // ?
}
if (checkX1 && checkZ2) {
map.saveRegion(world, xxb, xxb2, zzt2, zzt); // ?
}
if (checkX2 && checkZ2) {
map.saveRegion(world, xxt2, xxt, zzt2, zzt); //
}
CuboidRegion currentPlotClear =
RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z),
currentPlotClear);
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager
.setChunkInPlotArea(null, new RunnableVal<ScopedQueueCoordinator>() {
@Override public void run(ScopedQueueCoordinator value) {
Location min = value.getMin();
int bx = min.getX();
int bz = min.getZ();
for (int x1 = 0; x1 < 16; x1++) {
for (int z1 = 0; z1 < 16; z1++) {
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
BaseBlock[] ids = map.allBlocks.get(plotLoc);
if (ids != null) {
for (int y = 0; y < Math.min(128, ids.length); y++) {
BaseBlock id = ids[y];
if (id != null) {
value.setBlock(x1, y, z1, id);
} else {
value.setBlock(x1, y, z1,
BlockTypes.AIR.getDefaultState());
}
if (x == bcx) {
xxb2 = p1x - 1;
checkX1 = true;
} else {
xxb2 = xxb;
}
boolean checkX2 = false;
int xxt2;
if (x == tcx) {
xxt2 = p2x + 1;
checkX2 = true;
} else {
xxt2 = xxt;
}
boolean checkZ1 = false;
int zzb2;
if (z == bcz) {
zzb2 = p1z - 1;
checkZ1 = true;
} else {
zzb2 = zzb;
}
boolean checkZ2 = false;
int zzt2;
if (z == tcz) {
zzt2 = p2z + 1;
checkZ2 = true;
} else {
zzt2 = zzt;
}
final ContentMap map = new ContentMap();
if (checkX1) {
map.saveRegion(world, xxb, xxb2, zzb2, zzt2); //
}
if (checkX2) {
map.saveRegion(world, xxt2, xxt, zzb2, zzt2); //
}
if (checkZ1) {
map.saveRegion(world, xxb2, xxt2, zzb, zzb2); //
}
if (checkZ2) {
map.saveRegion(world, xxb2, xxt2, zzt2, zzt); //
}
if (checkX1 && checkZ1) {
map.saveRegion(world, xxb, xxb2, zzb, zzb2); //
}
if (checkX2 && checkZ1) {
map.saveRegion(world, xxt2, xxt, zzb, zzb2); // ?
}
if (checkX1 && checkZ2) {
map.saveRegion(world, xxb, xxb2, zzt2, zzt); // ?
}
if (checkX2 && checkZ2) {
map.saveRegion(world, xxt2, xxt, zzt2, zzt); //
}
CuboidRegion currentPlotClear =
RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z),
currentPlotClear);
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager
.setChunkInPlotArea(null, new RunnableVal<ScopedQueueCoordinator>() {
@Override public void run(ScopedQueueCoordinator value) {
Location min = value.getMin();
int bx = min.getX();
int bz = min.getZ();
for (int x1 = 0; x1 < 16; x1++) {
for (int z1 = 0; z1 < 16; z1++) {
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
BaseBlock[] ids = map.allBlocks.get(plotLoc);
if (ids != null) {
for (int y = 0; y < Math.min(128, ids.length); y++) {
BaseBlock id = ids[y];
if (id != null) {
value.setBlock(x1, y, z1, id);
} else {
value.setBlock(x1, y, z1,
BlockTypes.AIR.getDefaultState());
}
for (int y = Math.min(128, ids.length);
y < ids.length; y++) {
BaseBlock id = ids[y];
if (id != null) {
value.setBlock(x1, y, z1, id);
}
}
for (int y = Math.min(128, ids.length); y < ids.length; y++) {
BaseBlock id = ids[y];
if (id != null) {
value.setBlock(x1, y, z1, id);
}
}
}
}
}
}, world.getName(), chunk));
//map.restoreBlocks(worldObj, 0, 0);
map.restoreEntities(Bukkit.getWorld(world.getName()), 0, 0);
}).withFinalAction(whenDone);
}
}, world.getName(), chunk));
//map.restoreBlocks(worldObj, 0, 0);
map.restoreEntities(Bukkit.getWorld(world.getName()), 0, 0);
});
queue.setCompleteTask(whenDone);
queue.enqueue();
return true;
}
@ -425,62 +348,6 @@ public class BukkitRegionManager extends RegionManager {
}
}
@Override public void swap(Location bot1, Location top1, Location bot2, Location top2,
final Runnable whenDone) {
CuboidRegion region1 =
RegionUtil.createRegion(bot1.getX(), top1.getX(), bot1.getZ(), top1.getZ());
CuboidRegion region2 =
RegionUtil.createRegion(bot2.getX(), top2.getX(), bot2.getZ(), top2.getZ());
final World world1 = Bukkit.getWorld(bot1.getWorldName());
final World world2 = Bukkit.getWorld(bot2.getWorldName());
checkNotNull(world1, "Critical error during swap.");
checkNotNull(world2, "Critical error during swap.");
int relX = bot2.getX() - bot1.getX();
int relZ = bot2.getZ() - bot1.getZ();
final ArrayDeque<ContentMap> maps = new ArrayDeque<>();
for (int x = bot1.getX() >> 4; x <= top1.getX() >> 4; x++) {
for (int z = bot1.getZ() >> 4; z <= top1.getZ() >> 4; z++) {
Chunk chunk1 = world1.getChunkAt(x, z);
Chunk chunk2 = world2.getChunkAt(x + (relX >> 4), z + (relZ >> 4));
maps.add(
BukkitChunkManager.swapChunk(world1, world2, chunk1, chunk2, region1, region2));
}
}
PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(() -> {
for (ContentMap map : maps) {
map.restoreEntities(world1, 0, 0);
TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
}
});
}
@Override
public void setBiome(final CuboidRegion region, final int extendBiome, final BiomeType biome,
final String world, final Runnable whenDone) {
Location pos1 = Location.at(world, region.getMinimumPoint().getX() - extendBiome,
region.getMinimumPoint().getY(), region.getMinimumPoint().getZ() - extendBiome);
Location pos2 = Location.at(world, region.getMaximumPoint().getX() + extendBiome,
region.getMaximumPoint().getY(), region.getMaximumPoint().getZ() + extendBiome);
final QueueCoordinator queue = PlotSquared.platform().getGlobalBlockQueue()
.getNewQueue(worldUtil.getWeWorld(world));
final int minX = pos1.getX();
final int minZ = pos1.getZ();
final int maxX = pos2.getX();
final int maxZ = pos2.getZ();
queue.setChunkConsumer(blockVector2 -> {
final int cx = blockVector2.getX() << 4;
final int cz = blockVector2.getZ() << 4;
WorldUtil
.setBiome(world, Math.max(minX, cx), Math.max(minZ, cz), Math.min(maxX, cx + 15),
Math.min(maxZ, cz + 15), biome);
worldUtil.refreshChunk(blockVector2.getBlockX(), blockVector2.getBlockZ(), world);
});
queue.enqueue();
}
private void count(int[] count, Entity entity) {
final com.sk89q.worldedit.world.entity.EntityType entityType =
BukkitAdapter.adapt(entity.getType());