Add wna block setting, use WorldEdit worlds rather than Strings.

This commit is contained in:
dordsor21 2020-07-17 14:38:50 +01:00
parent 09aca839a8
commit ed77522c08
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B
9 changed files with 178 additions and 314 deletions

View File

@ -24,7 +24,7 @@ dependencies {
compile(project(":PlotSquared-Core"))
compile("com.destroystokyo.paper:paper-api:1.16.1-R0.1-SNAPSHOT")
implementation("org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT")
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.1.0") {
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.2.0-SNAPSHOT") {
exclude(module: "bukkit")
}

View File

@ -1,239 +0,0 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.queue.BasicLocalBlockQueue;
import com.plotsquared.core.util.BlockUtil;
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;
import com.sk89q.worldedit.world.block.BlockState;
import io.papermc.lib.PaperLib;
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 javax.annotation.Nonnull;
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);
}
}
@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);
}
}
}
}
@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);
}
}
}

View File

@ -25,22 +25,44 @@
*/
package com.plotsquared.bukkit.queue;
import com.plotsquared.bukkit.schematic.StateWrapper;
import com.plotsquared.bukkit.util.BukkitBlockUtil;
import com.plotsquared.core.queue.BasicQueueCoordinator;
import com.plotsquared.core.queue.LocalChunk;
import com.plotsquared.core.util.BlockUtil;
import com.plotsquared.core.util.MainUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
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 org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Container;
import org.bukkit.block.data.BlockData;
import javax.annotation.Nonnull;
public class BukkitQueueCoordinator extends BasicQueueCoordinator {
public BukkitQueueCoordinator(String world) {
private final World world;
private final SideEffectSet sideEffectSet;
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) {
World worldObj = Bukkit.getWorld(getWorld());
org.bukkit.World worldObj = BukkitAdapter.adapt(world);
if (worldObj != null) {
Block block = worldObj.getBlockAt(x, y, z);
return BukkitBlockUtil.get(block);
@ -49,4 +71,101 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
}
}
@Override public boolean enqueue() {
BukkitChunkCoordinator.builder().inWorld(BukkitAdapter.adapt(world))
.withChunks(getBlockChunks().keySet()).withInitialBatchSize(3).withMaxIterationTime(40)
.withThrowableConsumer(Throwable::printStackTrace).withConsumer(chunk -> {
LocalChunk localChunk =
getBlockChunks().get(BlockVector2.at(chunk.getX(), chunk.getZ()));
if (localChunk == null) {
throw new NullPointerException(
"LocalChunk cannot be null when accessed from ChunkCoordinator");
}
World worldObj = getWorld();
int sx = chunk.getX() << 4;
int sz = chunk.getX() << 4;
for (int layer = 0; layer < localChunk.getBaseblocks().length; layer++) {
BaseBlock[] blocksLayer = localChunk.getBaseblocks()[layer];
if (blocksLayer == null) {
continue;
}
for (int j = 0; j < blocksLayer.length; j++) {
if (blocksLayer[j] == null) {
continue;
}
BaseBlock block = blocksLayer[j];
int x = sx + MainUtil.x_loc[layer][j];
int y = MainUtil.y_loc[layer][j];
int z = sz + MainUtil.z_loc[layer][j];
try {
worldObj.setBlock(BlockVector3.at(x, y, z), block, sideEffectSet);
} catch (WorldEditException ignored) {
// Fallback to not so nice method
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());
}
}
}
}
for (int layer = 0; layer < localChunk.getBaseblocks().length; layer++) {
BiomeType[] biomesLayer = localChunk.getBiomes()[layer];
if (biomesLayer == null) {
continue;
}
for (int j = 0; j < biomesLayer.length; j++) {
if (biomesLayer[j] == null) {
continue;
}
BiomeType biome = biomesLayer[j];
int x = sx + MainUtil.x_loc[layer][j];
int y = MainUtil.y_loc[layer][j];
int z = sz + MainUtil.z_loc[layer][j];
worldObj.setBiome(BlockVector3.at(x, y, z), biome);
}
}
if (localChunk.getTiles().size() > 0) {
localChunk.getTiles().forEach(((blockVector3, tag) -> {
try {
BaseBlock block = worldObj.getBlock(blockVector3).toBaseBlock(tag);
worldObj.setBlock(blockVector3, block, sideEffectSet);
} catch (WorldEditException ignored) {
StateWrapper sw = new StateWrapper(tag);
sw.restoreTag(worldObj.getName(), blockVector3.getX(), blockVector3.getY(),
blockVector3.getZ());
}
}));
}
});
return super.enqueue();
}
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));
}
}

