some minor refactoring

This commit is contained in:
Jesse Boyd
2019-08-18 02:09:09 +01:00
parent d1af07b6ae
commit d434dfcfdd
64 changed files with 1892 additions and 812 deletions

View File

@ -13,16 +13,11 @@ import com.boydti.fawe.bukkit.util.BukkitTaskMan;
import com.boydti.fawe.bukkit.util.ItemUtil;
import com.boydti.fawe.bukkit.util.VaultUtil;
import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
import com.boydti.fawe.bukkit.v0.ChunkListener_8;
import com.boydti.fawe.bukkit.v0.ChunkListener_9;
import com.boydti.fawe.bukkit.v1_13.BukkitQueue_1_13;
import com.boydti.fawe.bukkit.v1_14.BukkitQueue_1_14;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.Jars;
import com.boydti.fawe.util.MainUtil;
@ -40,9 +35,11 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileOutputStream;
@ -52,6 +49,9 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class FaweBukkit implements IFawe, Listener {
@ -279,102 +279,6 @@ public class FaweBukkit implements IFawe, Listener {
return new BukkitTaskMan(plugin);
}
private boolean hasNMS = true;
private boolean playerChunk = false;
@Override
public FaweQueue getNewQueue(String world, boolean fast) {
if (playerChunk != (playerChunk = true)) {
try {
Field fieldDirtyCount = BukkitReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
fieldDirtyCount.setAccessible(true);
int mod = fieldDirtyCount.getModifiers();
if ((mod & Modifier.VOLATILE) == 0) {
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(fieldDirtyCount, mod + Modifier.VOLATILE);
}
} catch (Throwable ignore) {}
}
try {
return getQueue(world);
} catch (Throwable throwable) {
// Disable incompatible settings
Settings.IMP.QUEUE.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
Settings.IMP.HISTORY.COMBINE_STAGES = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
if (hasNMS) {
debug("====== NO NMS BLOCK PLACER FOUND ======");
debug("FAWE couldn't find a fast block placer");
debug("Bukkit version: " + Bukkit.getVersion());
debug("NMS label: " + plugin.getClass().getSimpleName().split("_")[1]);
debug("Fallback placer: " + BukkitQueue_All.class);
debug("=======================================");
debug("Download the version of FAWE for your platform");
debug(" - http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target");
debug("=======================================");
throwable.printStackTrace();
debug("=======================================");
TaskManager.IMP.laterAsync(
() -> MainUtil.sendAdmin("&cNo NMS placer found, see console!"), 1);
hasNMS = false;
}
return new BukkitQueue_All(world);
}
}
/**
* The FaweQueue is a core part of block placement<br>
* - The queue returned here is used in the SetQueue class (SetQueue handles the implementation specific queue)<br>
* - Block changes are grouped by chunk (as it's more efficient for lighting/packet sending)<br>
* - The FaweQueue returned here will provide the wrapper around the chunk object (FaweChunk)<br>
* - When a block change is requested, the SetQueue will first check if the chunk exists in the queue, or it will create and add it<br>
*/
@Override
public FaweQueue getNewQueue(World world, boolean fast) {
if (fast) {
if (playerChunk != (playerChunk = true)) {
try {
Field fieldDirtyCount = BukkitReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
fieldDirtyCount.setAccessible(true);
int mod = fieldDirtyCount.getModifiers();
if ((mod & Modifier.VOLATILE) == 0) {
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(fieldDirtyCount, mod + Modifier.VOLATILE);
}
} catch (Throwable ignore) {
}
}
Throwable error;
try {
return getQueue(world);
} catch (Throwable throwable) {
error = throwable;
}
// Disable incompatible settings
Settings.IMP.QUEUE.PARALLEL_THREADS = 1; // BukkitAPI placer is too slow to parallel thread at the chunk level
Settings.IMP.HISTORY.COMBINE_STAGES = false; // Performing a chunk copy (if possible) wouldn't be faster using the BukkitAPI
if (hasNMS) {
debug("====== NO NMS BLOCK PLACER FOUND ======");
debug("FAWE couldn't find a fast block placer");
debug("Bukkit version: " + Bukkit.getVersion());
debug("NMS label: " + plugin.getClass().getSimpleName());
debug("Fallback placer: " + BukkitQueue_All.class);
debug("=======================================");
debug("Download the version of FAWE for your platform");
debug(" - http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target");
debug("=======================================");
error.printStackTrace();
debug("=======================================");
TaskManager.IMP.laterAsync(
() -> MainUtil.sendAdmin("&cNo NMS placer found, see console!"), 1);
hasNMS = false;
}
}
return new BukkitQueue_All(world);
}
public Plugin getPlugin() {
return plugin;
}
@ -479,6 +383,25 @@ public class FaweBukkit implements IFawe, Listener {
return managers;
}
private volatile boolean keepUnloaded;
@EventHandler(priority = EventPriority.MONITOR)
public void onWorldLoad(WorldLoadEvent event) {
if (keepUnloaded) {
org.bukkit.World world = event.getWorld();
world.setKeepSpawnInMemory(false);
}
}
public synchronized <T> T createWorldUnloaded(Supplier<T> task) {
keepUnloaded = true;
try {
return task.get();
} finally {
keepUnloaded = false;
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
@ -520,51 +443,4 @@ public class FaweBukkit implements IFawe, Listener {
return null;
// return ((BlocksHubBukkit) blocksHubPlugin).getApi();
}
private Version version = null;
public Version getVersion() {
Version tmp = this.version;
if (tmp == null) {
tmp = Version.NONE;
for (Version v : Version.values()) {
try {
BukkitQueue_0.checkVersion(v.name());
this.version = tmp = v;
break;
} catch (IllegalStateException ignored) {}
}
}
return tmp;
}
public enum Version {
v1_14_R1,
v1_13_R2,
NONE,
}
private FaweQueue getQueue(World world) {
switch (getVersion()) {
case v1_13_R2:
return new BukkitQueue_1_13(world);
case v1_14_R1:
return new BukkitQueue_1_14(world);
default:
case NONE:
return new BukkitQueue_All(world);
}
}
private FaweQueue getQueue(String world) {
switch (getVersion()) {
case v1_13_R2:
return new BukkitQueue_1_13(world);
case v1_14_R1:
return new BukkitQueue_1_14(world);
default:
case NONE:
return new BukkitQueue_All(world);
}
}
}

View File

@ -1,54 +1,76 @@
package com.boydti.fawe.bukkit.beta;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.bukkit.v1_14.BukkitQueue_1_14;
import com.boydti.fawe.bukkit.v1_14.adapter.Spigot_v1_14_R1;
import com.boydti.fawe.jnbt.anvil.BitArray4096;
import com.boydti.fawe.util.MemUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.object.collection.BitArray4096;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockTypes;
import net.minecraft.server.v1_14_R1.BiomeBase;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.Chunk;
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_14_R1.ChunkProviderServer;
import net.minecraft.server.v1_14_R1.ChunkSection;
import net.minecraft.server.v1_14_R1.DataBits;
import net.minecraft.server.v1_14_R1.DataPalette;
import net.minecraft.server.v1_14_R1.DataPaletteBlock;
import net.minecraft.server.v1_14_R1.DataPaletteHash;
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.World;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.NBTTagInt;
import net.minecraft.server.v1_14_R1.TileEntity;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
import org.bukkit.event.entity.CreatureSpawnEvent;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
public class BukkitGetBlocks extends CharGetBlocks {
public ChunkSection[] sections;
public Chunk nmsChunk;
public World nmsWorld;
public CraftWorld world;
public int X, Z;
private boolean forceLoad;
public BukkitGetBlocks(World nmsWorld, int X, int Z, boolean forceLoad) {
this.nmsWorld = nmsWorld;
public BukkitGetBlocks(World world, int X, int Z, boolean forceLoad) {
this.world = (CraftWorld) world;
this.X = X;
this.Z = Z;
if (forceLoad) {
((WorldServer) nmsWorld).setForceLoaded(X, Z, this.forceLoad = true);
this.world.getHandle().setForceLoaded(X, Z, this.forceLoad = true);
}
}
@Override
protected void finalize() {
if (forceLoad) {
((WorldServer) nmsWorld).setForceLoaded(X, Z, forceLoad = false);
this.world.getHandle().setForceLoaded(X, Z, forceLoad = false);
}
}
@ -69,14 +91,310 @@ public class BukkitGetBlocks extends CharGetBlocks {
return load(layer, null);
}
private void updateGet(BukkitGetBlocks get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) {
synchronized (get) {
if (this.nmsChunk != nmsChunk) {
this.nmsChunk = nmsChunk;
this.sections = sections.clone();
this.reset();
}
if (this.sections == null) {
this.sections = sections.clone();
}
if (this.sections[layer] != section) {
this.sections[layer] = section;
}
this.blocks[layer] = arr;
}
}
private void removeEntity(Entity entity) {
entity.die();
entity.valid = false;
}
@Override
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
try {
WorldServer nmsWorld = world.getHandle();
Chunk nmsChunk = BukkitQueue.ensureLoaded(nmsWorld, X, Z);
// Remove existing tiles
{
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
if (!tiles.isEmpty()) {
final Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<BlockPosition, TileEntity> entry = iterator.next();
final BlockPosition pos = entry.getKey();
final int lx = pos.getX() & 15;
final int ly = pos.getY();
final int lz = pos.getZ() & 15;
final int layer = ly >> 4;
if (!set.hasSection(layer)) {
continue;
}
if (set.getBlock(lx, ly, lz).getOrdinal() != 0) {
TileEntity tile = entry.getValue();
tile.n();
tile.invalidateBlockCache();
}
}
}
}
int bitMask = 0;
synchronized (nmsChunk) {
ChunkSection[] sections = nmsChunk.getSections();
for (int layer = 0; layer < 16; layer++) {
if (!set.hasSection(layer)) continue;
bitMask |= 1 << layer;
char[] setArr = set.getArray(layer);
ChunkSection newSection;
ChunkSection existingSection = sections[layer];
if (existingSection == null) {
newSection = BukkitQueue.newChunkSection(layer, setArr);
if (BukkitQueue.setSectionAtomic(sections, null, newSection, layer)) {
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
continue;
} else {
existingSection = sections[layer];
if (existingSection == null) {
System.out.println("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer);
continue;
}
}
}
DelegateLock lock = BukkitQueue.applyLock(existingSection);
synchronized (this) {
synchronized (lock) {
lock.untilFree();
ChunkSection getSection;
if (this.nmsChunk != nmsChunk) {
this.nmsChunk = nmsChunk;
this.sections = null;
this.reset();
} else {
getSection = this.getSections()[layer];
if (getSection != existingSection) {
this.sections[layer] = existingSection;
this.reset();
} else if (lock.isModified()) {
this.reset(layer);
}
}
char[] getArr = this.load(layer);
for (int i = 0; i < 4096; i++) {
char value = setArr[i];
if (value != 0) {
getArr[i] = value;
}
}
newSection = BukkitQueue.newChunkSection(layer, getArr);
if (!BukkitQueue.setSectionAtomic(sections, existingSection, newSection, layer)) {
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
continue;
} else {
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
}
}
}
}
// Biomes
BiomeType[] biomes = set.getBiomes();
if (biomes != null) {
// set biomes
final BiomeBase[] currentBiomes = nmsChunk.getBiomeIndex();
for (int i = 0; i < biomes.length; i++) {
final BiomeType biome = biomes[i];
if (biome != null) {
final Biome craftBiome = BukkitAdapter.adapt(biome);
currentBiomes[i] = CraftBlock.biomeToBiomeBase(craftBiome);
}
}
}
Runnable[] syncTasks = null;
int bx = X << 4;
int bz = Z << 4;
Set<UUID> entityRemoves = set.getEntityRemoves();
if (entityRemoves != null && !entityRemoves.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[3];
syncTasks[2] = new Runnable() {
@Override
public void run() {
final List<Entity>[] entities = nmsChunk.getEntitySlices();
for (int i = 0; i < entities.length; i++) {
final Collection<Entity> ents = entities[i];
if (!ents.isEmpty()) {
final Iterator<Entity> iter = ents.iterator();
while (iter.hasNext()) {
final Entity entity = iter.next();
if (entityRemoves.contains(entity.getUniqueID())) {
iter.remove();
removeEntity(entity);
}
}
}
}
}
};
}
Set<CompoundTag> entities = set.getEntities();
if (entities != null && !entities.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[2];
syncTasks[1] = new Runnable() {
@Override
public void run() {
for (final CompoundTag nativeTag : entities) {
final Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
final StringTag idTag = (StringTag) entityTagMap.get("Id");
final ListTag posTag = (ListTag) entityTagMap.get("Pos");
final ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
if (idTag == null || posTag == null || rotTag == null) {
Fawe.debug("Unknown entity tag: " + nativeTag);
continue;
}
final double x = posTag.getDouble(0);
final double y = posTag.getDouble(1);
final double z = posTag.getDouble(2);
final float yaw = rotTag.getFloat(0);
final float pitch = rotTag.getFloat(1);
final String id = idTag.getValue();
EntityTypes<?> type = EntityTypes.a(id).orElse(null);
if (type != null) {
Entity entity = type.a(nmsWorld);
if (entity != null) {
UUID uuid = entity.getUniqueID();
entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
if (nativeTag != null) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
final NBTTagCompound tag = (NBTTagCompound) adapter.fromNative(nativeTag);
for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}
entity.f(tag);
}
entity.setLocation(x, y, z, yaw, pitch);
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
}
}
}
}
};
}
// set tiles
Map<Short, CompoundTag> tiles = set.getTiles();
if (tiles != null && !tiles.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[1];
syncTasks[0] = new Runnable() {
@Override
public void run() {
for (final Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue();
final short blockHash = entry.getKey();
final int x = (blockHash >> 12 & 0xF) + bx;
final int y = (blockHash & 0xFF);
final int z = (blockHash >> 8 & 0xF) + bz;
final BlockPosition pos = new BlockPosition(x, y, z);
synchronized (nmsWorld) {
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
if (tileEntity == null || tileEntity.isRemoved()) {
nmsWorld.removeTileEntity(pos);
tileEntity = nmsWorld.getTileEntity(pos);
}
if (tileEntity != null) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
final NBTTagCompound tag = (NBTTagCompound) adapter.fromNative(nativeTag);
tag.set("x", new NBTTagInt(x));
tag.set("y", new NBTTagInt(y));
tag.set("z", new NBTTagInt(z));
tileEntity.load(tag);
}
}
}
}
};
}
Runnable callback;
if (bitMask == 0) {
callback = null;
} else {
int finalMask = bitMask;
callback = () -> {
// Set Modified
nmsChunk.d(true); // Set Modified
nmsChunk.mustNotSave = false;
nmsChunk.markDirty();
// send to player
BukkitQueue.sendChunk(nmsWorld, X, Z, finalMask);
if (finalizer != null) finalizer.run();
};
}
if (syncTasks != null) {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
Runnable[] finalSyncTasks = syncTasks;
// Chain the sync tasks and the callback
Callable<Future> chain = new Callable<Future>() {
@Override
public Future call() {
// Run the sync tasks
for (int i = 1; i < finalSyncTasks.length; i++) {
Runnable task = finalSyncTasks[i];
if (task != null) {
task.run();
}
}
if (callback == null) {
if (finalizer != null) finalizer.run();
return null;
} else {
return queueHandler.async(callback, null);
}
}
};
return (T) (Future) queueHandler.sync(chain);
} else {
if (callback == null) {
if (finalizer != null) finalizer.run();
} else {
callback.run();
}
}
}
return null;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
@Override
public synchronized char[] load(int layer, char[] data) {
ChunkSection section = getSections()[layer];
// Section is null, return empty array
if (section == null) {
return FaweCache.EMPTY_CHAR_4096;
return FaweCache.IMP.EMPTY_CHAR_4096;
}
if (data == null || data == FaweCache.EMPTY_CHAR_4096) {
if (data == null || data == FaweCache.IMP.EMPTY_CHAR_4096) {
data = new char[4096];
}
DelegateLock lock = BukkitQueue.applyLock(section);
@ -88,8 +406,8 @@ public class BukkitGetBlocks extends CharGetBlocks {
Spigot_v1_14_R1 adapter = ((Spigot_v1_14_R1) WorldEditPlugin.getInstance().getBukkitImplAdapter());
final DataPaletteBlock<IBlockData> blocks = section.getBlocks();
final DataBits bits = (DataBits) BukkitQueue_1_14.fieldBits.get(blocks);
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitQueue_1_14.fieldPalette.get(blocks);
final DataBits bits = (DataBits) BukkitQueue.fieldBits.get(blocks);
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitQueue.fieldPalette.get(blocks);
final int bitsPerEntry = bits.c();
final long[] blockStates = bits.a();
@ -103,8 +421,8 @@ public class BukkitGetBlocks extends CharGetBlocks {
num_palette = ((DataPaletteHash<IBlockData>) palette).b();
} else {
num_palette = 0;
int[] paletteToBlockInts = FaweCache.PALETTE_TO_BLOCK.get();
char[] paletteToBlockChars = FaweCache.PALETTE_TO_BLOCK_CHAR.get();
int[] paletteToBlockInts = FaweCache.IMP.PALETTE_TO_BLOCK.get();
char[] paletteToBlockChars = FaweCache.IMP.PALETTE_TO_BLOCK_CHAR.get();
try {
for (int i = 0; i < 4096; i++) {
char paletteVal = data[i];
@ -130,7 +448,7 @@ public class BukkitGetBlocks extends CharGetBlocks {
return data;
}
char[] paletteToBlockChars = FaweCache.PALETTE_TO_BLOCK_CHAR.get();
char[] paletteToBlockChars = FaweCache.IMP.PALETTE_TO_BLOCK_CHAR.get();
try {
final int size = num_palette;
if (size != 1) {
@ -188,7 +506,7 @@ public class BukkitGetBlocks extends CharGetBlocks {
synchronized (this) {
tmp = nmsChunk;
if (tmp == null) {
nmsChunk = tmp = BukkitQueue.ensureLoaded(nmsWorld, X, Z);
nmsChunk = tmp = BukkitQueue.ensureLoaded(this.world.getHandle(), X, Z);
}
}
}

View File

@ -2,15 +2,18 @@ package com.boydti.fawe.bukkit.beta;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.SimpleCharQueueExtent;
import com.boydti.fawe.beta.implementation.WorldChunkCache;
import com.boydti.fawe.beta.implementation.IChunkCache;
import com.boydti.fawe.bukkit.v1_14.adapter.BlockMaterial_1_14;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.BitArray4096;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
@ -42,30 +45,19 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.Lock;
import java.util.function.Supplier;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkNotNull;
public class BukkitQueue extends SimpleCharQueueExtent {
private org.bukkit.World bukkitWorld;
private WorldServer nmsWorld;
@Override
public void enableQueue() {
public BukkitQueue() {
}
@Override
public void disableQueue() {
}
@Override
public synchronized void init(WorldChunkCache cache) {
World world = cache.getWorld();
public synchronized void init(Extent extent, IChunkCache<IChunkGet> get, IChunkCache<IChunkSet> set) {
World world = WorldWrapper.unwrap(extent);
if (world == null) throw new IllegalArgumentException("Get must be a world.");
if (world instanceof BukkitWorld) {
this.bukkitWorld = ((BukkitWorld) world).getWorld();
} else {
@ -74,15 +66,7 @@ public class BukkitQueue extends SimpleCharQueueExtent {
checkNotNull(this.bukkitWorld);
CraftWorld craftWorld = ((CraftWorld) bukkitWorld);
this.nmsWorld = craftWorld.getHandle();
super.init(cache);
}
public WorldServer getNmsWorld() {
return nmsWorld;
}
public org.bukkit.World getBukkitWorld() {
return bukkitWorld;
super.init(extent, get, set);
}
@Override
@ -90,22 +74,6 @@ public class BukkitQueue extends SimpleCharQueueExtent {
super.reset();
}
// private static final IterableThreadLocal<BukkitFullChunk> FULL_CHUNKS = new IterableThreadLocal<BukkitFullChunk>() {
// @Override
// public BukkitFullChunk init() {
// return new BukkitFullChunk();
// }
// };
@Override
public IChunk create(boolean isFull) {
// if (full) {
// //TODO implement
// return FULL_CHUNKS.get();
// }
return new BukkitChunkHolder();
}
/*
NMS fields
*/
@ -235,7 +203,7 @@ public class BukkitQueue extends SimpleCharQueueExtent {
return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(X, Z));
}
private PlayerChunk getPlayerChunk(final int cx, final int cz) {
private static PlayerChunk getPlayerChunk(net.minecraft.server.v1_14_R1.WorldServer nmsWorld, final int cx, final int cz) {
PlayerChunkMap chunkMap = nmsWorld.getChunkProvider().playerChunkMap;
PlayerChunk playerChunk = chunkMap.visibleChunks.get(ChunkCoordIntPair.pair(cx, cz));
if (playerChunk == null) {
@ -244,9 +212,8 @@ public class BukkitQueue extends SimpleCharQueueExtent {
return playerChunk;
}
@Override
public void sendChunk(final int X, final int Z, final int mask) {
PlayerChunk playerChunk = getPlayerChunk(X, Z);
public static void sendChunk(net.minecraft.server.v1_14_R1.WorldServer nmsWorld, int X, int Z, int mask) {
PlayerChunk playerChunk = getPlayerChunk(nmsWorld, X, Z);
if (playerChunk == null) {
return;
}
@ -256,7 +223,7 @@ public class BukkitQueue extends SimpleCharQueueExtent {
// sections[layer] = new ChunkSection(layer << 4);
// }
// }
if (playerChunk.k()) {
if (playerChunk.hasBeenLoaded()) {
TaskManager.IMP.sync(new Supplier<Object>() {
@Override
public Object get() {
@ -284,6 +251,11 @@ public class BukkitQueue extends SimpleCharQueueExtent {
return;
}
@Override
public void sendChunk(final int X, final int Z, final int mask) {
sendChunk(nmsWorld, X, Z, mask);
}
/*
NMS conversion
*/
@ -293,10 +265,10 @@ public class BukkitQueue extends SimpleCharQueueExtent {
if (blocks == null) {
return section;
}
final int[] blockToPalette = FaweCache.BLOCK_TO_PALETTE.get();
final int[] paletteToBlock = FaweCache.PALETTE_TO_BLOCK.get();
final long[] blockStates = FaweCache.BLOCK_STATES.get();
final int[] blocksCopy = FaweCache.SECTION_BLOCKS.get();
final int[] blockToPalette = FaweCache.IMP.BLOCK_TO_PALETTE.get();
final int[] paletteToBlock = FaweCache.IMP.PALETTE_TO_BLOCK.get();
final long[] blockStates = FaweCache.IMP.BLOCK_STATES.get();
final int[] blocksCopy = FaweCache.IMP.SECTION_BLOCKS.get();
try {
int num_palette = 0;
int air = 0;

View File

@ -1,11 +1,78 @@
package com.boydti.fawe.bukkit.beta;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.bukkit.v0.ChunkListener;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class BukkitQueueHandler extends QueueHandler {
@Override
public IQueueExtent create() {
return new BukkitQueue();
}
}
private volatile boolean timingsEnabled;
private static boolean alertTimingsChange = true;
private static Field fieldTimingsEnabled;
private static Field fieldAsyncCatcherEnabled;
private static Method methodCheck;
static {
try {
fieldAsyncCatcherEnabled = Class.forName("org.spigotmc.AsyncCatcher").getField("enabled");
fieldAsyncCatcherEnabled.setAccessible(true);
} catch (Throwable ignore) {}
try {
fieldTimingsEnabled = Class.forName("co.aikar.timings.Timings").getDeclaredField("timingsEnabled");
fieldTimingsEnabled.setAccessible(true);
methodCheck = Class.forName("co.aikar.timings.TimingsManager").getDeclaredMethod("recheckEnabled");
methodCheck.setAccessible(true);
} catch (Throwable ignore){}
}
@Override
public void startSet(boolean parallel) {
ChunkListener.physicsFreeze = true;
if (parallel) {
try {
if (fieldAsyncCatcherEnabled != null) {
fieldAsyncCatcherEnabled.set(null, false);
}
if (fieldTimingsEnabled != null) {
timingsEnabled = (boolean) fieldTimingsEnabled.get(null);
if (timingsEnabled) {
if (alertTimingsChange) {
alertTimingsChange = false;
Fawe.debug("Having `parallel-threads` > 1 interferes with the timings.");
}
fieldTimingsEnabled.set(null, false);
methodCheck.invoke(null);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
@Override
public void endSet(boolean parallel) {
ChunkListener.physicsFreeze = false;
if (parallel) {
try {
if (fieldAsyncCatcherEnabled != null) {
fieldAsyncCatcherEnabled.set(null, true);
}
if (fieldTimingsEnabled != null && timingsEnabled) {
fieldTimingsEnabled.set(null, true);
methodCheck.invoke(null);
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
}

View File

@ -1,11 +1,11 @@
package com.boydti.fawe.bukkit.listener;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
import com.boydti.fawe.command.CFICommands;
import com.boydti.fawe.object.brush.visualization.cfi.HeightMapMCAGenerator;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.brush.BrushSettings;
import com.boydti.fawe.object.extent.FastWorldEditExtent;
import com.boydti.fawe.util.EditSessionBuilder;
import com.boydti.fawe.util.ExtentTraverser;
import com.boydti.fawe.util.TaskManager;
@ -16,6 +16,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -286,7 +287,8 @@ public class BukkitImageListener implements Listener {
.combineStages(false).autoQueue(false).blockBag(null).limitUnlimited()
.build();
ExtentTraverser last = new ExtentTraverser(es.getExtent()).last();
if (last.get() instanceof FastWorldEditExtent) {
Extent extent = last.get();
if (extent instanceof IQueueExtent) {
last = last.previous();
}
last.setNext(generator);

View File

@ -1,12 +1,9 @@
package com.boydti.fawe.bukkit.listener;
import com.boydti.fawe.command.CFICommands;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal3;
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.util.SetQueue;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
@ -58,98 +55,99 @@ public class CFIPacketListener implements Listener {
this.plugin = plugin;
this.protocolmanager = ProtocolLibrary.getProtocolManager();
// Direct digging to the virtual world
registerBlockEvent(PacketType.Play.Client.BLOCK_DIG, false, new RunnableVal3<PacketEvent, VirtualWorld, BlockVector3>() {
@Override
public void run(Builder event, URI gen, String pt) {
try {
Player plr = event.getPlayer();
BlockVector3 realPos = pt.add(gen.getOrigin().toBlockPoint());
if (!sendBlockChange(plr, gen, pt, Interaction.HIT)) {
gen.setBlock(pt, BlockTypes.AIR.getDefaultState());
}
} catch (WorldEditException e) {
e.printStackTrace();
}
}
});
// Direct placing to the virtual world
RunnableVal3<PacketEvent, VirtualWorld, BlockVector3> placeTask = new RunnableVal3<PacketEvent, VirtualWorld, BlockVector3>() {
@Override
public void run(Builder event, URI gen, String pt) {
try {
Player plr = event.getPlayer();
List<EnumWrappers.Hand> hands = event.getPacket().getHands().getValues();
EnumWrappers.Hand enumHand = hands.isEmpty() ? EnumWrappers.Hand.MAIN_HAND : hands.get(0);
PlayerInventory inv = plr.getInventory();
ItemStack hand = enumHand == EnumWrappers.Hand.MAIN_HAND ? inv.getItemInMainHand() : inv.getItemInOffHand();
if (hand.getType().isBlock()) {
Material type = hand.getType();
switch (type) {
case AIR:
case CAVE_AIR:
case VOID_AIR:
break;
default: {
BlockStateHolder block = BukkitAdapter.asBlockState(hand);
if (block != null) {
gen.setBlock(pt, block);
return;
}
}
}
}
pt = getRelPos(event, gen);
sendBlockChange(plr, gen, pt, Interaction.OPEN);
} catch (WorldEditException e) {
e.printStackTrace();
}
}
};
registerBlockEvent(PacketType.Play.Client.BLOCK_PLACE, true, placeTask);
registerBlockEvent(PacketType.Play.Client.USE_ITEM, true, placeTask);
// Cancel block change packets where the real world overlaps with the virtual one
registerBlockEvent(PacketType.Play.Server.BLOCK_CHANGE, false, new RunnableVal3<PacketEvent, VirtualWorld, BlockVector3>() {
@Override
public void run(Builder event, URI gen, String pt) {
// Do nothing
}
});
// Modify chunk packets where the real world overlaps with the virtual one
protocolmanager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
@Override
public void onPacketSending(PacketEvent event) {
if (!event.isServerPacket()) return;
VirtualWorld gen = getGenerator(event);
if (gen != null) {
BlockVector3 origin = gen.getOrigin().toBlockPoint();
PacketContainer packet = event.getPacket();
StructureModifier<Integer> ints = packet.getIntegers();
int cx = ints.read(0);
int cz = ints.read(1);
int ocx = origin.getBlockX() >> 4;
int ocz = origin.getBlockZ() >> 4;
if (gen.contains(BlockVector3.at((cx - ocx) << 4, 0, (cz - ocz) << 4))) {
event.setCancelled(true);
Player plr = event.getPlayer();
FaweQueue queue = SetQueue.IMP.getNewQueue(plr.getWorld().getName(), true, false);
FaweChunk toSend = gen.getSnapshot(cx - ocx, cz - ocz);
toSend.setLoc(gen, cx, cz);
queue.sendChunkUpdate(toSend, FawePlayer.wrap(plr));
}
}
}
});
// TODO NOT IMPLEMENTED
// // Direct digging to the virtual world
// registerBlockEvent(PacketType.Play.Client.BLOCK_DIG, false, new RunnableVal3<PacketEvent, VirtualWorld, BlockVector3>() {
// @Override
// public void run(Builder event, URI gen, String pt) {
// try {
// Player plr = event.getPlayer();
// BlockVector3 realPos = pt.add(gen.getOrigin().toBlockPoint());
// if (!sendBlockChange(plr, gen, pt, Interaction.HIT)) {
// gen.setBlock(pt, BlockTypes.AIR.getDefaultState());
// }
// } catch (WorldEditException e) {
// e.printStackTrace();
// }
// }
// });
//
// // Direct placing to the virtual world
// RunnableVal3<PacketEvent, VirtualWorld, BlockVector3> placeTask = new RunnableVal3<PacketEvent, VirtualWorld, BlockVector3>() {
// @Override
// public void run(Builder event, URI gen, String pt) {
// try {
// Player plr = event.getPlayer();
// List<EnumWrappers.Hand> hands = event.getPacket().getHands().getValues();
//
// EnumWrappers.Hand enumHand = hands.isEmpty() ? EnumWrappers.Hand.MAIN_HAND : hands.get(0);
// PlayerInventory inv = plr.getInventory();
// ItemStack hand = enumHand == EnumWrappers.Hand.MAIN_HAND ? inv.getItemInMainHand() : inv.getItemInOffHand();
// if (hand.getType().isBlock()) {
// Material type = hand.getType();
// switch (type) {
// case AIR:
// case CAVE_AIR:
// case VOID_AIR:
// break;
// default: {
// BlockStateHolder block = BukkitAdapter.asBlockState(hand);
// if (block != null) {
// gen.setBlock(pt, block);
// return;
// }
// }
// }
// }
// pt = getRelPos(event, gen);
// sendBlockChange(plr, gen, pt, Interaction.OPEN);
// } catch (WorldEditException e) {
// e.printStackTrace();
// }
// }
// };
// registerBlockEvent(PacketType.Play.Client.BLOCK_PLACE, true, placeTask);
// registerBlockEvent(PacketType.Play.Client.USE_ITEM, true, placeTask);
//
// // Cancel block change packets where the real world overlaps with the virtual one
// registerBlockEvent(PacketType.Play.Server.BLOCK_CHANGE, false, new RunnableVal3<PacketEvent, VirtualWorld, BlockVector3>() {
// @Override
// public void run(Builder event, URI gen, String pt) {
// // Do nothing
// }
// });
//
// // Modify chunk packets where the real world overlaps with the virtual one
// protocolmanager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
// @Override
// public void onPacketSending(PacketEvent event) {
// if (!event.isServerPacket()) return;
//
// VirtualWorld gen = getGenerator(event);
// if (gen != null) {
// BlockVector3 origin = gen.getOrigin().toBlockPoint();
// PacketContainer packet = event.getPacket();
// StructureModifier<Integer> ints = packet.getIntegers();
// int cx = ints.read(0);
// int cz = ints.read(1);
//
// int ocx = origin.getBlockX() >> 4;
// int ocz = origin.getBlockZ() >> 4;
//
// if (gen.contains(BlockVector3.at((cx - ocx) << 4, 0, (cz - ocz) << 4))) {
// event.setCancelled(true);
//
// Player plr = event.getPlayer();
//
// FaweQueue queue = SetQueue.IMP.getNewQueue(plr.getWorld().getName(), true, false);
//
// FaweChunk toSend = gen.getSnapshot(cx - ocx, cz - ocz);
// toSend.setLoc(gen, cx, cz);
// queue.sendChunkUpdate(toSend, FawePlayer.wrap(plr));
// }
// }
// }
// });
// The following few listeners are to ignore block collisions where the virtual and real world overlap

View File

@ -3,16 +3,12 @@ package com.boydti.fawe.bukkit.regions;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.queue.NullFaweQueue;
import com.boydti.fawe.regions.FaweMask;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockTypes;
import jdk.nashorn.internal.ir.Block;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventException;
@ -21,7 +17,6 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.plugin.RegisteredListener;
import java.util.ArrayList;
import org.bukkit.util.BlockVector;
public class FreeBuildRegion extends BukkitMaskManager {
private final ArrayList<RegisteredListener> listeners;
@ -60,7 +55,7 @@ public class FreeBuildRegion extends BukkitMaskManager {
BlockVector3 pos1 = BlockVector3.ZERO;
BlockVector3 pos2 = BlockVector3.ZERO;
AsyncBlock block = new AsyncBlock(asyncWorld, new NullFaweQueue(asyncWorld.getWorldName(), BlockTypes.STONE.getDefaultState()), 0, 0, 0);
AsyncBlock block = new AsyncBlock(asyncWorld, 0, 0, 0);
BlockBreakEvent event = new BlockBreakEvent(block, BukkitAdapter.adapt(player.toWorldEditPlayer()));
return new FaweMask(pos1, pos2) {

View File

@ -1,10 +1,14 @@
package com.boydti.fawe.bukkit.util;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.bukkit.beta.BukkitQueue;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.bukkit.inventory.ItemStack;
@ -13,6 +17,8 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static com.google.gson.internal.$Gson$Preconditions.checkNotNull;
public class ItemUtil {
private final Method methodAsNMSCopy;
@ -21,10 +27,13 @@ public class ItemUtil {
private final Method methodSetTag;
private final Method methodAsBukkitCopy;
private final Field fieldHandle;
private final BukkitImplAdapter adapter;
private SoftReference<Int2ObjectOpenHashMap<WeakReference<Tag>>> hashToNMSTag = new SoftReference(new Int2ObjectOpenHashMap<>());
public ItemUtil() throws Exception {
this.adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
checkNotNull(adapter);
Class<?> classCraftItemStack = BukkitReflectionUtils.getCbClass("inventory.CraftItemStack");
Class<?> classNMSItem = BukkitReflectionUtils.getNmsClass("ItemStack");
this.methodAsNMSCopy = ReflectionUtils.setAccessible(classCraftItemStack.getDeclaredMethod("asNMSCopy", ItemStack.class));
@ -68,7 +77,7 @@ public class ItemUtil {
Tag nativeTag = nativeTagRef.get();
if (nativeTag != null) return (CompoundTag) nativeTag;
}
Tag nativeTag = BukkitQueue_0.toNative(nmsTag);
Tag nativeTag = adapter.toNative(nmsTag);
map.put(nmsTag.hashCode(), new WeakReference<>(nativeTag));
return null;
}
@ -86,7 +95,7 @@ public class ItemUtil {
copy = true;
nmsItem = methodAsNMSCopy.invoke(null, item);
}
Object nmsTag = BukkitQueue_0.fromNative(tag);
Object nmsTag = adapter.fromNative(tag);
methodSetTag.invoke(nmsItem, nmsTag);
if (copy) return (ItemStack) methodAsBukkitCopy.invoke(null, nmsItem);
return item;

View File

@ -382,7 +382,7 @@
// int z = location.getBlockZ();
//
// org.bukkit.block.Block bukkitBlock = location.getBlock();
// BaseBlock block = FaweCache.getBlock(bukkitBlock.getTypeId(), bukkitBlock.getData());
// BaseBlock block = FaweCache.IMP.getBlock(bukkitBlock.getTypeId(), bukkitBlock.getData());
//
// // Read the NBT data
// Object nmsWorld = getHandleWorld.invoke(craftWorld);

View File

@ -51,6 +51,7 @@ import com.sk89q.worldedit.registry.state.EnumProperty;
import com.sk89q.worldedit.registry.state.IntegerProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -104,6 +105,7 @@ import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_14_R1.util.CraftMagicNumbers;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.slf4j.Logger;
@ -250,6 +252,21 @@ public final class Spigot_v1_14_R1 extends CachedBukkitAdapter implements Bukkit
// Code that is less likely to break
// ------------------------------------------------------------------------
@Override
public int getDataVersion() {
return CraftMagicNumbers.INSTANCE.getDataVersion();
}
@Override
public DataFixer getDataFixer() {
try {
Class<?> converter = Class.forName("com.sk89q.worldedit.bukkit.adapter.impl.DataConverters_1_14_R4");
return (DataFixer) converter.getDeclaredField("INSTANCE").get(null);
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("deprecation")
@Override
public BaseBlock getBlock(Location location) {
@ -409,15 +426,15 @@ public final class Spigot_v1_14_R1 extends CachedBukkitAdapter implements Bukkit
for (IBlockState state : blockStateList.d()) {
Property property;
if (state instanceof BlockStateBoolean) {
property = new BooleanProperty(state.a(), ImmutableList.copyOf(state.d()));
property = new BooleanProperty(state.a(), ImmutableList.copyOf(state.getValues()));
} else if (state instanceof BlockStateDirection) {
property = new DirectionalProperty(state.a(),
(List<Direction>) state.d().stream().map(e -> Direction.valueOf(((INamable) e).getName().toUpperCase())).collect(Collectors.toList()));
(List<Direction>) state.getValues().stream().map(e -> Direction.valueOf(((INamable) e).getName().toUpperCase())).collect(Collectors.toList()));
} else if (state instanceof BlockStateEnum) {
property = new EnumProperty(state.a(),
(List<String>) state.d().stream().map(e -> ((INamable) e).getName()).collect(Collectors.toList()));
(List<String>) state.getValues().stream().map(e -> ((INamable) e).getName()).collect(Collectors.toList()));
} else if (state instanceof BlockStateInteger) {
property = new IntegerProperty(state.a(), ImmutableList.copyOf(state.d()));
property = new IntegerProperty(state.a(), ImmutableList.copyOf(state.getValues()));
} else {
throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName());
}

View File

@ -1,13 +1,14 @@
package com.boydti.fawe.bukkit.wrapper;
import com.boydti.fawe.bukkit.wrapper.state.AsyncSign;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.TaskManager;
import com.destroystokyo.paper.block.BlockSoundGroup;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.bukkit.FluidCollisionMode;
@ -34,12 +35,10 @@ public class AsyncBlock implements Block {
public int z;
public int y;
public int x;
public final FaweQueue queue;
public final AsyncWorld world;
public AsyncBlock(AsyncWorld world, FaweQueue queue, int x, int y, int z) {
public AsyncBlock(AsyncWorld world, int x, int y, int z) {
this.world = world;
this.queue = queue;
this.x = x;
this.y = Math.max(0, Math.min(255, y));
this.z = z;
@ -54,25 +53,24 @@ public class AsyncBlock implements Block {
@Override
@Deprecated
public byte getData() {
return (byte) (queue.getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId()) & 0xF);
return (byte) getPropertyId();
}
public int getPropertyId() {
return (queue.getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId()) >> BlockTypes.BIT_OFFSET);
return world.getBlock(x, y, z).getInternalId() >> BlockTypes.BIT_OFFSET;
}
public int getCombinedId() {
return queue.getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId());
return world.getBlock(x, y, z).getInternalId();
}
public int getTypeId() {
int id = (queue.getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId()));
return BlockTypes.getFromStateId(id).getInternalId();
return world.getBlock(x, y, z).getBlockType().getInternalId();
}
@NotNull @Override
public AsyncBlock getRelative(int modX, int modY, int modZ) {
return new AsyncBlock(world, queue, x + modX, y + modY, z + modZ);
return new AsyncBlock(world, x + modX, y + modY, z + modZ);
}
@NotNull @Override
@ -92,7 +90,7 @@ public class AsyncBlock implements Block {
@NotNull @Override
public BlockData getBlockData() {
return BukkitAdapter.getBlockData(queue.getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId()));
return BukkitAdapter.adapt(world.getBlock(x, y, z));
}
@Deprecated
@ -102,7 +100,7 @@ public class AsyncBlock implements Block {
@Deprecated
public boolean setCombinedId(int combinedId) {
return queue.setBlock(x, y, z, combinedId);
return world.setBlock(x, y, z, BlockState.getFromInternalId(combinedId));
}
@Deprecated
@ -112,7 +110,7 @@ public class AsyncBlock implements Block {
@Deprecated
public boolean setTypeId(int typeId) {
return queue.setBlock(x, y, z, BlockTypes.get(typeId).getDefaultState());
return world.setBlock(x, y, z, BlockTypes.get(typeId).getDefaultState());
}
@Deprecated
@ -122,17 +120,17 @@ public class AsyncBlock implements Block {
@Override
public byte getLightLevel() {
return (byte) queue.getLight(x, y, z);
return (byte) world.getLight(x, y, z);
}
@Override
public byte getLightFromSky() {
return (byte) queue.getSkyLight(x, y, z);
return (byte) world.getSkyLight(x, y, z);
}
@Override
public byte getLightFromBlocks() {
return (byte) queue.getEmmittedLight(x, y, z);
return (byte) world.getBlockLight(x, y, z);
}
@NotNull @Override
@ -179,7 +177,7 @@ public class AsyncBlock implements Block {
@Override
public void setBlockData(@NotNull BlockData blockData) {
try {
queue.setBlock(x, y, z, BukkitAdapter.adapt(blockData));
world.setBlock(x, y, z, BukkitAdapter.adapt(blockData));
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
@ -193,7 +191,7 @@ public class AsyncBlock implements Block {
@Override
public void setType(@NotNull Material type) {
try {
queue.setBlock(x, y, z, BukkitAdapter.adapt(type).getDefaultState());
world.setBlock(x, y, z, BukkitAdapter.adapt(type).getDefaultState());
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
@ -219,9 +217,8 @@ public class AsyncBlock implements Block {
@NotNull @Override
public AsyncBlockState getState() {
int combined = queue.getCombinedId4Data(x, y, z, 0);
BlockType type = BlockTypes.getFromStateId(combined);
switch (type.getInternalId()) {
BaseBlock state = world.getFullBlock(x, y, z);
switch (state.getBlockType().getInternalId()) {
case BlockID.ACACIA_SIGN:
case BlockID.SPRUCE_SIGN:
case BlockID.ACACIA_WALL_SIGN:
@ -234,9 +231,9 @@ public class AsyncBlock implements Block {
case BlockID.JUNGLE_WALL_SIGN:
case BlockID.OAK_SIGN:
case BlockID.OAK_WALL_SIGN:
return new AsyncSign(this, combined);
return new AsyncSign(this, state);
default:
return new AsyncBlockState(this, combined);
return new AsyncBlockState(this, state);
}
}
@ -248,13 +245,13 @@ public class AsyncBlock implements Block {
@NotNull @Override
public Biome getBiome() {
return world.getAdapter().adapt(queue.getBiomeType(x, z));
return world.getAdapter().adapt(world.getBiomeType(x, z));
}
@Override
public void setBiome(@NotNull Biome bio) {
BiomeType biome = world.getAdapter().adapt(bio);
queue.setBiome(x, z, biome);
world.setBiome(x, 0, z, biome);
}
@Override
@ -301,9 +298,7 @@ public class AsyncBlock implements Block {
@Override
public boolean isLiquid() {
int combined = queue.getCombinedId4Data(x, y, z, 0);
BlockType type = BlockTypes.getFromStateId(combined);
return type.getMaterial().isLiquid();
return world.getBlock(x, y, z).getMaterial().isLiquid();
}
@Override

View File

@ -6,6 +6,8 @@ import java.util.List;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.bukkit.Chunk;
import org.bukkit.Location;
@ -20,30 +22,26 @@ import org.bukkit.plugin.Plugin;
public class AsyncBlockState implements BlockState {
private int combinedId;
private BaseBlock state;
private BlockData blockData;
private CompoundTag nbt;
private final AsyncBlock block;
public AsyncBlockState(AsyncBlock block) {
this(block, block.queue.getCombinedId4Data(block.x, block.y, block.z, 0));
this(block, block.world.getFullBlock(block.x, block.y, block.z));
}
public AsyncBlockState(AsyncBlock block, int combined) {
this.combinedId = combined;
public AsyncBlockState(AsyncBlock block, BaseBlock state) {
this.state = state;
this.block = block;
this.blockData = BukkitAdapter.getBlockData(combined);
if (BlockTypes.getFromStateId(combined).getMaterial().hasContainer()) {
this.nbt = block.queue.getTileEntity(block.x, block.y, block.z);
}
this.blockData = BukkitAdapter.adapt(state);
}
public int getTypeId() {
return BlockTypes.getFromStateId(combinedId).getInternalId();
return state.getBlockType().getInternalId();
}
public int getPropertyId() {
return combinedId >> BlockTypes.BIT_OFFSET;
return state.getInternalId() >> BlockTypes.BIT_OFFSET;
}
@Override
@ -68,7 +66,7 @@ public class AsyncBlockState implements BlockState {
@Override
public byte getLightLevel() {
return (byte) BlockTypes.getFromStateId(combinedId).getMaterial().getLightValue();
return (byte) state.getMaterial().getLightValue();
}
@Override
@ -114,7 +112,14 @@ public class AsyncBlockState implements BlockState {
@Override
public void setBlockData(BlockData blockData) {
this.blockData = blockData;
this.combinedId = BukkitAdapter.adapt(blockData).getInternalId();
CompoundTag nbt = state.getNbtData();
BlockType oldType = state.getBlockType();
com.sk89q.worldedit.world.block.BlockState newState = BukkitAdapter.adapt(blockData);
if (nbt != null && newState.getBlockType() == oldType) {
state = newState.toBaseBlock(nbt);
} else {
state = newState.toBaseBlock();
}
}
@Override
@ -135,33 +140,30 @@ public class AsyncBlockState implements BlockState {
@Override
public boolean update(boolean force, boolean applyPhysics) {
try {
boolean result = block.queue.setBlock(block.x, block.y, block.z, BukkitAdapter.adapt(blockData));
if (nbt != null) {
block.queue.setTile(block.x, block.y, block.z, nbt);
}
return result;
return block.world.setBlock(block.x, block.y, block.z, state);
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
public CompoundTag getNbtData() {
return nbt;
return state.getNbtData();
}
public void setNbtData(CompoundTag nbt) {
this.nbt = nbt;
state = this.state.toBaseBlock(nbt);
}
@Override
public byte getRawData() {
return (byte) (combinedId >> BlockTypes.BIT_OFFSET);
return (byte) (state.getInternalId() >> BlockTypes.BIT_OFFSET);
}
@Override
public void setRawData(byte data) {
this.combinedId = getTypeId() + (data << BlockTypes.BIT_OFFSET);
this.blockData = BukkitAdapter.getBlockData(this.combinedId);
int combinedId = getTypeId() + (data << BlockTypes.BIT_OFFSET);
state = com.sk89q.worldedit.world.block.BlockState.getFromInternalId(combinedId).toBaseBlock(state.getNbtData());
this.blockData = BukkitAdapter.adapt(state);
}
@Override

View File

@ -1,8 +1,6 @@
package com.boydti.fawe.bukkit.wrapper;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.TaskManager;
@ -21,11 +19,9 @@ public class AsyncChunk implements Chunk {
private final AsyncWorld world;
private final int z;
private final int x;
private final FaweQueue queue;
public AsyncChunk(World world, FaweQueue queue, int x, int z) {
public AsyncChunk(World world, int x, int z) {
this.world = world instanceof AsyncWorld ? (AsyncWorld) world : new AsyncWorld(world, true);
this.queue = queue;
this.x = x;
this.z = z;
}
@ -61,7 +57,7 @@ public class AsyncChunk implements Chunk {
@Override
public AsyncBlock getBlock(int x, int y, int z) {
return new AsyncBlock(world, queue, (this.x << 4) + x, y, (this.z << 4) + z);
return new AsyncBlock(world, (this.x << 4) + x, y, (this.z << 4) + z);
}
@Override
@ -87,8 +83,7 @@ public class AsyncChunk implements Chunk {
task.run();
return task.value;
}
if (queue instanceof BukkitQueue_0) {
BukkitQueue_0 bq = (BukkitQueue_0) queue;
if (world.isWorld()) {
if (world.isChunkLoaded(x, z)) {
if (world.isChunkLoaded(x, z)) {
task.run();

View File

@ -1,32 +1,36 @@
package com.boydti.fawe.bukkit.wrapper;
import com.bekvon.bukkit.residence.commands.material;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.queue.DelegateFaweQueue;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.PassthroughExtent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.world.biome.BiomeType;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import java.util.function.Supplier;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.bukkit.*;
import com.sk89q.worldedit.world.block.BlockState;
import org.bukkit.BlockChangeDelegate;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Difficulty;
import org.bukkit.Effect;
import org.bukkit.FluidCollisionMode;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.StructureType;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.WorldBorder;
import org.bukkit.WorldCreator;
import org.bukkit.WorldType;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
@ -50,6 +54,17 @@ import org.bukkit.util.Consumer;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Modify the world from an async thread<br>
@ -60,10 +75,9 @@ import org.jetbrains.annotations.NotNull;
* @see #wrap(World)
* @see #create(WorldCreator)
*/
public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue {
public class AsyncWorld extends PassthroughExtent implements World {
private World parent;
private FaweQueue queue;
private BukkitImplAdapter adapter;
@Override
@ -78,7 +92,7 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
*/
@Deprecated
public AsyncWorld(World parent, boolean autoQueue) {
this(parent, FaweAPI.createQueue(parent.getName(), autoQueue));
this(parent, FaweAPI.createQueue(new BukkitWorld(parent), autoQueue));
}
public AsyncWorld(String world, boolean autoQueue) {
@ -91,19 +105,10 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
* @param queue
*/
@Deprecated
public AsyncWorld(World parent, FaweQueue queue) {
super(queue);
public AsyncWorld(World parent, Extent extent) {
super(extent);
this.parent = parent;
this.queue = queue;
if (queue instanceof BukkitQueue_0) {
this.adapter = BukkitQueue_0.getAdapter();
} else {
try {
this.adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
} catch (Throwable e) {
e.printStackTrace();
}
}
this.adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
}
/**
@ -118,32 +123,15 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
return new AsyncWorld(world, false);
}
public void changeWorld(World world, FaweQueue queue) {
this.parent = world;
if (queue != this.queue) {
if (this.queue != null) {
final FaweQueue oldQueue = this.queue;
TaskManager.IMP.async(oldQueue::flush);
}
this.queue = queue;
}
setParent(queue);
}
@Override
public String toString() {
return super.toString() + ":" + queue.toString();
return getName();
}
public World getBukkitWorld() {
return parent;
}
@Override
public FaweQueue getQueue() {
return queue;
}
/**
* Create a world async (untested)
* - Only optimized for 1.10
@ -151,8 +139,8 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
* @return
*/
public synchronized static AsyncWorld create(final WorldCreator creator) {
BukkitQueue_0 queue = (BukkitQueue_0) SetQueue.IMP.getNewQueue(creator.name(), true, false);
World world = queue.createWorld(creator);
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
@Nullable World world = adapter.createWorld(creator);
return wrap(world);
}
@ -163,9 +151,7 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
}
public void flush() {
if (queue != null) {
queue.flush();
}
getExtent().commit();
}
@Override
@ -240,7 +226,7 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
@Override
public AsyncBlock getBlockAt(final int x, final int y, final int z) {
return new AsyncBlock(this, queue, x, y, z);
return new AsyncBlock(this, x, y, z);
}
@Override
@ -251,9 +237,8 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
@Override
public int getHighestBlockYAt(int x, int z) {
for (int y = getMaxHeight() - 1; y >= 0; y--) {
int stateId = queue.getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId());
BlockType type = BlockTypes.getFromStateId(stateId);
if (!type.getMaterial().isAir()) return y;
BlockState state = this.getBlock(x, y, z);
if (!state.getMaterial().isAir()) return y;
}
return 0;
}
@ -276,7 +261,7 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
@Override
public AsyncChunk getChunkAt(int x, int z) {
return new AsyncChunk(this, queue, x, z);
return new AsyncChunk(this, x, z);
}
@Override
@ -422,8 +407,7 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
@Override
@Deprecated
public boolean refreshChunk(int x, int z) {
queue.sendChunk(queue.getFaweChunk(x, z));
return true;
return parent.refreshChunk(x, z);
}
@Override
@ -825,13 +809,13 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
@Override
public Biome getBiome(int x, int z) {
return adapter.adapt(queue.getBiomeType(x, z));
return adapter.adapt(getExtent().getBiomeType(x, z));
}
@Override
public void setBiome(int x, int z, Biome bio) {
BiomeType biome = adapter.adapt(bio);
queue.setBiome(x, z, biome);
getExtent().setBiome(x, 0, z, biome);
}
@Override
@ -1114,6 +1098,11 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
return parent.locateNearestStructure(arg0, arg1, arg2, arg3);
}
@Override
public int getViewDistance() {
return parent.getViewDistance();
}
@Override
public RayTraceResult rayTrace(Location arg0, Vector arg1, double arg2, FluidCollisionMode arg3, boolean arg4,
double arg5, Predicate<Entity> arg6) {

View File

@ -54,7 +54,7 @@ public final class AsyncDataContainer implements PersistentDataContainer {
Validate.notNull(key, "The provided key for the custom value was null");
Validate.notNull(type, "The provided type for the custom value was null");
Validate.notNull(value, "The provided value for the custom value was null");
get().put(key.toString(), FaweCache.asTag(type.toPrimitive(value, null)));
get().put(key.toString(), FaweCache.IMP.asTag(type.toPrimitive(value, null)));
}
public <T, Z> boolean has(NamespacedKey key, PersistentDataType<T, Z> type) {

View File

@ -10,6 +10,8 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
import com.sk89q.worldedit.util.formatting.text.serializer.legacy.LegacyComponentSerializer;
import java.util.Map;
import com.sk89q.worldedit.world.block.BaseBlock;
import org.bukkit.DyeColor;
import org.bukkit.block.Sign;
import org.bukkit.persistence.PersistentDataContainer;
@ -17,8 +19,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AsyncSign extends AsyncBlockState implements Sign {
public AsyncSign(AsyncBlock block, int combined) {
super(block, combined);
public AsyncSign(AsyncBlock block, BaseBlock state) {
super(block, state);
}
private boolean isEditable = false;

View File

@ -330,10 +330,6 @@ public enum BukkitAdapter {
return getAdapter().adapt(block);
}
public static BlockData getBlockData(int combinedId) {
return getAdapter().getBlockData(combinedId);
}
/**
* Create a WorldEdit BlockState from a Bukkit ItemStack
*

View File

@ -21,6 +21,10 @@ package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.bukkit.beta.BukkitGetBlocks;
import com.boydti.fawe.config.Settings;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
@ -494,9 +498,19 @@ public class BukkitWorld extends AbstractWorld {
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
}
@Override
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
return false;
}
@Override
public boolean setBiome(BlockVector2 position, BiomeType biome) {
getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome));
return true;
}
@Override
public IChunkGet get(int chunkX, int chunkZ) {
return new BukkitGetBlocks(getWorldChecked(), chunkX, chunkZ, Settings.IMP.QUEUE.POOL);
}
}

View File

@ -41,18 +41,18 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.internal.command.CommandUtil;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemCategory;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Biome;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.entity.BaseEntity;
@ -33,6 +35,8 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@ -149,4 +153,8 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
* @param player The player
*/
void sendFakeOP(Player player);
default @org.jetbrains.annotations.Nullable World createWorld(WorldCreator creator) {
return ((FaweBukkit) Fawe.imp()).createWorldUnloaded(creator::createWorld);
}
}

View File

@ -303,10 +303,6 @@ public interface IBukkitAdapter {
*/
BlockData adapt(BlockStateHolder block);
default BlockData getBlockData(int combinedId) {
return adapt(BlockState.getFromInternalId(combinedId));
}
/**
* Create a WorldEdit BlockStateHolder from a Bukkit ItemStack
*