mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-11 20:13:55 +00:00
some minor refactoring
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
Reference in New Issue
Block a user