Cherry-pick WNA, minor changes. 1.16 VERY WIP

First noticed incident of operations ruining ChunkSections. Do not build and use this unless you're testing.

Rushed some of the changes, gotta sleep. Would be nice to get a review of this one from @mattbdev and @dordsor21
This commit is contained in:
Octavia Togami
2020-03-22 21:02:04 -07:00
committed by IronApollo
parent 82adab77b4
commit b59b95c282
31 changed files with 1170 additions and 345 deletions

View File

@ -0,0 +1,176 @@
package com.boydti.fawe.bukkit.adapter.mc1_14;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_14_R4;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import net.minecraft.server.v1_14_R1.Block;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.Chunk;
import net.minecraft.server.v1_14_R1.ChunkProviderServer;
import net.minecraft.server.v1_14_R1.EnumDirection;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.NBTBase;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.PlayerChunk;
import net.minecraft.server.v1_14_R1.TileEntity;
import net.minecraft.server.v1_14_R1.World;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
import org.bukkit.event.block.BlockPhysicsEvent;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Objects;
public class FAWEWorldNativeAccess_1_14 implements WorldNativeAccess<Chunk, IBlockData, BlockPosition> {
private static final int UPDATE = 1, NOTIFY = 2;
private final FAWE_Spigot_v1_14_R4 adapter;
private final WeakReference<World> world;
private SideEffectSet sideEffectSet;
public FAWEWorldNativeAccess_1_14(FAWE_Spigot_v1_14_R4 adapter, WeakReference<World> world) {
this.adapter = adapter;
this.world = world;
}
private World getWorld() {
return Objects.requireNonNull(world.get(), "The reference to the world was lost");
}
@Override
public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) {
this.sideEffectSet = sideEffectSet;
}
@Override
public Chunk getChunk(int x, int z) {
return getWorld().getChunkAt(x, z);
}
@Override
public IBlockData toNative(com.sk89q.worldedit.world.block.BlockState state) {
int stateId = BlockStateIdAccess.getBlockStateId(state);
return BlockStateIdAccess.isValidInternalId(stateId)
? Block.getByCombinedId(stateId)
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
}
@Override
public IBlockData getBlockState(Chunk chunk, BlockPosition position) {
return chunk.getType(position);
}
@Nullable
@Override
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
return chunk.setType(position, state, false);
}
@Override
public IBlockData getValidBlockForPosition(IBlockData block, BlockPosition position) {
return Block.b(block, getWorld(), position);
}
@Override
public BlockPosition getPosition(int x, int y, int z) {
return new BlockPosition(x, y, z);
}
@Override
public void updateLightingForBlock(BlockPosition position) {
getWorld().getChunkProvider().getLightEngine().a(position);
}
@Override
public boolean updateTileEntity(BlockPosition position, CompoundTag tag) {
// We will assume that the tile entity was created for us,
// though we do not do this on the other versions
TileEntity tileEntity = getWorld().getTileEntity(position);
if (tileEntity == null) {
return false;
}
NBTBase nativeTag = adapter.fromNative(tag);
tileEntity.load((NBTTagCompound) nativeTag);
return true;
}
@Override
public void notifyBlockUpdate(BlockPosition position, IBlockData oldState, IBlockData newState) {
getWorld().notify(position, oldState, newState, UPDATE | NOTIFY);
}
@Override
public boolean isChunkTicking(Chunk chunk) {
return chunk.getState().isAtLeast(PlayerChunk.State.TICKING);
}
@Override
public void markBlockChanged(BlockPosition position) {
((ChunkProviderServer) getWorld().getChunkProvider()).flagDirty(position);
}
private static final EnumDirection[] NEIGHBOUR_ORDER = {
EnumDirection.WEST, EnumDirection.EAST,
EnumDirection.DOWN, EnumDirection.UP,
EnumDirection.NORTH, EnumDirection.SOUTH
};
@Override
public void notifyNeighbors(BlockPosition pos, IBlockData oldState, IBlockData newState) {
World world = getWorld();
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
world.update(pos, oldState.getBlock());
} else {
// When we don't want events, manually run the physics without them.
// Un-nest neighbour updating
for (EnumDirection direction : NEIGHBOUR_ORDER) {
BlockPosition shifted = pos.shift(direction);
world.getType(shifted).doPhysics(world, shifted, oldState.getBlock(), pos, false);
}
}
if (newState.isComplexRedstone()) {
world.updateAdjacentComparators(pos, newState.getBlock());
}
}
@Override
public void updateNeighbors(BlockPosition pos, IBlockData oldState, IBlockData newState, int recursionLimit) {
World world = getWorld();
// a == updateNeighbors
// b == updateDiagonalNeighbors
oldState.b(world, pos, NOTIFY);
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
CraftWorld craftWorld = world.getWorld();
if (craftWorld != null) {
BlockPhysicsEvent event = new BlockPhysicsEvent(
craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()),
CraftBlockData.fromData(newState));
world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
}
}
newState.a(world, pos, NOTIFY);
newState.b(world, pos, NOTIFY);
}
@Override
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
getWorld().a(pos, oldState, newState);
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING));
}
}

