From 6d056847c14c9b1f30d11b564bb070faf9894f9e Mon Sep 17 00:00:00 2001 From: wizjany Date: Wed, 24 Jun 2020 23:30:55 -0400 Subject: [PATCH 01/14] Update adapter jar. (cherry picked from commit 9e186225bd25f4805d09081f8b8ca717f61a73a4) --- .../src/main/resources/worldedit-adapters.jar | Bin 651063 -> 438312 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/worldedit-bukkit/src/main/resources/worldedit-adapters.jar b/worldedit-bukkit/src/main/resources/worldedit-adapters.jar index 3024c70c526b15fd6f33bcc45dad516a3ff0b416..f64be9496855f8263acdefa5fc75a1817eb5a411 100644 GIT binary patch delta 149933 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

5)_GMr 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%0AIjO*l_8Q?)eBqDwkm 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 b%lvmyNtkmoa7i(kP4G870)t5sMgIGLbF{qH delta 324860 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 Date: Thu, 25 Jun 2020 19:56:10 -0400 Subject: [PATCH 02/14] 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); From b7debce4d427612fe92b236bfc0986dd4ad3bd08 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 03/14] 1.16.1 Prep work --- worldedit-bukkit/build.gradle.kts | 3 +- .../BlockMaterial_1_16_1.java} | 29 ++-- .../BukkitAdapter_1_16_1.java} | 55 +++---- .../BukkitGetBlocks_1_16_1.java} | 146 ++++++++---------- .../MapChunkUtil_1_16_1.java} | 14 +- .../nbt/LazyCompoundTag_1_16_1.java} | 20 +-- .../worldedit/bukkit/WorldEditPlugin.java | 2 - ...1_15_R1.java => FAWE_Spigot_v1_16_R1.java} | 50 +++--- .../fawe/object/brush/CopyPastaBrush.java | 3 +- 9 files changed, 146 insertions(+), 176 deletions(-) rename worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/{mc1_15/BlockMaterial_1_15.java => mc1_16_1/BlockMaterial_1_16_1.java} (79%) rename worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/{mc1_15/BukkitAdapter_1_15.java => mc1_16_1/BukkitAdapter_1_16_1.java} (86%) rename worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/{mc1_15/BukkitGetBlocks_1_15.java => mc1_16_1/BukkitGetBlocks_1_16_1.java} (86%) rename worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/{mc1_15/MapChunkUtil_1_15.java => mc1_16_1/MapChunkUtil_1_16_1.java} (76%) rename worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/{mc1_15/nbt/LazyCompoundTag_1_15.java => mc1_16_1/nbt/LazyCompoundTag_1_16_1.java} (88%) rename worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/{FAWE_Spigot_v1_15_R1.java => FAWE_Spigot_v1_16_R1.java} (91%) 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_16_1/BlockMaterial_1_16_1.java similarity index 79% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BlockMaterial_1_15.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BlockMaterial_1_16_1.java index 3a7c205ac..ef492dbdd 100644 --- 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_16_1/BlockMaterial_1_16_1.java @@ -1,15 +1,11 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; +package com.boydti.fawe.bukkit.adapter.mc1_16_1; 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; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.block.data.CraftBlockData; -public class BlockMaterial_1_15 implements BlockMaterial { +public class BlockMaterial_1_16_1 implements BlockMaterial { private final Block block; private final IBlockData defaultState; private final Material material; @@ -17,17 +13,17 @@ public class BlockMaterial_1_15 implements BlockMaterial { private final CraftBlockData craftBlockData; private final org.bukkit.Material craftMaterial; - public BlockMaterial_1_15(Block block) { + public BlockMaterial_1_16_1(Block block) { this(block, block.getBlockData()); } - public BlockMaterial_1_15(Block block, IBlockData defaultState) { + public BlockMaterial_1_16_1(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"); + this.isTranslucent = !(boolean) ReflectionUtil.getField(Block.class, block, "v"); //TODO Update Mapping for 1.16.1 } public Block getBlock() { @@ -78,7 +74,7 @@ public class BlockMaterial_1_15 implements BlockMaterial { @Override public float getHardness() { - return block.strength; + return craftBlockData.getState().strength; } @Override @@ -88,12 +84,12 @@ public class BlockMaterial_1_15 implements BlockMaterial { @Override public float getSlipperiness() { - return block.m(); + return block.getFrictionFactor(); } @Override public int getLightValue() { - return defaultState.h(); + return defaultState.f(); } @Override @@ -128,7 +124,8 @@ public class BlockMaterial_1_15 implements BlockMaterial { @Override public boolean isToolRequired() { - return !material.isAlwaysDestroyable(); + //TODO Removed in 1.16.1 Replacement not found. + return true; } @Override @@ -148,6 +145,6 @@ public class BlockMaterial_1_15 implements BlockMaterial { @Override public int getMapColor() { - return material.i().rgb; + return material.h().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_16_1/BukkitAdapter_1_16_1.java similarity index 86% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitAdapter_1_15.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java index be791aa66..adab97743 100644 --- 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_16_1/BukkitAdapter_1_16_1.java @@ -1,4 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; +package com.boydti.fawe.bukkit.adapter.mc1_16_1; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; @@ -14,22 +14,9 @@ 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 net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.CraftChunk; +import org.bukkit.craftbukkit.v1_16_R1.CraftWorld; import sun.misc.Unsafe; import java.lang.invoke.MethodHandle; @@ -43,7 +30,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; -public final class BukkitAdapter_1_15 extends NMSAdapter { +public final class BukkitAdapter_1_16_1 extends NMSAdapter { /* NMS fields */ @@ -60,6 +47,8 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { private final static MethodHandle methodGetVisibleChunk; + public final static MethodHandle methodSetLightNibbleArray; + private static final int CHUNKSECTION_BASE; private static final int CHUNKSECTION_SHIFT; @@ -86,12 +75,14 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { 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); + Method declaredSetLightNibbleArray = LightEngineStorage.class.getDeclaredMethod("a", long.class, NibbleArray.class); + declaredSetLightNibbleArray.setAccessible(true); + methodSetLightNibbleArray = MethodHandles.lookup().unreflect(declaredSetLightNibbleArray); + Field tmp = DataPaletteBlock.class.getDeclaredField("j"); ReflectionUtils.setAccessibleNonFinal(tmp); fieldLock = tmp; @@ -120,6 +111,7 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { } protected static DelegateLock applyLock(ChunkSection section) { + //todo there has to be a better way to do this. Maybe using a() in DataPaletteBlock which acquires the lock in NMS? try { synchronized (section) { DataPaletteBlock blocks = section.getBlocks(); @@ -159,7 +151,7 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { 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) { + public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int cx, final int cz) { PlayerChunkMap chunkMap = nmsWorld.getChunkProvider().playerChunkMap; try { return (PlayerChunk)methodGetVisibleChunk.invoke(chunkMap, ChunkCoordIntPair.pair(cx, cz)); @@ -168,7 +160,7 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { } } - public static void sendChunk(net.minecraft.server.v1_15_R1.WorldServer nmsWorld, int X, int Z, int mask, boolean lighting) { + public static void sendChunk(WorldServer nmsWorld, int X, int Z, int mask, boolean lighting) { PlayerChunk playerChunk = getPlayerChunk(nmsWorld, X, Z); if (playerChunk == null) { return; @@ -227,9 +219,11 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { Map ticking_blocks = new HashMap<>(); int air; if (get == null) { - air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks, fastmode); + 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); + air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, + num_palette_buffer, get, set, ticking_blocks, fastmode); } int num_palette = num_palette_buffer[0]; // BlockStates @@ -257,14 +251,14 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { 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); + palette = new DataPaletteLinear<>(Block.REGISTRY_ID, bitsPerEntry, dataPaletteBlocks, GameProfileSerializer::c); // 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(); + final IBlockData ibd = ((BlockMaterial_1_16_1) state.getMaterial()).getState(); palette.a(ibd); } try { @@ -272,10 +266,11 @@ public final class BukkitAdapter_1_15 extends NMSAdapter { 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)); - }); + if (!fastmode) { + 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); } 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_16_1/BukkitGetBlocks_1_16_1.java similarity index 86% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/BukkitGetBlocks_1_15.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index c9fbca585..61940e1fc 100644 --- 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_16_1/BukkitGetBlocks_1_16_1.java @@ -1,6 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; - -import static org.slf4j.LoggerFactory.getLogger; +package com.boydti.fawe.bukkit.adapter.mc1_16_1; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; @@ -9,71 +7,47 @@ 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.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1; 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.jnbt.*; 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.bukkit.adapter.impl.FAWE_Spigot_v1_16_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 net.minecraft.server.v1_16_R1.*; +import org.bukkit.World; +import org.bukkit.block.Biome; +import org.bukkit.craftbukkit.v1_16_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nullable; +import java.util.*; 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 { +import static org.slf4j.LoggerFactory.getLogger; + +public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { + + private static final Logger log = LoggerFactory.getLogger( + BukkitGetBlocks_1_16_1.class); + 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()))); + private final static Function nmsTile2We = tileEntity -> new LazyCompoundTag_1_16_1(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); public ChunkSection[] sections; public Chunk nmsChunk; public WorldServer world; @@ -81,11 +55,11 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { public NibbleArray[] blockLight = new NibbleArray[16]; public NibbleArray[] skyLight = new NibbleArray[16]; - public BukkitGetBlocks_1_15(World world, int X, int Z) { + public BukkitGetBlocks_1_16_1(World world, int X, int Z) { this(((CraftWorld) world).getHandle(), X, Z); } - public BukkitGetBlocks_1_15(WorldServer world, int X, int Z) { + public BukkitGetBlocks_1_16_1(WorldServer world, int X, int Z) { this.world = world; this.X = X; this.Z = Z; @@ -120,7 +94,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { if (tileEntity == null) { return null; } - return new LazyCompoundTag_1_15(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); + return new LazyCompoundTag_1_16_1(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); } @Override @@ -219,19 +193,21 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { @NotNull @Override public Iterator iterator() { - Iterable result = StreamSupport - .stream(Iterables.concat(slices).spliterator(), false).map(input -> { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance() - .getBukkitImplAdapter(); + Iterable result = Iterables.transform(Iterables.concat(slices), new com.google.common.base.Function() { + @Nullable + @Override + public CompoundTag apply(@Nullable Entity 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) { + private void updateGet(BukkitGetBlocks_1_16_1 get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) { synchronized (get) { if (this.nmsChunk != nmsChunk) { this.nmsChunk = nmsChunk; @@ -242,7 +218,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { this.sections = sections.clone(); } if (this.sections[layer] != section) { - this.sections[layer] = section; + this.sections[layer] = new ChunkSection[]{section}.clone()[0]; } this.blocks[layer] = arr; } @@ -254,7 +230,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { } public Chunk ensureLoaded(net.minecraft.server.v1_15_R1.World nmsWorld, int X, int Z) { - return BukkitAdapter_1_15.ensureLoaded(nmsWorld, X, Z); + return BukkitAdapter_1_16_1.ensureLoaded(nmsWorld, X, Z); } @Override @@ -266,6 +242,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { // Remove existing tiles { + // Create a copy so that we can remove blocks Map tiles = new HashMap<>(nmsChunk.getTileEntities()); if (!tiles.isEmpty()) { for (Map.Entry entry : tiles.entrySet()) { @@ -277,7 +254,9 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { if (!set.hasSection(layer)) { continue; } - if (set.getBlock(lx, ly, lz).getOrdinal() != 0) { + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != 0) { TileEntity tile = entry.getValue(); nmsChunk.removeTileEntity(tile.getPosition()); } @@ -290,7 +269,9 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { ChunkSection[] sections = nmsChunk.getSections(); for (int layer = 0; layer < 16; layer++) { - if (!set.hasSection(layer)) continue; + if (!set.hasSection(layer)){ + continue; + } bitMask |= 1 << layer; @@ -298,8 +279,8 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { 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)) { + newSection = BukkitAdapter_1_16_1.newChunkSection(layer, setArr, fastmode); + if (BukkitAdapter_1_16_1.setSectionAtomic(sections, null, newSection, layer)) { updateGet(this, nmsChunk, sections, newSection, setArr, layer); continue; } else { @@ -310,11 +291,11 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { } } } + BukkitAdapter_1_16_1.fieldTickingBlockCount.set(existingSection, (short) 0); //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_16_1.applyLock(existingSection); - DelegateLock lock = BukkitAdapter_1_15.applyLock(existingSection); synchronized (this) { synchronized (lock) { lock.untilFree(); @@ -330,8 +311,10 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { } 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)) { + newSection = BukkitAdapter_1_16_1 + .newChunkSection(layer, this::load, setArr, fastmode); + if (!BukkitAdapter_1_16_1 + .setSectionAtomic(sections, existingSection, newSection, layer)) { System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); continue; } else { @@ -421,7 +404,8 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { 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); + getLogger( + BukkitGetBlocks_1_16_1.class).debug("Unknown entity tag: " + nativeTag); continue; } final double x = posTag.getDouble(0); @@ -500,7 +484,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { nmsChunk.mustNotSave = false; nmsChunk.markDirty(); // send to player - BukkitAdapter_1_15.sendChunk(nmsWorld, X, Z, finalMask, finalLightUpdate); + BukkitAdapter_1_16_1.sendChunk(nmsWorld, X, Z, finalMask, finalLightUpdate); if (finalizer != null) finalizer.run(); }; } @@ -554,31 +538,27 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { if (data == null || data == FaweCache.IMP.EMPTY_CHAR_4096) { data = new char[4096]; } - DelegateLock lock = BukkitAdapter_1_15.applyLock(section); + DelegateLock lock = BukkitAdapter_1_16_1.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()); + FAWE_Spigot_v1_16_R1 adapter = ((FAWE_Spigot_v1_16_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); + final DataBits bits = (DataBits) BukkitAdapter_1_16_1.fieldBits.get(blocks); + final DataPalette palette = (DataPalette) BukkitAdapter_1_16_1.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; @@ -590,7 +570,6 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { 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(); @@ -614,7 +593,6 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { 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; } @@ -644,7 +622,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { } } - private final char ordinal(IBlockData ibd, FAWE_Spigot_v1_15_R1 adapter) { + private final char ordinal(IBlockData ibd, FAWE_Spigot_v1_16_R1 adapter) { if (ibd == null) { return BlockTypes.AIR.getDefaultState().getOrdinalChar(); } else { @@ -705,6 +683,8 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { @Override public boolean trim(boolean aggressive) { + skyLight = new NibbleArray[16]; + blockLight = new NibbleArray[16]; if (aggressive) { sections = null; nmsChunk = null; @@ -718,7 +698,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { try { final DataPaletteBlock blocksExisting = existing.getBlocks(); - final DataPalette palette = (DataPalette) BukkitAdapter_1_15.fieldPalette.get(blocksExisting); + final DataPalette palette = (DataPalette) BukkitAdapter_1_16_1.fieldPalette.get(blocksExisting); int paletteSize; if (palette instanceof DataPaletteLinear) { 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_16_1/MapChunkUtil_1_16_1.java similarity index 76% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/MapChunkUtil_1_15.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/MapChunkUtil_1_16_1.java index afdebf1bc..062f623ac 100644 --- 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_16_1/MapChunkUtil_1_16_1.java @@ -1,17 +1,17 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15; +package com.boydti.fawe.bukkit.adapter.mc1_16_1; import com.boydti.fawe.bukkit.adapter.MapChunkUtil; -import net.minecraft.server.v1_15_R1.PacketPlayOutMapChunk; +import net.minecraft.server.v1_16_R1.PacketPlayOutMapChunk; -public class MapChunkUtil_1_15 extends MapChunkUtil { - public MapChunkUtil_1_15() throws NoSuchFieldException { +public class MapChunkUtil_1_16_1 extends MapChunkUtil { + public MapChunkUtil_1_16_1() 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"); + fieldChunkData = PacketPlayOutMapChunk.class.getDeclaredField("f"); + fieldBlockEntities = PacketPlayOutMapChunk.class.getDeclaredField("g"); + fieldFull = PacketPlayOutMapChunk.class.getDeclaredField("h"); fieldX.setAccessible(true); fieldZ.setAccessible(true); fieldBitMask.setAccessible(true); 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_16_1/nbt/LazyCompoundTag_1_16_1.java similarity index 88% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15/nbt/LazyCompoundTag_1_15.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/nbt/LazyCompoundTag_1_16_1.java index 6faa934f6..07a6da3d5 100644 --- 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_16_1/nbt/LazyCompoundTag_1_16_1.java @@ -1,14 +1,14 @@ -package com.boydti.fawe.bukkit.adapter.mc1_15.nbt; +package com.boydti.fawe.bukkit.adapter.mc1_16_1.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 net.minecraft.server.v1_16_R1.NBTBase; +import net.minecraft.server.v1_16_R1.NBTNumber; +import net.minecraft.server.v1_16_R1.NBTTagCompound; +import net.minecraft.server.v1_16_R1.NBTTagList; import java.util.ArrayList; import java.util.Collections; @@ -16,15 +16,15 @@ import java.util.List; import java.util.Map; import java.util.function.Supplier; -public class LazyCompoundTag_1_15 extends CompoundTag { +public class LazyCompoundTag_1_16_1 extends CompoundTag { private final Supplier nmsTag; - public LazyCompoundTag_1_15(Supplier tag) { + public LazyCompoundTag_1_16_1(Supplier tag) { super(null); this.nmsTag = tag; } - public LazyCompoundTag_1_15(NBTTagCompound tag) { + public LazyCompoundTag_1_16_1(NBTTagCompound tag) { this(() -> tag); } @@ -93,7 +93,7 @@ public class LazyCompoundTag_1_15 extends CompoundTag { NBTTagList nbtList = (NBTTagList) tag; for (NBTBase elem : nbtList) { if (elem instanceof NBTTagCompound) { - list.add(new LazyCompoundTag_1_15((NBTTagCompound) elem)); + list.add(new LazyCompoundTag_1_16_1((NBTTagCompound) elem)); } else { list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); } @@ -149,4 +149,4 @@ public class LazyCompoundTag_1_15 extends CompoundTag { 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_16_R1.java similarity index 91% rename from worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java rename to worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java index 49dfea72f..5cf63b4d3 100644 --- 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_16_R1.java @@ -26,11 +26,8 @@ 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.boydti.fawe.bukkit.adapter.mc1_16_1.BlockMaterial_1_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; import com.sk89q.jnbt.Tag; @@ -48,7 +45,6 @@ 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; @@ -81,16 +77,16 @@ 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; +public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { + private final Spigot_v1_16_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(); + public FAWE_Spigot_v1_16_R1() throws NoSuchFieldException, NoSuchMethodException { + this.parent = new Spigot_v1_16_R1(); } @Override @@ -99,11 +95,11 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I } private synchronized boolean init() { - if (ibdToStateOrdinal != null) return false; + if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) 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(); + BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); ibdToStateOrdinal[id] = state.getOrdinalChar(); } @@ -113,13 +109,15 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I @Override public BlockMaterial getMaterial(BlockType blockType) { Block block = getBlock(blockType); - return new BlockMaterial_1_15(block); + return new BlockMaterial_1_16_1(block); } @Override public BlockMaterial getMaterial(BlockState state) { IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new BlockMaterial_1_15(bs.getBlock(), bs); + return new BlockMaterial_1_16_1(bs.getBlock(), bs); + + } public Block getBlock(BlockType blockType) { @@ -166,14 +164,14 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I World nmsWorld = nmsChunk.getWorld(); BlockPosition blockPos = new BlockPosition(x, y, z); - IBlockData blockData = ((BlockMaterial_1_15) state.getMaterial()).getState(); + IBlockData blockData = ((BlockMaterial_1_16_1) 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(); + existing = ((BlockMaterial_1_16_1) BlockTypes.AIR.getDefaultState().getMaterial()).getState(); } else { existing = section.getType(x & 15, y & 15, z & 15); } @@ -245,7 +243,7 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I @Override public OptionalInt getInternalBlockStateId(BlockState state) { - BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial(); + BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial(); IBlockData mcState = material.getCraftBlockData().getState(); return OptionalInt.of(Block.REGISTRY_ID.getId(mcState)); } @@ -286,7 +284,7 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I } catch (NullPointerException e) { init(); return adaptToChar(ibd); - } catch (ArrayIndexOutOfBoundsException e1) { + } 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; } @@ -295,7 +293,7 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I @Override public > BlockData adapt(B state) { - BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial(); + BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial(); return material.getCraftBlockData(); } @@ -304,12 +302,12 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true); } - private MapChunkUtil_1_15 mapUtil = new MapChunkUtil_1_15(); + private MapChunkUtil_1_16_1 mapUtil = new MapChunkUtil_1_16_1(); @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()); + PlayerChunk map = BukkitAdapter_1_16_1.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ()); if (map != null && map.hasBeenLoaded()) { boolean flag = false; PlayerChunk.d players = map.players; @@ -362,8 +360,8 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I @Override public NBTBase fromNative(Tag foreign) { - if (foreign instanceof LazyCompoundTag_1_15) { - return ((LazyCompoundTag_1_15) foreign).get(); + if (foreign instanceof LazyCompoundTag_1_16_1) { + return ((LazyCompoundTag_1_16_1) foreign).get(); } return parent.fromNative(foreign); } @@ -399,7 +397,7 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I env, gen){ @Override - public boolean addEntityChunk(net.minecraft.server.v1_15_R1.Entity entity) { + public boolean addEntityChunk(Entity entity) { //Fixes #320; Prevent adding entities so we aren't attempting to spawn them asynchronously return false; } @@ -410,7 +408,7 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I Fawe.get().getQueueHandler().startSet(true); try { IQueueExtent extent = new SingleThreadQueueExtent(); - extent.init(null, (x, z) -> new BukkitGetBlocks_1_15(freshWorld, x, z) { + extent.init(null, (x, z) -> new BukkitGetBlocks_1_16_1(freshWorld, x, z) { @Override public Chunk ensureLoaded(World nmsWorld, int X, int Z) { Chunk cached = nmsWorld.getChunkIfLoaded(X, Z); @@ -446,7 +444,7 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I @Override public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new BukkitGetBlocks_1_15(world, chunkX, chunkZ); + return new BukkitGetBlocks_1_16_1(world, chunkX, chunkZ); } @Override 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); From aab10adb7977dc485b91b3f1e3c2335b2d8ca2be Mon Sep 17 00:00:00 2001 From: MattBDev <4009945+MattBDev@users.noreply.github.com> Date: Thu, 25 Jun 2020 20:57:06 -0400 Subject: [PATCH 04/14] Fixed all but one remaining API changes in 1.16.1 No testing has been performed yet. --- .../adapter/mc1_16_1/BukkitAdapter_1_16_1.java | 13 +++---------- .../adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java | 4 ++-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java index adab97743..74ae46eb2 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java @@ -47,8 +47,6 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { private final static MethodHandle methodGetVisibleChunk; - public final static MethodHandle methodSetLightNibbleArray; - private static final int CHUNKSECTION_BASE; private static final int CHUNKSECTION_SHIFT; @@ -79,10 +77,6 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { declaredGetVisibleChunk.setAccessible(true); methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk); - Method declaredSetLightNibbleArray = LightEngineStorage.class.getDeclaredMethod("a", long.class, NibbleArray.class); - declaredSetLightNibbleArray.setAccessible(true); - methodSetLightNibbleArray = MethodHandles.lookup().unreflect(declaredSetLightNibbleArray); - Field tmp = DataPaletteBlock.class.getDeclaredField("j"); ReflectionUtils.setAccessibleNonFinal(tmp); fieldLock = tmp; @@ -130,7 +124,7 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { } public static Chunk ensureLoaded(World nmsWorld, int X, int Z) { - Chunk nmsChunk = nmsWorld.getChunkIfLoaded(X, Z); + Chunk nmsChunk = nmsWorld.getChunkProvider().getChunkAt(X, Z, false); if (nmsChunk != null) { return nmsChunk; } @@ -183,7 +177,8 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { if (lighting) { ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(X, Z); - PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine()); + boolean trustEdges = false; //Added in 1.16.1 Not sure what it does. + PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges); playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> { p.playerConnection.sendPacket(packet); }); @@ -194,9 +189,7 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { } return null; }); - return; } - return; } /* diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 61940e1fc..110a47298 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -229,7 +229,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { entity.valid = false; } - public Chunk ensureLoaded(net.minecraft.server.v1_15_R1.World nmsWorld, int X, int Z) { + public Chunk ensureLoaded(net.minecraft.server.v1_16_R1.World nmsWorld, int X, int Z) { return BukkitAdapter_1_16_1.ensureLoaded(nmsWorld, X, Z); } @@ -428,7 +428,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { tag.remove(name); } - entity.f(tag); + entity.save(tag); } entity.setLocation(x, y, z, yaw, pitch); nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); From f2bc8d86fcd43c787c9864a5d11b93fd1701803e Mon Sep 17 00:00:00 2001 From: IronApollo Date: Fri, 26 Jun 2020 19:08:45 -0400 Subject: [PATCH 05/14] Work towards 1.16 compatibility This commit will allow the branch to build properly but the plugin will not function properly due to the lack of a proper adapter implementation. Proceeding will require the implementation of the SideEffects system from upstream (https://github.com/EngineHub/WorldEdit/commit/865c3a24d25156cbffbf44630506a08d2ff4755a#diff-8fd33296e427c87d0296ad7f3ccc050a). --- .../mc1_16_1/BukkitAdapter_1_16_1.java | 5 + .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 4 +- .../worldedit/bukkit/WorldEditPlugin.java | 2 + .../adapter/impl/FAWE_Spigot_v1_16_R1.java | 165 +++++++++--------- 4 files changed, 94 insertions(+), 82 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java index 74ae46eb2..7b1549d65 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java @@ -38,6 +38,8 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { public final static Field fieldPalette; public final static Field fieldSize; + public final static Field fieldBitsPerEntry; + public final static Field fieldFluidCount; public final static Field fieldTickingBlockCount; public final static Field fieldNonEmptyBlockCount; @@ -61,6 +63,9 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { fieldPalette = DataPaletteBlock.class.getDeclaredField("h"); fieldPalette.setAccessible(true); + fieldBitsPerEntry = DataBits.class.getDeclaredField("c"); + fieldBitsPerEntry.setAccessible(true); + fieldFluidCount = ChunkSection.class.getDeclaredField("e"); fieldFluidCount.setAccessible(true); fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount"); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 110a47298..b07589339 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -465,7 +465,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { tag.set("x", NBTTagInt.a(x)); tag.set("y", NBTTagInt.a(y)); tag.set("z", NBTTagInt.a(z)); - tileEntity.load(tag); + tileEntity.load(tileEntity.getBlock(), tag); } } } @@ -550,7 +550,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { final DataBits bits = (DataBits) BukkitAdapter_1_16_1.fieldBits.get(blocks); final DataPalette palette = (DataPalette) BukkitAdapter_1_16_1.fieldPalette.get(blocks); - final int bitsPerEntry = bits.c(); + final int bitsPerEntry = (int) BukkitAdapter_1_16_1.fieldBitsPerEntry.get(bits); final long[] blockStates = bits.a(); new BitArray(bitsPerEntry, 4096, blockStates).toRaw(data); 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 ae66a73af..3124b04f6 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 @@ -34,6 +34,7 @@ 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_R2; +import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_16_R1; import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; import com.sk89q.worldedit.event.platform.PlatformReadyEvent; @@ -371,6 +372,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter try { adapterLoader.addClass(FAWE_Spigot_v1_14_R4.class); adapterLoader.addClass(FAWE_Spigot_v1_15_R2.class); + adapterLoader.addClass(FAWE_Spigot_v1_16_R1.class); } catch (Throwable throwable) { throwable.printStackTrace(); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java index 5cf63b4d3..695aeca79 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java @@ -27,6 +27,9 @@ 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.nbt.LazyCompoundTag_1_16_1; import com.google.common.io.Files; import com.sk89q.jnbt.CompoundTag; @@ -49,18 +52,18 @@ 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 net.minecraft.server.v1_16_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.craftbukkit.v1_16_R1.CraftChunk; +import org.bukkit.craftbukkit.v1_16_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock; +import org.bukkit.craftbukkit.v1_16_R1.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.generator.ChunkGenerator; @@ -192,7 +195,7 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I tag.set("x", NBTTagInt.a(x)); tag.set("y", NBTTagInt.a(y)); tag.set("z", NBTTagInt.a(z)); - tileEntity.load(tag); // readTagIntoTileEntity - load data + tileEntity.load(tileEntity.getBlock(), tag); // readTagIntoTileEntity - load data } } } else { @@ -368,78 +371,80 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I @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; - } +// 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(); +// Convertable.ConversionSession originalDataManager = server.convertable; +//// Convertable.ConversionSession saveHandler = new Convertable.ConversionSession(world.getName(), world.); +// 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, originalDataManager, +// newWorldData, +// originalWorld.worldProvider.getDimensionManager(), +// originalWorld.getMethodProfiler(), +// server.worldLoadListenerFactory.create(11), +// env, +// gen){ +// @Override +// public boolean addEntityChunk(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_16_1(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; - 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(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_16_1(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; + return false; //TODO: rework or remove for 1.16 } @Override From 82adab77b4693289a95d934db79532065d2df679 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Sun, 8 Mar 2020 16:09:36 +1000 Subject: [PATCH 06/14] Additional work towards 1.16 compatibility - Very basic implementation of the SideEffects system. Will definitely need fine tuning for it to be functional, but is not considered a priority in my opinion. - Minor changes to the World interface and World implementations related to the SideEffects system. Shouldn't be the cause of any new bugs but be on the lookout. - Included debug in BukkitImplLoader.java to assist contributors in understanding what needs to be implemented for the adapter to load properly. Still very WIP but we're a few steps closer. So far, this is coming along better than I anticipated. Hopefully we can keep the momentum. --- config/checkstyle/checkstyle.xml | 2 +- .../bukkit/BukkitServerInterface.java | 16 +++- .../sk89q/worldedit/bukkit/BukkitWorld.java | 32 ++++--- .../bukkit/adapter/BukkitImplAdapter.java | 20 +++- .../bukkit/adapter/BukkitImplLoader.java | 13 ++- .../adapter/IDelegateBukkitImplAdapter.java | 8 +- .../adapter/impl/FAWE_Spigot_v1_14_R4.java | 23 ++++- .../adapter/impl/FAWE_Spigot_v1_15_R2.java | 25 +++-- .../adapter/impl/FAWE_Spigot_v1_16_R1.java | 25 +++-- .../com/sk89q/worldedit/cli/CLIPlatform.java | 8 ++ .../cli/schematic/ClipboardWorld.java | 11 ++- .../com/boydti/fawe/jnbt/anvil/MCAWorld.java | 14 +++ .../cfi/HeightMapMCAGenerator.java | 22 +++-- .../boydti/fawe/wrappers/WorldWrapper.java | 16 +++- .../java/com/sk89q/worldedit/EditSession.java | 15 +++ .../com/sk89q/worldedit/LocalSession.java | 31 +++++- .../worldedit/command/GeneralCommands.java | 69 +++++++++++--- .../command/argument/EnumConverter.java | 7 ++ .../command/argument/SideEffectConverter.java | 75 +++++++++++++++ .../extension/platform/Platform.java | 4 + .../platform/PlatformCommandManager.java | 2 + .../extension/platform/PlatformManager.java | 6 ++ .../worldedit/extent/buffer/ExtentBuffer.java | 5 +- .../extent/reorder/ChunkBatchingExtent.java | 1 - ...tModeExtent.java => SideEffectExtent.java} | 86 ++++++----------- .../com/sk89q/worldedit/util/SideEffect.java | 68 ++++++++++++++ .../sk89q/worldedit/util/SideEffectSet.java | 94 +++++++++++++++++++ .../formatting/component/SideEffectBox.java | 88 +++++++++++++++++ .../sk89q/worldedit/world/AbstractWorld.java | 3 +- .../com/sk89q/worldedit/world/NullWorld.java | 11 ++- .../java/com/sk89q/worldedit/world/World.java | 41 +++++++- .../src/main/resources/lang/strings.json | 20 ++++ worldedit-fabric/build.gradle.kts | 4 - .../worldedit/fabric/FabricPlatform.java | 15 ++- .../sk89q/worldedit/fabric/FabricWorld.java | 71 +++++++++++--- worldedit-forge/build.gradle.kts | 7 +- .../sk89q/worldedit/forge/ForgePlatform.java | 13 +++ .../com/sk89q/worldedit/forge/ForgeWorld.java | 73 ++++++++++++-- .../worldedit/sponge/SpongePlatform.java | 9 ++ 39 files changed, 877 insertions(+), 176 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SideEffectConverter.java rename worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/{FastModeExtent.java => SideEffectExtent.java} (63%) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffectSet.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SideEffectBox.java diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index ab1c6d499..8dbf07f8f 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -68,6 +68,6 @@ - + diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index d948d0e0a..99a4b183b 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.bukkit; +import com.google.common.collect.Sets; import com.sk89q.bukkit.util.CommandInfo; import com.sk89q.bukkit.util.CommandRegistration; import com.sk89q.worldedit.LocalConfiguration; @@ -30,6 +31,7 @@ import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.MultiUserPlatform; import com.sk89q.worldedit.extension.platform.Preference; import com.sk89q.worldedit.extension.platform.Watchdog; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.registry.Registries; @@ -44,8 +46,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; import java.util.List; -import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -218,6 +220,18 @@ public class BukkitServerInterface implements MultiUserPlatform { return capabilities; } + private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( + SideEffect.NEIGHBORS + ); + + @Override + public Set getSupportedSideEffects() { + if (plugin.getBukkitImplAdapter() != null) { + return plugin.getBukkitImplAdapter().getSupportedSideEffects(); + } + return SUPPORTED_SIDE_EFFECTS; + } + public void unregisterCommands() { dynamicCommands.unregisterCommands(); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 2818a8434..f11fc13d3 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -25,6 +25,7 @@ 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.Sets; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; @@ -38,6 +39,8 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BiomeType; @@ -48,12 +51,7 @@ import com.sk89q.worldedit.world.weather.WeatherTypes; import io.papermc.lib.PaperLib; import java.lang.ref.WeakReference; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import javax.annotation.Nullable; import org.bukkit.Effect; import org.bukkit.TreeType; @@ -466,11 +464,11 @@ public class BukkitWorld extends AbstractWorld { } @Override - public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException { + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); if (adapter != null) { try { - return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight); + return adapter.setBlock(BukkitAdapter.adapt(getWorld(), 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()); @@ -478,12 +476,12 @@ public class BukkitWorld extends AbstractWorld { } e.printStackTrace(); Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); - bukkitBlock.setBlockData(BukkitAdapter.adapt(block), notifyAndLight); + 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), false); + bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny()); return true; } } @@ -499,14 +497,20 @@ public class BukkitWorld extends AbstractWorld { } @Override - public boolean notifyAndLightBlock(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType) throws WorldEditException { + public Set applySideEffects(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); if (adapter != null) { - adapter.notifyAndLightBlock(BukkitAdapter.adapt(getWorld(), position), previousType); - return true; + adapter.applySideEffects(BukkitAdapter.adapt(getWorld(), position), previousType, sideEffectSet); + return Sets.intersection( + adapter.getSupportedSideEffects(), + sideEffectSet.getSideEffectsToApply() + ); } - return false; + return Sets.intersection( + WorldEditPlugin.getInstance().getInternalPlatform().getSupportedSideEffects(), + sideEffectSet.getSideEffectsToApply() + ); } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index 591626f0f..416b4b621 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -34,6 +34,8 @@ 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; @@ -43,6 +45,7 @@ import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.registry.BlockMaterial; import java.util.Map; import java.util.OptionalInt; +import java.util.Set; import javax.annotation.Nullable; import org.bukkit.Location; import org.bukkit.World; @@ -99,19 +102,19 @@ public interface BukkitImplAdapter extends IBukkitAdapter { * * @param location the location * @param state the block - * @param notifyAndLight notify and light if set + * @param sideEffectSet side effects to apply * @return true if a block was likely changed */ - > boolean setBlock(Location location, B state, boolean notifyAndLight); + boolean setBlock(Location location, BlockStateHolder state, SideEffectSet sideEffectSet); /** - * Notifies the simulation that the block at the given location has - * been changed and it must be re-lighted (and issue other events). + * 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 notifyAndLightBlock(Location position, BlockState previousType); + void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet); /** * Get the state for the given entity. @@ -186,6 +189,13 @@ public interface BukkitImplAdapter extends IBukkitAdapter { */ BaseItemStack adapt(ItemStack itemStack); + /** + * Get the {@link SideEffect}s that this adapter supports. + * + * @return The side effects that are supported + */ + Set getSupportedSideEffects(); + default OptionalInt getInternalBlockStateId(BlockData data) { // return OptionalInt.empty(); return getInternalBlockStateId(BukkitAdapter.adapt(data)); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java index 172aaa2e7..00807b4b5 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java @@ -155,11 +155,20 @@ public class BukkitImplLoader { */ public BukkitImplAdapter loadAdapter() throws AdapterLoadException { for (String className : adapterCandidates) { + System.out.println("Candidate: " + className); try { Class cls = Class.forName(className); - if (cls.isSynthetic()) continue; + if (cls.isSynthetic()){ + System.out.println(className + " is synthetic, continuing"); + continue; + }else{ + System.out.println(className + " is not synthetic"); + } if (BukkitImplAdapter.class.isAssignableFrom(cls)) { + System.out.println(className + " is assignable from BukkitImplAdapter, returning"); return (BukkitImplAdapter) cls.newInstance(); + }else{ + System.out.println(className + " is NOT assignable from BukkitImplAdapter, returning"); } } catch (ClassNotFoundException e) { log.warn("Failed to load the Bukkit adapter class '" + className + @@ -170,6 +179,8 @@ public class BukkitImplLoader { } catch (Throwable e) { if (className.equals(customCandidate)) { log.warn("Failed to load the Bukkit adapter class '" + className + "'", e); + }else{ + log.warn(className + " is not custom candidate.", e); } } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java index 6656c032f..9f5499dcd 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java @@ -12,6 +12,7 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; +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; @@ -66,12 +67,7 @@ public interface IDelegateBukkitImplAdapter extends BukkitImplAdapter { } default > boolean setBlock(Location location, B state, boolean notifyAndLight) { - return getParent().setBlock(location, state, notifyAndLight); - } - - @Override - default void notifyAndLightBlock(Location position, BlockState previousType) { - getParent().notifyAndLightBlock(position, previousType); + return getParent().setBlock(location, state, SideEffectSet.none()); } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java index b5094f0db..21bcf1718 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java @@ -45,6 +45,8 @@ 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.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; @@ -71,6 +73,7 @@ import java.io.File; import java.io.IOException; import java.util.Map; import java.util.OptionalInt; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.function.Supplier; @@ -148,6 +151,21 @@ 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 getSupportedSideEffects() { + return SideEffectSet.defaults().getSideEffectsToApply(); + } + @Override public > boolean setBlock(Location location, B state, boolean notifyAndLight) { return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight); @@ -292,11 +310,6 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I 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_14 mapUtil = new MapChunkUtil_1_14(); @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java index 3ee354bd6..ffbe28f1d 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java @@ -47,6 +47,8 @@ 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.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; @@ -73,6 +75,7 @@ import java.io.File; import java.io.IOException; import java.util.Map; import java.util.OptionalInt; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -157,12 +160,27 @@ 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 getSupportedSideEffects() { + return SideEffectSet.defaults().getSideEffectsToApply(); + } + @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) { + 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(); World nmsWorld = nmsChunk.getWorld(); @@ -301,11 +319,6 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I 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_2 mapUtil = new MapChunkUtil_1_15_2(); @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java index 695aeca79..a97372095 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java @@ -47,6 +47,8 @@ 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.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.*; @@ -72,6 +74,7 @@ import java.io.File; import java.io.IOException; import java.util.Map; import java.util.OptionalInt; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -156,12 +159,27 @@ 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 getSupportedSideEffects() { + return SideEffectSet.defaults().getSideEffectsToApply(); + } + @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) { + 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(); World nmsWorld = nmsChunk.getWorld(); @@ -300,11 +318,6 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I 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_16_1 mapUtil = new MapChunkUtil_1_16_1(); @Override diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java index c2e9eaba9..7dcfa2daf 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java @@ -19,10 +19,12 @@ package com.sk89q.worldedit.cli; +import com.google.common.collect.ImmutableSet; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.AbstractPlatform; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Preference; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.entity.EntityTypes; @@ -33,6 +35,7 @@ import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Timer; import java.util.TimerTask; @@ -153,6 +156,11 @@ class CLIPlatform extends AbstractPlatform { return capabilities; } + @Override + public Set getSupportedSideEffects() { + return ImmutableSet.of(); + } + public void addWorld(World world) { worlds.add(world); } diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java index 69d1cb1c9..6be24d545 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.cli.schematic; +import com.google.common.collect.ImmutableSet; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.WorldEditException; @@ -34,6 +35,8 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BiomeType; @@ -46,6 +49,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.Locale; +import java.util.Set; import javax.annotation.Nullable; @@ -74,15 +78,14 @@ public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld } @Override - public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) - throws WorldEditException { + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { dirty = true; return clipboard.setBlock(position, block); } @Override - public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException { - return false; + public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException { + return ImmutableSet.of(); } @Override diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAWorld.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAWorld.java index a13cd75b6..6046c5928 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAWorld.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAWorld.java @@ -13,12 +13,16 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; import java.io.File; +import java.util.Set; import static com.google.common.base.Preconditions.checkArgument; @@ -35,6 +39,11 @@ public class MCAWorld extends AbstractWorld { return path.getName(); } + @Override + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { + return false; + } + @Override public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException { @@ -46,6 +55,11 @@ public class MCAWorld extends AbstractWorld { return false; } + @Override + public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException { + return SideEffectSet.none().getSideEffectsToApply(); + } + @Override public boolean clearContainerBlockContents(BlockVector3 position) { return false; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java index 1e90346c4..b50bce169 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java @@ -29,10 +29,7 @@ import com.boydti.fawe.util.TextureUtil; import com.boydti.fawe.util.image.Drawable; import com.boydti.fawe.util.image.ImageViewer; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.*; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.clipboard.Clipboard; @@ -48,9 +45,7 @@ import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.ClipboardHolder; -import com.sk89q.worldedit.util.Identifiable; -import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.TreeGenerator; +import com.sk89q.worldedit.util.*; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; @@ -68,6 +63,7 @@ import java.lang.reflect.Field; import java.nio.file.Path; import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; import java.util.function.Supplier; @@ -750,12 +746,24 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr return BlockVector3.at(getWidth() - 1, 255, getLength() - 1); } + @Override + public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) + throws WorldEditException{ + return SideEffectSet.none().getSideEffectsToApply(); + } + @Override public > boolean setBlock(BlockVector3 position, B block) throws WorldEditException { return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block); } + @Override + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) + throws WorldEditException { + return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block); + } + private boolean setBlock(int x, int y, int z, char combined) { int index = z * getWidth() + x; if (index < 0 || index >= getArea()) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java b/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java index 771262350..812b440dc 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java @@ -24,9 +24,7 @@ import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.TreeGenerator; +import com.sk89q.worldedit.util.*; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; @@ -38,6 +36,7 @@ import com.sk89q.worldedit.world.weather.WeatherType; import javax.annotation.Nullable; import java.util.List; +import java.util.Set; public class WorldWrapper extends AbstractWorld { @@ -88,6 +87,12 @@ public class WorldWrapper extends AbstractWorld { return parent.useItem(position, item, face); } + @Override + public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) + throws WorldEditException{ + return parent.applySideEffects(position, previousType, sideEffectSet); + } + @Override public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException { return parent.setBlock(position, block, notifyAndLight); @@ -99,6 +104,11 @@ public class WorldWrapper extends AbstractWorld { return parent.setBlock(x, y, z, block); } + @Override + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { + return parent.setBlock(position, block, sideEffects); + } + @Override public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException { return parent.setTile(x, y, z, tile); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index efc4eaa51..e3e38757c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -117,6 +117,7 @@ import com.sk89q.worldedit.regions.shape.RegionShape; import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; @@ -572,6 +573,20 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { disableHistory(enabled); } + /** + * Set which block updates should occur. + * + * @param sideEffectSet side effects to enable + */ + public void setSideEffectApplier(SideEffectSet sideEffectSet) { + //Do nothing; TODO: SideEffects currently not fully implemented in FAWE. + } + + public SideEffectSet getSideEffectApplier() { + //Do nothing; TODO: SideEffects currently not fully implemented in FAWE. + return SideEffectSet.defaults(); + } + /** * Disable history (or re-enable) * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index cc22a2972..eeb297713 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -72,6 +72,7 @@ import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Identifiable; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; @@ -145,7 +146,7 @@ public class LocalSession implements TextureHolder { private transient Snapshot snapshotExperimental; private transient boolean hasCUISupport = false; private transient int cuiVersion = -1; - private transient boolean fastMode = false; + private transient SideEffectSet sideEffectSet = SideEffectSet.defaults(); private transient Mask mask; private transient Mask sourceMask; private transient TextureUtil texture; @@ -1494,7 +1495,7 @@ public class LocalSession implements TextureHolder { builder.blockBag(blockBag); } builder.command(command); - builder.fastmode(fastMode); + builder.fastmode(!this.sideEffectSet.doesApplyAny()); editSession = builder.build(); @@ -1513,7 +1514,7 @@ public class LocalSession implements TextureHolder { } private void prepareEditingExtents(EditSession editSession, Actor actor) { - editSession.setFastMode(fastMode); + editSession.setSideEffectApplier(sideEffectSet); editSession.setReorderMode(reorderMode); if (editSession.getSurvivalExtent() != null) { editSession.getSurvivalExtent().setStripNbt(!actor.hasPermission("worldedit.setnbt")); @@ -1521,13 +1522,32 @@ public class LocalSession implements TextureHolder { editSession.setTickingWatchdog(tickingWatchdog); } + /** + * Gets the side effect applier of this session. + * + * @return the side effect applier + */ + public SideEffectSet getSideEffectSet() { + return this.sideEffectSet; + } + + /** + * Sets the side effect applier for this session + * + * @param sideEffectSet the side effect applier + */ + public void setSideEffectSet(SideEffectSet sideEffectSet) { + this.sideEffectSet = sideEffectSet; + } + /** * Checks if the session has fast mode enabled. * * @return true if fast mode is enabled */ + @Deprecated public boolean hasFastMode() { - return fastMode; + return !this.sideEffectSet.doesApplyAny(); } /** @@ -1535,8 +1555,9 @@ public class LocalSession implements TextureHolder { * * @param fastMode true if fast mode is enabled */ + @Deprecated public void setFastMode(boolean fastMode) { - this.fastMode = fastMode; + this.sideEffectSet = fastMode ? SideEffectSet.none() : SideEffectSet.defaults(); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 91e6c76b4..923add56e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -49,10 +49,13 @@ import java.util.ArrayList; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.formatting.component.PaginationBox; +import com.sk89q.worldedit.util.formatting.component.SideEffectBox; +import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.format.TextColor; -import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.item.ItemType; import java.io.FileNotFoundException; @@ -142,24 +145,62 @@ public class GeneralCommands { @Command( name = "/fast", - desc = "Toggle fast mode" + desc = "Toggle fast mode side effects" ) @CommandPermissions("worldedit.fast") public void fast(Actor actor, LocalSession session, - @Arg(desc = "The new fast mode state", def = "") - Boolean fastMode) { - boolean hasFastMode = session.hasFastMode(); - if (fastMode != null && fastMode == hasFastMode) { - actor.printError(TranslatableComponent.of(fastMode ? "worldedit.fast.enabled.already" : "worldedit.fast.disabled.already")); - return; + @Arg(desc = "The side effect", def = "") + SideEffect sideEffect, + @Arg(desc = "The new side effect state", def = "") + SideEffect.State newState, + @Switch(name = 'h', desc = "Show the info box") + boolean showInfoBox) throws WorldEditException { + if (sideEffect != null) { + SideEffect.State currentState = session.getSideEffectSet().getState(sideEffect); + if (newState != null && newState == currentState) { + if (!showInfoBox) { + actor.printError(TranslatableComponent.of( + "worldedit.fast.sideeffect.already-set", + TranslatableComponent.of(sideEffect.getDisplayName()), + TranslatableComponent.of(newState.getDisplayName()) + )); + } + return; + } + + if (newState != null) { + session.setSideEffectSet(session.getSideEffectSet().with(sideEffect, newState)); + if (!showInfoBox) { + actor.printInfo(TranslatableComponent.of( + "worldedit.fast.sideeffect.set", + TranslatableComponent.of(sideEffect.getDisplayName()), + TranslatableComponent.of(newState.getDisplayName()) + )); + } + } else { + actor.printInfo(TranslatableComponent.of( + "worldedit.fast.sideeffect.get", + TranslatableComponent.of(sideEffect.getDisplayName()), + TranslatableComponent.of(currentState.getDisplayName()) + )); + } + } else if (newState != null) { + SideEffectSet applier = session.getSideEffectSet(); + for (SideEffect sideEffectEntry : SideEffect.values()) { + applier = applier.with(sideEffectEntry, newState); + } + session.setSideEffectSet(applier); + if (!showInfoBox) { + actor.printInfo(TranslatableComponent.of( + "worldedit.fast.sideeffect.set-all", + TranslatableComponent.of(newState.getDisplayName()) + )); + } } - if (hasFastMode) { - session.setFastMode(false); - actor.printInfo(TranslatableComponent.of("worldedit.fast.disabled")); - } else { - session.setFastMode(true); - actor.printInfo(TranslatableComponent.of("worldedit.fast.enabled")); + if (sideEffect == null || showInfoBox) { + SideEffectBox sideEffectBox = new SideEffectBox(session.getSideEffectSet()); + actor.print(sideEffectBox.create(1)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java index 7dc2192c7..f0f8e8ddd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java @@ -23,6 +23,7 @@ import com.boydti.fawe.object.brush.scroll.Scroll; import com.google.common.collect.ImmutableSet; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.command.util.HookMode; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.TreeGenerator; import org.enginehub.piston.CommandManager; import org.enginehub.piston.converter.ArgumentConverter; @@ -30,6 +31,7 @@ import org.enginehub.piston.converter.MultiKeyConverter; import org.enginehub.piston.inject.Key; import javax.annotation.Nullable; + import java.util.EnumSet; import java.util.Locale; import java.util.Set; @@ -48,6 +50,11 @@ public final class EnumConverter { full(EditSession.ReorderMode.class, r -> ImmutableSet.of(r.getDisplayName()), null)); + commandManager.registerConverter(Key.of(SideEffect.State.class), + MultiKeyConverter.from( + EnumSet.of(SideEffect.State.OFF, SideEffect.State.ON), + r -> ImmutableSet.of(r.name().toLowerCase(Locale.US)), + null)); commandManager.registerConverter(Key.of(HookMode.class), basic(HookMode.class)); commandManager.registerConverter(Key.of(Scroll.Action.class), diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SideEffectConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SideEffectConverter.java new file mode 100644 index 000000000..fd0ab684f --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SideEffectConverter.java @@ -0,0 +1,75 @@ +/* + * 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.command.argument; + +import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix; + +import com.google.common.collect.ImmutableList; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.command.util.EntityRemover; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import org.enginehub.piston.CommandManager; +import org.enginehub.piston.converter.ArgumentConverter; +import org.enginehub.piston.converter.ConversionResult; +import org.enginehub.piston.converter.FailedConversion; +import org.enginehub.piston.converter.SuccessfulConversion; +import org.enginehub.piston.inject.InjectedValueAccess; +import org.enginehub.piston.inject.Key; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +public class SideEffectConverter implements ArgumentConverter { + + public static void register(CommandManager commandManager) { + commandManager.registerConverter(Key.of(SideEffect.class), new SideEffectConverter()); + } + + private final TextComponent choices = TextComponent.of("any side effect"); + + private SideEffectConverter() { + } + + private Collection getSideEffects() { + return WorldEdit.getInstance().getPlatformManager().getSupportedSideEffects(); + } + + @Override + public Component describeAcceptableArguments() { + return choices; + } + + @Override + public List getSuggestions(String input, InjectedValueAccess context) { + return limitByPrefix(getSideEffects().stream().map(sideEffect -> sideEffect.name().toLowerCase(Locale.US)), input); + } + + @Override + public ConversionResult convert(String argument, InjectedValueAccess context) { + try { + return SuccessfulConversion.fromSingle(SideEffect.valueOf(argument.toUpperCase(Locale.US))); + } catch (Exception e) { + return FailedConversion.from(e); + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java index d82ed52c1..1f92543aa 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java @@ -21,14 +21,17 @@ package com.sk89q.worldedit.extension.platform; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.registry.Registries; import org.enginehub.piston.CommandManager; import javax.annotation.Nullable; + import java.util.List; import java.util.Map; +import java.util.Set; /** * Represents a platform that WorldEdit has been implemented for. @@ -174,4 +177,5 @@ public interface Platform { */ Map getCapabilities(); + Set getSupportedSideEffects(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java index 305c7f540..2b533f170 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java @@ -94,6 +94,7 @@ import com.sk89q.worldedit.command.argument.ExpressionConverter; import com.sk89q.worldedit.command.argument.FactoryConverter; import com.sk89q.worldedit.command.argument.RegionFactoryConverter; import com.sk89q.worldedit.command.argument.RegistryConverter; +import com.sk89q.worldedit.command.argument.SideEffectConverter; import com.sk89q.worldedit.command.argument.VectorConverter; import com.sk89q.worldedit.command.argument.WorldConverter; import com.sk89q.worldedit.command.argument.ZonedDateTimeConverter; @@ -255,6 +256,7 @@ public final class PlatformCommandManager { RegionFactoryConverter.register(commandManager); WorldConverter.register(commandManager); ExpressionConverter.register(commandManager); + SideEffectConverter.register(commandManager); registerBindings(new ConsumeBindings(worldEdit, this)); registerBindings(new PrimitiveBindings(worldEdit)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java index 9422a9abf..6ce088ac3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java @@ -48,9 +48,11 @@ import com.sk89q.worldedit.event.platform.PlayerInputEvent; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.session.request.Request; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.eventbus.Subscribe; import com.sk89q.worldedit.world.World; import java.util.ArrayList; +import java.util.Collection; import java.util.EnumMap; import java.util.Iterator; import java.util.List; @@ -304,6 +306,10 @@ public class PlatformManager { return queryCapability(Capability.CONFIGURATION).getConfiguration(); } + public Collection getSupportedSideEffects() { + return queryCapability(Capability.WORLD_EDITING).getSupportedSideEffects(); + } + @Subscribe public void handlePlatformReady(PlatformReadyEvent event) { choosePreferred(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java index 4ae9a3ad5..699b73d43 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java @@ -21,17 +21,16 @@ package com.sk89q.worldedit.extent.buffer; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.collect.Maps; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.AbstractBufferingExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Masks; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.collection.BlockMap; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; import java.util.Map; -import java.util.Optional; /** * Buffers changes to an {@link Extent} and allows retrieval of the changed blocks, @@ -39,7 +38,7 @@ import java.util.Optional; */ public class ExtentBuffer extends AbstractBufferingExtent { - private final Map buffer = Maps.newHashMap(); + private final Map buffer = BlockMap.create(); private final Mask mask; /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java index 60cc68cf7..8b34e4778 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.extent.reorder; -import com.google.common.collect.ImmutableSortedSet; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.AbstractBufferingExtent; import com.sk89q.worldedit.extent.Extent; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java similarity index 63% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java index a29eff306..1a6b78505 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java @@ -27,67 +27,38 @@ import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.RunContext; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.util.collection.BlockMap; import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockTypes; import java.util.HashSet; import java.util.Iterator; -import java.util.List; +import java.util.Map; import java.util.Set; /** - * Implements "fast mode" which may skip physics, lighting, etc. + * An extent that sets blocks in the world, with a {@link SideEffectSet}. */ -public class FastModeExtent extends AbstractDelegateExtent { +public class SideEffectExtent extends AbstractDelegateExtent { private final World world; - private final Set positions = new HashSet<>(); + private final Map positions = BlockMap.create(); private final Set dirtyChunks = new HashSet<>(); - private boolean enabled = true; + private SideEffectSet sideEffectSet = SideEffectSet.defaults(); private boolean postEditSimulation; - /** - * Create a new instance with fast mode enabled. - * - * @param world the world - */ - public FastModeExtent(World world) { - this(world, true); - } - /** * Create a new instance. * * @param world the world - * @param enabled true to enable fast mode */ - public FastModeExtent(World world, boolean enabled) { + public SideEffectExtent(World world) { super(world); checkNotNull(world); this.world = world; - this.enabled = enabled; - if (enabled) { - this.postEditSimulation = true; - } - } - - /** - * Return whether fast mode is enabled. - * - * @return true if fast mode is enabled - */ - public boolean isEnabled() { - return enabled; - } - - /** - * Set fast mode enable status. - * - * @param enabled true to enable fast mode - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; } public boolean isPostEditSimulationEnabled() { @@ -98,26 +69,28 @@ public class FastModeExtent extends AbstractDelegateExtent { this.postEditSimulation = enabled; } + public SideEffectSet getSideEffectSet() { + return this.sideEffectSet; + } + + public void setSideEffectSet(SideEffectSet sideEffectSet) { + this.sideEffectSet = sideEffectSet; + } + @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { - if (enabled || postEditSimulation) { + if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.DELAYED) { dirtyChunks.add(BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4)); - - if (world.setBlock(location, block, false)) { - if (!enabled && postEditSimulation) { - positions.add(location); - } - return true; - } - - return false; - } else { - return world.setBlock(location, block, true); } + if (postEditSimulation) { + positions.put(location, world.getBlock(location)); + } + + return world.setBlock(location, block, postEditSimulation ? SideEffectSet.none() : sideEffectSet); } public boolean commitRequired() { - return enabled || postEditSimulation; + return postEditSimulation || !dirtyChunks.isEmpty(); } @Override @@ -132,11 +105,11 @@ public class FastModeExtent extends AbstractDelegateExtent { world.fixAfterFastMode(dirtyChunks); } - if (!enabled && postEditSimulation) { - Iterator positionIterator = positions.iterator(); + if (postEditSimulation) { + Iterator> positionIterator = positions.entrySet().iterator(); while (run.shouldContinue() && positionIterator.hasNext()) { - BlockVector3 position = positionIterator.next(); - world.notifyAndLightBlock(position, BlockTypes.AIR.getDefaultState()); + Map.Entry position = positionIterator.next(); + world.applySideEffects(position.getKey(), position.getValue(), sideEffectSet); positionIterator.remove(); } @@ -151,5 +124,4 @@ public class FastModeExtent extends AbstractDelegateExtent { } }; } - } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java new file mode 100644 index 000000000..c4c814fcb --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java @@ -0,0 +1,68 @@ +/* + * 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.util; + +import java.util.Locale; + +public enum SideEffect { + LIGHTING(State.ON), + NEIGHBORS(State.ON), + CONNECTIONS(State.ON), + ENTITY_AI(State.OFF), + PLUGIN_EVENTS(State.OFF); + + private final String displayName; + private final String description; + private final State defaultValue; + + SideEffect(State defaultValue) { + this.displayName = "worldedit.sideeffect." + this.name().toLowerCase(Locale.US); + this.description = "worldedit.sideeffect." + this.name().toLowerCase(Locale.US) + ".description"; + this.defaultValue = defaultValue; + } + + public String getDisplayName() { + return this.displayName; + } + + public String getDescription() { + return this.description; + } + + public State getDefaultValue() { + return this.defaultValue; + } + + public enum State { + OFF, + ON, + DELAYED; + + private final String displayName; + + State() { + this.displayName = "worldedit.sideeffect.state." + this.name().toLowerCase(Locale.US); + } + + public String getDisplayName() { + return this.displayName; + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffectSet.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffectSet.java new file mode 100644 index 000000000..d88b37097 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffectSet.java @@ -0,0 +1,94 @@ +/* + * 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.util; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class SideEffectSet { + private static final SideEffectSet DEFAULT = new SideEffectSet( + Arrays.stream(SideEffect.values()).collect(Collectors.toMap(Function.identity(), SideEffect::getDefaultValue)) + ); + private static final SideEffectSet NONE = new SideEffectSet(); + + private final Map sideEffects; + private final Set appliedSideEffects; + private final boolean appliesAny; + + private SideEffectSet() { + this(ImmutableMap.of()); + } + + public SideEffectSet(Map sideEffects) { + this.sideEffects = Maps.immutableEnumMap(sideEffects); + + appliedSideEffects = sideEffects.entrySet() + .stream() + .filter(entry -> entry.getValue() != SideEffect.State.OFF) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + appliesAny = !appliedSideEffects.isEmpty(); + } + + public SideEffectSet with(SideEffect sideEffect, SideEffect.State state) { + Map entries = this.sideEffects.isEmpty() ? Maps.newEnumMap(SideEffect.class) : new EnumMap<>(this.sideEffects); + entries.put(sideEffect, state); + return new SideEffectSet(entries); + } + + public boolean doesApplyAny() { + return this.appliesAny; + } + + public SideEffect.State getState(SideEffect effect) { + return sideEffects.getOrDefault(effect, effect.getDefaultValue()); + } + + /** + * Gets whether this side effect is not off. + * + * This returns whether it is either delayed or on. + * + * @param effect The side effect + * @return Whether it should apply + */ + public boolean shouldApply(SideEffect effect) { + return getState(effect) != SideEffect.State.OFF; + } + + public Set getSideEffectsToApply() { + return this.appliedSideEffects; + } + + public static SideEffectSet defaults() { + return DEFAULT; + } + + public static SideEffectSet none() { + return NONE; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SideEffectBox.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SideEffectBox.java new file mode 100644 index 000000000..14403313e --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/SideEffectBox.java @@ -0,0 +1,88 @@ +/* + * 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.util.formatting.component; + +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; +import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; +import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; +import com.sk89q.worldedit.util.formatting.text.format.TextColor; + +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; + +public class SideEffectBox extends PaginationBox { + + private static List sideEffects; + + private SideEffectSet sideEffectSet; + + private static List getSideEffects() { + if (sideEffects == null) { + sideEffects = WorldEdit.getInstance().getPlatformManager().getSupportedSideEffects() + .stream() + .sorted(Comparator.comparing(Enum::name)) + .collect(Collectors.toList()); + } + + return sideEffects; + } + + public SideEffectBox(SideEffectSet sideEffectSet) { + super("Side Effects"); + + this.sideEffectSet = sideEffectSet; + } + + private static final SideEffect.State[] SHOWN_VALUES = {SideEffect.State.OFF, SideEffect.State.ON}; + + @Override + public Component getComponent(int number) { + SideEffect effect = getSideEffects().get(number); + SideEffect.State state = this.sideEffectSet.getState(effect); + + TextComponent.Builder builder = TextComponent.builder(); + builder = builder.append(TranslatableComponent.of(effect.getDisplayName(), TextColor.YELLOW) + .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of(effect.getDescription())))); + for (SideEffect.State uiState : SHOWN_VALUES) { + builder = builder.append(TextComponent.space()); + builder = builder.append(TranslatableComponent.of(uiState.getDisplayName(), uiState == state ? TextColor.WHITE : TextColor.GRAY) + .clickEvent(ClickEvent.runCommand("//fast -h " + effect.name().toLowerCase(Locale.US) + " " + uiState.name().toLowerCase(Locale.US))) + .hoverEvent(HoverEvent.showText(uiState == state + ? TranslatableComponent.of("worldedit.sideeffect.box.current") + : TranslatableComponent.of("worldedit.sideeffect.box.change-to", TranslatableComponent.of(uiState.getDisplayName())) + )) + ); + } + + return builder.build(); + } + + @Override + public int getComponentsSize() { + return getSideEffects().size(); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java index c333f1269..34e7179b0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java @@ -32,6 +32,7 @@ import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.block.BlockType; @@ -57,7 +58,7 @@ public abstract class AbstractWorld implements World { @Override public final > boolean setBlock(BlockVector3 pt, B block) throws WorldEditException { - return setBlock(pt, block, true); + return setBlock(pt, block, SideEffectSet.defaults()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java index f37665232..f3d6dd18a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -23,6 +23,7 @@ import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.implementation.packet.ChunkPacket; import com.boydti.fawe.beta.implementation.blocks.NullChunkGet; import com.sk89q.jnbt.CompoundTag; +import com.google.common.collect.ImmutableSet; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.WorldEditException; @@ -35,6 +36,8 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; @@ -48,6 +51,7 @@ import com.sk89q.worldedit.world.weather.WeatherTypes; import javax.annotation.Nullable; import java.util.Collections; import java.util.List; +import java.util.Set; /** * A null implementation of {@link World} that drops all changes and @@ -71,13 +75,14 @@ public class NullWorld extends AbstractWorld { } @Override - public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException { + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { return false; } @Override - public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException { - return false; + public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) + throws WorldEditException { + return ImmutableSet.of(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 5c6ba7df3..9388dcace 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -37,15 +37,19 @@ import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.TreeGenerator; 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.weather.WeatherType; -import javax.annotation.Nullable; import java.nio.file.Path; import java.util.Locale; +import java.util.Set; + +import javax.annotation.Nullable; /** * Represents a world (dimension). @@ -112,10 +116,28 @@ public interface World extends Extent, Keyed, IChunkCache { * @param notifyAndLight true to to notify and light * @return true if the block was successfully set (return value may not be accurate) */ + @Deprecated default > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException { - return setBlock(position, block); + return setBlock(position, block, notifyAndLight ? SideEffectSet.defaults() : SideEffectSet.none()); } + /** + * Similar to {@link Extent#setBlock(BlockVector3, BlockStateHolder)} but a + * {@code sideEffects} parameter indicates which side effects should be applied + * to the block. This includes block updates, lighting, and others. See {@link SideEffect} + * for a full list. + * + *

Not all implementations support all side effects. Use + * {@link Platform#getSupportedSideEffects()} for a list of supported side effects. + * Non-supported side effects will be ignored.

+ * + * @param position position of the block + * @param block block to set + * @param sideEffects which side effects to perform + * @return true if the block was successfully set (return value may not be accurate) + */ + > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException; + /** * Notifies the simulation that the block at the given location has * been changed and it must be re-lighted (and issue other events). @@ -124,7 +146,20 @@ public interface World extends Extent, Keyed, IChunkCache { * @param previousType the type of the previous block that was there * @return true if the block was successfully notified */ - boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException; + @Deprecated + default boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException { + return !applySideEffects(position, previousType, SideEffectSet.defaults()).isEmpty(); + } + + /** + * Applies a set of 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 which side effects to perform + * @return a set of side effects that were applied + */ + Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException; /** * Get the light level at the given block. diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index fe79f060d..4708d4596 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -210,6 +210,10 @@ "worldedit.fast.enabled": "Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.", "worldedit.fast.disabled.already": "Fast mode already disabled.", "worldedit.fast.enabled.already": "Fast mode already enabled.", + "worldedit.fast.sideeffect.set": "Side effect \"{0}\" set to {1}", + "worldedit.fast.sideeffect.get": "Side effect \"{0}\" is set to {1}", + "worldedit.fast.sideeffect.already-set": "Side effect \"{0}\" is already {1}", + "worldedit.fast.sideeffect.set-all": "All side effects set to {0}", "worldedit.reorder.current": "The reorder mode is {0}", "worldedit.reorder.set": "The reorder mode is now {0}", "worldedit.gmask.disabled": "Global mask disabled.", @@ -494,6 +498,22 @@ "worldedit.selection.sphere.explain.secondary": "Radius set to {0}.", "worldedit.selection.sphere.explain.secondary-defined": "Radius set to {0} ({1}).", + "worldedit.sideeffect.lighting": "Lighting", + "worldedit.sideeffect.lighting.description": "Updates block lighting", + "worldedit.sideeffect.neighbors": "Neighbors", + "worldedit.sideeffect.neighbors.description": "Notifies nearby blocks of changes", + "worldedit.sideeffect.connections": "Connections", + "worldedit.sideeffect.connections.description": "Updates connections for blocks like fences", + "worldedit.sideeffect.entity_ai": "Entity AI", + "worldedit.sideeffect.entity_ai.description": "Updates Entity AI paths for the block changes", + "worldedit.sideeffect.plugin_events": "Plugin Events", + "worldedit.sideeffect.plugin_events.description": "Tells other plugins/mods about these changes when applicable", + "worldedit.sideeffect.state.on": "On", + "worldedit.sideeffect.state.delayed": "Delayed", + "worldedit.sideeffect.state.off": "Off", + "worldedit.sideeffect.box.current": "Current", + "worldedit.sideeffect.box.change-to": "Click to set to {0}", + "worldedit.help.command-not-found": "The command '{0}' could not be found.", "worldedit.help.no-subcommands": "'{0}' has no sub-commands. (Maybe '{1}' is for a parameter?)", "worldedit.help.subcommand-not-found": "The sub-command '{0}' under '{1}' could not be found.", diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index be85099fa..1cf6df8dd 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -61,16 +61,12 @@ tasks.named("processResources") { } } -<<<<<<< HEAD -addJarManifest(includeClasspath = true) -======= tasks.named("jar") { manifest { attributes("Class-Path" to CLASSPATH, "WorldEdit-Version" to project.version) } } ->>>>>>> 18a55bc14... Add new experimental snapshot API (#524) tasks.named("shadowJar") { archiveClassifier.set("dist-dev") diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java index beb6d5208..7fb18b0e7 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.fabric; +import com.google.common.collect.Sets; import com.sk89q.worldedit.command.util.PermissionCondition; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.AbstractPlatform; @@ -27,13 +28,13 @@ import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.MultiUserPlatform; import com.sk89q.worldedit.extension.platform.Preference; import com.sk89q.worldedit.extension.platform.Watchdog; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.registry.Registries; import net.minecraft.SharedConstants; import net.minecraft.server.MinecraftServer; import net.minecraft.server.PlayerManager; -import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.MinecraftDedicatedServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; @@ -200,6 +201,18 @@ class FabricPlatform extends AbstractPlatform implements MultiUserPlatform { return capabilities; } + private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( + SideEffect.CONNECTIONS, + SideEffect.ENTITY_AI, + SideEffect.LIGHTING, + SideEffect.NEIGHBORS + ); + + @Override + public Set getSupportedSideEffects() { + return SUPPORTED_SIDE_EFFECTS; + } + @Override public Collection getConnectedUsers() { List users = new ArrayList<>(); diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java index 886523df5..e085d2326 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java @@ -24,6 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.common.collect.Sets; import com.google.common.io.Files; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.EditSession; @@ -42,6 +43,8 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BiomeType; @@ -61,6 +64,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; import net.minecraft.server.MinecraftServer; import net.minecraft.server.WorldGenerationProgressListener; +import net.minecraft.server.world.ChunkHolder; import net.minecraft.server.world.ServerChunkManager; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; @@ -71,6 +75,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraft.world.WorldSaveHandler; +import net.minecraft.world.biome.DefaultBiomeFeatures; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkManager; import net.minecraft.world.chunk.ChunkStatus; @@ -104,6 +109,7 @@ import java.util.Locale; import java.util.Optional; import java.util.OptionalInt; import java.util.Random; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; @@ -185,8 +191,44 @@ public class FabricWorld extends AbstractWorld { return null; } + public void markAndNotifyBlock(World world, BlockPos pos, @Nullable WorldChunk worldChunk, net.minecraft.block.BlockState blockState, + net.minecraft.block.BlockState state, SideEffectSet sideEffectSet) { + Block block = state.getBlock(); + net.minecraft.block.BlockState blockState2 = world.getBlockState(pos); + if (blockState2 == state) { + if (blockState != blockState2) { + world.checkBlockRerender(pos, blockState, blockState2); + } + + if (world.isClient || worldChunk.getLevelType() != null && worldChunk.getLevelType().isAfter(ChunkHolder.LevelType.TICKING)) { + if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) { + world.updateListeners(pos, blockState, state, UPDATE | NOTIFY); + } else { + // If we want to skip entity AI, just call the chunk dirty flag. + ((ServerChunkManager) world.getChunkManager()).markForUpdate(pos); + } + } + + if (!world.isClient && sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) { + world.updateNeighbors(pos, blockState.getBlock()); + if (state.hasComparatorOutput()) { + world.updateHorizontalAdjacent(pos, block); + } + } + + if (sideEffectSet.shouldApply(SideEffect.CONNECTIONS)) { + blockState.method_11637(world, pos, 2); + state.updateNeighborStates(world, pos, 2); + state.method_11637(world, pos, 2); + } + + // This is disabled for other platforms, but keep it for mods. + world.onBlockChanged(pos, blockState, blockState2); + } + } + @Override - public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException { + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { checkNotNull(position); checkNotNull(block); @@ -196,7 +238,7 @@ public class FabricWorld extends AbstractWorld { int z = position.getBlockZ(); // First set the block - Chunk chunk = world.getChunk(x >> 4, z >> 4); + WorldChunk chunk = world.getChunk(x >> 4, z >> 4); BlockPos pos = new BlockPos(x, y, z); net.minecraft.block.BlockState old = chunk.getBlockState(pos); OptionalInt stateId = BlockStateIdAccess.getBlockStateId(block.toImmutableState()); @@ -221,26 +263,27 @@ public class FabricWorld extends AbstractWorld { } } - if (successful && notifyAndLight) { - world.getChunkManager().getLightingProvider().enqueueLightUpdate(pos); - world.scheduleBlockRender(pos, old, newState); - world.updateListeners(pos, old, newState, UPDATE | NOTIFY); - world.updateNeighbors(pos, newState.getBlock()); - if (old.hasComparatorOutput()) { - world.updateHorizontalAdjacent(pos, newState.getBlock()); + if (successful) { + if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { + world.getChunkManager().getLightingProvider().checkBlock(pos); } + markAndNotifyBlock(world, pos, chunk, old, newState, sideEffects); } return successful; } @Override - public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException { + public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException { BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ()); - net.minecraft.block.BlockState state = getWorld().getBlockState(pos); - getWorld().updateListeners(pos, FabricAdapter.adapt(previousType), state, 1 | 2); - getWorld().updateNeighbors(pos, state.getBlock()); - return true; + net.minecraft.block.BlockState oldData = FabricAdapter.adapt(previousType); + net.minecraft.block.BlockState newData = getWorld().getBlockState(pos); + + if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { + getWorld().getChunkManager().getLightingProvider().checkBlock(pos); + } + markAndNotifyBlock(getWorld(), pos, null, oldData, newData, sideEffectSet); // Update + return Sets.intersection(FabricWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply()); } @Override diff --git a/worldedit-forge/build.gradle.kts b/worldedit-forge/build.gradle.kts index 23d52162d..f3b938ca7 100644 --- a/worldedit-forge/build.gradle.kts +++ b/worldedit-forge/build.gradle.kts @@ -77,7 +77,12 @@ tasks.named("processResources") { } } -addJarManifest(includeClasspath = false) +tasks.named("jar") { + manifest { + attributes("Class-Path" to CLASSPATH, + "WorldEdit-Version" to project.version) + } +} tasks.named("shadowJar") { dependencies { diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java index e1af09064..b844425eb 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java @@ -27,6 +27,7 @@ import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.MultiUserPlatform; import com.sk89q.worldedit.extension.platform.Preference; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.registry.Registries; @@ -206,6 +207,18 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform { return capabilities; } + private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( + SideEffect.CONNECTIONS, + SideEffect.ENTITY_AI, + SideEffect.LIGHTING, + SideEffect.NEIGHBORS + ); + + @Override + public Set getSupportedSideEffects() { + return SUPPORTED_SIDE_EFFECTS; + } + @Override public Collection getConnectedUsers() { List users = new ArrayList<>(); diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java index f9096578b..5d69754a6 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -19,6 +19,8 @@ package com.sk89q.worldedit.forge; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -96,13 +98,13 @@ import net.minecraft.world.gen.feature.SwampTreeFeature; import net.minecraft.world.gen.feature.TallTaigaTreeFeature; import net.minecraft.world.gen.feature.TreeFeature; +import net.minecraft.world.server.ChunkHolder; import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerWorld; import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.WorldInfo; import net.minecraftforge.common.DimensionManager; -import javax.annotation.Nullable; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; @@ -117,7 +119,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; -import static com.google.common.base.Preconditions.checkNotNull; +import javax.annotation.Nullable; /** * An adapter to Minecraft worlds for WorldEdit. @@ -130,7 +132,7 @@ public class ForgeWorld extends AbstractWorld { private static final net.minecraft.block.BlockState JUNGLE_LOG = Blocks.JUNGLE_LOG.getDefaultState(); private static final net.minecraft.block.BlockState JUNGLE_LEAF = Blocks.JUNGLE_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE); private static final net.minecraft.block.BlockState JUNGLE_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE); - + private final WeakReference worldRef; /** @@ -192,8 +194,51 @@ public class ForgeWorld extends AbstractWorld { return null; } + /** + * This is a heavily modified function stripped from MC to apply worldedit-modifications. + * + * @see World#markAndNotifyBlock + */ + public void markAndNotifyBlock(World world, BlockPos pos, @Nullable Chunk chunk, net.minecraft.block.BlockState blockstate, + net.minecraft.block.BlockState newState, SideEffectSet sideEffectSet) { + Block block = newState.getBlock(); + net.minecraft.block.BlockState blockstate1 = world.getBlockState(pos); + if (blockstate1 == newState) { + if (blockstate != blockstate1) { + world.markBlockRangeForRenderUpdate(pos, blockstate, blockstate1); + } + + // Remove redundant branches + if (world.isRemote || chunk == null || chunk.getLocationType().isAtLeast(ChunkHolder.LocationType.TICKING)) { + if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) { + world.notifyBlockUpdate(pos, blockstate, newState, UPDATE | NOTIFY); + } else { + // If we want to skip entity AI, just call the chunk dirty flag. + ((ServerChunkProvider) world.getChunkProvider()).markBlockChanged(pos); + } + } + + if (!world.isRemote && sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) { + world.notifyNeighbors(pos, blockstate.getBlock()); + if (newState.hasComparatorInputOverride()) { + world.updateComparatorOutputLevel(pos, block); + } + } + + // Make connection updates optional + if (sideEffectSet.shouldApply(SideEffect.CONNECTIONS)) { + blockstate.updateDiagonalNeighbors(world, pos, 2); + newState.updateNeighbors(world, pos, 2); + newState.updateDiagonalNeighbors(world, pos, 2); + } + + // This is disabled for other platforms, but keep it for mods. + world.onBlockStateChange(pos, blockstate, blockstate1); + } + } + @Override - public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException { + public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { checkNotNull(position); checkNotNull(block); @@ -224,19 +269,27 @@ public class ForgeWorld extends AbstractWorld { } } - if (successful && notifyAndLight) { - world.getChunkProvider().getLightManager().checkBlock(pos); - world.markAndNotifyBlock(pos, chunk, old, newState, UPDATE | NOTIFY); + if (successful) { + if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { + world.getChunkProvider().getLightManager().checkBlock(pos); + } + markAndNotifyBlock(world, pos, chunk, old, newState, sideEffects); } return successful; } @Override - public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException { + public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException { BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ()); - getWorld().notifyBlockUpdate(pos, ForgeAdapter.adapt(previousType), getWorld().getBlockState(pos), 1 | 2); - return true; + net.minecraft.block.BlockState oldData = ForgeAdapter.adapt(previousType); + net.minecraft.block.BlockState newData = getWorld().getBlockState(pos); + + if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { + getWorld().getChunkProvider().getLightManager().checkBlock(pos); + } + markAndNotifyBlock(getWorld(), pos, null, oldData, newData, sideEffectSet); // Update + return Sets.intersection(ForgeWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply()); } @Override diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index 33849e915..ddfaad17b 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -20,6 +20,8 @@ package com.sk89q.worldedit.sponge; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.event.platform.CommandEvent; @@ -31,6 +33,7 @@ import com.sk89q.worldedit.extension.platform.MultiUserPlatform; import com.sk89q.worldedit.extension.platform.Preference; import com.sk89q.worldedit.internal.command.CommandUtil; import com.sk89q.worldedit.sponge.config.SpongeConfiguration; +import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.registry.Registries; import org.enginehub.piston.Command; @@ -50,6 +53,7 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import static java.util.stream.Collectors.toList; @@ -192,6 +196,11 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { return capabilities; } + @Override + public Set getSupportedSideEffects() { + return ImmutableSet.of(); + } + @Override public Collection getConnectedUsers() { List users = new ArrayList<>(); From b59b95c282caa93c5d8cfdb9fc518ee2c8b2de74 Mon Sep 17 00:00:00 2001 From: Octavia Togami Date: Sun, 22 Mar 2020 21:02:04 -0700 Subject: [PATCH 07/14] 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 --- .../mc1_14/FAWEWorldNativeAccess_1_14.java | 176 +++++++++++++++++ .../FAWEWorldNativeAccess_1_15_2.java | 173 ++++++++++++++++ .../mc1_16_1/BlockMaterial_1_16_1.java | 2 +- .../mc1_16_1/FAWEWorldNativeAccess_1_16.java | 174 +++++++++++++++++ .../fawe/bukkit/wrapper/AsyncWorld.java | 28 ++- .../wrapper/state/AsyncDataContainer.java | 22 ++- .../sk89q/worldedit/bukkit/BukkitWorld.java | 50 ++--- .../bukkit/adapter/BukkitImplAdapter.java | 22 +-- .../adapter/IDelegateBukkitImplAdapter.java | 4 - .../adapter/impl/FAWE_Spigot_v1_14_R4.java | 29 +-- .../adapter/impl/FAWE_Spigot_v1_15_R2.java | 28 +-- .../adapter/impl/FAWE_Spigot_v1_16_R1.java | 28 +-- .../internal/wna/WorldNativeAccess.java | 184 ++++++++++++++++++ .../worldedit/internal/wna/package-info.java | 25 +++ .../com/sk89q/worldedit/util/SideEffect.java | 4 +- .../src/main/resources/lang/strings.json | 8 +- worldedit-fabric/build.gradle.kts | 4 +- .../sk89q/worldedit/fabric/FabricAdapter.java | 1 + .../worldedit/fabric/FabricDataFixer.java | 7 +- .../sk89q/worldedit/fabric/FabricEntity.java | 1 + .../worldedit/fabric/FabricPlatform.java | 2 +- .../sk89q/worldedit/fabric/FabricPlayer.java | 7 +- .../sk89q/worldedit/fabric/FabricWorld.java | 93 +-------- .../internal/FabricWorldNativeAccess.java | 139 +++++++++++++ .../fabric/{ => internal}/NBTConverter.java | 4 +- .../net/handler/WECUIPacketHandler.java | 8 +- .../sk89q/worldedit/forge/ForgeEntity.java | 1 + .../sk89q/worldedit/forge/ForgePlatform.java | 2 +- .../com/sk89q/worldedit/forge/ForgeWorld.java | 102 +--------- .../internal/ForgeWorldNativeAccess.java | 152 +++++++++++++++ .../forge/internal/TileEntityUtils.java | 35 +--- 31 files changed, 1170 insertions(+), 345 deletions(-) create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/FAWEWorldNativeAccess_1_14.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/package-info.java create mode 100644 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldNativeAccess.java rename worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/{ => internal}/NBTConverter.java (99%) create mode 100644 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeWorldNativeAccess.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/FAWEWorldNativeAccess_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/FAWEWorldNativeAccess_1_14.java new file mode 100644 index 000000000..9bcfc1ddd --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/FAWEWorldNativeAccess_1_14.java @@ -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 { + private static final int UPDATE = 1, NOTIFY = 2; + + private final FAWE_Spigot_v1_14_R4 adapter; + private final WeakReference world; + private SideEffectSet sideEffectSet; + + public FAWEWorldNativeAccess_1_14(FAWE_Spigot_v1_14_R4 adapter, WeakReference 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 > 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)); + } +} \ No newline at end of file diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java new file mode 100644 index 000000000..9ce24d789 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/FAWEWorldNativeAccess_1_15_2.java @@ -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 { + private static final int UPDATE = 1, NOTIFY = 2; + + private final FAWE_Spigot_v1_15_R2 adapter; + private final WeakReference world; + private SideEffectSet sideEffectSet; + + public FAWEWorldNativeAccess_1_15_2(FAWE_Spigot_v1_15_R2 adapter, WeakReference 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 > 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)); + } +} \ No newline at end of file diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BlockMaterial_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BlockMaterial_1_16_1.java index ef492dbdd..dfa348a78 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BlockMaterial_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BlockMaterial_1_16_1.java @@ -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() { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java new file mode 100644 index 000000000..6b68ae95d --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/FAWEWorldNativeAccess_1_16.java @@ -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 { + private static final int UPDATE = 1, NOTIFY = 2; + + private final FAWE_Spigot_v1_16_R1 adapter; + private final WeakReference world; + private SideEffectSet sideEffectSet; + + public FAWEWorldNativeAccess_1_16(FAWE_Spigot_v1_16_R1 adapter, WeakReference 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 > 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)); + } +} \ No newline at end of file diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java index 4252d3f32..60e0f8037 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java @@ -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); } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java index f1fbbcbb2..e64db1124 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java @@ -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 getKeys() { + Set 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()); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index f11fc13d3..588071c34 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -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 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 > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - if (adapter != null) { + public > 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 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 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 diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index 416b4b621..d77073045 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -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 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. diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java index 9f5499dcd..5bf4d88af 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java @@ -66,10 +66,6 @@ public interface IDelegateBukkitImplAdapter extends BukkitImplAdapter { return getParent().getBlock(location); } - default > boolean setBlock(Location location, B state, boolean notifyAndLight) { - return getParent().setBlock(location, state, SideEffectSet.none()); - } - @Override @Nullable default BaseEntity getEntity(Entity entity) { diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java index 21bcf1718..09aa43ca3 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java @@ -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 getSupportedSideEffects() { return SideEffectSet.defaults().getSideEffectsToApply(); } - @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, 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()); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java index ffbe28f1d..85dd26089 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java @@ -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 getSupportedSideEffects() { return SideEffectSet.defaults().getSideEffectsToApply(); } - @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, 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()); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java index a97372095..3a5f2af11 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R1.java @@ -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 getSupportedSideEffects() { return SideEffectSet.defaults().getSideEffectsToApply(); } - @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, 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()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java new file mode 100644 index 000000000..ac32171e7 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java @@ -0,0 +1,184 @@ +/* + * 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.internal.wna; + +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; + +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Natively access and perform operations on the world. + * + * @param the native chunk type + * @param the native block state type + * @param the native position type + */ +public interface WorldNativeAccess { + + default > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { + checkNotNull(position); + checkNotNull(block); + setCurrentSideEffectSet(sideEffects); + + int x = position.getBlockX(); + int y = position.getBlockY(); + int z = position.getBlockZ(); + + // First set the block + NC chunk = getChunk(x >> 4, z >> 4); + NP pos = getPosition(x, y, z); + NBS old = getBlockState(chunk, pos); + NBS newState = toNative(block.toImmutableState()); + // change block prior to placing if it should be fixed + if (sideEffects.shouldApply(SideEffect.VALIDATION)) { + newState = getValidBlockForPosition(newState, pos); + } + NBS successState = setBlockState(chunk, pos, newState); + boolean successful = successState != null; + + // Create the TileEntity + if (successful || old == newState) { + if (block instanceof BaseBlock) { + BaseBlock baseBlock = (BaseBlock) block; + CompoundTag tag = baseBlock.getNbtData(); + if (tag != null) { + tag = tag.createBuilder() + .putString("id", baseBlock.getNbtId()) + .putInt("x", position.getX()) + .putInt("y", position.getY()) + .putInt("z", position.getZ()) + .build(); + // update if TE changed as well + successful = updateTileEntity(pos, tag); + } + } + } + + if (successful) { + if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { + updateLightingForBlock(pos); + } + markAndNotifyBlock(pos, chunk, old, newState, sideEffects); + } + + return successful; + } + + default void applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) { + setCurrentSideEffectSet(sideEffectSet); + NP pos = getPosition(position.getX(), position.getY(), position.getZ()); + NC chunk = getChunk(position.getX() >> 4, position.getZ() >> 4); + NBS oldData = toNative(previousType); + NBS newData = getBlockState(chunk, pos); + + if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { + updateLightingForBlock(pos); + } + + markAndNotifyBlock(pos, chunk, oldData, newData, sideEffectSet); + } + + // state-keeping functions for WNA + // may be thread-unsafe, as this is single-threaded code + + /** + * Receive the current side-effect set from the high level call. + * + * This allows the implementation to branch on the side-effects internally. + * + * @param sideEffectSet the set of side-effects + */ + default void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { + } + + // access functions + + NC getChunk(int x, int z); + + NBS toNative(BlockState state); + + NBS getBlockState(NC chunk, NP position); + + @Nullable + NBS setBlockState(NC chunk, NP position, NBS state); + + NBS getValidBlockForPosition(NBS block, NP position); + + NP getPosition(int x, int y, int z); + + void updateLightingForBlock(NP position); + + boolean updateTileEntity(NP position, CompoundTag tag); + + void notifyBlockUpdate(NP position, NBS oldState, NBS newState); + + boolean isChunkTicking(NC chunk); + + void markBlockChanged(NP position); + + void notifyNeighbors(NP pos, NBS oldState, NBS newState); + + void updateNeighbors(NP pos, NBS oldState, NBS newState, int recursionLimit); + + void onBlockStateChange(NP pos, NBS oldState, NBS newState); + + /** + * This is a heavily modified function stripped from MC to apply worldedit-modifications. + * + * See Forge's World.markAndNotifyBlock + */ + default void markAndNotifyBlock(NP pos, NC chunk, NBS oldState, NBS newState, SideEffectSet sideEffectSet) { + NBS blockState1 = getBlockState(chunk, pos); + if (blockState1 != newState) { + return; + } + + // Remove redundant branches + if (isChunkTicking(chunk)) { + if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) { + notifyBlockUpdate(pos, oldState, newState); + } else { + // If we want to skip entity AI, just mark the block for sending + markBlockChanged(pos); + } + } + + if (sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) { + notifyNeighbors(pos, oldState, newState); + } + + // Make connection updates optional + if (sideEffectSet.shouldApply(SideEffect.VALIDATION)) { + updateNeighbors(pos, oldState, newState, 512); + } + + onBlockStateChange(pos, oldState, newState); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/package-info.java new file mode 100644 index 000000000..69009eb59 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/package-info.java @@ -0,0 +1,25 @@ +/* + * 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 . + */ + +/** + * "WNA", or WorldEdit Native Access. + * + * Contains internal helper functions for sharing code between platforms. + */ +package com.sk89q.worldedit.internal.wna; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java index c4c814fcb..5b142a364 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/SideEffect.java @@ -24,9 +24,9 @@ import java.util.Locale; public enum SideEffect { LIGHTING(State.ON), NEIGHBORS(State.ON), - CONNECTIONS(State.ON), + VALIDATION(State.ON), ENTITY_AI(State.OFF), - PLUGIN_EVENTS(State.OFF); + EVENTS(State.OFF); private final String displayName; private final String description; diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 4708d4596..016a3d60d 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -502,12 +502,12 @@ "worldedit.sideeffect.lighting.description": "Updates block lighting", "worldedit.sideeffect.neighbors": "Neighbors", "worldedit.sideeffect.neighbors.description": "Notifies nearby blocks of changes", - "worldedit.sideeffect.connections": "Connections", - "worldedit.sideeffect.connections.description": "Updates connections for blocks like fences", + "worldedit.sideeffect.validation": "Validation", + "worldedit.sideeffect.validation.description": "Validates and fixes inconsistent world state, such as disconnected blocks", "worldedit.sideeffect.entity_ai": "Entity AI", "worldedit.sideeffect.entity_ai.description": "Updates Entity AI paths for the block changes", - "worldedit.sideeffect.plugin_events": "Plugin Events", - "worldedit.sideeffect.plugin_events.description": "Tells other plugins/mods about these changes when applicable", + "worldedit.sideeffect.events": "Mod/Plugin Events", + "worldedit.sideeffect.events.description": "Tells other mods/plugins about these changes when applicable", "worldedit.sideeffect.state.on": "On", "worldedit.sideeffect.state.delayed": "Delayed", "worldedit.sideeffect.state.off": "Off", diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index 1cf6df8dd..4b7a7b079 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -7,8 +7,8 @@ applyShadowConfiguration() apply(plugin = "fabric-loom") val minecraftVersion = "1.15.2" -val yarnMappings = "1.15.2+build.8:v2" -val loaderVersion = "0.7.6+build.180" +val yarnMappings = "1.15.2+build.14:v2" +val loaderVersion = "0.7.8+build.189" configurations.all { resolutionStrategy { diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java index 317274331..33219c7a3 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java @@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableList; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.fabric.internal.NBTConverter; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.registry.state.BooleanProperty; diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricDataFixer.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricDataFixer.java index f307b789c..d82bb8f75 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricDataFixer.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricDataFixer.java @@ -36,9 +36,10 @@ import com.mojang.datafixers.DataFixerBuilder; import com.mojang.datafixers.Dynamic; import com.mojang.datafixers.schemas.Schema; import com.sk89q.jnbt.CompoundTag; -import net.minecraft.datafixers.NbtOps; -import net.minecraft.datafixers.Schemas; -import net.minecraft.datafixers.TypeReferences; +import com.sk89q.worldedit.fabric.internal.NBTConverter; +import net.minecraft.datafixer.NbtOps; +import net.minecraft.datafixer.Schemas; +import net.minecraft.datafixer.TypeReferences; import net.minecraft.nbt.FloatTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.StringTag; diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricEntity.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricEntity.java index d1fb75a04..4ea3969fd 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricEntity.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricEntity.java @@ -25,6 +25,7 @@ import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.metadata.EntityProperties; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.fabric.internal.NBTConverter; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.NullWorld; diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java index 7fb18b0e7..bef543f6e 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java @@ -202,7 +202,7 @@ class FabricPlatform extends AbstractPlatform implements MultiUserPlatform { } private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.CONNECTIONS, + SideEffect.VALIDATION, SideEffect.ENTITY_AI, SideEffect.LIGHTING, SideEffect.NEIGHBORS diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java index 48507f8fe..1ee00d311 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java @@ -25,6 +25,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.fabric.internal.NBTConverter; import com.sk89q.worldedit.fabric.mixin.AccessorServerPlayerEntity; import com.sk89q.worldedit.fabric.net.handler.WECUIPacketHandler; import com.sk89q.worldedit.internal.cui.CUIEvent; @@ -42,10 +43,10 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypes; import io.netty.buffer.Unpooled; import net.minecraft.block.Block; -import net.minecraft.client.network.packet.BlockEntityUpdateS2CPacket; -import net.minecraft.client.network.packet.BlockUpdateS2CPacket; -import net.minecraft.client.network.packet.CustomPayloadS2CPacket; import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; +import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket; +import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java index e085d2326..93e05a820 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java @@ -34,6 +34,8 @@ import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.fabric.internal.FabricWorldNativeAccess; +import com.sk89q.worldedit.fabric.internal.NBTConverter; import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.math.BlockVector2; @@ -64,7 +66,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; import net.minecraft.server.MinecraftServer; import net.minecraft.server.WorldGenerationProgressListener; -import net.minecraft.server.world.ChunkHolder; import net.minecraft.server.world.ServerChunkManager; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; @@ -129,6 +130,7 @@ public class FabricWorld extends AbstractWorld { private static final net.minecraft.block.BlockState JUNGLE_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE); private final WeakReference worldRef; + private final FabricWorldNativeAccess worldNativeAccess; /** * Construct a new world. @@ -138,6 +140,7 @@ public class FabricWorld extends AbstractWorld { FabricWorld(World world) { checkNotNull(world); this.worldRef = new WeakReference<>(world); + this.worldNativeAccess = new FabricWorldNativeAccess(worldRef); } /** @@ -191,98 +194,14 @@ public class FabricWorld extends AbstractWorld { return null; } - public void markAndNotifyBlock(World world, BlockPos pos, @Nullable WorldChunk worldChunk, net.minecraft.block.BlockState blockState, - net.minecraft.block.BlockState state, SideEffectSet sideEffectSet) { - Block block = state.getBlock(); - net.minecraft.block.BlockState blockState2 = world.getBlockState(pos); - if (blockState2 == state) { - if (blockState != blockState2) { - world.checkBlockRerender(pos, blockState, blockState2); - } - - if (world.isClient || worldChunk.getLevelType() != null && worldChunk.getLevelType().isAfter(ChunkHolder.LevelType.TICKING)) { - if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) { - world.updateListeners(pos, blockState, state, UPDATE | NOTIFY); - } else { - // If we want to skip entity AI, just call the chunk dirty flag. - ((ServerChunkManager) world.getChunkManager()).markForUpdate(pos); - } - } - - if (!world.isClient && sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) { - world.updateNeighbors(pos, blockState.getBlock()); - if (state.hasComparatorOutput()) { - world.updateHorizontalAdjacent(pos, block); - } - } - - if (sideEffectSet.shouldApply(SideEffect.CONNECTIONS)) { - blockState.method_11637(world, pos, 2); - state.updateNeighborStates(world, pos, 2); - state.method_11637(world, pos, 2); - } - - // This is disabled for other platforms, but keep it for mods. - world.onBlockChanged(pos, blockState, blockState2); - } - } - @Override public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { - checkNotNull(position); - checkNotNull(block); - - World world = getWorldChecked(); - int x = position.getBlockX(); - int y = position.getBlockY(); - int z = position.getBlockZ(); - - // First set the block - WorldChunk chunk = world.getChunk(x >> 4, z >> 4); - BlockPos pos = new BlockPos(x, y, z); - net.minecraft.block.BlockState old = chunk.getBlockState(pos); - OptionalInt stateId = BlockStateIdAccess.getBlockStateId(block.toImmutableState()); - net.minecraft.block.BlockState newState = stateId.isPresent() ? Block.getStateFromRawId(stateId.getAsInt()) : FabricAdapter.adapt(block.toImmutableState()); - net.minecraft.block.BlockState successState = chunk.setBlockState(pos, newState, false); - boolean successful = successState != null; - - // Create the TileEntity - if (successful || old == newState) { - if (block instanceof BaseBlock) { - CompoundTag tag = ((BaseBlock) block).getNbtData(); - if (tag != null) { - net.minecraft.nbt.CompoundTag nativeTag = NBTConverter.toNative(tag); - BlockEntity tileEntity = getWorld().getWorldChunk(pos).getBlockEntity(pos); - if (tileEntity != null) { - tileEntity.fromTag(nativeTag); - tileEntity.setPos(pos); - tileEntity.setWorld(world); - successful = true; // update if TE changed as well - } - } - } - } - - if (successful) { - if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { - world.getChunkManager().getLightingProvider().checkBlock(pos); - } - markAndNotifyBlock(world, pos, chunk, old, newState, sideEffects); - } - - return successful; + return worldNativeAccess.setBlock(position, block, sideEffects); } @Override public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException { - BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ()); - net.minecraft.block.BlockState oldData = FabricAdapter.adapt(previousType); - net.minecraft.block.BlockState newData = getWorld().getBlockState(pos); - - if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { - getWorld().getChunkManager().getLightingProvider().checkBlock(pos); - } - markAndNotifyBlock(getWorld(), pos, null, oldData, newData, sideEffectSet); // Update + worldNativeAccess.applySideEffects(position, previousType, sideEffectSet); return Sets.intersection(FabricWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply()); } diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldNativeAccess.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldNativeAccess.java new file mode 100644 index 000000000..6d64e39de --- /dev/null +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldNativeAccess.java @@ -0,0 +1,139 @@ +/* + * 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.fabric.internal; + +import com.sk89q.worldedit.fabric.FabricAdapter; +import com.sk89q.worldedit.internal.block.BlockStateIdAccess; +import com.sk89q.worldedit.internal.wna.WorldNativeAccess; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.world.ChunkHolder; +import net.minecraft.server.world.ServerChunkManager; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.chunk.WorldChunk; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.Objects; + +public class FabricWorldNativeAccess implements WorldNativeAccess { + private static final int UPDATE = 1, NOTIFY = 2; + + private final WeakReference world; + + public FabricWorldNativeAccess(WeakReference world) { + this.world = world; + } + + private World getWorld() { + return Objects.requireNonNull(world.get(), "The reference to the world was lost"); + } + + @Override + public WorldChunk getChunk(int x, int z) { + return getWorld().getChunk(x, z); + } + + @Override + public BlockState toNative(com.sk89q.worldedit.world.block.BlockState state) { + int stateId = BlockStateIdAccess.getBlockStateId(state); + return BlockStateIdAccess.isValidInternalId(stateId) + ? Block.getStateFromRawId(stateId) + : FabricAdapter.adapt(state); + } + + @Override + public BlockState getBlockState(WorldChunk chunk, BlockPos position) { + return chunk.getBlockState(position); + } + + @Nullable + @Override + public BlockState setBlockState(WorldChunk chunk, BlockPos position, BlockState state) { + return chunk.setBlockState(position, state, false); + } + + @Override + public BlockState getValidBlockForPosition(BlockState block, BlockPos position) { + return Block.getRenderingState(block, getWorld(), position); + } + + @Override + public BlockPos getPosition(int x, int y, int z) { + return new BlockPos(x, y, z); + } + + @Override + public void updateLightingForBlock(BlockPos position) { + getWorld().getChunkManager().getLightingProvider().checkBlock(position); + } + + @Override + public boolean updateTileEntity(BlockPos position, com.sk89q.jnbt.CompoundTag tag) { + CompoundTag nativeTag = NBTConverter.toNative(tag); + BlockEntity tileEntity = getWorld().getWorldChunk(position).getBlockEntity(position); + if (tileEntity == null) { + return false; + } + tileEntity.setLocation(getWorld(), position); + tileEntity.fromTag(nativeTag); + return true; + } + + @Override + public void notifyBlockUpdate(BlockPos position, BlockState oldState, BlockState newState) { + getWorld().updateListeners(position, oldState, newState, UPDATE | NOTIFY); + } + + @Override + public boolean isChunkTicking(WorldChunk chunk) { + return chunk.getLevelType().isAfter(ChunkHolder.LevelType.TICKING); + } + + @Override + public void markBlockChanged(BlockPos position) { + ((ServerChunkManager) getWorld().getChunkManager()).markForUpdate(position); + } + + @Override + public void notifyNeighbors(BlockPos pos, BlockState oldState, BlockState newState) { + getWorld().updateNeighbors(pos, oldState.getBlock()); + if (newState.hasComparatorOutput()) { + getWorld().updateHorizontalAdjacent(pos, newState.getBlock()); + } + } + + @Override + public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newState) { + World world = getWorld(); + // method_11637 = updateDiagonalNeighbors + oldState.method_11637(world, pos, NOTIFY); + newState.updateNeighborStates(world, pos, NOTIFY); + newState.method_11637(world, pos, NOTIFY); + } + + @Override + public void onBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) { + getWorld().onBlockChanged(pos, oldState, newState); + } +} diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/NBTConverter.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java similarity index 99% rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/NBTConverter.java rename to worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java index 450dfcb65..2cdc6be4e 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/NBTConverter.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.fabric; +package com.sk89q.worldedit.fabric.internal; import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.ByteTag; @@ -44,7 +44,7 @@ import java.util.Set; /** * Converts between JNBT and Minecraft NBT classes. */ -final class NBTConverter { +public final class NBTConverter { private NBTConverter() { } diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/net/handler/WECUIPacketHandler.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/net/handler/WECUIPacketHandler.java index 816d6c76f..4571e50d2 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/net/handler/WECUIPacketHandler.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/net/handler/WECUIPacketHandler.java @@ -23,15 +23,9 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.fabric.FabricAdapter; import com.sk89q.worldedit.fabric.FabricPlayer; import com.sk89q.worldedit.fabric.FabricWorldEdit; -import net.fabricmc.fabric.api.network.PacketConsumer; -import net.fabricmc.fabric.api.network.PacketContext; import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.packet.CustomPayloadS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.network.packet.CustomPayloadC2SPacket; import net.minecraft.util.Identifier; -import net.minecraft.util.PacketByteBuf; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -58,4 +52,4 @@ public final class WECUIPacketHandler { session.describeCUI(actor); }); } -} \ No newline at end of file +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java index a7f99e1a7..d522107d6 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java @@ -25,6 +25,7 @@ import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.metadata.EntityProperties; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.forge.internal.NBTConverter; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.NullWorld; diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java index b844425eb..7c682b81d 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java @@ -208,7 +208,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform { } private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.CONNECTIONS, + SideEffect.VALIDATION, SideEffect.ENTITY_AI, SideEffect.LIGHTING, SideEffect.NEIGHBORS diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java index 5d69754a6..4aa3b7a92 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -19,8 +19,6 @@ package com.sk89q.worldedit.forge; -import static com.google.common.base.Preconditions.checkNotNull; - import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -34,6 +32,9 @@ import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.forge.internal.ForgeWorldNativeAccess; +import com.sk89q.worldedit.forge.internal.NBTConverter; +import com.sk89q.worldedit.forge.internal.TileEntityUtils; import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.util.BiomeMath; @@ -105,6 +106,7 @@ import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.WorldInfo; import net.minecraftforge.common.DimensionManager; +import javax.annotation.Nullable; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; @@ -119,7 +121,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; -import javax.annotation.Nullable; +import static com.google.common.base.Preconditions.checkNotNull; /** * An adapter to Minecraft worlds for WorldEdit. @@ -127,13 +129,13 @@ import javax.annotation.Nullable; public class ForgeWorld extends AbstractWorld { private static final Random random = new Random(); - private static final int UPDATE = 1, NOTIFY = 2; private static final net.minecraft.block.BlockState JUNGLE_LOG = Blocks.JUNGLE_LOG.getDefaultState(); private static final net.minecraft.block.BlockState JUNGLE_LEAF = Blocks.JUNGLE_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE); private static final net.minecraft.block.BlockState JUNGLE_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE); private final WeakReference worldRef; + private final ForgeWorldNativeAccess nativeAccess; /** * Construct a new world. @@ -143,6 +145,7 @@ public class ForgeWorld extends AbstractWorld { ForgeWorld(World world) { checkNotNull(world); this.worldRef = new WeakReference<>(world); + this.nativeAccess = new ForgeWorldNativeAccess(worldRef); } /** @@ -194,101 +197,14 @@ public class ForgeWorld extends AbstractWorld { return null; } - /** - * This is a heavily modified function stripped from MC to apply worldedit-modifications. - * - * @see World#markAndNotifyBlock - */ - public void markAndNotifyBlock(World world, BlockPos pos, @Nullable Chunk chunk, net.minecraft.block.BlockState blockstate, - net.minecraft.block.BlockState newState, SideEffectSet sideEffectSet) { - Block block = newState.getBlock(); - net.minecraft.block.BlockState blockstate1 = world.getBlockState(pos); - if (blockstate1 == newState) { - if (blockstate != blockstate1) { - world.markBlockRangeForRenderUpdate(pos, blockstate, blockstate1); - } - - // Remove redundant branches - if (world.isRemote || chunk == null || chunk.getLocationType().isAtLeast(ChunkHolder.LocationType.TICKING)) { - if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) { - world.notifyBlockUpdate(pos, blockstate, newState, UPDATE | NOTIFY); - } else { - // If we want to skip entity AI, just call the chunk dirty flag. - ((ServerChunkProvider) world.getChunkProvider()).markBlockChanged(pos); - } - } - - if (!world.isRemote && sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) { - world.notifyNeighbors(pos, blockstate.getBlock()); - if (newState.hasComparatorInputOverride()) { - world.updateComparatorOutputLevel(pos, block); - } - } - - // Make connection updates optional - if (sideEffectSet.shouldApply(SideEffect.CONNECTIONS)) { - blockstate.updateDiagonalNeighbors(world, pos, 2); - newState.updateNeighbors(world, pos, 2); - newState.updateDiagonalNeighbors(world, pos, 2); - } - - // This is disabled for other platforms, but keep it for mods. - world.onBlockStateChange(pos, blockstate, blockstate1); - } - } - @Override public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException { - checkNotNull(position); - checkNotNull(block); - - World world = getWorldChecked(); - int x = position.getBlockX(); - int y = position.getBlockY(); - int z = position.getBlockZ(); - - // First set the block - Chunk chunk = world.getChunk(x >> 4, z >> 4); - BlockPos pos = new BlockPos(x, y, z); - net.minecraft.block.BlockState old = chunk.getBlockState(pos); - OptionalInt stateId = BlockStateIdAccess.getBlockStateId(block.toImmutableState()); - net.minecraft.block.BlockState newState = stateId.isPresent() ? Block.getStateById(stateId.getAsInt()) : ForgeAdapter.adapt(block.toImmutableState()); - net.minecraft.block.BlockState successState = chunk.setBlockState(pos, newState, false); - boolean successful = successState != null; - - // Create the TileEntity - if (successful || old == newState) { - if (block instanceof BaseBlock) { - CompoundTag tag = ((BaseBlock) block).getNbtData(); - if (tag != null) { - CompoundNBT nativeTag = NBTConverter.toNative(tag); - nativeTag.putString("id", ((BaseBlock) block).getNbtId()); - TileEntityUtils.setTileEntity(world, position, nativeTag); - successful = true; // update if TE changed as well - } - } - } - - if (successful) { - if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { - world.getChunkProvider().getLightManager().checkBlock(pos); - } - markAndNotifyBlock(world, pos, chunk, old, newState, sideEffects); - } - - return successful; + return nativeAccess.setBlock(position, block, sideEffects); } @Override public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException { - BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ()); - net.minecraft.block.BlockState oldData = ForgeAdapter.adapt(previousType); - net.minecraft.block.BlockState newData = getWorld().getBlockState(pos); - - if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) { - getWorld().getChunkProvider().getLightManager().checkBlock(pos); - } - markAndNotifyBlock(getWorld(), pos, null, oldData, newData, sideEffectSet); // Update + nativeAccess.applySideEffects(position, previousType, sideEffectSet); return Sets.intersection(ForgeWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply()); } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeWorldNativeAccess.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeWorldNativeAccess.java new file mode 100644 index 000000000..33784f1e7 --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/ForgeWorldNativeAccess.java @@ -0,0 +1,152 @@ +/* + * 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.forge.internal; + +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.forge.ForgeAdapter; +import com.sk89q.worldedit.internal.block.BlockStateIdAccess; +import com.sk89q.worldedit.internal.wna.WorldNativeAccess; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.server.ChunkHolder; +import net.minecraft.world.server.ServerChunkProvider; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.Objects; + +public class ForgeWorldNativeAccess implements WorldNativeAccess { + private static final int UPDATE = 1, NOTIFY = 2; + + private final WeakReference world; + private SideEffectSet sideEffectSet; + + public ForgeWorldNativeAccess(WeakReference world) { + 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().getChunk(x, z); + } + + @Override + public BlockState toNative(com.sk89q.worldedit.world.block.BlockState state) { + int stateId = BlockStateIdAccess.getBlockStateId(state); + return BlockStateIdAccess.isValidInternalId(stateId) + ? Block.getStateById(stateId) + : ForgeAdapter.adapt(state); + } + + @Override + public BlockState getBlockState(Chunk chunk, BlockPos position) { + return chunk.getBlockState(position); + } + + @Nullable + @Override + public BlockState setBlockState(Chunk chunk, BlockPos position, BlockState state) { + return chunk.setBlockState(position, state, false); + } + + @Override + public BlockState getValidBlockForPosition(BlockState block, BlockPos position) { + return Block.getValidBlockForPosition(block, getWorld(), position); + } + + @Override + public BlockPos getPosition(int x, int y, int z) { + return new BlockPos(x, y, z); + } + + @Override + public void updateLightingForBlock(BlockPos position) { + getWorld().getChunkProvider().getLightManager().checkBlock(position); + } + + @Override + public boolean updateTileEntity(BlockPos position, CompoundTag tag) { + CompoundNBT nativeTag = NBTConverter.toNative(tag); + return TileEntityUtils.setTileEntity(getWorld(), position, nativeTag); + } + + @Override + public void notifyBlockUpdate(BlockPos position, BlockState oldState, BlockState newState) { + getWorld().notifyBlockUpdate(position, oldState, newState, UPDATE | NOTIFY); + } + + @Override + public boolean isChunkTicking(Chunk chunk) { + return chunk.getLocationType().isAtLeast(ChunkHolder.LocationType.TICKING); + } + + @Override + public void markBlockChanged(BlockPos position) { + ((ServerChunkProvider) getWorld().getChunkProvider()).markBlockChanged(position); + } + + @Override + public void notifyNeighbors(BlockPos pos, BlockState oldState, BlockState newState) { + World world = getWorld(); + if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { + world.notifyNeighbors(pos, oldState.getBlock()); + } else { + // Manually update each side + Block block = oldState.getBlock(); + world.neighborChanged(pos.west(), block, pos); + world.neighborChanged(pos.east(), block, pos); + world.neighborChanged(pos.down(), block, pos); + world.neighborChanged(pos.up(), block, pos); + world.neighborChanged(pos.north(), block, pos); + world.neighborChanged(pos.south(), block, pos); + } + if (newState.hasComparatorInputOverride()) { + world.updateComparatorOutputLevel(pos, newState.getBlock()); + } + } + + @Override + public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newState) { + World world = getWorld(); + oldState.updateDiagonalNeighbors(world, pos, NOTIFY); + newState.updateNeighbors(world, pos, NOTIFY); + newState.updateDiagonalNeighbors(world, pos, NOTIFY); + } + + @Override + public void onBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) { + getWorld().onBlockStateChange(pos, oldState, newState); + } +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/TileEntityUtils.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/TileEntityUtils.java index 29d2b187e..dc3297c7b 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/TileEntityUtils.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/TileEntityUtils.java @@ -24,13 +24,10 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.sk89q.worldedit.math.BlockVector3; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.nbt.IntNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import javax.annotation.Nullable; - /** * Utility methods for setting tile entities in the world. */ @@ -39,39 +36,21 @@ public final class TileEntityUtils { private TileEntityUtils() { } - /** - * Update the given tag compound with position information. - * - * @param tag the tag - * @param position the position - */ - private static void updateForSet(CompoundNBT tag, BlockVector3 position) { - checkNotNull(tag); - checkNotNull(position); - - tag.put("x", new IntNBT(position.getBlockX())); - tag.put("y", new IntNBT(position.getBlockY())); - tag.put("z", new IntNBT(position.getBlockZ())); - } - /** * Set a tile entity at the given location using the tile entity ID from * the tag. * * @param world the world * @param position the position - * @param tag the tag for the tile entity (may be null to do nothing) + * @param tag the tag for the tile entity */ - static boolean setTileEntity(World world, BlockVector3 position, @Nullable CompoundNBT tag) { - if (tag != null) { - updateForSet(tag, position); - TileEntity tileEntity = TileEntity.create(tag); - if (tileEntity == null) { - return false; - } - world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); - return true; + static boolean setTileEntity(World world, BlockPos position, CompoundNBT tag) { + TileEntity tileEntity = TileEntity.create(tag); + if (tileEntity == null) { + return false; } + world.setTileEntity(new BlockPos(position.getX(), position.getY(), position.getZ()), tileEntity); + return true; } public static CompoundNBT copyNbtData(TileEntity tile) { From f84958957cbf28793662c675f4ccc17769b5c10c Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 30 Jun 2020 13:44:26 +0100 Subject: [PATCH 08/14] Fix various lighting issues fixes #496 possibly fixes #497 --- .../adapter/mc1_14/BukkitGetBlocks_1_14.java | 43 ++++++++++++++++--- .../adapter/mc1_15/BukkitGetBlocks_1_15.java | 43 ++++++++++++++++--- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 37 +++++++++++++--- .../implementation/blocks/CharSetBlocks.java | 12 ++++++ 4 files changed, 115 insertions(+), 20 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java index eace17737..7196fb21b 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java @@ -56,7 +56,7 @@ import net.minecraft.server.v1_14_R1.Entity; import net.minecraft.server.v1_14_R1.EntityTypes; import net.minecraft.server.v1_14_R1.EnumSkyBlock; import net.minecraft.server.v1_14_R1.IBlockData; -import net.minecraft.server.v1_14_R1.LightEngineThreaded; +import net.minecraft.server.v1_14_R1.LightEngine; import net.minecraft.server.v1_14_R1.NBTTagCompound; import net.minecraft.server.v1_14_R1.NBTTagInt; import net.minecraft.server.v1_14_R1.NibbleArray; @@ -69,8 +69,13 @@ import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock; import org.bukkit.event.entity.CreatureSpawnEvent; import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class BukkitGetBlocks_1_14 extends CharGetBlocks { + + private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_14.class); + public ChunkSection[] sections; public Chunk nmsChunk; public WorldServer world; @@ -129,7 +134,17 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { int layer = y >> 4; if (skyLight[layer] == null) { //getDataLayerData - skyLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(SectionPosition.a(nmsChunk.getPos(), layer)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 15); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibbleArray); + } + skyLight[layer] = nibbleArray; } 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))); @@ -140,7 +155,17 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { int layer = y >> 4; if (blockLight[layer] == null) { //getDataLayerData - blockLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(SectionPosition.a(nmsChunk.getPos(), layer)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 15); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.BLOCK, sectionPosition, nibbleArray); + } + blockLight[layer] = nibbleArray; } 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))); @@ -299,7 +324,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { } else { existingSection = sections[layer]; if (existingSection == null) { - System.out.println("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); + log.error("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); continue; } } @@ -326,7 +351,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { } newSection = BukkitAdapter_1_14.newChunkSection(layer, this::load, setArr, fastmode); if (!BukkitAdapter_1_14.setSectionAtomic(sections, existingSection, newSection, layer)) { - System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); + log.error("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); @@ -667,9 +692,13 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { if (light[Y] == null) { continue; } - NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), Y); + NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(sectionPosition); if (nibble == null) { - continue; + byte[] a = new byte[2048]; + Arrays.fill(a, skyBlock == EnumSkyBlock.SKY ? (byte) 15 : (byte) 0); + nibble = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibble); } synchronized (nibble) { for (int i = 0; i < 4096; i++) { 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 index c9fbca585..57cc44026 100644 --- 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 @@ -57,7 +57,7 @@ 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.LightEngine; import net.minecraft.server.v1_15_R1.NBTTagCompound; import net.minecraft.server.v1_15_R1.NBTTagInt; import net.minecraft.server.v1_15_R1.NibbleArray; @@ -70,8 +70,13 @@ 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; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class BukkitGetBlocks_1_15 extends CharGetBlocks { + + private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_15.class); + 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; @@ -136,7 +141,17 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { 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)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 15); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibbleArray); + } + skyLight[layer] = nibbleArray; } 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))); @@ -146,7 +161,17 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { 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)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 15); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.BLOCK, sectionPosition, nibbleArray); + } + blockLight[layer] = nibbleArray; } 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))); @@ -305,7 +330,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { } else { existingSection = sections[layer]; if (existingSection == null) { - System.out.println("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); + log.error("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); continue; } } @@ -332,7 +357,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { } 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); + log.error("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); @@ -684,9 +709,13 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks { if (light[Y] == null) { continue; } - NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), Y); + NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(sectionPosition); if (nibble == null) { - continue; + byte[] a = new byte[2048]; + Arrays.fill(a, skyBlock == EnumSkyBlock.SKY ? (byte) 15 : (byte) 0); + nibble = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibble); } synchronized (nibble) { for (int i = 0; i < 4096; i++) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index 3292cc556..90dc417b4 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -40,6 +40,7 @@ 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.LightEngine; import net.minecraft.server.v1_15_R1.NBTTagCompound; import net.minecraft.server.v1_15_R1.NBTTagInt; import net.minecraft.server.v1_15_R1.NibbleArray; @@ -140,7 +141,17 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { 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)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 15); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibbleArray); + } + skyLight[layer] = nibbleArray; } 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))); @@ -150,7 +161,17 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { 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)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's not got any emitted light. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 0); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.BLOCK, sectionPosition, nibbleArray); + } + blockLight[layer] = nibbleArray; } 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))); @@ -316,7 +337,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { } else { existingSection = sections[layer]; if (existingSection == null) { - System.out.println("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); + log.error("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); continue; } } @@ -343,7 +364,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { } newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode); if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) { - System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); + log.error("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); @@ -689,9 +710,13 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { if (light[Y] == null) { continue; } - NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), Y); + NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(sectionPosition); if (nibble == null) { - continue; + byte[] a = new byte[2048]; + Arrays.fill(a, skyBlock == EnumSkyBlock.SKY ? (byte) 15 : (byte) 0); + nibble = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibble); } synchronized (nibble) { for (int i = 0; i < 4096; i++) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java index 1dda73c3a..744e92f06 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java @@ -181,6 +181,18 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { } @Override public void setFullBright(int layer) { + if (light == null) { + light = new char[16][]; + } + if (light[layer] == null) { + light[layer] = new char[4096]; + } + if (skyLight == null) { + skyLight = new char[16][]; + } + if (skyLight[layer] == null) { + skyLight[layer] = new char[4096]; + } Arrays.fill(light[layer], (char) 15); Arrays.fill(skyLight[layer], (char) 15); } From 4ca19acb489b219518e964c2ff7ce3f16ad137bb Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 30 Jun 2020 13:51:27 +0100 Subject: [PATCH 09/14] implement 1.16 methods --- .../fawe/bukkit/wrapper/AsyncWorld.java | 32 ++++++++++++++----- .../wrapper/state/AsyncDataContainer.java | 11 +++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java index 4252d3f32..c6b72076b 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/AsyncWorld.java @@ -884,6 +884,14 @@ 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(); @@ -1284,19 +1292,27 @@ public class AsyncWorld extends PassthroughExtent implements World { return parent.getHighestBlockAt(location, heightmap); } - public long getTicksPerWaterSpawns() { - throw new UnsupportedOperationException(); + public long getTicksPerWaterSpawns() throws UnsupportedOperationException { + return parent.getTicksPerWaterSpawns(); } - public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) { - throw new UnsupportedOperationException(); + public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) throws UnsupportedOperationException { + parent.setTicksPerWaterSpawns(ticksPerWaterSpawns); } - public long getTicksPerAmbientSpawns() { - throw new UnsupportedOperationException(); + @Override public long getTicksPerWaterAmbientSpawns() { + return parent.getTicksPerWaterAmbientSpawns(); } - public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) { - throw new UnsupportedOperationException(); + @Override public void setTicksPerWaterAmbientSpawns(int ticksPerAmbientSpawns) { + parent.setTicksPerWaterAmbientSpawns(ticksPerAmbientSpawns); + } + + public long getTicksPerAmbientSpawns() throws UnsupportedOperationException { + return parent.getTicksPerAmbientSpawns(); + } + + public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) throws UnsupportedOperationException { + parent.setTicksPerAmbientSpawns(ticksPerAmbientSpawns); } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java index f1fbbcbb2..51da9f50c 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/wrapper/state/AsyncDataContainer.java @@ -5,16 +5,21 @@ import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Objects; +import java.util.Set; + 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; + private final Set keys = new HashSet<>(); public AsyncDataContainer(CompoundTag root) { this.root = root; @@ -47,6 +52,7 @@ public final class AsyncDataContainer implements PersistentDataContainer { Validate.notNull(type, "The provided type for the custom value was null"); Validate.notNull(value, "The provided value for the custom value was null"); get().put(key.toString(), FaweCache.IMP.asTag(type.toPrimitive(value, null))); + keys.add(key); } public boolean has(NamespacedKey key, PersistentDataType type) { @@ -69,9 +75,14 @@ public final class AsyncDataContainer implements PersistentDataContainer { return z != null ? z : defaultValue; } + @Override public @NotNull Set getKeys() { + return keys; + } + public void remove(NamespacedKey key) { Validate.notNull(key, "The provided key for the custom value was null"); get(false).remove(key.toString()); + keys.remove(key); } public boolean isEmpty() { From 3f3c49c0a81afdb90e58af6a1a575356eb824dc3 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 1 Jul 2020 12:41:20 +0100 Subject: [PATCH 10/14] Looks like working block setting and removal --- .../com/boydti/fawe/bukkit/FaweBukkit.java | 8 ++ .../mc1_16_1/BukkitAdapter_1_16_1.java | 8 +- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 4 +- .../main/java/com/boydti/fawe/FaweCache.java | 98 ++++++++++++++- .../src/main/java/com/boydti/fawe/IFawe.java | 4 + .../java/com/boydti/fawe/beta/IBlocks.java | 13 +- .../implementation/packet/ChunkPacket.java | 5 +- .../collection/BitArrayUnstretched.java | 115 ++++++++++++++++++ 8 files changed, 244 insertions(+), 11 deletions(-) create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java index 823904be1..b6a8a7755 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -58,6 +58,7 @@ public class FaweBukkit implements IFawe, Listener { private boolean listeningImages; private BukkitImageListener imageListener; private CFIPacketListener packetListener; + private final boolean chunksStretched; public VaultUtil getVault() { return this.vault; @@ -99,6 +100,8 @@ public class FaweBukkit implements IFawe, Listener { // The tick limiter new ChunkListener_9(); }); + + chunksStretched = Integer.parseInt(Bukkit.getMinecraftVersion().split("\\.")[1]) >= 16; } @Override // Please don't delete this again, it's WIP @@ -302,6 +305,11 @@ public class FaweBukkit implements IFawe, Listener { return null; } + @Override + public boolean isChunksStretched() { + return chunksStretched; + } + private void setupPlotSquared() { Plugin plotSquared = this.plugin.getServer().getPluginManager().getPlugin("PlotSquared"); if (plotSquared == null) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java index 7b1549d65..a8e096e0c 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitAdapter_1_16_1.java @@ -5,7 +5,7 @@ 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.object.collection.BitArrayUnstretched; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.TaskManager; @@ -232,11 +232,13 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter { bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries } - final int blockBitArrayEnd = (bitsPerEntry * 4096) >> 6; + final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); + final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); + if (num_palette == 1) { for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0; } else { - final BitArray bitArray = new BitArray(bitsPerEntry, 4096, blockStates); + final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); bitArray.fromRaw(blocksCopy); } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index b07589339..a4eed61aa 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -10,7 +10,7 @@ import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.collection.AdaptedMap; -import com.boydti.fawe.object.collection.BitArray; +import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.google.common.base.Suppliers; import com.google.common.collect.Iterables; import com.sk89q.jnbt.Tag; @@ -553,7 +553,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { final int bitsPerEntry = (int) BukkitAdapter_1_16_1.fieldBitsPerEntry.get(bits); final long[] blockStates = bits.a(); - new BitArray(bitsPerEntry, 4096, blockStates).toRaw(data); + new BitArrayUnstretched(bitsPerEntry, blockStates).toRaw(data); int num_palette; if (palette instanceof DataPaletteLinear) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java index ee43fdc36..859503291 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java @@ -1,7 +1,6 @@ package com.boydti.fawe; import static com.google.common.base.Preconditions.checkNotNull; -import static org.slf4j.LoggerFactory.getLogger; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.Trimable; @@ -9,6 +8,7 @@ import com.boydti.fawe.beta.implementation.queue.Pool; import com.boydti.fawe.beta.implementation.queue.QueuePool; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.collection.BitArray; +import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.boydti.fawe.object.collection.CleanableThreadLocal; import com.boydti.fawe.object.collection.VariableThreadLocal; import com.boydti.fawe.object.exception.FaweBlockBagException; @@ -299,6 +299,102 @@ public enum FaweCache implements Trimable { } } + /** + * Convert raw int array to unstretched palette (1.16) + * @param layerOffset + * @param blocks + * @return palette + */ + public Palette toPaletteUnstretched(int layerOffset, char[] blocks) { + return toPaletteUnstretched(layerOffset, null, blocks); + } + + /** + * Convert raw int array to unstretched palette (1.16) + * @param layerOffset + * @param blocks + * @return palette + */ + public Palette toPaletteUnstretched(int layerOffset, int[] blocks) { + return toPaletteUnstretched(layerOffset, blocks, null); + } + + private Palette toPaletteUnstretched(int layerOffset, int[] blocksInts, char[] blocksChars) { + int[] blockToPalette = BLOCK_TO_PALETTE.get(); + int[] paletteToBlock = PALETTE_TO_BLOCK.get(); + long[] blockStates = BLOCK_STATES.get(); + int[] blocksCopy = SECTION_BLOCKS.get(); + + try { + int num_palette = 0; + int blockIndexStart = layerOffset << 12; + int blockIndexEnd = blockIndexStart + 4096; + if (blocksChars != null) { + for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { + int ordinal = blocksChars[i]; + int palette = blockToPalette[ordinal]; + if (palette == Integer.MAX_VALUE) { + blockToPalette[ordinal] = palette = num_palette; + paletteToBlock[num_palette] = ordinal; + num_palette++; + } + blocksCopy[j] = palette; + } + } else if (blocksInts != null) { + for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { + int ordinal = blocksInts[i]; + int palette = blockToPalette[ordinal]; + if (palette == Integer.MAX_VALUE) { + // BlockState state = BlockTypesCache.states[ordinal]; + blockToPalette[ordinal] = palette = num_palette; + paletteToBlock[num_palette] = ordinal; + num_palette++; + } + blocksCopy[j] = palette; + } + } else { + throw new IllegalArgumentException(); + } + + for (int i = 0; i < num_palette; i++) { + blockToPalette[paletteToBlock[i]] = Integer.MAX_VALUE; + } + + // 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 + } + int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); + int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); + if (num_palette == 1) { + // Set a value, because minecraft needs it for some reason + blockStates[0] = 0; + blockBitArrayEnd = 1; + } else { + BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); + bitArray.fromRaw(blocksCopy); + } + + // Construct palette + Palette palette = PALETTE_CACHE.get(); + palette.bitsPerEntry = bitsPerEntry; + palette.paletteToBlockLength = num_palette; + palette.paletteToBlock = paletteToBlock; + + palette.blockStatesLength = blockBitArrayEnd; + palette.blockStates = blockStates; + + return palette; + } catch (Throwable e) { + e.printStackTrace(); + Arrays.fill(blockToPalette, Integer.MAX_VALUE); + throw e; + } + } + /* * Vector cache */ diff --git a/worldedit-core/src/main/java/com/boydti/fawe/IFawe.java b/worldedit-core/src/main/java/com/boydti/fawe/IFawe.java index 20a15faab..6941fb728 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/IFawe.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/IFawe.java @@ -41,4 +41,8 @@ public interface IFawe { Preloader getPreloader(); + default boolean isChunksStretched() { + return true; + } + } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java index c042e7a23..42fbac580 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java @@ -45,11 +45,11 @@ public interface IBlocks extends Trimable { IBlocks reset(); - default byte[] toByteArray(boolean full) { - return toByteArray(null, getBitMask(), full); + default byte[] toByteArray(boolean full, boolean stretched) { + return toByteArray(null, getBitMask(), full, stretched); } - default byte[] toByteArray(byte[] buffer, int bitMask, boolean full) { + default byte[] toByteArray(byte[] buffer, int bitMask, boolean full, boolean stretched) { if (buffer == null) { buffer = new byte[1024]; } @@ -81,7 +81,12 @@ public interface IBlocks extends Trimable { } sectionWriter.writeShort(nonEmpty); // non empty - FaweCache.Palette palette = FaweCache.IMP.toPalette(0, ids); + FaweCache.Palette palette; + if (stretched) { + palette = FaweCache.IMP.toPalette(0, ids); + } else { + palette = FaweCache.IMP.toPaletteUnstretched(0, ids); + } sectionWriter.writeByte(palette.bitsPerEntry); // bits per block sectionWriter.writeVarInt(palette.paletteToBlockLength); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java index b904c5cd6..5638c962e 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java @@ -1,10 +1,12 @@ package com.boydti.fawe.beta.implementation.packet; +import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IBlocks; import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.WorldEdit; import java.util.HashMap; import java.util.function.Function; @@ -64,7 +66,7 @@ public class ChunkPacket implements Function, Supplier { if (sectionBytes == null) { IBlocks tmpChunk = getChunk(); byte[] buf = FaweCache.IMP.BYTE_BUFFER_8192.get(); - sectionBytes = tmpChunk.toByteArray(buf, tmpChunk.getBitMask(), this.full); + sectionBytes = tmpChunk.toByteArray(buf, tmpChunk.getBitMask(), this.full, Fawe.imp().isChunksStretched()); } tmp = sectionBytes; } @@ -72,6 +74,7 @@ public class ChunkPacket implements Function, Supplier { return tmp; } + public Object getNativePacket() { return nativePacket; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java new file mode 100644 index 000000000..9572eecc9 --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/BitArrayUnstretched.java @@ -0,0 +1,115 @@ +package com.boydti.fawe.object.collection; + +import com.boydti.fawe.util.MathMan; + +public final class BitArrayUnstretched { + + private final long[] data; + private final int bitsPerEntry; + private final int maxSeqLocIndex; + private final int emptyBitCount; + private final long mask; + private final int longLen; + + public BitArrayUnstretched(int bitsPerEntry, long[] buffer) { + this.bitsPerEntry = bitsPerEntry; + this.mask = (1L << bitsPerEntry) - 1L; + this.emptyBitCount = 64 % bitsPerEntry; + this.maxSeqLocIndex = 64 - (bitsPerEntry + emptyBitCount); + final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); + this.longLen = MathMan.ceilZero((float) 4096 / blocksPerLong); + if (buffer.length < longLen) { + this.data = new long[longLen]; + } else { + this.data = buffer; + } + } + + public long[] getData() { + return data; + } + + public final void set(int index, int value) { + if (longLen == 0) return; + int bitIndexStart = index * bitsPerEntry + MathMan.floorZero((double) index / longLen) * emptyBitCount; + int longIndexStart = bitIndexStart >> 6; + int localBitIndexStart = bitIndexStart & 63; + this.data[longIndexStart] = this.data[longIndexStart] & ~(mask << localBitIndexStart) | (long) value << localBitIndexStart; + } + + public final int get(int index) { + if (longLen == 0) return 0; + int bitIndexStart = index * bitsPerEntry + MathMan.floorZero((double) index / longLen) * emptyBitCount; + + int longIndexStart = bitIndexStart >> 6; + + int localBitIndexStart = bitIndexStart & 63; + return (int)(this.data[longIndexStart] >>> localBitIndexStart & mask); + } + + public int getLength() { + return longLen; + } + + public final void fromRaw(int[] arr) { + final long[] data = this.data; + final int bitsPerEntry = this.bitsPerEntry; + final int maxSeqLocIndex = this.maxSeqLocIndex; + + int localStart = 0; + int arrI = 0; + long l = 0; + for (int i = 0; i < longLen; i++) { + int lastVal; + for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { + lastVal = arr[arrI++]; + l |= ((long) lastVal << localStart); + } + localStart = 0; + data[i] = l; + l = 0; + } + } + + public final int[] toRaw() { + return toRaw(new int[4096]); + } + + public final int[] toRaw(int[] buffer) { + final long[] data = this.data; + final int bitsPerEntry = this.bitsPerEntry; + final int maxSeqLocIndex = this.maxSeqLocIndex; + + int localStart = 0; + int arrI = 0; + for (int i = 0; i < longLen; i++) { + long l = data[i]; + char lastVal; + for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { + lastVal = (char) (l >>> localStart & this.mask); + buffer[arrI++] = lastVal; + } + localStart = 0; + } + return buffer; + } + + public final char[] toRaw(char[] buffer) { + final long[] data = this.data; + final int bitsPerEntry = this.bitsPerEntry; + final int maxSeqLocIndex = this.maxSeqLocIndex; + + int localStart = 0; + int arrI = 0; + for (int i = 0; i < longLen; i++) { + long l = data[i]; + char lastVal; + for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { + lastVal = (char) (l >>> localStart & this.mask); + buffer[arrI++] = lastVal; + } + localStart = 0; + } + return buffer; + } +} From 6be429cc96ae6c7ad6574c822a50d9c3ed461a99 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 1 Jul 2020 12:55:58 +0100 Subject: [PATCH 11/14] Lighting: - bring fixes to 1.16 - Fix for all lighting where it only set sky lighting if not present, even if it was trying to set block lighting (unlikely to have caused issues as block lighting seems always to be present, but wrong nonetheless) --- .../adapter/mc1_14/BukkitGetBlocks_1_14.java | 2 +- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 2 +- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 41 +++++++++++++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java index 7196fb21b..ae871b419 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java @@ -698,7 +698,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { byte[] a = new byte[2048]; Arrays.fill(a, skyBlock == EnumSkyBlock.SKY ? (byte) 15 : (byte) 0); nibble = new NibbleArray(a); - ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibble); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(skyBlock, sectionPosition, nibble); } synchronized (nibble) { for (int i = 0; i < 4096; i++) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index 90dc417b4..e0cbf7266 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -716,7 +716,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { byte[] a = new byte[2048]; Arrays.fill(a, skyBlock == EnumSkyBlock.SKY ? (byte) 15 : (byte) 0); nibble = new NibbleArray(a); - ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibble); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(skyBlock, sectionPosition, nibble); } synchronized (nibble) { for (int i = 0; i < 4096; i++) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index a4eed61aa..d6dada109 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -43,8 +43,7 @@ import static org.slf4j.LoggerFactory.getLogger; public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { - private static final Logger log = LoggerFactory.getLogger( - BukkitGetBlocks_1_16_1.class); + private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_1.class); private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); private final static Function nmsTile2We = tileEntity -> new LazyCompoundTag_1_16_1(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); @@ -110,7 +109,17 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { 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)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 15); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.SKY, sectionPosition, nibbleArray, true); + } + skyLight[layer] = nibbleArray; } 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))); @@ -119,8 +128,18 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { @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)); + if (skyLight[layer] == null) { + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + NibbleArray nibbleArray = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (nibbleArray == null) { + byte[] a = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(a, (byte) 15); + nibbleArray = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(EnumSkyBlock.BLOCK, sectionPosition, nibbleArray, true); + } + skyLight[layer] = nibbleArray; } 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))); @@ -286,7 +305,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { } else { existingSection = sections[layer]; if (existingSection == null) { - System.out.println("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); + log.error("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer); continue; } } @@ -315,7 +334,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { .newChunkSection(layer, this::load, setArr, fastmode); if (!BukkitAdapter_1_16_1 .setSectionAtomic(sections, existingSection, newSection, layer)) { - System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); + log.error("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); continue; } else { updateGet(this, nmsChunk, sections, newSection, setArr, layer); @@ -662,9 +681,13 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { if (light[Y] == null) { continue; } - NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(SectionPosition.a(nmsChunk.getPos(), Y)); + SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), Y); + NibbleArray nibble = world.getChunkProvider().getLightEngine().a(skyBlock).a(sectionPosition); if (nibble == null) { - continue; + byte[] a = new byte[2048]; + Arrays.fill(a, skyBlock == EnumSkyBlock.SKY ? (byte) 15 : (byte) 0); + nibble = new NibbleArray(a); + ((LightEngine) world.getChunkProvider().getLightEngine()).a(skyBlock, sectionPosition, nibble, true); } synchronized (nibble) { for (int i = 0; i < 4096; i++) { From 0bb6bc3563526a56d26f7640bb1b22a16ccf70ce Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Wed, 1 Jul 2020 14:01:39 +0200 Subject: [PATCH 12/14] Start reimplementation of simplex pattern (#520) * Start reimplementation of simplex pattern * Fix suggestions * Allow nested weighted patterns * Add documentation and improve error handling * Remove unnecessary code and obsolete TODOs --- .../main/java/com/sk89q/util/StringUtil.java | 34 +++++ .../extension/factory/BlockFactory.java | 4 +- .../extension/factory/PatternFactory.java | 4 + .../extension/factory/parser/RichParser.java | 118 ++++++++++++++++++ .../parser/pattern/RandomPatternParser.java | 12 +- .../parser/pattern/SimplexPatternParser.java | 75 +++++++++++ .../function/pattern/RandomPattern.java | 13 ++ 7 files changed, 253 insertions(+), 7 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/RichParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SimplexPatternParser.java diff --git a/worldedit-core/src/main/java/com/sk89q/util/StringUtil.java b/worldedit-core/src/main/java/com/sk89q/util/StringUtil.java index 1aceda930..8231d3aa8 100644 --- a/worldedit-core/src/main/java/com/sk89q/util/StringUtil.java +++ b/worldedit-core/src/main/java/com/sk89q/util/StringUtil.java @@ -20,6 +20,7 @@ package com.sk89q.util; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Locale; @@ -331,4 +332,37 @@ public final class StringUtil { return parsableBlocks; } + + /** + * Splits a string respecting enclosing quotes. + * + * @param input the input to split. + * @param delimiter the delimiter to split on. + * @param open the opening quote character. + * @param close the closing quote character. + * @return a list of split strings. + */ + public static List split(String input, char delimiter, char open, char close) { + if (input.indexOf(open) == -1 && input.indexOf(close) == -1) { + return Arrays.asList(input.split(String.valueOf(delimiter))); + } + int level = 0; + int begin = 0; + List split = new ArrayList<>(); + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (c == delimiter && level == 0) { + split.add(input.substring(begin, i)); + begin = i + 1; + } else if (c == open) { + level++; + } else if (c == close) { + level--; + } + } + if (begin < input.length()) { + split.add(input.substring(begin)); + } + return split; + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java index 4f5a4fdbc..693cd9b8e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java @@ -58,8 +58,8 @@ public class BlockFactory extends AbstractFactory { */ public Set parseFromListInput(String input, ParserContext context) throws InputParseException { Set blocks = new HashSet<>(); - String[] splits = input.split(","); - for (String token : StringUtil.parseListInQuotes(splits, ',', '[', ']', true)) { + // String[] splits = input.split(","); + for (String token : StringUtil.split(input, ',', '[', ']')) { blocks.add(parseFromInput(token, context)); } return blocks; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java index 014229a3e..41bece423 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java @@ -24,6 +24,7 @@ import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPattern import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.SimplexPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser; import com.sk89q.worldedit.function.pattern.Pattern; @@ -54,6 +55,9 @@ public final class PatternFactory extends AbstractFactory { register(new TypeOrStateApplyingPatternParser(worldEdit)); register(new RandomStatePatternParser(worldEdit)); register(new BlockCategoryPatternParser(worldEdit)); + + // FAWE + register(new SimplexPatternParser(worldEdit)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/RichParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/RichParser.java new file mode 100644 index 000000000..6bd9261fa --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/RichParser.java @@ -0,0 +1,118 @@ +package com.sk89q.worldedit.extension.factory.parser; + +import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.internal.registry.InputParser; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import java.util.stream.Stream; + +/** + * A rich parser allows parsing of patterns and masks with extra arguments, + * e.g. #simplex[scale][pattern]. + * + * @param the parse result. + */ +public abstract class RichParser extends InputParser { + private final String prefix; + private final String required; + + /** + * Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}. + * + * @param worldEdit the worldedit instance. + * @param prefix the prefix of this parser result. + */ + protected RichParser(WorldEdit worldEdit, String prefix) { + super(worldEdit); + this.prefix = prefix; + this.required = prefix + "["; + } + + @Override + public Stream getSuggestions(String input) { + // we don't even want to start suggesting if it's not meant to be this parser result + if (input.length() > this.required.length() && !input.startsWith(this.required)) { + return Stream.empty(); + } + // suggest until the first [ as long as it isn't fully typed + if (input.length() < this.required.length()) { + return Stream.of(this.required).filter(s -> s.startsWith(input)); + } + // we know that it is at least "" + String[] strings = extractArguments(input.substring(this.prefix.length()), false); + StringJoiner joiner = new StringJoiner(","); + for (int i = 0; i < strings.length - 1; i++) { + joiner.add("[" + strings[i] + "]"); + } + String previous = this.prefix + joiner; + return getSuggestions(strings[strings.length - 1], strings.length - 1).map(s -> previous + "[" + s + "]"); + } + + @Override + public E parseFromInput(String input, ParserContext context) throws InputParseException { + if (!input.startsWith(this.prefix)) return null; + if (input.length() < this.prefix.length()) return null; + String[] arguments = extractArguments(input.substring(prefix.length()), true); + return parseFromInput(arguments, context); + } + + /** + * Returns a stream of suggestions for the argument at the given index. + * + * @param argumentInput the already provided input for the argument at the given index. + * @param index the index of the argument to get suggestions for. + * @return a stream of suggestions matching the given input for the argument at the given index. + */ + protected abstract Stream getSuggestions(String argumentInput, int index); + + /** + * Parses the already split arguments. + * + * @param arguments the array of arguments that were split (can be empty). + * @param context the context of this parsing process. + * @return the resulting parsed type. + * @throws InputParseException if the input couldn't be parsed correctly. + */ + protected abstract E parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException; + + /** + * Extracts arguments enclosed by {@code []} into an array. + * Example: {@code [Hello][World]} results in a list containing {@code Hello} and {@code World}. + * + * @param input the input to extract arguments from. + * @param requireClosing whether or not the extraction requires valid bracketing. + * @return an array of extracted arguments. + * @throws InputParseException if {@code requireClosing == true} and the count of [ != the count of ] + */ + protected String[] extractArguments(String input, boolean requireClosing) throws InputParseException { + int open = 0; // the "level" + int openIndex = 0; + int i = 0; + List arguments = new ArrayList<>(); + for (; i < input.length(); i++) { + if (input.charAt(i) == '[') { + if (open++ == 0) { + openIndex = i; + } + } + if (input.charAt(i) == ']') { + if (--open == 0) { + arguments.add(input.substring(openIndex + 1, i)); + } + } + } + if (!requireClosing && open > 0) { + arguments.add(input.substring(openIndex + 1)); + } + if (requireClosing && open != 0) { + throw new InputParseException("Invalid bracketing, are you missing a '[' or ']'?"); + } + return arguments.toArray(new String[0]); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java index 81b1b11e3..66c55be3e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java @@ -38,8 +38,9 @@ public class RandomPatternParser extends InputParser { @Override public Stream getSuggestions(String input) { - String[] splits = input.split(",", -1); - List patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true); + List patterns = StringUtil.split(input, ',', '[', ']'); + /*String[] splits = input.split(",", -1); + List patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true);*/ if (patterns.size() == 1) { return Stream.empty(); } @@ -63,8 +64,9 @@ public class RandomPatternParser extends InputParser { public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { RandomPattern randomPattern = new RandomPattern(); - String[] splits = input.split(",", -1); - List patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true); + List patterns = StringUtil.split(input, ',', '[', ']'); + /*String[] splits = input.split(",", -1); + List patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true);*/ if (patterns.size() == 1) { return null; // let a 'single'-pattern parser handle it } @@ -74,7 +76,7 @@ public class RandomPatternParser extends InputParser { // Parse special percentage syntax if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) { - String[] p = token.split("%"); + String[] p = token.split("%", 2); if (p.length < 2) { throw new InputParseException("Missing the type after the % symbol for '" + input + "'"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SimplexPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SimplexPatternParser.java new file mode 100644 index 000000000..547f96390 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SimplexPatternParser.java @@ -0,0 +1,75 @@ +package com.sk89q.worldedit.extension.factory.parser.pattern; + +import com.boydti.fawe.object.random.SimplexRandom; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.factory.parser.RichParser; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.pattern.RandomPattern; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import org.jetbrains.annotations.NotNull; + +import java.util.stream.Stream; + +public class SimplexPatternParser extends RichParser { + private static final String SIMPLEX_PREFIX = "#simplex"; + + public SimplexPatternParser(WorldEdit worldEdit) { + super(worldEdit, SIMPLEX_PREFIX); + } + + @Override + protected Stream getSuggestions(String argumentInput, int index) { + if (index == 0) { + if (argumentInput.isEmpty()) { + return Stream.of("1", "2", "3", "4", "5", "6", "7", "8", "9"); + } + // if already a valid number, suggest more digits + if (isDouble(argumentInput)) { + Stream numbers = Stream.of("", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); + if (argumentInput.indexOf('.') == -1) { + numbers = Stream.concat(numbers, Stream.of(".")); + } + return numbers.map(s -> argumentInput + s); + } + // no valid input anymore + return Stream.empty(); + } + if (index == 1) { + return worldEdit.getPatternFactory().getSuggestions(argumentInput).stream(); + } + return Stream.empty(); + } + + @Override + protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) { + if (arguments.length != 2) { + throw new InputParseException("Simplex requires a scale and a pattern, e.g. #simplex[5][dirt,stone]"); + } + double scale = Double.parseDouble(arguments[0]); + scale = 1d / Math.max(1, scale); + Pattern inner = worldEdit.getPatternFactory().parseFromInput(arguments[1], context); + if (inner instanceof RandomPattern) { + return new RandomPattern(new SimplexRandom(scale), (RandomPattern) inner); + } else if (inner instanceof BlockStateHolder) { + return inner; // single blocks won't have any impact on how simplex behaves + } else { + throw new InputParseException("Pattern " + inner.getClass().getSimpleName() + " cannot be used with #simplex"); + } + } + + private static boolean isDouble(String input) { + boolean point = false; + for (char c : input.toCharArray()) { + if (!Character.isDigit(c)) { + if (c == '.' && !point) { + point = true; + } else { + return false; + } + } + } + return true; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java index d5ecc2b44..3e02cdfaa 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java @@ -52,6 +52,19 @@ public class RandomPattern extends AbstractPattern { this.random = random; } + /** + * Create a random pattern from an existing one but with a different random. + * + * @param random the new random to use. + * @param parent the existing random pattern. + */ + public RandomPattern(SimpleRandom random, RandomPattern parent) { + this.random = random; + this.weights = parent.weights; + this.collection = RandomCollection.of(weights, random); + this.patterns = parent.patterns; + } + /** * Add a pattern to the weight list of patterns. * From efc1a888d852f377a01a4ebcaf2682f6ca70e33d Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 1 Jul 2020 13:17:19 +0100 Subject: [PATCH 13/14] update links, versions, etc --- README.md | 4 ++-- build.gradle.kts | 2 +- worldedit-core/src/main/java/com/boydti/fawe/Fawe.java | 2 +- worldedit-core/src/main/java/com/boydti/fawe/FaweVersion.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ae6f79e90..09b28f24b 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ FAWE is a fork of WorldEdit that has huge speed and memory improvements and cons ## Downloads ### 1.13+ * [Download](https://intellectualsites.github.io/download/fawe.html) -* [Jenkins](https://ci.athion.net/job/FastAsyncWorldEdit-1.15/) +* [Jenkins](https://ci.athion.net/job/FastAsyncWorldEdit-1.16/) ### < 1.12.2 * [Download](https://intellectualsites.github.io/download/fawe.html) @@ -35,7 +35,7 @@ $ gradlew setupDecompWorkspace $ gradlew build ``` -The jar is located in `worldedit-bukkit/build/libs/FastAsyncWorldEdit-1.15-###.jar` +The jar is located in `worldedit-bukkit/build/libs/FastAsyncWorldEdit-1.16-###.jar` ## Contributing Have an idea for an optimization, or a cool feature? diff --git a/build.gradle.kts b/build.gradle.kts index b6e47f76c..84e6e066f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ logger.lifecycle(""" ******************************************* """) //TODO FIX THIS WHEN I FEEL LIKE IT -var rootVersion = "1.15" +var rootVersion = "1.16" var revision: String = "" var buildNumber = "" var date: String = "" diff --git a/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java b/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java index 6f61bdda8..6675390eb 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/Fawe.java @@ -305,7 +305,7 @@ public class Fawe { br.close(); this.version = FaweVersion.tryParse(versionString, commitString, dateString); Settings.IMP.DATE = new Date(100 + version.year, version.month, version.day).toGMTString(); - Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-1.15/" + version.build; + Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-1.16/" + version.build; Settings.IMP.COMMIT = "https://github.com/IntellectualSites/FastAsyncWorldEdit/commit/" + Integer.toHexString(version.hash); } catch (Throwable ignore) {} try { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweVersion.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweVersion.java index 7fd480dfb..3c4f08062 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweVersion.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweVersion.java @@ -32,9 +32,9 @@ public class FaweVersion { @Override public String toString() { if (hash == 0 && build == 0) { - return "FastAsyncWorldEdit-1.15-NoVer-SNAPSHOT"; + return "FastAsyncWorldEdit-1.16-NoVer-SNAPSHOT"; } else { - return "FastAsyncWorldEdit-1.15" + build; + return "FastAsyncWorldEdit-1.16" + build; } } From fdbef4e12c930d90c790c797d9c28eab17a7f85e Mon Sep 17 00:00:00 2001 From: N0tMyFaultOG Date: Wed, 1 Jul 2020 14:22:04 +0200 Subject: [PATCH 14/14] Update DummyFawe.src --- .../src/main/resources/DummyFawe.src | Bin 2052 -> 2052 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/worldedit-bukkit/src/main/resources/DummyFawe.src b/worldedit-bukkit/src/main/resources/DummyFawe.src index c0bd44906fdc650d680bfea40a15958905c85d57..53af3b0077288d3e919e92ebf5eea14e88e450bf 100644 GIT binary patch delta 1086 zcmV-E1i|}+5QGr05&{T>a^X-tvPHv_8Uh-B+%^n`?*r_A801*&8rT#l(7h#S0`!nv zdnkIKCE8Y378O#O8Ryqm_RP*E+tJ6I2Igauq9p2-9nAQ&{|pj7$l}yr#8!XOCfx02 zFz#uuXzqGibTHijN9;aYaL;$U1F{%O_IHon<8R&LySp8D^KgBfp8lF1#V`@e)Bf*& zPqR0SzrVlVe}ND_{(*=4{hv(kgC}e0ey@qO5Wj!C-+!g>W%&%zhJWsM9(gvh`jn@; z-G0C2;4KCD7J*T357(c@VSVLkA2{O6Lp2$z8Qqoozk@FE5>UUsxDoy0L8N0Guc3d4 zF@Tk~Y?ir^#;p+7_*cN1*@W(wH<^Kdo{f7OjQrKkXbE&VX_f=#Fi{iE5RB>u;`B%A;5NN=s!)ShO5lJE!?Xz8fRSJ7l!fnqOB?Ae zsD|t`9bKs=ujG*a)hVU``3alQ-tcj@jh1?_4>QPf1qlpJ))~)o=#bMCk?YiAjnl{t zsQ3vP8^9DAB{YCO&OU7yX+al;+31!uC-C_Kr-e(rbkS+5F^mmNI$-+L>vEifgBj0x zMJFLPksu14ZU8m5k_t_l=dpo*3=_w++2$FV9RHi9Fi_Y2Ld-7kbIb3h^~^q2pfnh) zAS&{q#!!+J7M7YPbOE^nIS7%#n(wukN3d2Z%#eChjggrsOciLRY7NS}^#U;#`{heY zp|BNRnEd%FXi=SaJ4qed&e1wHU7X#bj)gV5+PXmFXt5y|a;fX8hM`e^3{534u7H69 zyNHoar#{40N>OwTA*HZ*UnxBKLe+loHklzG)Pa|Yf|R91Oj^<#^$aI$VY;Nbp$TM6 z?Lka_bMzc#>Ux{nYdTVG8AB#r@#JI8i88Eg#YHXmA7G+og<@wcDAg zNx_YJm9k~5d^%mW&8ci3Imw1l85#Mt+eoo_1tOcol1;bDGBW_LZNJD^?xV3~rgR0| zfNCa}1DDG~f&dR{QMSSjmPkJg#@b5O;xT`Qt?$=6kml{nPR_-D$-)5&<|7oP)~aWq zFN&HuS$ix>$Q5ygTj!ACZ(8fE zGHblvCvSa63dR?-8nBv7z`4?`+04MT7KTY==_+|`>#)953oz@zdk|{tpUYmoE@)`1@|>k!K^TPkFxE z?e|*_-cpc%BQWai;ri1!tgk%p14n#)s3v1Iqq|c7chDtX0_wLHH=GT-oc>51+@`lq6>9KC2^_Ftm==K>F!D>CvhZzxX(PP_ z)sUU0qbt?qjU3XyI>i(qKVcKv8$Qmq(NYigVFr1rAc4WjI^$Um9deo?a-CYNaT>V+ z6+ay$hOvQ32TY%OU5;~bFylF| z=p@7@5=5cX4WPzWQlUxnJT{PjVd9uJ+dM;)$p zL`6Q-7)p}D!cy~uE+AJR2O%<8^Q{*12-Zr48B%YmF)|Z{sRGSZtwDLWULeL|zkE$8 z6t==ElRsYtEvoZwC#gf*IaelCNt!NI`A@4kg}ABNlSX8Uf_f+OqVn_G=Yq% zJ&4I~j-I1TU2ju+O-HINW5}c{o_wr1QHGVRcxg<#)E&=+_y#8O)`wcq2|}SoUZ8+Z znMxHVG~*O1!-J(3%Tp?UcoJGyF%0`dgow)r2oq#&W19GEdGHjB8>5lz#!+BZX?}7xzcr=&O>4bX zW{ubTW!T5q!16Gp>I9Iwgn;E#)!Z3*}UBwPYVo`>lu>d?`XkpgU)LQ;}4Q%m6 z!*Eq~{{c`-0Rj}0r3M$XLk3#`2uTMvP`1u~7n7z3Fb_36DW|s3)d4j;DW|s3)sy81 EAGbmW