mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-03-14 05:49:44 +01:00

There's still the issue of Spigot's (or paper's) terrible GC that does nothing and stores everything in PS old gen memory so the server just numpties itself though.
246 lines
9.7 KiB
Java
246 lines
9.7 KiB
Java
/*
|
|
* _____ _ _ _____ _
|
|
* | __ \| | | | / ____| | |
|
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
* | |
|
|
* |_|
|
|
* 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/>.
|
|
*/
|
|
package com.plotsquared.bukkit.queue;
|
|
|
|
import com.plotsquared.bukkit.schematic.StateWrapper;
|
|
import com.plotsquared.bukkit.util.BukkitBlockUtil;
|
|
import com.plotsquared.core.PlotSquared;
|
|
import com.plotsquared.core.queue.BasicLocalBlockQueue;
|
|
import com.plotsquared.core.util.BlockUtil;
|
|
import com.plotsquared.core.util.MainUtil;
|
|
import com.plotsquared.core.util.task.TaskManager;
|
|
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;
|
|
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;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.Container;
|
|
import org.bukkit.block.data.BlockData;
|
|
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.function.Consumer;
|
|
|
|
public class BukkitLocalQueue extends BasicLocalBlockQueue {
|
|
|
|
public BukkitLocalQueue(String world) {
|
|
super(world);
|
|
}
|
|
|
|
@Override public LocalChunk getLocalChunk(int x, int z) {
|
|
return new BasicLocalChunk(this, x, z) {
|
|
// Custom stuff?
|
|
};
|
|
}
|
|
|
|
@Override public void optimize() {
|
|
|
|
}
|
|
|
|
@Override public BlockState getBlock(int x, int y, int z) {
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
|
if (worldObj != null) {
|
|
Block block = worldObj.getBlockAt(x, y, z);
|
|
return BukkitBlockUtil.get(block);
|
|
} else {
|
|
return BlockUtil.get(0, 0);
|
|
}
|
|
}
|
|
|
|
@Override public void refreshChunk(int x, int z) {
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
|
if (worldObj != null) {
|
|
worldObj.refreshChunk(x, z);
|
|
} else {
|
|
PlotSquared.debug("Error Refreshing Chunk");
|
|
}
|
|
}
|
|
|
|
@Override public void fixChunkLighting(int x, int z) {
|
|
// Do nothing
|
|
}
|
|
|
|
@Override public final void regenChunk(int x, int z) {
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
|
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);
|
|
}
|
|
}
|
|
} else {
|
|
PlotSquared.debug("Error Regenerating Chunk");
|
|
}
|
|
}
|
|
|
|
@Override public final void setComponents(LocalChunk lc)
|
|
throws ExecutionException, InterruptedException {
|
|
setBaseBlocks(lc);
|
|
}
|
|
|
|
public void setBaseBlocks(LocalChunk localChunk) {
|
|
World worldObj = Bukkit.getWorld(getWorld());
|
|
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);
|
|
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);
|
|
|
|
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 {
|
|
PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true)
|
|
.thenAccept(chunkConsumer);
|
|
}
|
|
}
|
|
|
|
private Chunk getChunk(final World world, final LocalChunk localChunk) {
|
|
Chunk chunk = null;
|
|
if (this.getChunkObject() != null && this.getChunkObject() instanceof Chunk) {
|
|
chunk = (Chunk) this.getChunkObject();
|
|
}
|
|
if (chunk == null) {
|
|
chunk = world.getChunkAt(localChunk.getX(), localChunk.getZ());
|
|
}
|
|
if (!chunk.isLoaded()) {
|
|
chunk.load(true);
|
|
}
|
|
return chunk;
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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 -> {
|
|
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);
|
|
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);
|
|
}
|
|
}
|
|
|
|
}
|