From be6bcafccc8914146fad08017548f33192bd0bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Wed, 8 Apr 2020 01:23:22 +0200 Subject: [PATCH] Make sure augmented generation doesn't crash the server --- .../generator/BukkitAugmentedGenerator.java | 2 +- .../bukkit/util/block/BukkitLocalQueue.java | 86 ++++++++++++------- .../plotsquared/plot/commands/Area.java | 4 +- .../plot/generator/AugmentedUtils.java | 12 ++- .../plot/util/block/BasicLocalBlockQueue.java | 1 + .../plot/util/block/LocalBlockQueue.java | 6 ++ 6 files changed, 75 insertions(+), 36 deletions(-) diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/generator/BukkitAugmentedGenerator.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/generator/BukkitAugmentedGenerator.java index 03b0c8123..63f0a5054 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/generator/BukkitAugmentedGenerator.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/generator/BukkitAugmentedGenerator.java @@ -27,6 +27,6 @@ public class BukkitAugmentedGenerator extends BlockPopulator { @Override public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk source) { - AugmentedUtils.generate(world.getName(), source.getX(), source.getZ(), null); + AugmentedUtils.generate(source, world.getName(), source.getX(), source.getZ(), null); } } diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java index 663d6144b..4fd54c735 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/block/BukkitLocalQueue.java @@ -18,6 +18,7 @@ import com.sk89q.worldedit.world.block.BlockState; import io.papermc.lib.PaperLib; import lombok.NonNull; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; @@ -25,6 +26,7 @@ import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; public class BukkitLocalQueue extends BasicLocalBlockQueue { @@ -88,7 +90,7 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue { @Override public final void setComponents(LocalChunk lc) throws ExecutionException, InterruptedException { setBaseBlocks(lc); - if (setBiome()) { + if (setBiome() && lc.biomes != null) { setBiomes(lc); } } @@ -98,40 +100,54 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue { if (worldObj == null) { throw new NullPointerException("World cannot be null."); } - PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true) - .thenAccept(chunk -> { - for (int layer = 0; layer < localChunk.baseblocks.length; layer++) { - BaseBlock[] blocksLayer = localChunk.baseblocks[layer]; - if (blocksLayer != null) { - for (int j = 0; j < blocksLayer.length; j++) { - if (blocksLayer[j] != null) { - BaseBlock block = blocksLayer[j]; - int x = MainUtil.x_loc[layer][j]; - int y = MainUtil.y_loc[layer][j]; - int z = MainUtil.z_loc[layer][j]; + final Consumer chunkConsumer = chunk -> { + for (int layer = 0; layer < localChunk.baseblocks.length; layer++) { + BaseBlock[] blocksLayer = localChunk.baseblocks[layer]; + if (blocksLayer != null) { + for (int j = 0; j < blocksLayer.length; j++) { + if (blocksLayer[j] != null) { + BaseBlock block = blocksLayer[j]; + int x = MainUtil.x_loc[layer][j]; + int y = MainUtil.y_loc[layer][j]; + int z = MainUtil.z_loc[layer][j]; - BlockData blockData = BukkitAdapter.adapt(block); + BlockData blockData = BukkitAdapter.adapt(block); - Block existing = chunk.getBlock(x, y, z); - if (BukkitBlockUtil.get(existing).equals(block) && existing - .getBlockData().matches(blockData)) { - continue; - } + Block existing = chunk.getBlock(x, y, z); + if (BukkitBlockUtil.get(existing).equals(block) && existing + .getBlockData().matches(blockData)) { + continue; + } - existing.setType(BukkitAdapter.adapt(block.getBlockType()), false); - existing.setBlockData(blockData, false); - if (block.hasNbtData()) { - CompoundTag tag = block.getNbtData(); - StateWrapper sw = new StateWrapper(tag); + existing.setType(BukkitAdapter.adapt(block.getBlockType()), false); + existing.setBlockData(blockData, false); + if (block.hasNbtData()) { + CompoundTag tag = block.getNbtData(); + StateWrapper sw = new StateWrapper(tag); - sw.restoreTag(worldObj.getName(), existing.getX(), - existing.getY(), existing.getZ()); - } + sw.restoreTag(worldObj.getName(), existing.getX(), + existing.getY(), existing.getZ()); } } } } - }); + } + }; + if (isForceSync()) { + chunkConsumer.accept(getChunk(worldObj, localChunk)); + } else { + PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true).thenAccept(chunkConsumer); + } + } + + private Chunk getChunk(final World world, final LocalChunk localChunk) { + if (this.getChunkObject() != null && this.getChunkObject() instanceof Chunk) { + final Chunk chunk = (Chunk) this.getChunkObject(); + if (chunk.getWorld().equals(world) && chunk.getX() == localChunk.getX() && chunk.getZ() == localChunk.getZ()) { + return chunk; + } + } + return world.getChunkAt(localChunk.getX(), localChunk.getZ()); } private void setMaterial(@NonNull final BlockState plotBlock, @NonNull final Block block) { @@ -148,7 +164,10 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue { if (worldObj == null) { throw new NullPointerException("World cannot be null."); } - PaperLib.getChunkAtAsync(worldObj, lc.getX(), lc.getZ(), true).thenAccept(chunk -> { + if (lc.biomes == null) { + throw new NullPointerException("Biomes cannot be null."); + } + final Consumer chunkConsumer = chunk -> { for (int x = 0; x < lc.biomes.length; x++) { BiomeType[] biomeZ = lc.biomes[x]; if (biomeZ != null) { @@ -157,13 +176,18 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue { BiomeType biomeType = biomeZ[z]; Biome biome = BukkitAdapter.adapt(biomeType); - worldObj - .setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, biome); + worldObj.setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, + biome); } } } } - }); + }; + if (this.isForceSync()) { + chunkConsumer.accept(getChunk(worldObj, lc)); + } else { + PaperLib.getChunkAtAsync(worldObj, lc.getX(), lc.getZ(), true).thenAccept(chunkConsumer); + } } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java index b56a384f8..e00faa4b6 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java @@ -147,7 +147,7 @@ public class Area extends SubCommand { ChunkManager.largeRegionTask(world, region, new RunnableVal() { @Override public void run(BlockVector2 value) { - AugmentedUtils.generate(world, value.getX(), + AugmentedUtils.generate(null, world, value.getX(), value.getZ(), null); } }, null); @@ -445,7 +445,7 @@ public class Area extends SubCommand { new RunnableVal() { @Override public void run(BlockVector2 value) { AugmentedUtils - .generate(area.getWorldName(), value.getX(), value.getZ(), null); + .generate(null, area.getWorldName(), value.getX(), value.getZ(), null); } }, () -> player.sendMessage("Regen complete")); return true; diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/AugmentedUtils.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/AugmentedUtils.java index 9b915ec01..a3cda56d0 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/AugmentedUtils.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/AugmentedUtils.java @@ -16,6 +16,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Set; @@ -29,7 +30,7 @@ public class AugmentedUtils { enabled = true; } - public static boolean generate(@NotNull final String world, final int chunkX, final int chunkZ, + public static boolean generate(@Nullable Object chunkObject, @NotNull final String world, final int chunkX, final int chunkZ, LocalBlockQueue queue) { if (!enabled) { return false; @@ -54,6 +55,7 @@ public class AugmentedUtils { // Mask if (queue == null) { queue = GlobalBlockQueue.IMP.getNewQueue(world, false); + queue.setChunkObject(chunkObject); } LocalBlockQueue primaryMask; // coordinates @@ -102,7 +104,7 @@ public class AugmentedUtils { for (int y = 1; y < 128; y++) { queue.setBlock(rx, y, rz, air); } - canPlace[x][z] = can; + canPlace[x][z] = true; has = true; } } @@ -134,6 +136,11 @@ public class AugmentedUtils { } toReturn = true; } + primaryMask.setChunkObject(chunkObject); + primaryMask.setForceSync(true); + secondaryMask.setChunkObject(chunkObject); + secondaryMask.setForceSync(true); + ScopedLocalBlockQueue scoped = new ScopedLocalBlockQueue(secondaryMask, new Location(area.getWorldName(), blockX, 0, blockZ), new Location(area.getWorldName(), blockX + 15, 255, blockZ + 15)); @@ -141,6 +148,7 @@ public class AugmentedUtils { generator.populateChunk(scoped, area); } if (queue != null) { + queue.setForceSync(true); queue.flush(); } return toReturn; diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java index 0f3bc38a5..6c12466b7 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/BasicLocalBlockQueue.java @@ -222,6 +222,7 @@ public abstract class BasicLocalBlockQueue extends LocalBlockQueue { public class BasicLocalChunk extends LocalChunk { + public BasicLocalChunk(BasicLocalBlockQueue parent, int x, int z) { super(parent, x, z); baseblocks = new BaseBlock[16][]; diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java index 95aed7897..fe1de0660 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java @@ -13,12 +13,18 @@ import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; +import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; public abstract class LocalBlockQueue { + @Getter @Setter private boolean forceSync = false; + @Getter @Setter @Nullable private Object chunkObject; + /** * Needed for compatibility with FAWE. *