View File

@ -28,26 +28,31 @@ package com.plotsquared.core.queue;
import com.plotsquared.core.util.PatternUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
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 lombok.Getter;
import javax.annotation.Nonnull;
import java.util.concurrent.ConcurrentHashMap;
public abstract class BasicQueueCoordinator extends QueueCoordinator {
private final String world;
private final ConcurrentHashMap<Long, LocalChunk> blockChunks = new ConcurrentHashMap<>();
private final World world;
@Getter private final ConcurrentHashMap<BlockVector2, LocalChunk> blockChunks =
new ConcurrentHashMap<>();
private long modified;
private LocalChunk lastWrappedChunk;
private int lastX = Integer.MIN_VALUE;
private int lastZ = Integer.MIN_VALUE;
private boolean setbiome = false;
@Getter private boolean settingBiomes = false;
@Getter private boolean settingTiles = false;
private GlobalBlockQueue globalBlockQueue;
public BasicQueueCoordinator(String world) {
public BasicQueueCoordinator(World world) {
this.world = world;
this.modified = System.currentTimeMillis();
}
@ -60,7 +65,7 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
@Override public abstract BlockState getBlock(int x, int y, int z);
@Override public final String getWorld() {
@Override public final World getWorld() {
return world;
}
@ -95,32 +100,29 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
@Override public final boolean setBiome(int x, int z, BiomeType biomeType) {
LocalChunk chunk = getChunk(x >> 4, z >> 4);
chunk.setBiome(x & 15, z & 15, biomeType);
setbiome = true;
settingBiomes = true;
return true;
}
@Override public final boolean setTile(int x, int y, int z, CompoundTag tag) {
LocalChunk chunk = getChunk(x >> 4, z >> 4);
chunk.setTile(x, y, z, tag);
settingTiles = true;
return true;
}
@Override public final boolean settingBiome() {
return setbiome;
}
public final void setChunk(LocalChunk chunk) {
this.blockChunks.put(chunk.longHash(), chunk);
this.blockChunks.put(BlockVector2.at(chunk.getX(), chunk.getZ()), chunk);
}
private LocalChunk getChunk(final int chunkX, final int ChunkZ) {
if (chunkX != lastX || ChunkZ != lastZ) {
private LocalChunk getChunk(final int chunkX, final int chunkZ) {
if (chunkX != lastX || chunkZ != lastZ) {
lastX = chunkX;
lastZ = ChunkZ;
long pair = (long) (chunkX) << 32 | (ChunkZ) & 0xFFFFFFFFL;
lastZ = chunkZ;
BlockVector2 pair = BlockVector2.at(chunkX, chunkZ);
lastWrappedChunk = this.blockChunks.get(pair);
if (lastWrappedChunk == null) {
lastWrappedChunk = this.getLocalChunk(chunkX, ChunkZ);
lastWrappedChunk = this.getLocalChunk(chunkX, chunkZ);
LocalChunk previous = this.blockChunks.put(pair, lastWrappedChunk);
if (previous == null) {
return lastWrappedChunk;

View File

@ -28,6 +28,7 @@ package com.plotsquared.core.queue;
import com.plotsquared.core.location.Location;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
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;
@ -112,15 +113,15 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator {
return null;
}
@Override @Nonnull public String getWorld() {
return "";
@Override @Nonnull public World getWorld() {
return super.getWorld();
}
@Override public Location getMax() {
return Location.at(getWorld(), top.getX(), top.getY(), top.getZ());
return Location.at(getWorld().getName(), top.getX(), top.getY(), top.getZ());
}
@Override public Location getMin() {
return Location.at(getWorld(), bot.getX(), bot.getY(), bot.getZ());
return Location.at(getWorld().getName(), bot.getX(), bot.getY(), bot.getZ());
}
}

View File

@ -27,13 +27,10 @@ package com.plotsquared.core.queue;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.function.pattern.Pattern;
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 lombok.Getter;
import lombok.Setter;
import javax.annotation.Nullable;
public class DelegateQueueCoordinator extends QueueCoordinator {
@ -84,11 +81,11 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
return parent.setBiome(x, z, biome);
}
@Override public boolean settingBiome() {
return parent.settingBiome();
@Override public boolean isSettingBiomes() {
return parent.isSettingBiomes();
}
@Override public String getWorld() {
@Override public World getWorld() {
return parent.getWorld();
}
@ -96,6 +93,10 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
return parent.setTile(x, y, z, tag);
}
@Override public boolean isSettingTiles() {
return parent.isSettingTiles();
}
@Override public boolean enqueue() {
if (parent != null) {
return parent.enqueue();

View File

@ -6,55 +6,35 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import lombok.Getter;
import java.util.HashMap;
public class LocalChunk {
public final BasicQueueCoordinator parent;
public final int z;
public final int x;
@Getter private final BasicQueueCoordinator parent;
@Getter private final int z;
@Getter private final int x;
public BaseBlock[][] baseblocks;
public BiomeType[][] biomes;
public HashMap<BlockVector3, CompoundTag> tiles = null;
@Getter private final BaseBlock[][] baseblocks;
@Getter private final BiomeType[][] biomes;
@Getter private final HashMap<BlockVector3, CompoundTag> tiles = new HashMap<>();
public LocalChunk(BasicQueueCoordinator parent, int x, int z) {
this.parent = parent;
this.x = x;
this.z = z;
baseblocks = new BaseBlock[16][];
biomes = new BiomeType[16][];
}
/**
* Get the parent queue this chunk belongs to
*
* @return
*/
public BasicQueueCoordinator getParent() {
return parent;
public void setBiome(final int x, final int y, final int z, final BiomeType biomeType) {
final int i = MainUtil.CACHE_I[y][x][z];
final int j = MainUtil.CACHE_J[y][x][z];
BiomeType[] array = this.biomes[i];
if (array == null) {
array = this.biomes[i] = new BiomeType[4096];
}
public int getX() {
return x;
}
public int getZ() {
return z;
}
public void setBiome(int x, int z, BiomeType biomeType) {
if (this.biomes == null) {
this.biomes = new BiomeType[16][];
}
BiomeType[] index = this.biomes[x];
if (index == null) {
index = this.biomes[x] = new BiomeType[16];
}
index[z] = biomeType;
}
public long longHash() {
return MathMan.pairInt(x, z);
array[j] = biomeType;
}
@Override public int hashCode() {
@ -72,9 +52,6 @@ public class LocalChunk {
}
public void setTile(final int x, final int y, final int z, final CompoundTag tag) {
if (tiles == null) {
tiles = new HashMap<>();
}
tiles.put(BlockVector3.at(x, y, z), tag);
}
}

View File

@ -31,6 +31,7 @@ import com.plotsquared.core.location.Location;
import com.plotsquared.core.util.PatternUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.function.pattern.Pattern;
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;
@ -73,20 +74,22 @@ public abstract class QueueCoordinator {
public abstract boolean setTile(int x, int y, int z, CompoundTag tag);
public abstract boolean isSettingTiles();
public abstract BlockState getBlock(int x, int y, int z);
public abstract boolean setBiome(int x, int z, BiomeType biome);
public abstract boolean settingBiome();
public abstract boolean isSettingBiomes();
public abstract String getWorld();
public abstract World getWorld();
public final void setModified() {
setModified(System.currentTimeMillis());
}
public boolean enqueue() {
return this.blockQueue.enqueue(this);
return blockQueue.enqueue(this);
}
public void setCuboid(Location pos1, Location pos2, BlockState block) {

View File

@ -93,11 +93,11 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
}
public Location getMin() {
return Location.at(this.getWorld(), this.minX, this.minY, this.minZ);
return Location.at(this.getWorld().getName(), this.minX, this.minY, this.minZ);
}
public Location getMax() {
return Location.at(this.getWorld(), this.maxX, this.maxY, this.maxZ);
return Location.at(this.getWorld().getName(), this.maxX, this.maxY, this.maxZ);
}
}