View File

@ -0,0 +1,173 @@
package com.boydti.fawe.bukkit.adapter.mc1_15_2;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_15_R2;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import net.minecraft.server.v1_15_R1.Block;
import net.minecraft.server.v1_15_R1.BlockPosition;
import net.minecraft.server.v1_15_R1.Chunk;
import net.minecraft.server.v1_15_R1.ChunkProviderServer;
import net.minecraft.server.v1_15_R1.EnumDirection;
import net.minecraft.server.v1_15_R1.IBlockData;
import net.minecraft.server.v1_15_R1.NBTBase;
import net.minecraft.server.v1_15_R1.NBTTagCompound;
import net.minecraft.server.v1_15_R1.PlayerChunk;
import net.minecraft.server.v1_15_R1.TileEntity;
import net.minecraft.server.v1_15_R1.World;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData;
import org.bukkit.event.block.BlockPhysicsEvent;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Objects;
public class FAWEWorldNativeAccess_1_15_2 implements WorldNativeAccess<Chunk, IBlockData, BlockPosition> {
private static final int UPDATE = 1, NOTIFY = 2;
private final FAWE_Spigot_v1_15_R2 adapter;
private final WeakReference<World> world;
private SideEffectSet sideEffectSet;
public FAWEWorldNativeAccess_1_15_2(FAWE_Spigot_v1_15_R2 adapter, WeakReference<World> world) {
this.adapter = adapter;
this.world = world;
}
private World getWorld() {
return Objects.requireNonNull(world.get(), "The reference to the world was lost");
}
@Override
public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) {
this.sideEffectSet = sideEffectSet;
}
@Override
public Chunk getChunk(int x, int z) {
return getWorld().getChunkAt(x, z);
}
@Override
public IBlockData toNative(com.sk89q.worldedit.world.block.BlockState state) {
int stateId = BlockStateIdAccess.getBlockStateId(state);
return BlockStateIdAccess.isValidInternalId(stateId)
? Block.getByCombinedId(stateId)
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
}
@Override
public IBlockData getBlockState(Chunk chunk, BlockPosition position) {
return chunk.getType(position);
}
@Nullable
@Override
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
return chunk.setType(position, state, false);
}
@Override
public IBlockData getValidBlockForPosition(IBlockData block, BlockPosition position) {
return Block.b(block, getWorld(), position);
}
@Override
public BlockPosition getPosition(int x, int y, int z) {
return new BlockPosition(x, y, z);
}
@Override
public void updateLightingForBlock(BlockPosition position) {
getWorld().getChunkProvider().getLightEngine().a(position);
}
@Override
public boolean updateTileEntity(BlockPosition position, CompoundTag tag) {
// We will assume that the tile entity was created for us,
// though we do not do this on the other versions
TileEntity tileEntity = getWorld().getTileEntity(position);
if (tileEntity == null) {
return false;
}
NBTBase nativeTag = adapter.fromNative(tag);
tileEntity.load((NBTTagCompound) nativeTag);
return true;
}
@Override
public void notifyBlockUpdate(BlockPosition position, IBlockData oldState, IBlockData newState) {
getWorld().notify(position, oldState, newState, UPDATE | NOTIFY);
}
@Override
public boolean isChunkTicking(Chunk chunk) {
return chunk.getState().isAtLeast(PlayerChunk.State.TICKING);
}
@Override
public void markBlockChanged(BlockPosition position) {
((ChunkProviderServer) getWorld().getChunkProvider()).flagDirty(position);
}
private static final EnumDirection[] NEIGHBOUR_ORDER = {
EnumDirection.WEST, EnumDirection.EAST,
EnumDirection.DOWN, EnumDirection.UP,
EnumDirection.NORTH, EnumDirection.SOUTH
};
@Override
public void notifyNeighbors(BlockPosition pos, IBlockData oldState, IBlockData newState) {
World world = getWorld();
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
world.update(pos, oldState.getBlock());
} else {
// When we don't want events, manually run the physics without them.
// Un-nest neighbour updating
for (EnumDirection direction : NEIGHBOUR_ORDER) {
BlockPosition shifted = pos.shift(direction);
world.getType(shifted).doPhysics(world, shifted, oldState.getBlock(), pos, false);
}
}
if (newState.isComplexRedstone()) {
world.updateAdjacentComparators(pos, newState.getBlock());
}
}
@Override
public void updateNeighbors(BlockPosition pos, IBlockData oldState, IBlockData newState, int recursionLimit) {
World world = getWorld();
// a == updateNeighbors
// b == updateDiagonalNeighbors
oldState.b(world, pos, NOTIFY);
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
CraftWorld craftWorld = world.getWorld();
if (craftWorld != null) {
BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState));
world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
}
}
newState.a(world, pos, NOTIFY);
newState.b(world, pos, NOTIFY);
}
@Override
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
getWorld().a(pos, oldState, newState);
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING));
}
}

