240 lines
9.4 KiB
Java
Raw Normal View History

/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
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;
2019-11-04 19:58:24 +00:00
import com.sk89q.worldedit.world.block.BlockState;
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;
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;
import org.bukkit.block.Container;
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;
import java.util.function.Consumer;
2018-08-10 17:01:10 +02:00
public class BukkitLocalQueue extends BasicLocalBlockQueue {
2016-06-13 14:47:50 +10:00
public BukkitLocalQueue(String world) {
super(world);
}
@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) {
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 {
setBaseBlocks(lc);
2016-06-13 14:47:50 +10:00
}
public void setBaseBlocks(LocalChunk localChunk) {
World worldObj = Bukkit.getWorld(getWorld());
2019-08-05 13:33:27 -04:00
if (worldObj == null) {
throw new NullPointerException("World cannot be null.");
}
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());
if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing
.getBlockData().matches(blockData)) {
continue;
}
if (existing.getState() instanceof Container) {
((Container) existing.getState()).getInventory().clear();
}
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());
}
}
}
}
}
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);
}
}
}
}
}
};
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);
}
}
private Chunk getChunk(final World world, final LocalChunk localChunk) {
2020-04-08 04:10:22 +02:00
Chunk chunk = null;
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 04:10:22 +02:00
return chunk;
}
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());
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
}
public void setBiomes(LocalChunk lc) {
World worldObj = Bukkit.getWorld(getWorld());
if (worldObj == null) {
throw new NullPointerException("World cannot be null.");
}
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++) {
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
}
}
}
}
};
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);
}
2016-06-13 14:47:50 +10:00
}
2016-08-26 03:02:50 +10:00
2018-08-10 17:01:10 +02:00
}