From 7d9dd3b15f90c345ade57cde1c4a94608715da6f Mon Sep 17 00:00:00 2001 From: MattBDev <4009945+MattBDev@users.noreply.github.com> Date: Thu, 25 Jun 2020 19:56:10 -0400 Subject: [PATCH] 1.16.1 Prep work --- worldedit-bukkit/build.gradle.kts | 3 +- .../adapter/mc1_15/BlockMaterial_1_15.java | 153 ---- .../adapter/mc1_15/BukkitAdapter_1_15.java | 299 ------- .../adapter/mc1_15/BukkitGetBlocks_1_15.java | 744 ------------------ .../adapter/mc1_15/MapChunkUtil_1_15.java | 28 - .../mc1_15/nbt/LazyCompoundTag_1_15.java | 152 ---- .../worldedit/bukkit/WorldEditPlugin.java | 2 - .../adapter/impl/FAWE_Spigot_v1_15_R1.java | 457 ----------- .../fawe/object/brush/CopyPastaBrush.java | 3 +- 9 files changed, 4 insertions(+), 1837 deletions(-) delete mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BlockMaterial_1_15.java delete mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java delete mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitGetBlocks_1_15.java delete mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/MapChunkUtil_1_15.java delete mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/nbt/LazyCompoundTag_1_15.java delete mode 100644 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 403a55709..305807b53 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -41,12 +41,13 @@ dependencies { "compile"("org.spigotmcv1_14_r1:spigotmcv1_14_r1:1_14_r1") "compile"("org.spigotmcv1_15_r1:spigotmcv1_15_r1:1_15_r1") "compile"("it.unimi.dsi:fastutil:8.2.1") - "api"("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT") { + "api"("com.destroystokyo.paper:paper-api:1.16.1-R0.1-SNAPSHOT") { exclude("junit", "junit") isTransitive = false } "compileOnly"("org.spigotmc:spigot:1.14.4-R0.1-SNAPSHOT") "compileOnly"("org.spigotmc:spigot:1.15.2-R0.1-SNAPSHOT") + "compileOnly"("org.spigotmc:spigot:1.16.1-R0.1-SNAPSHOT") "implementation"("io.papermc:paperlib:1.0.2") "compileOnly"("com.sk89q:dummypermscompat:1.10") "implementation"("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1") diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BlockMaterial_1_15.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BlockMaterial_1_15.java deleted file mode 100644 index 3a7c205ac..000000000 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BlockMaterial_1_15.java +++ /dev/null @@ -1,153 +0,0 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; - -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.server.v1_15_R1.Block; -import net.minecraft.server.v1_15_R1.EnumPistonReaction; -import net.minecraft.server.v1_15_R1.IBlockData; -import net.minecraft.server.v1_15_R1.ITileEntity; -import net.minecraft.server.v1_15_R1.Material; -import org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData; - -public class BlockMaterial_1_15 implements BlockMaterial { - private final Block block; - private final IBlockData defaultState; - private final Material material; - private final boolean isTranslucent; - private final CraftBlockData craftBlockData; - private final org.bukkit.Material craftMaterial; - - public BlockMaterial_1_15(Block block) { - this(block, block.getBlockData()); - } - - public BlockMaterial_1_15(Block block, IBlockData defaultState) { - this.block = block; - this.defaultState = defaultState; - this.material = defaultState.getMaterial(); - this.craftBlockData = CraftBlockData.fromData(defaultState); - this.craftMaterial = craftBlockData.getMaterial(); - this.isTranslucent = !(boolean) ReflectionUtil.getField(Block.class, block, "v"); - } - - public Block getBlock() { - return block; - } - - public IBlockData getState() { - return defaultState; - } - - public CraftBlockData getCraftBlockData() { - return craftBlockData; - } - - public Material getMaterial() { - return material; - } - - @Override - public boolean isAir() { - return defaultState.isAir(); - } - - @Override - public boolean isFullCube() { - return craftMaterial.isOccluding(); - } - - @Override - public boolean isOpaque() { - return material.f(); - } - - @Override - public boolean isPowerSource() { - return defaultState.isPowerSource(); - } - - @Override - public boolean isLiquid() { - return material.isLiquid(); - } - - @Override - public boolean isSolid() { - return material.isBuildable(); - } - - @Override - public float getHardness() { - return block.strength; - } - - @Override - public float getResistance() { - return block.getDurability(); - } - - @Override - public float getSlipperiness() { - return block.m(); - } - - @Override - public int getLightValue() { - return defaultState.h(); - } - - @Override - public int getLightOpacity() { - return !isTranslucent() ? 15 : 0; - } - - @Override - public boolean isFragileWhenPushed() { - return material.getPushReaction() == EnumPistonReaction.DESTROY; - } - - @Override - public boolean isUnpushable() { - return material.getPushReaction() == EnumPistonReaction.BLOCK; - } - - @Override - public boolean isTicksRandomly() { - return block.isTicking(defaultState); - } - - @Override - public boolean isMovementBlocker() { - return material.isSolid(); - } - - @Override - public boolean isBurnable() { - return material.isBurnable(); - } - - @Override - public boolean isToolRequired() { - return !material.isAlwaysDestroyable(); - } - - @Override - public boolean isReplacedDuringPlacement() { - return material.isReplaceable(); - } - - @Override - public boolean isTranslucent() { - return isTranslucent; - } - - @Override - public boolean hasContainer() { - return block instanceof ITileEntity; - } - - @Override - public int getMapColor() { - return material.i().rgb; - } -} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java deleted file mode 100644 index be791aa66..000000000 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java +++ /dev/null @@ -1,299 +0,0 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; - -import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.bukkit.adapter.DelegateLock; -import com.boydti.fawe.bukkit.adapter.NMSAdapter; -import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.collection.BitArray; -import com.boydti.fawe.util.MathMan; -import com.boydti.fawe.util.ReflectionUtils; -import com.boydti.fawe.util.TaskManager; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import net.jpountz.util.UnsafeUtils; -import net.minecraft.server.v1_15_R1.Block; -import net.minecraft.server.v1_15_R1.Chunk; -import net.minecraft.server.v1_15_R1.ChunkCoordIntPair; -import net.minecraft.server.v1_15_R1.ChunkSection; -import net.minecraft.server.v1_15_R1.DataBits; -import net.minecraft.server.v1_15_R1.DataPalette; -import net.minecraft.server.v1_15_R1.DataPaletteBlock; -import net.minecraft.server.v1_15_R1.DataPaletteLinear; -import net.minecraft.server.v1_15_R1.GameProfileSerializer; -import net.minecraft.server.v1_15_R1.IBlockData; -import net.minecraft.server.v1_15_R1.PacketPlayOutLightUpdate; -import net.minecraft.server.v1_15_R1.PlayerChunk; -import net.minecraft.server.v1_15_R1.PlayerChunkMap; -import net.minecraft.server.v1_15_R1.World; -import org.bukkit.craftbukkit.v1_15_R1.CraftChunk; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import sun.misc.Unsafe; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Function; - -public final class BukkitAdapter_1_15 extends NMSAdapter { - /* - NMS fields - */ - public final static Field fieldBits; - public final static Field fieldPalette; - public final static Field fieldSize; - - public final static Field fieldFluidCount; - public final static Field fieldTickingBlockCount; - public final static Field fieldNonEmptyBlockCount; - - private final static Field fieldDirtyCount; - private final static Field fieldDirtyBits; - - private final static MethodHandle methodGetVisibleChunk; - - private static final int CHUNKSECTION_BASE; - private static final int CHUNKSECTION_SHIFT; - - private static final Field fieldLock; - - static { - try { - fieldSize = DataPaletteBlock.class.getDeclaredField("i"); - fieldSize.setAccessible(true); - fieldBits = DataPaletteBlock.class.getDeclaredField("a"); - fieldBits.setAccessible(true); - fieldPalette = DataPaletteBlock.class.getDeclaredField("h"); - fieldPalette.setAccessible(true); - - fieldFluidCount = ChunkSection.class.getDeclaredField("e"); - fieldFluidCount.setAccessible(true); - fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount"); - fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount"); - fieldNonEmptyBlockCount.setAccessible(true); - - fieldDirtyCount = PlayerChunk.class.getDeclaredField("dirtyCount"); - fieldDirtyCount.setAccessible(true); - fieldDirtyBits = PlayerChunk.class.getDeclaredField("r"); - fieldDirtyBits.setAccessible(true); - - fieldTickingBlockCount.setAccessible(true); - - Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class); - declaredGetVisibleChunk.setAccessible(true); - methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk); - - Field tmp = DataPaletteBlock.class.getDeclaredField("j"); - ReflectionUtils.setAccessibleNonFinal(tmp); - fieldLock = tmp; - fieldLock.setAccessible(true); - - Unsafe unsafe = UnsafeUtils.getUNSAFE(); - CHUNKSECTION_BASE = unsafe.arrayBaseOffset(ChunkSection[].class); - int scale = unsafe.arrayIndexScale(ChunkSection[].class); - if ((scale & (scale - 1)) != 0) - throw new Error("data type scale not a power of two"); - CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale); - } catch (RuntimeException e) { - throw e; - } catch (Throwable rethrow) { - rethrow.printStackTrace(); - throw new RuntimeException(rethrow); - } - } - - protected static boolean setSectionAtomic(ChunkSection[] sections, ChunkSection expected, ChunkSection value, int layer) { - long offset = ((long) layer << CHUNKSECTION_SHIFT) + CHUNKSECTION_BASE; - if (layer >= 0 && layer < sections.length) { - return UnsafeUtils.getUNSAFE().compareAndSwapObject(sections, offset, expected, value); - } - return false; - } - - protected static DelegateLock applyLock(ChunkSection section) { - try { - synchronized (section) { - DataPaletteBlock blocks = section.getBlocks(); - ReentrantLock currentLock = (ReentrantLock) fieldLock.get(blocks); - if (currentLock instanceof DelegateLock) { - return (DelegateLock) currentLock; - } - DelegateLock newLock = new DelegateLock(currentLock); - fieldLock.set(blocks, newLock); - return newLock; - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static Chunk ensureLoaded(World nmsWorld, int X, int Z) { - Chunk nmsChunk = nmsWorld.getChunkIfLoaded(X, Z); - if (nmsChunk != null) { - return nmsChunk; - } - if (Fawe.isMainThread()) { - return nmsWorld.getChunkAt(X, Z); - } - if (PaperLib.isPaper()) { - CraftWorld craftWorld = nmsWorld.getWorld(); - CompletableFuture future = craftWorld.getChunkAtAsync(X, Z, true); - try { - CraftChunk chunk = (CraftChunk) future.get(); - return chunk.getHandle(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - // TODO optimize - return TaskManager.IMP.sync(() -> nmsWorld.getChunkAt(X, Z)); - } - - public static PlayerChunk getPlayerChunk(net.minecraft.server.v1_15_R1.WorldServer nmsWorld, final int cx, final int cz) { - PlayerChunkMap chunkMap = nmsWorld.getChunkProvider().playerChunkMap; - try { - return (PlayerChunk)methodGetVisibleChunk.invoke(chunkMap, ChunkCoordIntPair.pair(cx, cz)); - } catch (Throwable thr) { - throw new RuntimeException(thr); - } - } - - public static void sendChunk(net.minecraft.server.v1_15_R1.WorldServer nmsWorld, int X, int Z, int mask, boolean lighting) { - PlayerChunk playerChunk = getPlayerChunk(nmsWorld, X, Z); - if (playerChunk == null) { - return; - } - if (playerChunk.hasBeenLoaded()) { - TaskManager.IMP.sync(() -> { - try { - int dirtyBits = fieldDirtyBits.getInt(playerChunk); - if (dirtyBits == 0) { - nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); - } - if (mask == 0) { - dirtyBits = 65535; - } else { - dirtyBits |= mask; - } - - fieldDirtyBits.set(playerChunk, dirtyBits); - fieldDirtyCount.set(playerChunk, 64); - - if (lighting) { - ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(X, Z); - PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine()); - playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { - p.playerConnection.sendPacket(packet); - }); - } - - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return null; - }); - return; - } - return; - } - - /* - NMS conversion - */ - public static ChunkSection newChunkSection(final int layer, final char[] blocks, boolean fastmode) { - return newChunkSection(layer, null, blocks, fastmode); - } - - public static ChunkSection newChunkSection(final int layer, final Function get, char[] set, boolean fastmode) { - if (set == null) { - return newChunkSection(layer); - } - 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_buffer = new int[1]; - Map ticking_blocks = new HashMap<>(); - int air; - if (get == null) { - air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks, fastmode); - } else { - air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks, fastmode); - } - int num_palette = num_palette_buffer[0]; - // BlockStates - int bitsPerEntry = MathMan.log2nlz(num_palette - 1); - if (Settings.IMP.PROTOCOL_SUPPORT_FIX || num_palette != 1) { - bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry - } else { - bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries - } - - final int blockBitArrayEnd = (bitsPerEntry * 4096) >> 6; - if (num_palette == 1) { - for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0; - } else { - final BitArray bitArray = new BitArray(bitsPerEntry, 4096, blockStates); - bitArray.fromRaw(blocksCopy); - } - - ChunkSection section = newChunkSection(layer); - // set palette & data bits - final DataPaletteBlock dataPaletteBlocks = section.getBlocks(); - // private DataPalette h; - // protected DataBits a; - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - final DataBits nmsBits = new DataBits(bitsPerEntry, 4096, bits); - final DataPalette palette; -// palette = new DataPaletteHash<>(Block.REGISTRY_ID, bitsPerEntry, dataPaletteBlocks, GameProfileSerializer::d, GameProfileSerializer::a); - palette = new DataPaletteLinear<>(Block.REGISTRY_ID, bitsPerEntry, dataPaletteBlocks, GameProfileSerializer::d); - - // set palette - for (int i = 0; i < num_palette; i++) { - final int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - final IBlockData ibd = ((BlockMaterial_1_15) state.getMaterial()).getState(); - palette.a(ibd); - } - try { - fieldBits.set(dataPaletteBlocks, nmsBits); - fieldPalette.set(dataPaletteBlocks, palette); - fieldSize.set(dataPaletteBlocks, bitsPerEntry); - setCount(ticking_blocks.size(), 4096 - air, section); - ticking_blocks.forEach((pos, ordinal) -> { - section.setType(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(), - Block.getByCombinedId(ordinal)); - }); - } catch (final IllegalAccessException | NoSuchFieldException e) { - throw new RuntimeException(e); - } - - return section; - } catch (final Throwable e) { - Arrays.fill(blockToPalette, Integer.MAX_VALUE); - throw e; - } - } - - private static ChunkSection newChunkSection(int layer) { - return new ChunkSection(layer << 4); - } - - public static void setCount(final int tickingBlockCount, final int nonEmptyBlockCount, final ChunkSection section) throws NoSuchFieldException, IllegalAccessException { - fieldFluidCount.setShort(section, (short) 0); // TODO FIXME - fieldTickingBlockCount.setShort(section, (short) tickingBlockCount); - fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount); - } -} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitGetBlocks_1_15.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitGetBlocks_1_15.java deleted file mode 100644 index c9fbca585..000000000 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitGetBlocks_1_15.java +++ /dev/null @@ -1,744 +0,0 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; - -import static org.slf4j.LoggerFactory.getLogger; - -import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.IChunkSet; -import com.boydti.fawe.beta.implementation.blocks.CharBlocks; -import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; -import com.boydti.fawe.beta.implementation.queue.QueueHandler; -import com.boydti.fawe.bukkit.adapter.DelegateLock; -import com.boydti.fawe.bukkit.adapter.mc1_15.nbt.LazyCompoundTag_1_15; -import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.collection.AdaptedMap; -import com.boydti.fawe.object.collection.BitArray; -import com.google.common.base.Suppliers; -import com.google.common.collect.Iterables; -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.bukkit.adapter.impl.FAWE_Spigot_v1_15_R1; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BlockTypes; -import java.util.AbstractSet; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; -import net.minecraft.server.v1_15_R1.BiomeBase; -import net.minecraft.server.v1_15_R1.BiomeStorage; -import net.minecraft.server.v1_15_R1.BlockPosition; -import net.minecraft.server.v1_15_R1.Chunk; -import net.minecraft.server.v1_15_R1.ChunkSection; -import net.minecraft.server.v1_15_R1.DataBits; -import net.minecraft.server.v1_15_R1.DataPalette; -import net.minecraft.server.v1_15_R1.DataPaletteBlock; -import net.minecraft.server.v1_15_R1.DataPaletteHash; -import net.minecraft.server.v1_15_R1.DataPaletteLinear; -import net.minecraft.server.v1_15_R1.Entity; -import net.minecraft.server.v1_15_R1.EntityTypes; -import net.minecraft.server.v1_15_R1.EnumSkyBlock; -import net.minecraft.server.v1_15_R1.IBlockData; -import net.minecraft.server.v1_15_R1.LightEngineThreaded; -import net.minecraft.server.v1_15_R1.NBTTagCompound; -import net.minecraft.server.v1_15_R1.NBTTagInt; -import net.minecraft.server.v1_15_R1.NibbleArray; -import net.minecraft.server.v1_15_R1.SectionPosition; -import net.minecraft.server.v1_15_R1.TileEntity; -import net.minecraft.server.v1_15_R1.WorldServer; -import org.bukkit.World; -import org.bukkit.block.Biome; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.jetbrains.annotations.NotNull; - -public class BukkitGetBlocks_1_15 extends CharGetBlocks { - private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private final static Function nmsTile2We = tileEntity -> new LazyCompoundTag_1_15(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); - public ChunkSection[] sections; - public Chunk nmsChunk; - public WorldServer world; - public int X, Z; - public NibbleArray[] blockLight = new NibbleArray[16]; - public NibbleArray[] skyLight = new NibbleArray[16]; - - public BukkitGetBlocks_1_15(World world, int X, int Z) { - this(((CraftWorld) world).getHandle(), X, Z); - } - - public BukkitGetBlocks_1_15(WorldServer world, int X, int Z) { - this.world = world; - this.X = X; - this.Z = Z; - } - - public int getX() { - return X; - } - - public int getZ() { - return Z; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - BiomeStorage index = getChunk().getBiomeIndex(); - BiomeBase base = null; - if (y == -1) { - for (y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) { - base = index.getBiome(x >> 2, y >> 2, z >> 2); - if (base != null) break; - } - } else { - base = index.getBiome(x >> 2, y >> 2, z >> 2); - } - return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null; - } - - @Override - public CompoundTag getTile(int x, int y, int z) { - TileEntity tileEntity = getChunk().getTileEntity(new BlockPosition((x & 15) + (X << 4), y, (z & 15) + (Z << 4))); - if (tileEntity == null) { - return null; - } - return new LazyCompoundTag_1_15(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); - } - - @Override - public Map getTiles() { - Map nmsTiles = getChunk().getTileEntities(); - if (nmsTiles.isEmpty()) { - return Collections.emptyMap(); - } - return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We); - } - - @Override - public int getSkyLight(int x, int y, int z) { - int layer = y >> 4; - if (skyLight[layer] == null) { - skyLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(SectionPosition.a(nmsChunk.getPos(), layer)); - } - long l = BlockPosition.a(x, y, z); - return skyLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); - } - - @Override - public int getEmmittedLight(int x, int y, int z) { - int layer = y >> 4; - if (blockLight[layer] == null) { - blockLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(SectionPosition.a(nmsChunk.getPos(), layer)); - } - long l = BlockPosition.a(x, y, z); - return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); - } - - @Override - public CompoundTag getEntity(UUID uuid) { - Entity entity = world.getEntity(uuid); - if (entity != null) { - org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - for (List entry : getChunk().getEntitySlices()) { - if (entry != null) { - for (Entity ent : entry) { - if (uuid.equals(ent.getUniqueID())) { - org.bukkit.entity.Entity bukkitEnt = ent.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - } - } - } - return null; - } - - @Override - public Set getEntities() { - List[] slices = getChunk().getEntitySlices(); - int size = 0; - for (List slice : slices) { - if (slice != null) size += slice.size(); - } - if (slices.length == 0) { - return Collections.emptySet(); - } - int finalSize = size; - return new AbstractSet() { - @Override - public int size() { - return finalSize; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object get) { - if (!(get instanceof CompoundTag)) { - return false; - } - CompoundTag getTag = (CompoundTag) get; - Map value = getTag.getValue(); - CompoundTag getParts = (CompoundTag) value.get("UUID"); - UUID getUUID = new UUID(getParts.getLong("Most"), getParts.getLong("Least")); - for (List slice : slices) { - if (slice != null) { - for (Entity entity : slice) { - UUID uuid = entity.getUniqueID(); - if (uuid.equals(getUUID)) { - return true; - } - } - } - } - return false; - } - - @NotNull - @Override - public Iterator iterator() { - Iterable result = StreamSupport - .stream(Iterables.concat(slices).spliterator(), false).map(input -> { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance() - .getBukkitImplAdapter(); - NBTTagCompound tag = new NBTTagCompound(); - return (CompoundTag) adapter.toNative(input.save(tag)); - }).collect(Collectors.toList()); - return result.iterator(); - } - }; - } - - private void updateGet(BukkitGetBlocks_1_15 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; - } - - public Chunk ensureLoaded(net.minecraft.server.v1_15_R1.World nmsWorld, int X, int Z) { - return BukkitAdapter_1_15.ensureLoaded(nmsWorld, X, Z); - } - - @Override - public > T call(IChunkSet set, Runnable finalizer) { - try { - WorldServer nmsWorld = world; - Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z); - boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE; - - // Remove existing tiles - { - Map tiles = new HashMap<>(nmsChunk.getTileEntities()); - if (!tiles.isEmpty()) { - for (Map.Entry entry : tiles.entrySet()) { - 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(); - nmsChunk.removeTileEntity(tile.getPosition()); - } - } - } - } - - 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.load(layer); - ChunkSection newSection; - ChunkSection existingSection = sections[layer]; - if (existingSection == null) { - newSection = BukkitAdapter_1_15.newChunkSection(layer, setArr, fastmode); - if (BukkitAdapter_1_15.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; - } - } - } - - //ensure that the server doesn't try to tick the chunksection while we're editing it. - BukkitAdapter_1_15.fieldTickingBlockCount.set(existingSection, (short) 0); - - DelegateLock lock = BukkitAdapter_1_15.applyLock(existingSection); - synchronized (this) { - synchronized (lock) { - lock.untilFree(); - if (this.nmsChunk != nmsChunk) { - this.nmsChunk = nmsChunk; - this.sections = null; - this.reset(); - } else if (existingSection != getSections()[layer]) { - this.sections[layer] = existingSection; - this.reset(); - } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { - this.reset(layer); - } else if (lock.isModified()) { - this.reset(layer); - } - newSection = BukkitAdapter_1_15.newChunkSection(layer, this::load, setArr, fastmode); - if (!BukkitAdapter_1_15.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 - BiomeStorage currentBiomes = nmsChunk.getBiomeIndex(); - for (int z = 0, i = 0; z < 16; z++) { - for (int x = 0; x < 16; x++, i++) { - final BiomeType biome = biomes[i]; - if (biome != null) { - final Biome craftBiome = BukkitAdapter.adapt(biome); - BiomeBase nmsBiome = CraftBlock.biomeToBiomeBase(craftBiome); - for (int y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) { - currentBiomes.setBiome(x >> 2, y >> 2, z >> 2, nmsBiome); - } - } - } - } - } - - boolean lightUpdate = false; - - // Lighting - char[][] light = set.getLight(); - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, EnumSkyBlock.BLOCK); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - char[][] skyLight = set.getSkyLight(); - if (skyLight != null) { - lightUpdate = true; - try { - fillLightNibble(skyLight, EnumSkyBlock.SKY); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - Runnable[] syncTasks = null; - - int bx = X << 4; - int bz = Z << 4; - - Set entityRemoves = set.getEntityRemoves(); - if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) syncTasks = new Runnable[3]; - - syncTasks[2] = () -> { - final List[] entities = nmsChunk.getEntitySlices(); - - for (final Collection ents : entities) { - if (!ents.isEmpty()) { - final Iterator iter = ents.iterator(); - while (iter.hasNext()) { - final Entity entity = iter.next(); - if (entityRemoves.contains(entity.getUniqueID())) { - iter.remove(); - removeEntity(entity); - } - } - } - } - }; - } - - Set entities = set.getEntities(); - if (entities != null && !entities.isEmpty()) { - if (syncTasks == null) syncTasks = new Runnable[2]; - - syncTasks[1] = () -> { - for (final CompoundTag nativeTag : entities) { - final Map entityTagMap = 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) { - getLogger(BukkitGetBlocks_1_15.class).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 tiles = set.getTiles(); - if (tiles != null && !tiles.isEmpty()) { - if (syncTasks == null) syncTasks = new Runnable[1]; - - syncTasks[0] = () -> { - for (final Map.Entry entry : tiles.entrySet()) { - final CompoundTag nativeTag = entry.getValue(); - final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.getX() + bx; - final int y = blockHash.getY(); - final int z = blockHash.getZ() + 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", NBTTagInt.a(x)); - tag.set("y", NBTTagInt.a(y)); - tag.set("z", NBTTagInt.a(z)); - tileEntity.load(tag); - } - } - } - }; - } - - Runnable callback; - if (bitMask == 0 && biomes == null && !lightUpdate) { - callback = null; - } else { - int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0; - boolean finalLightUpdate = lightUpdate; - callback = () -> { - // Set Modified - nmsChunk.d(true); // Set Modified - nmsChunk.mustNotSave = false; - nmsChunk.markDirty(); - // send to player - BukkitAdapter_1_15.sendChunk(nmsWorld, X, Z, finalMask, finalLightUpdate); - if (finalizer != null) finalizer.run(); - }; - } - if (syncTasks != null) { - QueueHandler queueHandler = Fawe.get().getQueueHandler(); - Runnable[] finalSyncTasks = syncTasks; - - // Chain the sync tasks and the callback - Callable chain = () -> { - try { - // Run the sync tasks - for (Runnable task : finalSyncTasks) { - if (task != null) { - task.run(); - } - } - if (callback == null) { - if (finalizer != null) finalizer.run(); - return null; - } else { - return queueHandler.async(callback, null); - } - } catch (Throwable e) { - e.printStackTrace(); - throw e; - } - }; - 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[] update(int layer, char[] data) { - ChunkSection section = getSections()[layer]; - // Section is null, return empty array - if (section == null) { - return FaweCache.IMP.EMPTY_CHAR_4096; - } - if (data == null || data == FaweCache.IMP.EMPTY_CHAR_4096) { - data = new char[4096]; - } - DelegateLock lock = BukkitAdapter_1_15.applyLock(section); - synchronized (lock) { - lock.untilFree(); - lock.setModified(false); - // Efficiently convert ChunkSection to raw data - try { - FAWE_Spigot_v1_15_R1 adapter = ((FAWE_Spigot_v1_15_R1) WorldEditPlugin.getInstance().getBukkitImplAdapter()); - - final DataPaletteBlock blocks = section.getBlocks(); - final DataBits bits = (DataBits) BukkitAdapter_1_15.fieldBits.get(blocks); - final DataPalette palette = (DataPalette) BukkitAdapter_1_15.fieldPalette.get(blocks); - - //getBits() - final int bitsPerEntry = bits.c(); - //getRaw() - final long[] blockStates = bits.a(); - - new BitArray(bitsPerEntry, 4096, blockStates).toRaw(data); - - int num_palette; - if (palette instanceof DataPaletteLinear) { - //Get the size of the palette - num_palette = ((DataPaletteLinear) palette).b(); - } else if (palette instanceof DataPaletteHash) { - //Get the size of the palette - num_palette = ((DataPaletteHash) palette).b(); - } else { - num_palette = 0; - 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]; - char ordinal = paletteToBlockChars[paletteVal]; - if (ordinal == Character.MAX_VALUE) { - paletteToBlockInts[num_palette++] = paletteVal; - //palette.a(Object) is palette.idFor(Object) - IBlockData ibd = palette.a(data[i]); - if (ibd == null) { - ordinal = BlockTypes.AIR.getDefaultState().getOrdinalChar(); - } else { - ordinal = adapter.adaptToChar(ibd); - } - paletteToBlockChars[paletteVal] = ordinal; - } - data[i] = ordinal; - } - } finally { - for (int i = 0; i < num_palette; i++) { - int paletteVal = paletteToBlockInts[i]; - paletteToBlockChars[paletteVal] = Character.MAX_VALUE; - } - } - return data; - } - - char[] paletteToOrdinal = FaweCache.IMP.PALETTE_TO_BLOCK_CHAR.get(); - try { - if (num_palette != 1) { - for (int i = 0; i < num_palette; i++) { - //palette.a(Object) is palette.idFor(Object) - char ordinal = ordinal(palette.a(i), adapter); - paletteToOrdinal[i] = ordinal; - } - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char val = paletteToOrdinal[paletteVal]; - if (val == Character.MAX_VALUE) { - val = ordinal(palette.a(i), adapter); - paletteToOrdinal[i] = val; - } - data[i] = val; - } - } else { - char ordinal = ordinal(palette.a(0), adapter); - Arrays.fill(data, ordinal); - } - } finally { - for (int i = 0; i < num_palette; i++) { - paletteToOrdinal[i] = Character.MAX_VALUE; - } - } - return data; - } catch (IllegalAccessException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - } - - private final char ordinal(IBlockData ibd, FAWE_Spigot_v1_15_R1 adapter) { - if (ibd == null) { - return BlockTypes.AIR.getDefaultState().getOrdinalChar(); - } else { - return adapter.adaptToChar(ibd); - } - } - - public ChunkSection[] getSections() { - ChunkSection[] tmp = sections; - if (tmp == null) { - synchronized (this) { - tmp = sections; - if (tmp == null) { - Chunk chunk = getChunk(); - sections = tmp = chunk.getSections().clone(); - } - } - } - return tmp; - } - - public Chunk getChunk() { - Chunk tmp = nmsChunk; - if (tmp == null) { - synchronized (this) { - tmp = nmsChunk; - if (tmp == null) { - nmsChunk = tmp = ensureLoaded(this.world, X, Z); - } - } - } - return tmp; - } - - private void fillLightNibble(char[][] light, EnumSkyBlock skyBlock) { - for (int Y = 0; Y < 16; Y++) { - if (light[Y] == null) { - continue; - } - NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y)); - if (nibble == null) { - continue; - } - synchronized (nibble) { - for (int i = 0; i < 4096; i++) { - if (light[Y][i] < 16) { - nibble.a(i, light[Y][i]); - } - } - } - } - } - - @Override - public boolean hasSection(int layer) { - return getSections()[layer] != null; - } - - @Override - public boolean trim(boolean aggressive) { - if (aggressive) { - sections = null; - nmsChunk = null; - return super.trim(true); - } else { - for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { - continue; - } - ChunkSection existing = getSections()[i]; - try { - final DataPaletteBlock blocksExisting = existing.getBlocks(); - - final DataPalette palette = (DataPalette) BukkitAdapter_1_15.fieldPalette.get(blocksExisting); - int paletteSize; - - if (palette instanceof DataPaletteLinear) { - paletteSize = ((DataPaletteLinear) palette).b(); - } else if (palette instanceof DataPaletteHash) { - paletteSize = ((DataPaletteHash) palette).b(); - } else { - super.trim(false, i); - continue; - } - if (paletteSize == 1) { - //If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks. - continue; - } - super.trim(false, i); - } catch (IllegalAccessException ignored) { - super.trim(false, i); - } - } - return true; - } - } -} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/MapChunkUtil_1_15.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/MapChunkUtil_1_15.java deleted file mode 100644 index afdebf1bc..000000000 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/MapChunkUtil_1_15.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; - -import com.boydti.fawe.bukkit.adapter.MapChunkUtil; -import net.minecraft.server.v1_15_R1.PacketPlayOutMapChunk; - -public class MapChunkUtil_1_15 extends MapChunkUtil { - public MapChunkUtil_1_15() throws NoSuchFieldException { - fieldX = PacketPlayOutMapChunk.class.getDeclaredField("a"); - fieldZ = PacketPlayOutMapChunk.class.getDeclaredField("b"); - fieldBitMask = PacketPlayOutMapChunk.class.getDeclaredField("c"); - fieldHeightMap = PacketPlayOutMapChunk.class.getDeclaredField("d"); - fieldChunkData = PacketPlayOutMapChunk.class.getDeclaredField("e"); - fieldBlockEntities = PacketPlayOutMapChunk.class.getDeclaredField("f"); - fieldFull = PacketPlayOutMapChunk.class.getDeclaredField("g"); - fieldX.setAccessible(true); - fieldZ.setAccessible(true); - fieldBitMask.setAccessible(true); - fieldHeightMap.setAccessible(true); - fieldChunkData.setAccessible(true); - fieldBlockEntities.setAccessible(true); - fieldFull.setAccessible(true); - } - - @Override - public PacketPlayOutMapChunk createPacket() { - return new PacketPlayOutMapChunk(); - } -} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/nbt/LazyCompoundTag_1_15.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/nbt/LazyCompoundTag_1_15.java deleted file mode 100644 index 6faa934f6..000000000 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/nbt/LazyCompoundTag_1_15.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15.nbt; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import net.minecraft.server.v1_15_R1.NBTBase; -import net.minecraft.server.v1_15_R1.NBTNumber; -import net.minecraft.server.v1_15_R1.NBTTagCompound; -import net.minecraft.server.v1_15_R1.NBTTagList; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -public class LazyCompoundTag_1_15 extends CompoundTag { - private final Supplier nmsTag; - - public LazyCompoundTag_1_15(Supplier tag) { - super(null); - this.nmsTag = tag; - } - - public LazyCompoundTag_1_15(NBTTagCompound tag) { - this(() -> tag); - } - - public NBTTagCompound get() { - return nmsTag.get(); - } - - @Override - public Map getValue() { - Map value = super.getValue(); - if (value == null) { - Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get()); - setValue(((CompoundTag) tag).getValue()); - } - return super.getValue(); - } - - public boolean containsKey(String key) { - return nmsTag.get().hasKey(key); - } - - public byte[] getByteArray(String key) { - return nmsTag.get().getByteArray(key); - } - - public byte getByte(String key) { - return nmsTag.get().getByte(key); - } - - public double getDouble(String key) { - return nmsTag.get().getDouble(key); - } - - public double asDouble(String key) { - NBTBase value = nmsTag.get().get(key); - if (value instanceof NBTNumber) { - return ((NBTNumber) value).asDouble(); - } - return 0; - } - - public float getFloat(String key) { - return nmsTag.get().getFloat(key); - } - - public int[] getIntArray(String key) { - return nmsTag.get().getIntArray(key); - } - - public int getInt(String key) { - return nmsTag.get().getInt(key); - } - - public int asInt(String key) { - NBTBase value = nmsTag.get().get(key); - if (value instanceof NBTNumber) { - return ((NBTNumber) value).asInt(); - } - return 0; - } - - public List getList(String key) { - NBTBase tag = nmsTag.get().get(key); - if (tag instanceof NBTTagList) { - ArrayList list = new ArrayList<>(); - NBTTagList nbtList = (NBTTagList) tag; - for (NBTBase elem : nbtList) { - if (elem instanceof NBTTagCompound) { - list.add(new LazyCompoundTag_1_15((NBTTagCompound) elem)); - } else { - list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); - } - } - return list; - } - return Collections.emptyList(); - } - - public ListTag getListTag(String key) { - NBTBase tag = nmsTag.get().get(key); - if (tag instanceof NBTTagList) { - return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag); - } - return new ListTag(StringTag.class, Collections.emptyList()); - } - - @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { - ListTag listTag = getListTag(key); - if (listTag.getType().equals(listType)) { - return (List) listTag.getValue(); - } else { - return Collections.emptyList(); - } - } - - public long[] getLongArray(String key) { - return nmsTag.get().getLongArray(key); - } - - public long getLong(String key) { - return nmsTag.get().getLong(key); - } - - public long asLong(String key) { - NBTBase value = nmsTag.get().get(key); - if (value instanceof NBTNumber) { - return ((NBTNumber) value).asLong(); - } - return 0; - } - - public short getShort(String key) { - return nmsTag.get().getShort(key); - } - - public String getString(String key) { - return nmsTag.get().getString(key); - } - - @Override - public String toString() { - return nmsTag.get().toString(); - } -} \ No newline at end of file diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index 376111663..ae66a73af 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -33,7 +33,6 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.bukkit.adapter.AdapterLoadException; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader; -import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_15_R1; import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_15_R2; import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; @@ -371,7 +370,6 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter BukkitImplLoader adapterLoader = new BukkitImplLoader(); try { adapterLoader.addClass(FAWE_Spigot_v1_14_R4.class); - adapterLoader.addClass(FAWE_Spigot_v1_15_R1.class); adapterLoader.addClass(FAWE_Spigot_v1_15_R2.class); } catch (Throwable throwable) { throwable.printStackTrace(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java deleted file mode 100644 index 49dfea72f..000000000 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.impl; - -import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.IChunkGet; -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.BlockMaterial_1_15; -import com.boydti.fawe.bukkit.adapter.mc1_15.BukkitAdapter_1_15; -import com.boydti.fawe.bukkit.adapter.mc1_15.BukkitGetBlocks_1_15; -import com.boydti.fawe.bukkit.adapter.mc1_15.MapChunkUtil_1_15; -import com.boydti.fawe.bukkit.adapter.mc1_15.nbt.LazyCompoundTag_1_15; -import com.google.common.io.Files; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.blocks.TileEntityBlock; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -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.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.Property; -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; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.server.v1_15_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World.Environment; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_15_R1.CraftChunk; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock; -import org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.generator.ChunkGenerator; - -import javax.annotation.Nullable; -import java.io.File; -import java.io.IOException; -import java.util.Map; -import java.util.OptionalInt; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static com.google.common.base.Preconditions.checkNotNull; - -public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { - private final Spigot_v1_15_R1 parent; - private char[] ibdToStateOrdinal; - - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - - public FAWE_Spigot_v1_15_R1() throws NoSuchFieldException, NoSuchMethodException { - this.parent = new Spigot_v1_15_R1(); - } - - @Override - public BukkitImplAdapter getParent() { - return parent; - } - - private synchronized boolean init() { - if (ibdToStateOrdinal != null) return false; - ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size - for (int i = 0; i < ibdToStateOrdinal.length; i++) { - BlockState state = BlockTypesCache.states[i]; - BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial(); - int id = Block.REGISTRY_ID.getId(material.getState()); - ibdToStateOrdinal[id] = state.getOrdinalChar(); - } - return true; - } - - @Override - public BlockMaterial getMaterial(BlockType blockType) { - Block block = getBlock(blockType); - return new BlockMaterial_1_15(block); - } - - @Override - public BlockMaterial getMaterial(BlockState state) { - IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new BlockMaterial_1_15(bs.getBlock(), bs); - } - - public Block getBlock(BlockType blockType) { - return IRegistry.BLOCK.get(new MinecraftKey(blockType.getNamespace(), blockType.getResource())); - } - - @SuppressWarnings("deprecation") - @Override - public BaseBlock getBlock(Location location) { - checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final WorldServer handle = craftWorld.getHandle(); - Chunk chunk = handle.getChunkAt(x >> 4, z >> 4); - final BlockPosition blockPos = new BlockPosition(x, y, z); - org.bukkit.block.Block bukkitBlock = location.getBlock(); - BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - if (state.getBlockType().getMaterial().hasContainer()) { - - // Read the NBT data - TileEntity te = chunk.a(blockPos, Chunk.EnumTileEntityState.CHECK); - if (te != null) { - NBTTagCompound tag = new NBTTagCompound(); - te.save(tag); // readTileEntityIntoTag - load data - return state.toBaseBlock((CompoundTag) toNative(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public > 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, B state, boolean update) { - CraftChunk craftChunk = (CraftChunk) chunk; - Chunk nmsChunk = craftChunk.getHandle(); - World nmsWorld = nmsChunk.getWorld(); - - BlockPosition blockPos = new BlockPosition(x, y, z); - IBlockData blockData = ((BlockMaterial_1_15) state.getMaterial()).getState(); - ChunkSection[] sections = nmsChunk.getSections(); - int y4 = y >> 4; - ChunkSection section = sections[y4]; - - IBlockData existing; - if (section == null) { - existing = ((BlockMaterial_1_15) BlockTypes.AIR.getDefaultState().getMaterial()).getState(); - } else { - existing = section.getType(x & 15, y & 15, z & 15); - } - - - nmsChunk.removeTileEntity(blockPos); // Force delete the old tile entity - - CompoundTag nativeTag = state instanceof BaseBlock ? ((BaseBlock)state).getNbtData() : null; - if (nativeTag != null || existing instanceof TileEntityBlock) { - nmsWorld.setTypeAndData(blockPos, blockData, 0); - // remove tile - if (nativeTag != null) { - // We will assume that the tile entity was created for us, - // though we do not do this on the Forge version - TileEntity tileEntity = nmsWorld.getTileEntity(blockPos); - if (tileEntity != null) { - NBTTagCompound tag = (NBTTagCompound) fromNative(nativeTag); - tag.set("x", NBTTagInt.a(x)); - tag.set("y", NBTTagInt.a(y)); - tag.set("z", NBTTagInt.a(z)); - tileEntity.load(tag); // readTagIntoTileEntity - load data - } - } - } else { - if (existing == blockData) return true; - if (section == null) { - if (blockData.isAir()) return true; - sections[y4] = section = new ChunkSection(y4 << 4); - } - nmsChunk.setType(blockPos, blockData, false); - } - if (update) { - nmsWorld.getMinecraftWorld().notify(blockPos, existing, blockData, 0); - } - return true; - } - - @Nullable - private static String getEntityId(Entity entity) { - MinecraftKey minecraftkey = EntityTypes.getName(entity.getEntityType()); - return minecraftkey == null ? null : minecraftkey.toString(); - } - - private static void readEntityIntoTag(Entity entity, NBTTagCompound tag) { - entity.save(tag); - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - String id = getEntityId(mcEntity); - - if (id != null) { - EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); - Supplier saveTag = () -> { - NBTTagCompound tag = new NBTTagCompound(); - readEntityIntoTag(mcEntity, tag); - return (CompoundTag) toNative(tag); - }; - return new LazyBaseEntity(type, saveTag); - } else { - return null; - } - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial(); - IBlockData mcState = material.getCraftBlockData().getState(); - return OptionalInt.of(Block.REGISTRY_ID.getId(mcState)); - } - - @Override - public BlockState adapt(BlockData blockData) { - CraftBlockData cbd = ((CraftBlockData) blockData); - IBlockData ibd = cbd.getState(); - return adapt(ibd); - } - - public BlockState adapt(IBlockData ibd) { - return BlockTypesCache.states[adaptToChar(ibd)]; - } - - /** - * @deprecated - * Method unused. Use #adaptToChar(IBlockData). - */ - @Deprecated - public int adaptToInt(IBlockData ibd) { - synchronized (this) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return ibdToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToInt(ibd); - } - } - } - - public char adaptToChar(IBlockData ibd) { - synchronized (this) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return ibdToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToChar(ibd); - } catch (ArrayIndexOutOfBoundsException e1) { - Fawe.debug("Attempted to convert " + ibd.getBlock() + " with ID " + Block.REGISTRY_ID.getId(ibd) + " to char. ibdToStateOrdinal length: " + ibdToStateOrdinal.length + ". Defaulting to air!"); - return 0; - } - } - } - - @Override - public > BlockData adapt(B state) { - BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial(); - return material.getCraftBlockData(); - } - - @Override - public void notifyAndLightBlock(Location position, BlockState previousType) { - this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true); - } - - private MapChunkUtil_1_15 mapUtil = new MapChunkUtil_1_15(); - - @Override - public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) { - WorldServer nmsWorld = ((CraftWorld) world).getHandle(); - PlayerChunk map = BukkitAdapter_1_15.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ()); - if (map != null && map.hasBeenLoaded()) { - boolean flag = false; - PlayerChunk.d players = map.players; - Stream stream = players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag); - - EntityPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle(); - stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) - .forEach(entityPlayer -> { - synchronized (packet) { - PacketPlayOutMapChunk nmsPacket = (PacketPlayOutMapChunk) packet.getNativePacket(); - if (nmsPacket == null) { - nmsPacket = mapUtil.create( this, packet); - packet.setNativePacket(nmsPacket); - } - try { - FaweCache.IMP.CHUNK_FLAG.get().set(true); - entityPlayer.playerConnection.sendPacket(nmsPacket); - } finally { - FaweCache.IMP.CHUNK_FLAG.get().set(false); - } - } - }); - } - } - - @Override - public Map> getProperties(BlockType blockType) { - return getParent().getProperties(blockType); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { - ItemStack stack = new ItemStack(IRegistry.ITEM.get(MinecraftKey.a(item.getType().getId())), item.getAmount()); - stack.setTag(((NBTTagCompound) fromNative(item.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbtData(((CompoundTag) toNative(nmsStack.getTag()))); - return weStack; - } - - @Override - public Tag toNative(NBTBase foreign) { - return parent.toNative(foreign); - } - - @Override - public NBTBase fromNative(Tag foreign) { - if (foreign instanceof LazyCompoundTag_1_15) { - return ((LazyCompoundTag_1_15) foreign).get(); - } - return parent.fromNative(foreign); - } - - @Override - public boolean regenerate(org.bukkit.World world, Region region, EditSession editSession) { - WorldServer originalWorld = ((CraftWorld) world).getHandle(); - ChunkProviderServer provider = originalWorld.getChunkProvider(); - if (!(provider instanceof ChunkProviderServer)) { - return false; - } - - File saveFolder = Files.createTempDir(); - // register this just in case something goes wrong - // normally it should be deleted at the end of this method - saveFolder.deleteOnExit(); - try { - MinecraftServer server = originalWorld.getServer().getServer(); - WorldNBTStorage originalDataManager = originalWorld.getDataManager(); - WorldNBTStorage saveHandler = new WorldNBTStorage(saveFolder, originalDataManager.getDirectory().getName(), server, originalDataManager.getDataFixer()); - WorldData newWorldData = new WorldData(originalWorld.worldData.a((NBTTagCompound) null), - server.dataConverterManager, getDataVersion(), null); - newWorldData.setName(UUID.randomUUID().toString()); - - ChunkGenerator gen = world.getGenerator(); - Environment env = world.getEnvironment(); - try (WorldServer freshWorld = new WorldServer(server, - server.executorService, saveHandler, - newWorldData, - originalWorld.worldProvider.getDimensionManager(), - originalWorld.getMethodProfiler(), - server.worldLoadListenerFactory.create(11), - env, - gen){ - @Override - public boolean addEntityChunk(net.minecraft.server.v1_15_R1.Entity entity) { - //Fixes #320; Prevent adding entities so we aren't attempting to spawn them asynchronously - return false; - } - }) { - - // Pre-gen all the chunks - // We need to also pull one more chunk in every direction - Fawe.get().getQueueHandler().startSet(true); - try { - IQueueExtent extent = new SingleThreadQueueExtent(); - extent.init(null, (x, z) -> new BukkitGetBlocks_1_15(freshWorld, x, z) { - @Override - public Chunk ensureLoaded(World nmsWorld, int X, int Z) { - Chunk cached = nmsWorld.getChunkIfLoaded(X, Z); - if (cached != null) return cached; - Future future = Fawe.get().getQueueHandler().sync((Supplier) () -> freshWorld.getChunkAt(X, Z)); - while (!future.isDone()) { - // this feels so dirty - freshWorld.getChunkProvider().runTasks(); - } - try { - return future.get(); - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } - } - }, null); - for (BlockVector3 vec : region) { - editSession.setBlock(vec, extent.getFullBlock(vec)); - } - } finally { - Fawe.get().getQueueHandler().endSet(true); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } catch (MaxChangedBlocksException e) { - throw new RuntimeException(e); - } finally { - saveFolder.delete(); - } - return true; - } - - @Override - public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new BukkitGetBlocks_1_15(world, chunkX, chunkZ); - } - - @Override - public int getInternalBiomeId(BiomeType biome) { - BiomeBase base = CraftBlock.biomeToBiomeBase(BukkitAdapter.adapt(biome)); - return IRegistry.BIOME.a(base); - } -} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java index 582136f57..8a74f5f3d 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java @@ -31,7 +31,8 @@ public class CopyPastaBrush implements Brush, ResettableTool { private final LocalSession session; private final Player player; - public boolean autoRotate, randomRotate; + public boolean autoRotate; + public boolean randomRotate; public CopyPastaBrush(Player player, LocalSession session, boolean randomRotate, boolean autoRotate) { session.setClipboard(null);