View File

@ -23,7 +23,7 @@ public class BlockMaterial_1_16_1 implements BlockMaterial {
this.material = defaultState.getMaterial();
this.craftBlockData = CraftBlockData.fromData(defaultState);
this.craftMaterial = craftBlockData.getMaterial();
this.isTranslucent = !(boolean) ReflectionUtil.getField(Block.class, block, "v"); //TODO Update Mapping for 1.16.1
this.isTranslucent = !(boolean) ReflectionUtil.getField(Block.class, block, "at"); //TODO Update Mapping for 1.16.1
}
public Block getBlock() {

View File

@ -0,0 +1,174 @@
package com.boydti.fawe.bukkit.adapter.mc1_16_1;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_16_R1;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import net.minecraft.server.v1_16_R1.Block;
import net.minecraft.server.v1_16_R1.BlockPosition;
import net.minecraft.server.v1_16_R1.Chunk;
import net.minecraft.server.v1_16_R1.ChunkProviderServer;
import net.minecraft.server.v1_16_R1.EnumDirection;
import net.minecraft.server.v1_16_R1.IBlockData;
import net.minecraft.server.v1_16_R1.NBTBase;
import net.minecraft.server.v1_16_R1.NBTTagCompound;
import net.minecraft.server.v1_16_R1.PlayerChunk;
import net.minecraft.server.v1_16_R1.TileEntity;
import net.minecraft.server.v1_16_R1.World;
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R1.block.data.CraftBlockData;
import org.bukkit.event.block.BlockPhysicsEvent;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Objects;
public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlockData, BlockPosition> {
private static final int UPDATE = 1, NOTIFY = 2;
private final FAWE_Spigot_v1_16_R1 adapter;
private final WeakReference<World> world;
private SideEffectSet sideEffectSet;
public FAWEWorldNativeAccess_1_16(FAWE_Spigot_v1_16_R1 adapter, WeakReference<World> world) {
this.adapter = adapter;
this.world = world;
}
private World getWorld() {
return Objects.requireNonNull(world.get(), "The reference to the world was lost");
}
@Override
public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) {
this.sideEffectSet = sideEffectSet;
}
@Override
public Chunk getChunk(int x, int z) {
return getWorld().getChunkAt(x, z);
}
@Override
public IBlockData toNative(BlockState state) {
int stateId = BlockStateIdAccess.getBlockStateId(state);
return BlockStateIdAccess.isValidInternalId(stateId)
? Block.getByCombinedId(stateId)
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
}
@Override
public IBlockData getBlockState(Chunk chunk, BlockPosition position) {
return chunk.getType(position);
}
@Nullable
@Override
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
return chunk.setType(position, state, false);
}
@Override
public IBlockData getValidBlockForPosition(IBlockData block, BlockPosition position) {
return Block.b(block, getWorld(), position);
}
@Override
public BlockPosition getPosition(int x, int y, int z) {
return new BlockPosition(x, y, z);
}
@Override
public void updateLightingForBlock(BlockPosition position) {
getWorld().getChunkProvider().getLightEngine().a(position);
}
@Override
public boolean updateTileEntity(BlockPosition position, CompoundTag tag) {
// We will assume that the tile entity was created for us,
// though we do not do this on the other versions
TileEntity tileEntity = getWorld().getTileEntity(position);
if (tileEntity == null) {
return false;
}
NBTBase nativeTag = adapter.fromNative(tag);
tileEntity.load(tileEntity.getBlock(), (NBTTagCompound) nativeTag);
return true;
}
@Override
public void notifyBlockUpdate(BlockPosition position, IBlockData oldState, IBlockData newState) {
getWorld().notify(position, oldState, newState, UPDATE | NOTIFY);
}
@Override
public boolean isChunkTicking(Chunk chunk) {
return chunk.getState().isAtLeast(PlayerChunk.State.TICKING);
}
@Override
public void markBlockChanged(BlockPosition position) {
((ChunkProviderServer) getWorld().getChunkProvider()).flagDirty(position);
}
private static final EnumDirection[] NEIGHBOUR_ORDER = {
EnumDirection.WEST, EnumDirection.EAST,
EnumDirection.DOWN, EnumDirection.UP,
EnumDirection.NORTH, EnumDirection.SOUTH
};
@Override
public void notifyNeighbors(BlockPosition pos, IBlockData oldState, IBlockData newState) {
World world = getWorld();
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
world.update(pos, oldState.getBlock());
} else {
// When we don't want events, manually run the physics without them.
// Un-nest neighbour updating
for (EnumDirection direction : NEIGHBOUR_ORDER) {
BlockPosition shifted = pos.shift(direction);
world.getType(shifted).doPhysics(world, shifted, oldState.getBlock(), pos, false);
}
}
if (newState.isComplexRedstone()) {
world.updateAdjacentComparators(pos, newState.getBlock());
}
}
@Override
public void updateNeighbors(BlockPosition pos, IBlockData oldState, IBlockData newState, int recursionLimit) {
World world = getWorld();
// a == updateNeighbors
// b == updateDiagonalNeighbors
oldState.b(world, pos, NOTIFY, recursionLimit);
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
CraftWorld craftWorld = world.getWorld();
if (craftWorld != null) {
BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState));
world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
}
}
newState.a(world, pos, NOTIFY, recursionLimit);
newState.b(world, pos, NOTIFY, recursionLimit);
}
@Override
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
getWorld().a(pos, oldState, newState);
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING));
}
}

