2020-04-16 04:52:39 +02:00
|
|
|
/*
|
|
|
|
* _____ _ _ _____ _
|
|
|
|
* | __ \| | | | / ____| | |
|
|
|
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
|
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
|
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
|
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
|
|
* | |
|
|
|
|
* |_|
|
|
|
|
* PlotSquared plot management system for Minecraft
|
|
|
|
* Copyright (C) 2020 IntellectualSites
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-04-15 15:26:54 -04:00
|
|
|
package com.plotsquared.bukkit.queue;
|
2016-06-13 14:47:50 +10:00
|
|
|
|
2020-04-15 15:26:54 -04:00
|
|
|
import com.plotsquared.bukkit.schematic.StateWrapper;
|
|
|
|
import com.plotsquared.bukkit.util.BukkitBlockUtil;
|
|
|
|
import com.plotsquared.core.queue.BasicLocalBlockQueue;
|
|
|
|
import com.plotsquared.core.util.BlockUtil;
|
2020-04-30 11:01:52 +01:00
|
|
|
import com.plotsquared.core.util.MainUtil;
|
2018-12-24 17:56:13 +00:00
|
|
|
import com.sk89q.jnbt.CompoundTag;
|
2020-03-20 12:05:13 +00:00
|
|
|
import com.sk89q.worldedit.EditSession;
|
|
|
|
import com.sk89q.worldedit.WorldEdit;
|
2018-12-24 17:56:13 +00:00
|
|
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
2020-03-20 12:05:13 +00:00
|
|
|
import com.sk89q.worldedit.math.BlockVector3;
|
|
|
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
2019-11-10 17:47:37 +00:00
|
|
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
2018-12-24 17:56:13 +00:00
|
|
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
2019-11-04 19:58:24 +00:00
|
|
|
import com.sk89q.worldedit.world.block.BlockState;
|
2019-09-11 19:04:29 -04:00
|
|
|
import io.papermc.lib.PaperLib;
|
2018-12-17 20:57:21 +01:00
|
|
|
import lombok.NonNull;
|
2016-06-13 14:47:50 +10:00
|
|
|
import org.bukkit.Bukkit;
|
2020-04-08 01:23:22 +02:00
|
|
|
import org.bukkit.Chunk;
|
2018-12-17 20:57:21 +01:00
|
|
|
import org.bukkit.Material;
|
2016-06-13 14:47:50 +10:00
|
|
|
import org.bukkit.World;
|
|
|
|
import org.bukkit.block.Biome;
|
|
|
|
import org.bukkit.block.Block;
|
2020-05-14 12:57:26 +01:00
|
|
|
import org.bukkit.block.Container;
|
2019-01-15 23:58:21 +00:00
|
|
|
import org.bukkit.block.data.BlockData;
|
2016-06-13 14:47:50 +10:00
|
|
|
|
2019-08-05 13:33:27 -04:00
|
|
|
import java.util.concurrent.ExecutionException;
|
2020-04-08 01:23:22 +02:00
|
|
|
import java.util.function.Consumer;
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2019-05-30 13:28:19 +02:00
|
|
|
public class BukkitLocalQueue extends BasicLocalBlockQueue {
|
2016-06-13 14:47:50 +10:00
|
|
|
|
|
|
|
public BukkitLocalQueue(String world) {
|
|
|
|
super(world);
|
|
|
|
}
|
|
|
|
|
2019-05-30 13:28:19 +02:00
|
|
|
@Override public LocalChunk getLocalChunk(int x, int z) {
|
|
|
|
return new BasicLocalChunk(this, x, z) {
|
2016-06-13 14:47:50 +10:00
|
|
|
// Custom stuff?
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public void optimize() {
|
2016-06-13 14:47:50 +10:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-11-04 19:55:55 +00:00
|
|
|
@Override public BlockState getBlock(int x, int y, int z) {
|
2016-06-13 14:47:50 +10:00
|
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
2019-04-29 15:19:49 -04:00
|
|
|
if (worldObj != null) {
|
|
|
|
Block block = worldObj.getBlockAt(x, y, z);
|
2019-11-04 19:55:55 +00:00
|
|
|
return BukkitBlockUtil.get(block);
|
2019-04-29 15:19:49 -04:00
|
|
|
} else {
|
2019-11-04 19:55:55 +00:00
|
|
|
return BlockUtil.get(0, 0);
|
2016-06-13 14:47:50 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public void refreshChunk(int x, int z) {
|
2016-06-13 14:47:50 +10:00
|
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
2019-05-17 16:21:03 -04:00
|
|
|
if (worldObj != null) {
|
|
|
|
worldObj.refreshChunk(x, z);
|
|
|
|
}
|
2016-06-13 14:47:50 +10:00
|
|
|
}
|
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public void fixChunkLighting(int x, int z) {
|
2016-06-13 14:47:50 +10:00
|
|
|
// Do nothing
|
|
|
|
}
|
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public final void regenChunk(int x, int z) {
|
2016-06-13 14:47:50 +10:00
|
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
2019-05-17 16:21:03 -04:00
|
|
|
if (worldObj != null) {
|
2020-03-20 12:05:13 +00:00
|
|
|
try {
|
|
|
|
worldObj.regenerateChunk(x, z);
|
|
|
|
} catch (UnsupportedOperationException e) {
|
|
|
|
com.sk89q.worldedit.world.World world = BukkitAdapter.adapt(worldObj);
|
|
|
|
try (EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
|
|
|
|
.getEditSession(world, -1);) {
|
|
|
|
CuboidRegion region =
|
|
|
|
new CuboidRegion(world, BlockVector3.at((x << 4), 0, (z << 4)),
|
|
|
|
BlockVector3.at((x << 4) + 15, 255, (z << 4) + 15));
|
|
|
|
world.regenerate(region, editSession);
|
|
|
|
}
|
|
|
|
}
|
2019-05-17 16:21:03 -04:00
|
|
|
}
|
2016-06-13 14:47:50 +10:00
|
|
|
}
|
|
|
|
|
2019-08-05 13:33:27 -04:00
|
|
|
@Override public final void setComponents(LocalChunk lc)
|
|
|
|
throws ExecutionException, InterruptedException {
|
2019-05-30 13:21:26 +02:00
|
|
|
setBaseBlocks(lc);
|
2016-06-13 14:47:50 +10:00
|
|
|
}
|
|
|
|
|
2019-09-11 19:04:29 -04:00
|
|
|
public void setBaseBlocks(LocalChunk localChunk) {
|
2018-12-24 17:56:13 +00:00
|
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
2019-08-05 13:33:27 -04:00
|
|
|
if (worldObj == null) {
|
|
|
|
throw new NullPointerException("World cannot be null.");
|
|
|
|
}
|
2020-04-08 01:23:22 +02:00
|
|
|
final Consumer<Chunk> 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);
|
|
|
|
|
|
|
|
Block existing = chunk.getBlock(x, y, z);
|
2020-04-30 11:01:52 +01:00
|
|
|
final BlockState existingBaseBlock =
|
|
|
|
BukkitAdapter.adapt(existing.getBlockData());
|
2020-04-08 02:02:20 +02:00
|
|
|
if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing
|
2020-04-08 01:23:22 +02:00
|
|
|
.getBlockData().matches(blockData)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-05-14 12:57:26 +01:00
|
|
|
if (existing.getState() instanceof Container) {
|
|
|
|
((Container) existing.getState()).getInventory().clear();
|
|
|
|
}
|
|
|
|
|
2020-04-08 01:23:22 +02:00
|
|
|
existing.setType(BukkitAdapter.adapt(block.getBlockType()), false);
|
|
|
|
existing.setBlockData(blockData, false);
|
|
|
|
if (block.hasNbtData()) {
|
|
|
|
CompoundTag tag = block.getNbtData();
|
|
|
|
StateWrapper sw = new StateWrapper(tag);
|
|
|
|
|
2020-04-30 11:01:52 +01:00
|
|
|
sw.restoreTag(worldObj.getName(), existing.getX(), existing.getY(),
|
|
|
|
existing.getZ());
|
2019-09-11 19:04:29 -04:00
|
|
|
}
|
2018-12-24 17:56:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-08 01:23:22 +02:00
|
|
|
}
|
2020-05-19 16:54:12 +01:00
|
|
|
if (setBiome() && localChunk.biomes != null) {
|
|
|
|
for (int x = 0; x < localChunk.biomes.length; x++) {
|
|
|
|
BiomeType[] biomeZ = localChunk.biomes[x];
|
|
|
|
if (biomeZ != null) {
|
|
|
|
for (int z = 0; z < biomeZ.length; z++) {
|
|
|
|
if (biomeZ[z] != null) {
|
|
|
|
BiomeType biomeType = biomeZ[z];
|
|
|
|
|
|
|
|
Biome biome = BukkitAdapter.adapt(biomeType);
|
|
|
|
worldObj.setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z,
|
|
|
|
biome);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-08 01:23:22 +02:00
|
|
|
};
|
|
|
|
if (isForceSync()) {
|
|
|
|
chunkConsumer.accept(getChunk(worldObj, localChunk));
|
|
|
|
} else {
|
2020-04-30 11:01:52 +01:00
|
|
|
PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true)
|
|
|
|
.thenAccept(chunkConsumer);
|
2020-04-08 01:23:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private Chunk getChunk(final World world, final LocalChunk localChunk) {
|
2020-04-08 04:10:22 +02:00
|
|
|
Chunk chunk = null;
|
2020-04-08 01:23:22 +02:00
|
|
|
if (this.getChunkObject() != null && this.getChunkObject() instanceof Chunk) {
|
2020-04-08 04:10:22 +02:00
|
|
|
chunk = (Chunk) this.getChunkObject();
|
|
|
|
}
|
|
|
|
if (chunk == null) {
|
|
|
|
chunk = world.getChunkAt(localChunk.getX(), localChunk.getZ());
|
|
|
|
}
|
|
|
|
if (!chunk.isLoaded()) {
|
|
|
|
chunk.load(true);
|
2020-04-08 01:23:22 +02:00
|
|
|
}
|
2020-04-08 04:10:22 +02:00
|
|
|
return chunk;
|
2018-12-24 17:56:13 +00:00
|
|
|
}
|
|
|
|
|
2019-11-04 19:55:55 +00:00
|
|
|
private void setMaterial(@NonNull final BlockState plotBlock, @NonNull final Block block) {
|
|
|
|
Material material = BukkitAdapter.adapt(plotBlock.getBlockType());
|
2018-12-20 17:20:13 +00:00
|
|
|
block.setType(material, false);
|
2018-12-17 20:57:21 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 19:55:55 +00:00
|
|
|
private boolean equals(@NonNull final BlockState plotBlock, @NonNull final Block block) {
|
|
|
|
return plotBlock.equals(BukkitBlockUtil.get(block));
|
2018-12-17 20:57:21 +01:00
|
|
|
}
|
|
|
|
|
2019-05-30 13:28:19 +02:00
|
|
|
public void setBiomes(LocalChunk lc) {
|
2020-03-24 08:08:56 +00:00
|
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
|
|
|
if (worldObj == null) {
|
|
|
|
throw new NullPointerException("World cannot be null.");
|
|
|
|
}
|
2020-04-08 01:23:22 +02:00
|
|
|
if (lc.biomes == null) {
|
|
|
|
throw new NullPointerException("Biomes cannot be null.");
|
|
|
|
}
|
|
|
|
final Consumer<Chunk> chunkConsumer = chunk -> {
|
2016-06-13 14:47:50 +10:00
|
|
|
for (int x = 0; x < lc.biomes.length; x++) {
|
2020-03-24 08:08:56 +00:00
|
|
|
BiomeType[] biomeZ = lc.biomes[x];
|
|
|
|
if (biomeZ != null) {
|
|
|
|
for (int z = 0; z < biomeZ.length; z++) {
|
|
|
|
if (biomeZ[z] != null) {
|
|
|
|
BiomeType biomeType = biomeZ[z];
|
|
|
|
|
|
|
|
Biome biome = BukkitAdapter.adapt(biomeType);
|
2020-04-30 11:01:52 +01:00
|
|
|
worldObj
|
|
|
|
.setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, biome);
|
2016-06-13 14:47:50 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-08 01:23:22 +02:00
|
|
|
};
|
|
|
|
if (this.isForceSync()) {
|
|
|
|
chunkConsumer.accept(getChunk(worldObj, lc));
|
|
|
|
} else {
|
2020-04-30 11:01:52 +01:00
|
|
|
PaperLib.getChunkAtAsync(worldObj, lc.getX(), lc.getZ(), true)
|
|
|
|
.thenAccept(chunkConsumer);
|
2020-04-08 01:23:22 +02:00
|
|
|
}
|
2016-06-13 14:47:50 +10:00
|
|
|
}
|
2016-08-26 03:02:50 +10:00
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
}
|