From 27498f68fba7ac43c0fa35ba2300a10d57f8af6b Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 23 Jul 2020 17:30:23 +0100 Subject: [PATCH] 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) --- .../bukkit/inject/BukkitModule.java | 5 +- .../bukkit/queue/BukkitChunkCoordinator.java | 9 +- .../bukkit/queue/BukkitQueueCoordinator.java | 53 +-- .../bukkit/util/BukkitChunkManager.java | 33 -- .../bukkit/util/BukkitRegionManager.java | 349 ++++++------------ .../com/plotsquared/core/command/Area.java | 165 +++++---- .../core/generator/AugmentedUtils.java | 25 +- .../core/generator/HybridPlotManager.java | 3 + .../core/generator/HybridUtils.java | 12 +- .../factory/ChunkCoordinatorFactory.java | 7 +- .../java/com/plotsquared/core/plot/Plot.java | 4 +- .../core/queue/BasicQueueCoordinator.java | 46 ++- .../core/queue/ChunkCoordinatorBuilder.java | 36 +- .../core/queue/DelegateQueueCoordinator.java | 36 ++ .../plotsquared/core/queue/LocalChunk.java | 18 +- .../core/queue/QueueCoordinator.java | 19 + .../plotsquared/core/queue/QueueProvider.java | 15 +- .../plotsquared/core/util/ChunkManager.java | 18 - .../plotsquared/core/util/RegionManager.java | 186 ++++++---- .../core/util/SchematicHandler.java | 3 +- build.gradle | 2 +- 21 files changed, 504 insertions(+), 540 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java index 3361add35..17afd5a1b 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java @@ -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); diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitChunkCoordinator.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitChunkCoordinator.java index 41ebeef24..3961cbdac 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitChunkCoordinator.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitChunkCoordinator.java @@ -69,6 +69,7 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator { private final org.bukkit.World bukkitWorld; private final Runnable whenDone; private final Consumer 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 requestedChunks, @Assisted @Nonnull final Runnable whenDone, - @Assisted @Nonnull final Consumer throwableConsumer) { + @Assisted @Nonnull final Consumer 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 diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java index cdb8a7b5e..a2bd8afeb 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitQueueCoordinator.java @@ -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 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)); - } - } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java index ed2898c65..4e5bfb49b 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java @@ -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]++; - } - - } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java index 795a4cab9..23ed242d7 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java @@ -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 getChunkChunks(String world) { Set 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 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 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() { - @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() { + @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 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()); diff --git a/Core/src/main/java/com/plotsquared/core/command/Area.java b/Core/src/main/java/com/plotsquared/core/command/Area.java index aad920373..5003b3b14 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Area.java +++ b/Core/src/main/java/com/plotsquared/core/command/Area.java @@ -27,8 +27,6 @@ package com.plotsquared.core.command; import com.google.inject.Inject; import com.plotsquared.core.PlotSquared; -import com.plotsquared.core.inject.annotations.WorldConfig; -import com.plotsquared.core.inject.annotations.WorldFile; import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.ConfigurationUtil; @@ -36,6 +34,8 @@ import com.plotsquared.core.configuration.file.YamlConfiguration; import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.generator.AugmentedUtils; import com.plotsquared.core.generator.HybridPlotWorld; +import com.plotsquared.core.inject.annotations.WorldConfig; +import com.plotsquared.core.inject.annotations.WorldFile; import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; import com.plotsquared.core.location.Location; import com.plotsquared.core.player.ConsolePlayer; @@ -46,6 +46,8 @@ import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.message.PlotMessage; import com.plotsquared.core.plot.world.PlotAreaManager; +import com.plotsquared.core.queue.GlobalBlockQueue; +import com.plotsquared.core.queue.QueueCoordinator; import com.plotsquared.core.setup.PlotAreaBuilder; import com.plotsquared.core.util.FileUtils; import com.plotsquared.core.util.MainUtil; @@ -57,7 +59,6 @@ import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.WorldUtil; -import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal3; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; @@ -68,12 +69,11 @@ import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.Operations; -import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; -import javax.annotation.Nonnull; +import javax.annotation.Nonnull; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -100,14 +100,14 @@ public class Area extends SubCommand { private final SetupUtils setupUtils; private final WorldUtil worldUtil; private final RegionManager regionManager; + private final GlobalBlockQueue blockQueue; @Inject public Area(@Nonnull final PlotAreaManager plotAreaManager, - @WorldConfig @Nonnull final YamlConfiguration worldConfiguration, - @WorldFile @Nonnull final File worldFile, - @Nonnull final HybridPlotWorldFactory hybridPlotWorldFactory, - @Nonnull final SetupUtils setupUtils, - @Nonnull final WorldUtil worldUtil, - @Nonnull final RegionManager regionManager) { + @WorldConfig @Nonnull final YamlConfiguration worldConfiguration, + @WorldFile @Nonnull final File worldFile, + @Nonnull final HybridPlotWorldFactory hybridPlotWorldFactory, + @Nonnull final SetupUtils setupUtils, @Nonnull final WorldUtil worldUtil, + @Nonnull final RegionManager regionManager, @Nonnull final GlobalBlockQueue blockQueue) { this.plotAreaManager = plotAreaManager; this.worldConfiguration = worldConfiguration; this.worldFile = worldFile; @@ -115,6 +115,7 @@ public class Area extends SubCommand { this.setupUtils = setupUtils; this.worldUtil = worldUtil; this.regionManager = regionManager; + this.blockQueue = blockQueue; } @Override public boolean onCommand(final PlotPlayer player, String[] args) { @@ -129,27 +130,32 @@ public class Area extends SubCommand { return false; } if (!Permissions.hasPermission(player, Captions.PERMISSION_AREA_CREATE)) { - MainUtil.sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_AREA_CREATE); + MainUtil.sendMessage(player, Captions.NO_PERMISSION, + Captions.PERMISSION_AREA_CREATE); return false; } if (args.length < 2) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_NEEDS_NAME); return false; } - final PlotArea existingArea = this.plotAreaManager.getPlotArea(player.getLocation().getWorldName(), args[1]); + final PlotArea existingArea = + this.plotAreaManager.getPlotArea(player.getLocation().getWorldName(), args[1]); if (existingArea != null && existingArea.getId().equalsIgnoreCase(args[1])) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_NAME_TAKEN); return false; } - final LocalSession localSession = WorldEdit.getInstance().getSessionManager().getIfPresent(player.toActor()); + final LocalSession localSession = + WorldEdit.getInstance().getSessionManager().getIfPresent(player.toActor()); if (localSession == null) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION); return false; } Region playerSelectedRegion = null; try { - playerSelectedRegion = localSession.getSelection(((Player) player.toActor()).getWorld()); - } catch (final Exception ignored) {} + playerSelectedRegion = + localSession.getSelection(((Player) player.toActor()).getWorld()); + } catch (final Exception ignored) { + } if (playerSelectedRegion == null) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_MISSING_SELECTION); return false; @@ -158,23 +164,28 @@ public class Area extends SubCommand { MainUtil.sendMessage(player, Captions.SINGLE_AREA_NOT_SQUARE); return false; } - if (this.plotAreaManager.getPlotAreas( - Objects.requireNonNull(playerSelectedRegion.getWorld()).getName(), CuboidRegion.makeCuboid(playerSelectedRegion)).length != 0) { + if (this.plotAreaManager + .getPlotAreas(Objects.requireNonNull(playerSelectedRegion.getWorld()).getName(), + CuboidRegion.makeCuboid(playerSelectedRegion)).length != 0) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_OVERLAPPING); } // Alter the region final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint(); final BlockVector3 playerSelectionMax = playerSelectedRegion.getMaximumPoint(); // Create a new selection that spans the entire vertical range of the world - final CuboidRegion selectedRegion = new CuboidRegion(playerSelectedRegion.getWorld(), - BlockVector3.at(playerSelectionMin.getX(), 0, playerSelectionMin.getZ()), - BlockVector3.at(playerSelectionMax.getX(), 255, playerSelectionMax.getZ())); + final CuboidRegion selectedRegion = + new CuboidRegion(playerSelectedRegion.getWorld(), + BlockVector3.at(playerSelectionMin.getX(), 0, playerSelectionMin.getZ()), + BlockVector3.at(playerSelectionMax.getX(), 255, playerSelectionMax.getZ())); // There's only one plot in the area... final PlotId plotId = PlotId.of(1, 1); - final HybridPlotWorld hybridPlotWorld = this.hybridPlotWorldFactory.create(player.getLocation().getWorldName(), args[1], - Objects.requireNonNull(PlotSquared.platform()).getDefaultGenerator(), plotId, plotId); + final HybridPlotWorld hybridPlotWorld = this.hybridPlotWorldFactory + .create(player.getLocation().getWorldName(), args[1], + Objects.requireNonNull(PlotSquared.platform()).getDefaultGenerator(), + plotId, plotId); // Plot size is the same as the region width - hybridPlotWorld.PLOT_WIDTH = hybridPlotWorld.SIZE = (short) selectedRegion.getWidth(); + hybridPlotWorld.PLOT_WIDTH = + hybridPlotWorld.SIZE = (short) selectedRegion.getWidth(); // We use a schematic generator hybridPlotWorld.setTerrain(PlotAreaTerrainType.NONE); // It is always a partial plot world @@ -182,23 +193,30 @@ public class Area extends SubCommand { // We save the schematic :D hybridPlotWorld.PLOT_SCHEMATIC = true; // Set the road width to 0 - hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0; + hybridPlotWorld.ROAD_WIDTH = + hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0; // Set the plot height to the selection height - hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = playerSelectionMin.getBlockY(); + hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = + hybridPlotWorld.WALL_HEIGHT = playerSelectionMin.getBlockY(); // No sign plz hybridPlotWorld.setAllowSigns(false); - final File parentFile = FileUtils.getFile(PlotSquared.platform().getDirectory(), "schematics" + File.separator + - "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator + - hybridPlotWorld.getId()); + final File parentFile = FileUtils.getFile(PlotSquared.platform().getDirectory(), + "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + + hybridPlotWorld.getWorldName() + File.separator + hybridPlotWorld + .getId()); if (!parentFile.exists() && !parentFile.mkdirs()) { MainUtil.sendMessage(player, Captions.SINGLE_AREA_COULD_NOT_MAKE_DIRECTORIES); return false; } final File file = new File(parentFile, "plot.schem"); - try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) { + try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC + .getWriter(new FileOutputStream(file))) { final BlockArrayClipboard clipboard = new BlockArrayClipboard(selectedRegion); - final EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(selectedRegion.getWorld(), -1); - final ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(editSession, selectedRegion, clipboard, selectedRegion.getMinimumPoint()); + final EditSession editSession = WorldEdit.getInstance().getEditSessionFactory() + .getEditSession(selectedRegion.getWorld(), -1); + final ForwardExtentCopy forwardExtentCopy = + new ForwardExtentCopy(editSession, selectedRegion, clipboard, + selectedRegion.getMinimumPoint()); forwardExtentCopy.setCopyingBiomes(true); forwardExtentCopy.setCopyingEntities(true); Operations.complete(forwardExtentCopy); @@ -221,14 +239,14 @@ public class Area extends SubCommand { // Now the schematic is saved, which is wonderful! PlotAreaBuilder singleBuilder = PlotAreaBuilder.ofPlotArea(hybridPlotWorld) - .plotManager(PlotSquared.platform().getPluginName()) - .generatorName(PlotSquared.platform().getPluginName()) - .maximumId(plotId) - .minimumId(plotId); + .plotManager(PlotSquared.platform().getPluginName()) + .generatorName(PlotSquared.platform().getPluginName()).maximumId(plotId) + .minimumId(plotId); Runnable singleRun = () -> { final String path = - "worlds." + hybridPlotWorld.getWorldName() + ".areas." + hybridPlotWorld.getId() + '-' - + singleBuilder.minimumId() + '-' + singleBuilder.maximumId(); + "worlds." + hybridPlotWorld.getWorldName() + ".areas." + hybridPlotWorld + .getId() + '-' + singleBuilder.minimumId() + '-' + singleBuilder + .maximumId(); final int offsetX = singlePos1.getX(); final int offsetZ = singlePos1.getZ(); if (offsetX != 0) { @@ -314,19 +332,20 @@ public class Area extends SubCommand { return false; } PlotAreaBuilder builder = PlotAreaBuilder.ofPlotArea(area) - .plotManager(PlotSquared.platform().getPluginName()) - .generatorName(PlotSquared.platform().getPluginName()) - .minimumId(PlotId.of(1, 1)) - .maximumId(PlotId.of(numX, numZ)); + .plotManager(PlotSquared.platform().getPluginName()) + .generatorName(PlotSquared.platform().getPluginName()) + .minimumId(PlotId.of(1, 1)).maximumId(PlotId.of(numX, numZ)); final String path = "worlds." + area.getWorldName() + ".areas." + area.getId() + '-' + builder.minimumId() + '-' + builder.maximumId(); Runnable run = () -> { if (offsetX != 0) { - this.worldConfiguration.set(path + ".road.offset.x", offsetX); + this.worldConfiguration + .set(path + ".road.offset.x", offsetX); } if (offsetZ != 0) { - this.worldConfiguration.set(path + ".road.offset.z", offsetZ); + this.worldConfiguration + .set(path + ".road.offset.z", offsetZ); } final String world = this.setupUtils.setupWorld(builder); if (this.worldUtil.isWorld(world)) { @@ -335,14 +354,13 @@ public class Area extends SubCommand { player.teleport(this.worldUtil.getSpawn(world), TeleportCause.COMMAND); if (area.getTerrain() != PlotAreaTerrainType.ALL) { - this.regionManager.largeRegionTask(world, region, - new RunnableVal() { - @Override public void run(BlockVector2 value) { - AugmentedUtils - .generate(null, world, value.getX(), - value.getZ(), null); - } - }, null); + QueueCoordinator queue = + blockQueue.getNewQueue(worldUtil.getWeWorld(world)); + queue.setChunkConsumer(chunk -> AugmentedUtils + .generate(null, world, chunk.getX(), chunk.getZ(), + queue)); + queue.setReadRegion(region); + queue.enqueue(); } } else { MainUtil.sendMessage(player, @@ -368,14 +386,16 @@ public class Area extends SubCommand { } PlotAreaBuilder builder = PlotAreaBuilder.newBuilder(); builder.worldName(split[0]); - final HybridPlotWorld pa = this.hybridPlotWorldFactory.create(builder.worldName(), - id, PlotSquared.platform().getDefaultGenerator(), null, null); + final HybridPlotWorld pa = this.hybridPlotWorldFactory + .create(builder.worldName(), id, + PlotSquared.platform().getDefaultGenerator(), null, null); PlotArea other = this.plotAreaManager.getPlotArea(pa.getWorldName(), id); if (other != null && Objects.equals(pa.getId(), other.getId())) { Captions.SETUP_WORLD_TAKEN.send(player, pa.toString()); return false; } - Set areas = this.plotAreaManager.getPlotAreasSet(pa.getWorldName()); + Set areas = + this.plotAreaManager.getPlotAreasSet(pa.getWorldName()); if (!areas.isEmpty()) { PlotArea area = areas.iterator().next(); pa.setType(area.getType()); @@ -454,7 +474,8 @@ public class Area extends SubCommand { if (!this.worldConfiguration.contains(path)) { this.worldConfiguration.createSection(path); } - ConfigurationSection section = this.worldConfiguration.getConfigurationSection(path); + ConfigurationSection section = + this.worldConfiguration.getConfigurationSection(path); pa.saveConfiguration(section); pa.loadConfiguration(section); builder.plotManager(PlotSquared.platform().getPluginName()); @@ -581,7 +602,8 @@ public class Area extends SubCommand { Captions.COMMAND_SYNTAX.send(player, getCommandString() + " list [#]"); return false; } - final List areas = new ArrayList<>(Arrays.asList(this.plotAreaManager.getAllPlotAreas())); + final List areas = + new ArrayList<>(Arrays.asList(this.plotAreaManager.getAllPlotAreas())); paginate(player, areas, 8, page, new RunnableVal3() { @Override public void run(Integer i, PlotArea area, PlotMessage message) { @@ -596,7 +618,8 @@ public class Area extends SubCommand { PlotId max = area.getMax(); name = area.getWorldName() + ';' + area.getId() + ';' + min + ';' + max; - int size = (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1); + int size = + (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1); percent = claimed == 0 ? 0 : size / (double) claimed; region = area.getRegion().toString(); } else { @@ -641,14 +664,14 @@ public class Area extends SubCommand { "$4Stop the server and delete: " + area.getWorldName() + "/region"); return false; } - this.regionManager.largeRegionTask(area.getWorldName(), area.getRegion(), - new RunnableVal() { - @Override public void run(BlockVector2 value) { - AugmentedUtils - .generate(null, area.getWorldName(), value.getX(), value.getZ(), - null); - } - }, () -> player.sendMessage("Regen complete")); + + QueueCoordinator queue = + blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); + queue.setChunkConsumer(chunk -> AugmentedUtils + .generate(null, area.getWorldName(), chunk.getX(), chunk.getZ(), queue)); + queue.setReadRegion(area.getRegion()); + queue.setCompleteTask(() -> player.sendMessage("Regen complete")); + queue.enqueue(); return true; } case "goto": @@ -676,11 +699,13 @@ public class Area extends SubCommand { } else { CuboidRegion region = area.getRegion(); center = Location.at(area.getWorldName(), region.getMinimumPoint().getX() - + (region.getMaximumPoint().getX() - region.getMinimumPoint().getX()) / 2, + + (region.getMaximumPoint().getX() - region.getMinimumPoint().getX()) / 2, 0, region.getMinimumPoint().getZ() - + (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ()) / 2); - this.worldUtil.getHighestBlock(area.getWorldName(), center.getX(), center.getZ(), y -> - player.teleport(center.withY(1 + y), TeleportCause.COMMAND)); + + (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ()) + / 2); + this.worldUtil + .getHighestBlock(area.getWorldName(), center.getX(), center.getZ(), + y -> player.teleport(center.withY(1 + y), TeleportCause.COMMAND)); } return true; case "delete": diff --git a/Core/src/main/java/com/plotsquared/core/generator/AugmentedUtils.java b/Core/src/main/java/com/plotsquared/core/generator/AugmentedUtils.java index 1a06a412d..8c797ba45 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/AugmentedUtils.java +++ b/Core/src/main/java/com/plotsquared/core/generator/AugmentedUtils.java @@ -72,6 +72,7 @@ public class AugmentedUtils { if (areas.isEmpty()) { return false; } + boolean enqueue = false; boolean generationResult = false; for (final PlotArea area : areas) { // A normal plot world may not contain any clusters @@ -81,14 +82,18 @@ public class AugmentedUtils { } // This means that full vanilla generation is used // so we do not interfere - if (area.getTerrain() == PlotAreaTerrainType.ALL) { + if (area.getTerrain() == PlotAreaTerrainType.ALL || !area.contains(blockX, blockZ)) { continue; } IndependentPlotGenerator generator = area.getGenerator(); // Mask if (queue == null) { - queue = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(world)); - queue.setChunkObject(chunkObject); + enqueue = true; + queue = PlotSquared.platform().getGlobalBlockQueue() + .getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(world)); + if (chunkObject != null) { + queue.setChunkObject(chunkObject); + } } QueueCoordinator primaryMask; // coordinates @@ -109,7 +114,6 @@ public class AugmentedUtils { relativeTopX = relativeTopZ = 15; primaryMask = queue; } - QueueCoordinator secondaryMask; BlockState air = BlockTypes.AIR.getDefaultState(); if (area.getTerrain() == PlotAreaTerrainType.ROAD) { @@ -147,10 +151,12 @@ public class AugmentedUtils { } generationResult = true; } - primaryMask.setChunkObject(chunkObject); - primaryMask.setForceSync(true); - secondaryMask.setChunkObject(chunkObject); - secondaryMask.setForceSync(true); + if (chunkObject != null) { + primaryMask.setChunkObject(chunkObject); + } + if (chunkObject != null) { + secondaryMask.setChunkObject(chunkObject); + } ScopedQueueCoordinator scoped = new ScopedQueueCoordinator(secondaryMask, Location.at(world, blockX, 0, blockZ), @@ -158,8 +164,7 @@ public class AugmentedUtils { generator.generateChunk(scoped, area); generator.populateChunk(scoped, area); } - if (queue != null) { - queue.setForceSync(true); + if (enqueue) { queue.enqueue(); } return generationResult; diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java index 3955a00ee..0353210a6 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java @@ -42,6 +42,7 @@ import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.WorldUtil; import com.sk89q.worldedit.function.pattern.Pattern; +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.BlockState; @@ -247,6 +248,8 @@ public class HybridPlotManager extends ClassicPlotManager { final BiomeType biome = hybridPlotWorld.getPlotBiome(); final QueueCoordinator queue = hybridPlotWorld.getQueue(); + queue.setReadRegion(new CuboidRegion(plot.getExtendedBottomAbs().getBlockVector3(), + plot.getExtendedTopAbs().getBlockVector3())); queue.setChunkConsumer(blockVector2 -> { // If the chunk isn't near the edge and it isn't an augmented world we can just regen the whole chunk if (canRegen && ChunkUtil.isWholeChunk(pos1, pos2, blockVector2)) { diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java index c54e494aa..11560e33c 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java @@ -161,7 +161,7 @@ public class HybridUtils { System.gc(); QueueCoordinator queue = area.getQueue(); - + queue.setReadRegion(region); queue.setChunkConsumer(blockVector2 -> { int X = blockVector2.getX(); int Z = blockVector2.getZ(); @@ -438,7 +438,6 @@ public class HybridUtils { if (!regenedRoad && Settings.DEBUG) { logger.info("[P2] Failed to regenerate roads"); } - chunkManager.unloadChunk(area.getWorldName(), chunk, true); } if (Settings.DEBUG) { logger.info("[P2] Cancelled road task"); @@ -500,15 +499,6 @@ public class HybridUtils { logger.error( "[P2] Error! Could not update '{}/region/r.{}.{}.mca' (Corrupt chunk?)", area.getWorldHash(), loc.getX(), loc.getZ()); - int sx = loc.getX() << 5; - int sz = loc.getZ() << 5; - for (int x = sx; x < sx + 32; x++) { - for (int z = sz; z < sz + 32; z++) { - chunkManager - .unloadChunk(area.getWorldName(), BlockVector2.at(x, z), - true); - } - } } TaskManager.runTaskLater(task, TaskTime.seconds(1L)); }); diff --git a/Core/src/main/java/com/plotsquared/core/inject/factory/ChunkCoordinatorFactory.java b/Core/src/main/java/com/plotsquared/core/inject/factory/ChunkCoordinatorFactory.java index 26b30b0c4..df87be525 100644 --- a/Core/src/main/java/com/plotsquared/core/inject/factory/ChunkCoordinatorFactory.java +++ b/Core/src/main/java/com/plotsquared/core/inject/factory/ChunkCoordinatorFactory.java @@ -28,7 +28,6 @@ package com.plotsquared.core.inject.factory; import com.plotsquared.core.queue.ChunkCoordinator; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.world.World; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import java.util.Collection; @@ -37,8 +36,8 @@ import java.util.function.Consumer; public interface ChunkCoordinatorFactory { @Nonnull ChunkCoordinator create(final long maxIterationTime, final int initialBatchSize, - @NotNull final Consumer chunkConsumer, @NotNull final World world, - @NotNull final Collection requestedChunks, @NotNull final Runnable whenDone, - @NotNull final Consumer throwableConsumer); + @Nonnull final Consumer chunkConsumer, @Nonnull final World world, + @Nonnull final Collection requestedChunks, @Nonnull final Runnable whenDone, + @Nonnull final Consumer throwableConsumer, final boolean unloadAfter); } diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java index 13ec128eb..a7bc5a033 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java +++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java @@ -3312,9 +3312,7 @@ public class Plot { Location pos2 = corners[1]; Location pos3 = pos1.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName()); - Location pos4 = - pos2.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName()); - regionManager.swap(pos1, pos2, pos3, pos4, this); + regionManager.swap(pos1, pos2, pos3, this); } } }.run(); diff --git a/Core/src/main/java/com/plotsquared/core/queue/BasicQueueCoordinator.java b/Core/src/main/java/com/plotsquared/core/queue/BasicQueueCoordinator.java index f60f43efa..cfb36ca65 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/BasicQueueCoordinator.java +++ b/Core/src/main/java/com/plotsquared/core/queue/BasicQueueCoordinator.java @@ -27,12 +27,16 @@ package com.plotsquared.core.queue; import com.plotsquared.core.util.PatternUtil; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.World; 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.entity.EntityTypes; import javax.annotation.Nonnull; import java.util.concurrent.ConcurrentHashMap; @@ -53,6 +57,8 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { private int[] regenStart; private int[] regenEnd; private Consumer consumer = null; + private boolean unloadAfter = true; + private CuboidRegion readRegion = null; private GlobalBlockQueue globalBlockQueue; @@ -61,12 +67,6 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { this.modified = System.currentTimeMillis(); } - public LocalChunk getLocalChunk(int x, int z) { - return new LocalChunk(this, x, z) { - // Allow implementation-specific custom stuff here - }; - } - @Override public abstract BlockState getBlock(int x, int y, int z); @Override public final World getWorld() { @@ -132,12 +132,30 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { return this.settingTiles; } + @Override public boolean setEntity(Entity entity) { + if (entity.getState() == null || entity.getState().getType() == EntityTypes.PLAYER) { + return false; + } + Location location = entity.getBlockLocation(); + LocalChunk chunk = getChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4); + chunk.setEntity(location, entity.getState()); + return true; + } + + @Override public CuboidRegion getReadRegion() { + return this.readRegion; + } + + @Override public void setReadRegion(CuboidRegion readRegion) { + this.readRegion = readRegion; + } + @Override public void regenChunk(int x, int z) { regen = true; // There will never only be one nullified coordinate pair if (regenStart == null) { - regenStart = new int[]{x, z}; - regenEnd = new int[]{x, z}; + regenStart = new int[] {x, z}; + regenEnd = new int[] {x, z}; return; } if (x < regenStart[0]) { @@ -154,6 +172,14 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { } } + @Override public boolean isUnloadAfter() { + return this.unloadAfter; + } + + @Override public void setUnloadAfter(boolean unloadAfter) { + this.unloadAfter = unloadAfter; + } + public int[] getRegenStart() { return regenStart; } @@ -189,7 +215,7 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { BlockVector2 pair = BlockVector2.at(chunkX, chunkZ); lastWrappedChunk = this.blockChunks.get(pair); if (lastWrappedChunk == null) { - lastWrappedChunk = this.getLocalChunk(chunkX, chunkZ); + lastWrappedChunk = new LocalChunk(this, chunkX, chunkZ); LocalChunk previous = this.blockChunks.put(pair, lastWrappedChunk); if (previous == null) { return lastWrappedChunk; @@ -199,6 +225,4 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { } return lastWrappedChunk; } - - } diff --git a/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java b/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java index 861ccc8ed..068d61aea 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java +++ b/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java @@ -30,6 +30,7 @@ import com.google.inject.Inject; import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory; import com.plotsquared.core.location.Location; import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.World; import org.jetbrains.annotations.NotNull; @@ -51,30 +52,32 @@ public class ChunkCoordinatorBuilder { }; private long maxIterationTime = 60; // A little over 1 tick; private int initialBatchSize = 4; + private boolean unloadAfter = true; + private CuboidRegion readRegion = null; @Inject public ChunkCoordinatorBuilder(@Nonnull ChunkCoordinatorFactory chunkCoordinatorFactory) { this.chunkCoordinatorFactory = chunkCoordinatorFactory; } - @NotNull public ChunkCoordinatorBuilder inWorld(@NotNull final World world) { + @Nonnull public ChunkCoordinatorBuilder inWorld(@Nonnull final World world) { this.world = Preconditions.checkNotNull(world, "World may not be null"); return this; } - @NotNull public ChunkCoordinatorBuilder withChunk(@NotNull final BlockVector2 chunkLocation) { + @Nonnull public ChunkCoordinatorBuilder withChunk(@Nonnull final BlockVector2 chunkLocation) { this.requestedChunks .add(Preconditions.checkNotNull(chunkLocation, "Chunk location may not be null")); return this; } - @NotNull public ChunkCoordinatorBuilder withChunks( - @NotNull final Collection chunkLocations) { + @Nonnull public ChunkCoordinatorBuilder withChunks( + @Nonnull final Collection chunkLocations) { chunkLocations.forEach(this::withChunk); return this; } - @NotNull public ChunkCoordinatorBuilder withRegion(Location pos1, Location pos2) { + @Nonnull public ChunkCoordinatorBuilder withRegion(Location pos1, Location pos2) { final int p1x = pos1.getX(); final int p1z = pos1.getZ(); final int p2x = pos2.getX(); @@ -95,45 +98,50 @@ public class ChunkCoordinatorBuilder { return this; } - @NotNull public ChunkCoordinatorBuilder withConsumer( - @NotNull final Consumer chunkConsumer) { + @Nonnull public ChunkCoordinatorBuilder withConsumer( + @Nonnull final Consumer chunkConsumer) { this.chunkConsumer = Preconditions.checkNotNull(chunkConsumer, "Chunk consumer may not be null"); return this; } - @NotNull public ChunkCoordinatorBuilder withFinalAction(@NotNull final Runnable whenDone) { + @Nonnull public ChunkCoordinatorBuilder withFinalAction(@Nonnull final Runnable whenDone) { this.whenDone = Preconditions.checkNotNull(whenDone, "Final action may not be null"); return this; } - @NotNull public ChunkCoordinatorBuilder withMaxIterationTime(final long maxIterationTime) { + @Nonnull public ChunkCoordinatorBuilder withMaxIterationTime(final long maxIterationTime) { Preconditions.checkArgument(maxIterationTime > 0, "Max iteration time must be positive"); this.maxIterationTime = maxIterationTime; return this; } - @NotNull public ChunkCoordinatorBuilder withInitialBatchSize(final int initialBatchSize) { + @Nonnull public ChunkCoordinatorBuilder withInitialBatchSize(final int initialBatchSize) { Preconditions.checkArgument(initialBatchSize > 0, "Initial batch size must be positive"); this.initialBatchSize = initialBatchSize; return this; } - @NotNull public ChunkCoordinatorBuilder withThrowableConsumer( - @NotNull final Consumer throwableConsumer) { + @Nonnull public ChunkCoordinatorBuilder withThrowableConsumer( + @Nonnull final Consumer throwableConsumer) { this.throwableConsumer = Preconditions.checkNotNull(throwableConsumer, "Throwable consumer may not be null"); return this; } - @NotNull public ChunkCoordinator build() { + @Nonnull public ChunkCoordinatorBuilder unloadAfter(final boolean unloadAfter) { + this.unloadAfter = unloadAfter; + return this; + } + + @Nonnull public ChunkCoordinator build() { Preconditions.checkNotNull(this.world, "No world was supplied"); Preconditions.checkNotNull(this.chunkConsumer, "No chunk consumer was supplied"); Preconditions.checkNotNull(this.whenDone, "No final action was supplied"); Preconditions.checkNotNull(this.throwableConsumer, "No throwable consumer was supplied"); return chunkCoordinatorFactory .create(this.maxIterationTime, this.initialBatchSize, this.chunkConsumer, this.world, - this.requestedChunks, this.whenDone, this.throwableConsumer); + this.requestedChunks, this.whenDone, this.throwableConsumer, this.unloadAfter); } } diff --git a/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java b/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java index d63773ddd..dd7e0ae01 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java +++ b/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java @@ -26,8 +26,10 @@ package com.plotsquared.core.queue; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; @@ -113,6 +115,13 @@ public class DelegateQueueCoordinator extends QueueCoordinator { return false; } + @Override public boolean setEntity(Entity entity) { + if (parent != null) { + return parent.setEntity(entity); + } + return false; + } + @Override public void regenChunk(int x, int z) { if (parent != null) { parent.regenChunk(x, z); @@ -170,4 +179,31 @@ public class DelegateQueueCoordinator extends QueueCoordinator { parent.setChunkConsumer(consumer); } } + + @Override public CuboidRegion getReadRegion() { + if (parent != null) { + return parent.getReadRegion(); + } + return null; + } + + @Override public void setReadRegion(CuboidRegion readRegion) { + if (parent != null) { + parent.setReadRegion(readRegion); + } + } + + @Override public boolean isUnloadAfter() { + if (parent != null) { + return parent.isUnloadAfter(); + } + return false; + } + + @Override public void setUnloadAfter(boolean setUnloadAfter) { + if (parent != null) { + parent.setUnloadAfter(setUnloadAfter); + } + + } } diff --git a/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java b/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java index e69c4f0d5..59a10f943 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java +++ b/Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java @@ -26,25 +26,27 @@ package com.plotsquared.core.queue; import com.plotsquared.core.util.ChunkUtil; -import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MathMan; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import java.util.HashMap; public class LocalChunk { - private final BasicQueueCoordinator parent; + private final QueueCoordinator parent; private final int x; private final int z; private final BaseBlock[][] baseblocks; private final BiomeType[][] biomes; private final HashMap tiles = new HashMap<>(); + private final HashMap entities = new HashMap<>(); - public LocalChunk(BasicQueueCoordinator parent, int x, int z) { + public LocalChunk(QueueCoordinator parent, int x, int z) { this.parent = parent; this.x = x; this.z = z; @@ -52,7 +54,7 @@ public class LocalChunk { biomes = new BiomeType[16][]; } - public BasicQueueCoordinator getParent() { + public QueueCoordinator getParent() { return this.parent; } @@ -103,4 +105,12 @@ public class LocalChunk { public void setTile(final int x, final int y, final int z, final CompoundTag tag) { tiles.put(BlockVector3.at(x, y, z), tag); } + + public void setEntity(Location location, BaseEntity entity) { + this.entities.put(location, entity); + } + + public HashMap getEntities() { + return this.entities; + } } diff --git a/Core/src/main/java/com/plotsquared/core/queue/QueueCoordinator.java b/Core/src/main/java/com/plotsquared/core/queue/QueueCoordinator.java index e1161ab20..57569bd7f 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/QueueCoordinator.java +++ b/Core/src/main/java/com/plotsquared/core/queue/QueueCoordinator.java @@ -30,8 +30,10 @@ import com.plotsquared.core.PlotSquared; import com.plotsquared.core.location.Location; import com.plotsquared.core.util.PatternUtil; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; @@ -40,6 +42,7 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; import java.util.function.Consumer; public abstract class QueueCoordinator { @@ -108,6 +111,22 @@ public abstract class QueueCoordinator { public abstract boolean isSettingBiomes(); + public void addEntities(List entities) { + for (Entity e : entities) { + this.setEntity(e); + } + } + + public abstract boolean setEntity(Entity entity); + + public abstract CuboidRegion getReadRegion(); + + public abstract void setReadRegion(CuboidRegion readRegion); + + public abstract void setUnloadAfter(boolean unloadAfter); + + public abstract boolean isUnloadAfter(); + public abstract void regenChunk(int x, int z); public abstract World getWorld(); diff --git a/Core/src/main/java/com/plotsquared/core/queue/QueueProvider.java b/Core/src/main/java/com/plotsquared/core/queue/QueueProvider.java index 27c6a6866..4c234b0c7 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/QueueProvider.java +++ b/Core/src/main/java/com/plotsquared/core/queue/QueueProvider.java @@ -28,23 +28,12 @@ package com.plotsquared.core.queue; import com.sk89q.worldedit.world.World; public abstract class QueueProvider { - public static QueueProvider of(final Class primary, - final Class fallback) { + public static QueueProvider of(final Class primary) { return new QueueProvider() { - private boolean failed = false; - @Override public QueueCoordinator getNewQueue(World world) { - if (!failed) { - try { - return (QueueCoordinator) primary.getConstructors()[0].newInstance(world); - } catch (Throwable e) { - e.printStackTrace(); - failed = true; - } - } try { - return (QueueCoordinator) fallback.getConstructors()[0].newInstance(world); + return (QueueCoordinator) primary.getConstructors()[0].newInstance(world); } catch (Throwable e) { e.printStackTrace(); } diff --git a/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java b/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java index e2e5c36e9..d9bfb4cd3 100644 --- a/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java @@ -27,7 +27,6 @@ package com.plotsquared.core.util; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.location.Location; -import com.plotsquared.core.plot.Plot; import com.plotsquared.core.queue.QueueCoordinator; import com.plotsquared.core.queue.ScopedQueueCoordinator; import com.plotsquared.core.util.task.RunnableVal; @@ -98,21 +97,4 @@ public abstract class ChunkManager { @Deprecated public abstract CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force); - @Deprecated public abstract void unloadChunk(String world, BlockVector2 loc, boolean save); - - public Plot hasPlot(String world, BlockVector2 chunk) { - int x1 = chunk.getX() << 4; - int z1 = chunk.getZ() << 4; - int x2 = x1 + 15; - int z2 = z1 + 15; - Location bot = Location.at(world, x1, 0, z1); - Plot plot = bot.getOwnedPlotAbs(); - if (plot != null) { - return plot; - } - Location top = Location.at(world, x2, 0, z2); - plot = top.getOwnedPlotAbs(); - return plot; - } - } diff --git a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java index 228b62a51..a4f5682cd 100644 --- a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java @@ -25,24 +25,27 @@ */ package com.plotsquared.core.util; +import com.google.inject.Inject; import com.plotsquared.core.PlotSquared; -import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory; import com.plotsquared.core.location.Location; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotManager; +import com.plotsquared.core.queue.BasicQueueCoordinator; +import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.queue.QueueCoordinator; -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.entity.Entity; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.File; import java.util.Collection; @@ -55,12 +58,9 @@ public abstract class RegionManager { LoggerFactory.getLogger("P2/" + RegionManager.class.getSimpleName()); public static RegionManager manager = null; - private final ChunkManager chunkManager; - - public RegionManager(@Nonnull final ChunkManager chunkManager, @Nonnull WorldUtil worldUtil, - @Nonnull ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory) { - this.chunkManager = chunkManager; - } + @Inject private WorldUtil worldUtil; + @Inject private ChunkManager chunkManager; + @Inject private GlobalBlockQueue blockQueue; public static BlockVector2 getRegion(Location location) { int x = location.getX() >> 9; @@ -68,46 +68,6 @@ public abstract class RegionManager { return BlockVector2.at(x, z); } - public void largeRegionTask(final String world, final CuboidRegion region, - final RunnableVal task, final Runnable whenDone) { - TaskManager.runTaskAsync(() -> { - HashSet chunks = new HashSet<>(); - Set mcrs = this.getChunkChunks(world); - for (BlockVector2 mcr : mcrs) { - int bx = mcr.getX() << 9; - int bz = mcr.getZ() << 9; - int tx = bx + 511; - int tz = bz + 511; - if (bx <= region.getMaximumPoint().getX() && tx >= region.getMinimumPoint().getX() - && bz <= region.getMaximumPoint().getZ() && tz >= region.getMinimumPoint() - .getZ()) { - for (int x = bx >> 4; x <= (tx >> 4); x++) { - int cbx = x << 4; - int ctx = cbx + 15; - if (cbx <= region.getMaximumPoint().getX() && ctx >= region - .getMinimumPoint().getX()) { - for (int z = bz >> 4; z <= (tz >> 4); z++) { - int cbz = z << 4; - int ctz = cbz + 15; - if (cbz <= region.getMaximumPoint().getZ() && ctz >= region - .getMinimumPoint().getZ()) { - chunks.add(BlockVector2.at(x, z)); - } - } - } - } - } - } - TaskManager.getPlatformImplementation() - .objectTask(chunks, new RunnableVal() { - @Override public void run(BlockVector2 value) { - chunkManager.loadChunk(world, value, false).thenRun(() -> task.run(value)); - } - }).thenAccept(ignore -> TaskManager.getPlatformImplementation() - .taskLater(whenDone, TaskTime.ticks(1L))); - }); - } - /** * 0 = Entity * 1 = Animal @@ -115,9 +75,6 @@ public abstract class RegionManager { * 3 = Mob * 4 = Boat * 5 = Misc - * - * @param plot - * @return */ public abstract int[] countEntities(Plot plot); @@ -146,10 +103,6 @@ public abstract class RegionManager { return chunks; } - public void deleteRegionFiles(String world, Collection chunks) { - deleteRegionFiles(world, chunks, null); - } - public void deleteRegionFiles(final String world, final Collection chunks, final Runnable whenDone) { TaskManager.runTaskAsync(() -> { @@ -167,16 +120,10 @@ public abstract class RegionManager { }); } - public boolean setCuboids(final PlotArea area, final Set regions, - final Pattern blocks, int minY, int maxY) { - return setCuboids(area, regions, blocks, minY, maxY, null); - } - - public boolean setCuboids(final PlotArea area, final Set regions, final Pattern blocks, int minY, int maxY, @Nullable QueueCoordinator queue) { boolean enqueue = false; - if(queue == null) { + if (queue == null) { queue = area.getQueue(); enqueue = true; } @@ -209,27 +156,116 @@ public abstract class RegionManager { /** * Copy a region to a new location (in the same world) */ - public abstract boolean copyRegion(Location pos1, Location pos2, Location newPos, - Runnable whenDone); + 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 com.sk89q.worldedit.world.World newWorld = + worldUtil.getWeWorld(newPos.getWorldName()); + final QueueCoordinator copyFrom = blockQueue.getNewQueue(oldWorld); + final BasicQueueCoordinator copyTo = + (BasicQueueCoordinator) blockQueue.getNewQueue(newWorld); + copyFromTo(pos1, pos2, relX, relZ, oldWorld, copyFrom, copyTo, false); + copyFrom.setCompleteTask(copyTo::enqueue); + copyFrom.setReadRegion(new CuboidRegion(BlockVector3.at(pos1.getX(), 0, pos1.getZ()), + BlockVector3.at(pos2.getX(), 0, pos2.getZ()))); + copyTo.setCompleteTask(whenDone); + copyFrom.enqueue(); + return true; + } /** * Assumptions:
* - pos1 and pos2 are in the same plot
* It can be harmful to the world if parameters outside this scope are provided - * - * @param pos1 - * @param pos2 - * @param whenDone - * @return */ public abstract boolean regenerateRegion(Location pos1, Location pos2, boolean ignoreAugment, Runnable whenDone); public abstract void clearAllEntities(Location pos1, Location pos2); - public abstract void swap(Location bot1, Location top1, Location bot2, Location top2, - Runnable whenDone); + public void swap(Location pos1, Location pos2, Location swapPos, final Runnable whenDone) { + int relX = swapPos.getX() - pos1.getX(); + int relZ = swapPos.getZ() - pos1.getZ(); - public abstract void setBiome(CuboidRegion region, int extendBiome, BiomeType biome, - String world, Runnable whenDone); + World world1 = worldUtil.getWeWorld(pos1.getWorldName()); + World world2 = worldUtil.getWeWorld(swapPos.getWorldName()); + + QueueCoordinator fromQueue1 = blockQueue.getNewQueue(world1); + QueueCoordinator fromQueue2 = blockQueue.getNewQueue(world2); + fromQueue1.setUnloadAfter(false); + fromQueue2.setUnloadAfter(false); + fromQueue1.setReadRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3())); + fromQueue2.setReadRegion(new CuboidRegion(swapPos.getBlockVector3(), BlockVector3 + .at(swapPos.getX() + pos2.getX() - pos1.getX(), 0, + swapPos.getZ() + pos2.getZ() - pos1.getZ()))); + QueueCoordinator toQueue1 = blockQueue.getNewQueue(world1); + QueueCoordinator toQueue2 = blockQueue.getNewQueue(world2); + + copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue1, toQueue2, true); + copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue2, toQueue1, true); + fromQueue1.setCompleteTask(fromQueue2::enqueue); + fromQueue2.setCompleteTask(toQueue1::enqueue); + toQueue1.setCompleteTask(toQueue2::enqueue); + toQueue2.setCompleteTask(whenDone); + } + + private void copyFromTo(Location pos1, Location pos2, int relX, int relZ, World world1, + QueueCoordinator fromQueue, QueueCoordinator toQueue, boolean removeEntities) { + fromQueue.setChunkConsumer(chunk -> { + int cx = chunk.getX(); + int cz = chunk.getZ(); + int cbx = cx << 4; + int cbz = cz << 4; + 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 y = 0; y < 256; y++) { + for (int x = bx; x <= tx; x++) { + for (int z = bz; z <= tz; z++) { + int rx = cbx + x; + int rz = cbz + z; + BlockVector3 loc = BlockVector3.at(rx, y, rz); + toQueue.setBlock(rx + relX, y, rz + relZ, world1.getFullBlock(loc)); + toQueue.setBiome(rx + relX, y, rz + relZ, world1.getBiome(loc)); + } + } + } + Region region = new CuboidRegion(BlockVector3.at(cbx + bx, 0, cbz + bz), + BlockVector3.at(cbx + tx, 255, cbz + tz)); + toQueue.addEntities(world1.getEntities(region)); + if (removeEntities) { + for (Entity entity : world1.getEntities(region)) { + entity.remove(); + } + } + }); + } + + 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 = blockQueue.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.setReadRegion(region); + 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.setCompleteTask(whenDone); + queue.enqueue(); + } } diff --git a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java index 0381945fa..1373562da 100644 --- a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java +++ b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java @@ -330,7 +330,8 @@ public abstract class SchematicHandler { final int bcz = p1z >> 4; final int tcx = p2x >> 4; final int tcz = p2z >> 4; - + queue.setReadRegion( + new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3())); queue.setChunkConsumer(blockVector2 -> { int x = blockVector2.getX(); int z = blockVector2.getZ(); diff --git a/build.gradle b/build.gradle index eacbc0fc2..d855d1ef3 100644 --- a/build.gradle +++ b/build.gradle @@ -81,7 +81,7 @@ subprojects { subproject -> dependencies { compile group: 'org.json', name: 'json', version: '20200518' - implementation("com.sk89q.worldedit:worldedit-core:7.0.0") { + implementation("com.sk89q.worldedit:worldedit-core:7.2.0-SNAPSHOT") { exclude(module: "bukkit-classloader-check") exclude(module: "mockito-core") exclude(module: "dummypermscompat")