View File

@ -884,6 +884,16 @@ public class AsyncWorld extends PassthroughExtent implements World {
parent.setWaterAnimalSpawnLimit(limit);
}
@Override
public int getWaterAmbientSpawnLimit() {
return 0;
}
@Override
public void setWaterAmbientSpawnLimit(int limit) {
}
@Override
public int getAmbientSpawnLimit() {
return parent.getAmbientSpawnLimit();
@ -1285,18 +1295,28 @@ public class AsyncWorld extends PassthroughExtent implements World {
}
public long getTicksPerWaterSpawns() {
throw new UnsupportedOperationException();
return parent.getTicksPerWaterSpawns();
}
public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) {
throw new UnsupportedOperationException();
parent.setTicksPerWaterSpawns(ticksPerWaterSpawns);
}
@Override
public long getTicksPerWaterAmbientSpawns() {
return parent.getTicksPerWaterAmbientSpawns();
}
@Override
public void setTicksPerWaterAmbientSpawns(int ticksPerAmbientSpawns) {
parent.setTicksPerWaterAmbientSpawns(ticksPerAmbientSpawns);
}
public long getTicksPerAmbientSpawns() {
throw new UnsupportedOperationException();
return parent.getTicksPerAmbientSpawns();
}
public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) {
throw new UnsupportedOperationException();
parent.setTicksPerAmbientSpawns(ticksPerAmbientSpawns);
}
}

View File

@ -3,15 +3,15 @@ package com.boydti.fawe.bukkit.wrapper.state;
import com.boydti.fawe.FaweCache;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import org.apache.commons.lang.Validate;
import org.bukkit.NamespacedKey;
import org.bukkit.persistence.PersistentDataAdapterContext;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
public final class AsyncDataContainer implements PersistentDataContainer {
private final CompoundTag root;
@ -69,6 +69,20 @@ public final class AsyncDataContainer implements PersistentDataContainer {
return z != null ? z : defaultValue;
}
@NotNull
@Override
public Set<NamespacedKey> getKeys() {
Set<NamespacedKey> keys = new HashSet<>();
this.get(false).keySet().forEach(key -> {
String[] keyData = key.split(":", 2);
if (keyData.length == 2) {
keys.add(new NamespacedKey(keyData[0], keyData[1]));
}
});
return keys;
}
public void remove(NamespacedKey key) {
Validate.notNull(key, "The provided key for the custom value was null");
get(false).remove(key.toString());

View File

@ -24,8 +24,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.sk89q.jnbt.CompoundTag;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
@ -34,6 +35,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -77,6 +79,7 @@ public class BukkitWorld extends AbstractWorld {
}
private final WeakReference<World> worldRef;
private final WorldNativeAccess<?, ?, ?> worldNativeAccess;
/**
* Construct the object.
@ -85,6 +88,12 @@ public class BukkitWorld extends AbstractWorld {
*/
public BukkitWorld(World world) {
this.worldRef = new WeakReference<>(world);
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
this.worldNativeAccess = adapter.createWorldNativeAccess(world);
} else {
this.worldNativeAccess = null;
}
}
@Override
@ -464,26 +473,22 @@ public class BukkitWorld extends AbstractWorld {
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) {
if (worldNativeAccess != null) {
try {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, sideEffects);
return worldNativeAccess.setBlock(position, block, sideEffects);
} catch (Exception e) {
if (block instanceof BaseBlock && ((BaseBlock) block).getNbtData() != null) {
logger.warn("Tried to set a corrupt tile entity at " + position.toString());
logger.warn(((BaseBlock) block).getNbtData().toString());
logger.warn("Tried to set a corrupt tile entity at " + position.toString() +
": " + ((BaseBlock) block).getNbtData(), e);
} else {
logger.warn("Failed to set block via adapter, falling back to generic", e);
}
e.printStackTrace();
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny());
return true;
}
} else {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny());
return true;
}
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny());
return true;
}
@Override
@ -497,20 +502,17 @@ public class BukkitWorld extends AbstractWorld {
}
@Override
public Set<SideEffect> applySideEffects(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
adapter.applySideEffects(BukkitAdapter.adapt(getWorld(), position), previousType, sideEffectSet);
public Set<SideEffect> applySideEffects(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType,
SideEffectSet sideEffectSet) {
if (worldNativeAccess != null) {
worldNativeAccess.applySideEffects(position, previousType, sideEffectSet);
return Sets.intersection(
adapter.getSupportedSideEffects(),
WorldEditPlugin.getInstance().getInternalPlatform().getSupportedSideEffects(),
sideEffectSet.getSideEffectsToApply()
);
}
return Sets.intersection(
WorldEditPlugin.getInstance().getInternalPlatform().getSupportedSideEffects(),
sideEffectSet.getSideEffectsToApply()
);
return ImmutableSet.of();
}
@Override

View File

@ -30,17 +30,16 @@ import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import java.util.Map;
@ -98,23 +97,12 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
BaseBlock getBlock(Location location);
/**
* Set the block at the given location.
* Create a {@link WorldNativeAccess} for the given world reference.
*
* @param location the location
* @param state the block
* @param sideEffectSet side effects to apply
* @return true if a block was likely changed
* @param world the world reference
* @return the native access object
*/
boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet);
/**
* Applies side effects on the given block.
*
* @param position position of the block
* @param previousType the type of the previous block that was there
* @param sideEffectSet side effects to apply
*/
void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet);
WorldNativeAccess<?, ?, ?> createWorldNativeAccess(World world);
/**
* Get the state for the given entity.

View File

@ -66,10 +66,6 @@ public interface IDelegateBukkitImplAdapter<T> extends BukkitImplAdapter<T> {
return getParent().getBlock(location);
}
default <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
return getParent().setBlock(location, state, SideEffectSet.none());
}
@Override
@Nullable
default BaseEntity getEntity(Entity entity) {

View File

@ -24,10 +24,7 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.boydti.fawe.beta.implementation.queue.SingleThreadQueueExtent;
import com.boydti.fawe.bukkit.adapter.mc1_14.BlockMaterial_1_14;
import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitAdapter_1_14;
import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14;
import com.boydti.fawe.bukkit.adapter.mc1_14.MapChunkUtil_1_14;
import com.boydti.fawe.bukkit.adapter.mc1_14.*;
import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14;
import com.google.common.io.Files;
import com.sk89q.jnbt.CompoundTag;
@ -42,13 +39,13 @@ import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.IDelegateBukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.LazyBaseEntity;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.*;
import com.sk89q.worldedit.world.entity.EntityType;
@ -71,6 +68,7 @@ import org.bukkit.generator.ChunkGenerator;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.OptionalInt;
import java.util.Set;
@ -151,26 +149,11 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I
return state.toBaseBlock();
}
@Override
public boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, sideEffectSet.shouldApply(SideEffect.LIGHTING));
}
@Override
public void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet) {
return; //TODO: properly implement SideEffects into FAWE
}
@Override
public Set<SideEffect> getSupportedSideEffects() {
return SideEffectSet.defaults().getSideEffectsToApply();
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
}
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
CraftChunk craftChunk = (CraftChunk) chunk;
Chunk nmsChunk = craftChunk.getHandle();
@ -222,6 +205,12 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I
return true;
}
@Override
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
return new FAWEWorldNativeAccess_1_14(this,
new WeakReference<>(((CraftWorld) world).getHandle()));
}
@Nullable
private static String getEntityId(Entity entity) {
MinecraftKey minecraftkey = EntityTypes.getName(entity.getEntityType());

View File

@ -26,10 +26,7 @@ import com.boydti.fawe.beta.IQueueChunk;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.boydti.fawe.beta.implementation.queue.SingleThreadQueueExtent;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.BlockMaterial_1_15_2;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.BukkitAdapter_1_15_2;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.BukkitGetBlocks_1_15_2;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.MapChunkUtil_1_15_2;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.*;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
import com.google.common.io.Files;
import com.sk89q.jnbt.CompoundTag;
@ -44,6 +41,7 @@ import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.IDelegateBukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.LazyBaseEntity;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
@ -73,6 +71,7 @@ import org.bukkit.generator.ChunkGenerator;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.OptionalInt;
import java.util.Set;
@ -160,26 +159,11 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
return state.toBaseBlock();
}
@Override
public boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, sideEffectSet.shouldApply(SideEffect.LIGHTING));
}
@Override
public void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet) {
return; //TODO: properly implement SideEffects into FAWE
}
@Override
public Set<SideEffect> getSupportedSideEffects() {
return SideEffectSet.defaults().getSideEffectsToApply();
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
}
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
CraftChunk craftChunk = (CraftChunk) chunk;
Chunk nmsChunk = craftChunk.getHandle();
@ -231,6 +215,12 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
return true;
}
@Override
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
return new FAWEWorldNativeAccess_1_15_2(this,
new WeakReference<>(((CraftWorld) world).getHandle()));
}
@Nullable
private static String getEntityId(Entity entity) {
MinecraftKey minecraftkey = EntityTypes.getName(entity.getEntityType());

View File

@ -26,10 +26,7 @@ import com.boydti.fawe.beta.IQueueChunk;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.boydti.fawe.beta.implementation.queue.SingleThreadQueueExtent;
import com.boydti.fawe.bukkit.adapter.mc1_16_1.BlockMaterial_1_16_1;
import com.boydti.fawe.bukkit.adapter.mc1_16_1.BukkitAdapter_1_16_1;
import com.boydti.fawe.bukkit.adapter.mc1_16_1.BukkitGetBlocks_1_16_1;
import com.boydti.fawe.bukkit.adapter.mc1_16_1.MapChunkUtil_1_16_1;
import com.boydti.fawe.bukkit.adapter.mc1_16_1.*;
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
import com.google.common.io.Files;
import com.sk89q.jnbt.CompoundTag;
@ -44,6 +41,7 @@ import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.IDelegateBukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.LazyBaseEntity;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
@ -72,6 +70,7 @@ import org.bukkit.generator.ChunkGenerator;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.OptionalInt;
import java.util.Set;
@ -159,26 +158,11 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I
return state.toBaseBlock();
}
@Override
public boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, sideEffectSet.shouldApply(SideEffect.LIGHTING));
}
@Override
public void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet) {
return; //TODO: properly implement SideEffects into FAWE
}
@Override
public Set<SideEffect> getSupportedSideEffects() {
return SideEffectSet.defaults().getSideEffectsToApply();
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
}
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
CraftChunk craftChunk = (CraftChunk) chunk;
Chunk nmsChunk = craftChunk.getHandle();
@ -230,6 +214,12 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I
return true;
}
@Override
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
return new FAWEWorldNativeAccess_1_16(this,
new WeakReference<>(((CraftWorld)world).getHandle()));
}
@Nullable
private static String getEntityId(Entity entity) {
MinecraftKey minecraftkey = EntityTypes.getName(entity.getEntityType());