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 55080de5f..33e200737 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 @@ -27,6 +27,7 @@ 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 io.papermc.lib.PaperLib; import net.minecraft.server.v1_15_R1.BiomeBase; import net.minecraft.server.v1_15_R1.BiomeStorage; import net.minecraft.server.v1_15_R1.BlockPosition; @@ -150,7 +151,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl public void setHeightmapToGet(HeightMapType type, int[] data) { BitArray bitArray = new BitArray(9, 256); bitArray.fromRaw(data); - nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); + getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); } public int getChunkZ() { @@ -176,25 +177,25 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl @Override public void removeSectionLighting(int layer, boolean sky) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); if (nibble != null) { lightUpdate = true; synchronized (nibble) { - byte[] bytes = nibble.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibble.getIfSet() : nibble.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } } if (sky) { - SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPositionSky = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky); if (nibble != null) { lightUpdate = true; synchronized (nibbleSky) { - byte[] bytes = nibbleSky.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibbleSky.getIfSet() : nibbleSky.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } @@ -225,7 +226,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl public int getSkyLight(int x, int y, int z) { int layer = y >> 4; if (skyLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -245,7 +246,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl public int getEmmittedLight(int x, int y, int z) { int layer = y >> 4; if (blockLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -352,7 +353,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl private void updateGet(BukkitGetBlocks_1_15_2 get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) { synchronized (get) { - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = sections.clone(); this.reset(); @@ -376,7 +377,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl } @Override - public > T call(IChunkSet set, Runnable finalizer) { + public synchronized > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world) : null; try { @@ -424,7 +425,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer, load(layer).clone()); + copy.storeSection(layer, loadPrivately(layer).clone()); } ChunkSection newSection; @@ -451,19 +452,19 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl synchronized (this) { synchronized (lock) { lock.untilFree(); - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); - } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { + } else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) { this.reset(layer); } else if (lock.isModified()) { this.reset(layer); } - newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode); + newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::loadPrivately, setArr, fastmode); if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); } else { @@ -676,6 +677,14 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl } } + private char[] loadPrivately(int layer) { + if (super.sections[layer].isFull()) { + return super.blocks[layer]; + } else { + return BukkitGetBlocks_1_15_2.this.update(layer, null); + } + } + @Override public synchronized void send(int mask, boolean lighting) { BukkitAdapter_1_15_2.sendChunk(world, chunkX, chunkZ, mask, lighting); 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 acef040e3..20182af7b 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 @@ -27,6 +27,7 @@ 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 io.papermc.lib.PaperLib; import net.minecraft.server.v1_16_R1.BiomeBase; import net.minecraft.server.v1_16_R1.BiomeStorage; import net.minecraft.server.v1_16_R1.BlockPosition; @@ -151,7 +152,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl public void setHeightmapToGet(HeightMapType type, int[] data) { BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256); bitArray.fromRaw(data); - nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); + getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); } public int getChunkZ() { @@ -177,25 +178,25 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl @Override public void removeSectionLighting(int layer, boolean sky) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); if (nibble != null) { lightUpdate = true; synchronized (nibble) { - byte[] bytes = nibble.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibble.getIfSet() : nibble.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } } if (sky) { - SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPositionSky = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky); if (nibble != null) { lightUpdate = true; synchronized (nibbleSky) { - byte[] bytes = nibbleSky.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibbleSky.getIfSet() : nibbleSky.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } @@ -226,7 +227,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl @Override public int getSkyLight(int x, int y, int z) { int layer = y >> 4; if (skyLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -245,7 +246,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl @Override public int getEmmittedLight(int x, int y, int z) { int layer = y >> 4; if (blockLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -352,7 +353,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl private void updateGet(BukkitGetBlocks_1_16_1 get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) { synchronized (get) { - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = sections.clone(); this.reset(); @@ -376,7 +377,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl } @Override - public > T call(IChunkSet set, Runnable finalizer) { + public synchronized > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world) : null; try { @@ -424,7 +425,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer, load(layer).clone()); + copy.storeSection(layer, loadPrivately(layer).clone()); } ChunkSection newSection; @@ -451,20 +452,20 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl synchronized (this) { synchronized (lock) { lock.untilFree(); - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); - } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { + } else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) { this.reset(layer); } else if (lock.isModified()) { this.reset(layer); } newSection = BukkitAdapter_1_16_1 - .newChunkSection(layer, this::load, setArr, fastmode); + .newChunkSection(layer, this::loadPrivately, setArr, fastmode); if (!BukkitAdapter_1_16_1 .setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); @@ -678,6 +679,14 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl } } + private char[] loadPrivately(int layer) { + if (super.sections[layer].isFull()) { + return super.blocks[layer]; + } else { + return BukkitGetBlocks_1_16_1.this.update(layer, null); + } + } + @Override public synchronized void send(int mask, boolean lighting) { BukkitAdapter_1_16_1.sendChunk(world, chunkX, chunkZ, mask, lighting); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index 94d8e2b15..23d47d3f4 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -27,6 +27,7 @@ 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 io.papermc.lib.PaperLib; import net.minecraft.server.v1_16_R2.BiomeBase; import net.minecraft.server.v1_16_R2.BiomeStorage; import net.minecraft.server.v1_16_R2.BlockPosition; @@ -151,7 +152,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl public void setHeightmapToGet(HeightMapType type, int[] data) { BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256); bitArray.fromRaw(data); - nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); + getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); } public int getChunkZ() { @@ -177,25 +178,25 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl @Override public void removeSectionLighting(int layer, boolean sky) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); if (nibble != null) { lightUpdate = true; synchronized (nibble) { - byte[] bytes = nibble.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibble.getIfSet() : nibble.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } } if (sky) { - SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPositionSky = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky); if (nibble != null) { lightUpdate = true; synchronized (nibbleSky) { - byte[] bytes = nibbleSky.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibbleSky.getIfSet() : nibbleSky.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } @@ -227,7 +228,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl public int getSkyLight(int x, int y, int z) { int layer = y >> 4; if (skyLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -247,7 +248,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl public int getEmmittedLight(int x, int y, int z) { int layer = y >> 4; if (blockLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -355,7 +356,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl private void updateGet(BukkitGetBlocks_1_16_2 get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) { synchronized (get) { - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = sections.clone(); this.reset(); @@ -379,7 +380,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl } @Override - public > T call(IChunkSet set, Runnable finalizer) { + public synchronized > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world) : null; try { @@ -427,7 +428,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer, load(layer).clone()); + copy.storeSection(layer, loadPrivately(layer).clone()); } ChunkSection newSection; @@ -454,20 +455,20 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl synchronized (this) { synchronized (lock) { lock.untilFree(); - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); - } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { + } else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) { this.reset(layer); } else if (lock.isModified()) { this.reset(layer); } newSection = BukkitAdapter_1_16_2 - .newChunkSection(layer, this::load, setArr, fastmode); + .newChunkSection(layer, this::loadPrivately, setArr, fastmode); if (!BukkitAdapter_1_16_2 .setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); @@ -681,6 +682,14 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl } } + private char[] loadPrivately(int layer) { + if (super.sections[layer].isFull()) { + return super.blocks[layer]; + } else { + return BukkitGetBlocks_1_16_2.this.update(layer, null); + } + } + @Override public synchronized void send(int mask, boolean lighting) { BukkitAdapter_1_16_2.sendChunk(world, chunkX, chunkZ, mask, lighting); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BlockMaterial_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BlockMaterial_1_16_5.java similarity index 94% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BlockMaterial_1_16_4.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BlockMaterial_1_16_5.java index f3d40b448..9be26c788 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BlockMaterial_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BlockMaterial_1_16_5.java @@ -1,4 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_16_4; +package com.boydti.fawe.bukkit.adapter.mc1_16_5; import com.sk89q.util.ReflectionUtil; import com.sk89q.worldedit.world.registry.BlockMaterial; @@ -12,7 +12,7 @@ import net.minecraft.server.v1_16_R3.ITileEntity; import net.minecraft.server.v1_16_R3.Material; import org.bukkit.craftbukkit.v1_16_R3.block.data.CraftBlockData; -public class BlockMaterial_1_16_4 implements BlockMaterial { +public class BlockMaterial_1_16_5 implements BlockMaterial { private final Block block; private final IBlockData defaultState; private final Material material; @@ -21,11 +21,11 @@ public class BlockMaterial_1_16_4 implements BlockMaterial { private final org.bukkit.Material craftMaterial; private final int opacity; - public BlockMaterial_1_16_4(Block block) { + public BlockMaterial_1_16_5(Block block) { this(block, block.getBlockData()); } - public BlockMaterial_1_16_4(Block block, IBlockData defaultState) { + public BlockMaterial_1_16_5(Block block, IBlockData defaultState) { this.block = block; this.defaultState = defaultState; this.material = defaultState.getMaterial(); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitAdapter_1_16_5.java similarity index 98% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitAdapter_1_16_5.java index e4101a22f..b044166a3 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitAdapter_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitAdapter_1_16_5.java @@ -1,4 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_16_4; +package com.boydti.fawe.bukkit.adapter.mc1_16_5; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; @@ -51,7 +51,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; -public final class BukkitAdapter_1_16_4 extends NMSAdapter { +public final class BukkitAdapter_1_16_5 extends NMSAdapter { /* NMS fields */ @@ -310,7 +310,7 @@ public final class BukkitAdapter_1_16_4 extends NMSAdapter { final int ordinal = paletteToBlock[i]; blockToPalette[ordinal] = Integer.MAX_VALUE; final BlockState state = BlockTypesCache.states[ordinal]; - final IBlockData ibd = ((BlockMaterial_1_16_4) state.getMaterial()).getState(); + final IBlockData ibd = ((BlockMaterial_1_16_5) state.getMaterial()).getState(); palette.a(ibd); } try { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitGetBlocks_1_16_5.java similarity index 92% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitGetBlocks_1_16_5.java index 37a26a089..3d28eedcc 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitGetBlocks_1_16_5.java @@ -1,4 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_16_4; +package com.boydti.fawe.bukkit.adapter.mc1_16_5; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; @@ -9,7 +9,7 @@ import com.boydti.fawe.beta.implementation.lighting.HeightMapType; import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.bukkit.adapter.BukkitGetBlocks; import com.boydti.fawe.bukkit.adapter.DelegateLock; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.nbt.LazyCompoundTag_1_16_5; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.collection.AdaptedMap; import com.boydti.fawe.object.collection.BitArrayUnstretched; @@ -27,6 +27,7 @@ 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 io.papermc.lib.PaperLib; import net.minecraft.server.v1_16_R3.BiomeBase; import net.minecraft.server.v1_16_R3.BiomeStorage; import net.minecraft.server.v1_16_R3.BlockPosition; @@ -76,12 +77,12 @@ import java.util.function.Function; import static org.slf4j.LoggerFactory.getLogger; -public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBlocks { +public class BukkitGetBlocks_1_16_5 extends CharGetBlocks implements BukkitGetBlocks { - private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_4.class); + private static final Logger log = LoggerFactory.getLogger(BukkitGetBlocks_1_16_5.class); private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private static final Function nmsTile2We = tileEntity -> new LazyCompoundTag_1_16_4(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); + private static final Function nmsTile2We = tileEntity -> new LazyCompoundTag_1_16_5(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); public ChunkSection[] sections; public Chunk nmsChunk; public WorldServer world; @@ -90,15 +91,15 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl public NibbleArray[] blockLight = new NibbleArray[16]; public NibbleArray[] skyLight = new NibbleArray[16]; private boolean createCopy = false; - private BukkitGetBlocks_1_16_4_Copy copy = null; + private BukkitGetBlocks_1_16_5_Copy copy = null; private boolean forceLoadSections = true; private boolean lightUpdate = false; - public BukkitGetBlocks_1_16_4(World world, int chunkX, int chunkZ) { + public BukkitGetBlocks_1_16_5(World world, int chunkX, int chunkZ) { this(((CraftWorld) world).getHandle(), chunkX, chunkZ); } - public BukkitGetBlocks_1_16_4(WorldServer world, int chunkX, int chunkZ) { + public BukkitGetBlocks_1_16_5(WorldServer world, int chunkX, int chunkZ) { this.world = world; this.chunkX = chunkX; this.chunkZ = chunkZ; @@ -151,7 +152,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl public void setHeightmapToGet(HeightMapType type, int[] data) { BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256); bitArray.fromRaw(data); - nmsChunk.heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); + getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a(bitArray.getData()); } public int getChunkZ() { @@ -177,25 +178,25 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl @Override public void removeSectionLighting(int layer, boolean sky) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibble = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(sectionPosition); if (nibble != null) { lightUpdate = true; synchronized (nibble) { - byte[] bytes = nibble.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibble.getIfSet() : nibble.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } } if (sky) { - SectionPosition sectionPositionSky = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPositionSky = SectionPosition.a(getChunk().getPos(), layer); NibbleArray nibbleSky = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(sectionPositionSky); if (nibble != null) { lightUpdate = true; synchronized (nibbleSky) { - byte[] bytes = nibbleSky.getCloneIfSet(); - if (bytes != NibbleArray.EMPTY_NIBBLE) { + byte[] bytes = PaperLib.isPaper() ? nibbleSky.getIfSet() : nibbleSky.asBytes(); + if (!PaperLib.isPaper() || bytes != NibbleArray.EMPTY_NIBBLE) { Arrays.fill(bytes, (byte) 0); } } @@ -211,7 +212,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl if (tileEntity == null) { return null; } - return new LazyCompoundTag_1_16_4(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); + return new LazyCompoundTag_1_16_5(Suppliers.memoize(() -> tileEntity.save(new NBTTagCompound()))); } @Override @@ -227,7 +228,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl public int getSkyLight(int x, int y, int z) { int layer = y >> 4; if (skyLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -247,7 +248,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl public int getEmmittedLight(int x, int y, int z) { int layer = y >> 4; if (blockLight[layer] == null) { - SectionPosition sectionPosition = SectionPosition.a(nmsChunk.getPos(), layer); + SectionPosition sectionPosition = SectionPosition.a(getChunk().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) { @@ -353,9 +354,9 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl }; } - private void updateGet(BukkitGetBlocks_1_16_4 get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) { + private void updateGet(BukkitGetBlocks_1_16_5 get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) { synchronized (get) { - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = sections.clone(); this.reset(); @@ -375,13 +376,13 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl } public Chunk ensureLoaded(net.minecraft.server.v1_16_R3.World nmsWorld, int chunkX, int chunkZ) { - return BukkitAdapter_1_16_4.ensureLoaded(nmsWorld, chunkX, chunkZ); + return BukkitAdapter_1_16_5.ensureLoaded(nmsWorld, chunkX, chunkZ); } @Override - public > T call(IChunkSet set, Runnable finalizer) { + public synchronized > T call(IChunkSet set, Runnable finalizer) { forceLoadSections = false; - copy = createCopy ? new BukkitGetBlocks_1_16_4_Copy(world) : null; + copy = createCopy ? new BukkitGetBlocks_1_16_5_Copy(world) : null; try { WorldServer nmsWorld = world; Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); @@ -427,14 +428,14 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl char[] setArr = set.load(layer).clone(); if (createCopy) { - copy.storeSection(layer, load(layer).clone()); + copy.storeSection(layer, loadPrivately(layer).clone()); } ChunkSection newSection; ChunkSection existingSection = sections[layer]; if (existingSection == null) { - newSection = BukkitAdapter_1_16_4.newChunkSection(layer, setArr, fastmode); - if (BukkitAdapter_1_16_4.setSectionAtomic(sections, null, newSection, layer)) { + newSection = BukkitAdapter_1_16_5.newChunkSection(layer, setArr, fastmode); + if (BukkitAdapter_1_16_5.setSectionAtomic(sections, null, newSection, layer)) { updateGet(this, nmsChunk, sections, newSection, setArr, layer); continue; } else { @@ -446,29 +447,29 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl } } } - BukkitAdapter_1_16_4.fieldTickingBlockCount.set(existingSection, (short) 0); + BukkitAdapter_1_16_5.fieldTickingBlockCount.set(existingSection, (short) 0); //ensure that the server doesn't try to tick the chunksection while we're editing it. - DelegateLock lock = BukkitAdapter_1_16_4.applyLock(existingSection); + DelegateLock lock = BukkitAdapter_1_16_5.applyLock(existingSection); synchronized (this) { synchronized (lock) { lock.untilFree(); - if (this.nmsChunk != nmsChunk) { + if (this.getChunk() != nmsChunk) { this.nmsChunk = nmsChunk; this.sections = null; this.reset(); } else if (existingSection != getSections(false)[layer]) { this.sections[layer] = existingSection; this.reset(); - } else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) { + } else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) { this.reset(layer); } else if (lock.isModified()) { this.reset(layer); } - newSection = BukkitAdapter_1_16_4 - .newChunkSection(layer, this::load, setArr, fastmode); - if (!BukkitAdapter_1_16_4 + newSection = BukkitAdapter_1_16_5 + .newChunkSection(layer, this::loadPrivately, setArr, fastmode); + if (!BukkitAdapter_1_16_5 .setSectionAtomic(sections, existingSection, newSection, layer)) { log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer); } else { @@ -502,10 +503,10 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl Map heightMaps = set.getHeightMaps(); for (Map.Entry entry : heightMaps.entrySet()) { - BukkitGetBlocks_1_16_4.this.setHeightmapToGet(entry.getKey(), entry.getValue()); + BukkitGetBlocks_1_16_5.this.setHeightmapToGet(entry.getKey(), entry.getValue()); } - BukkitGetBlocks_1_16_4.this.setLightingToGet(set.getLight()); - BukkitGetBlocks_1_16_4.this.setSkyLightingToGet(set.getSkyLight()); + BukkitGetBlocks_1_16_5.this.setLightingToGet(set.getLight()); + BukkitGetBlocks_1_16_5.this.setSkyLightingToGet(set.getSkyLight()); Runnable[] syncTasks = null; @@ -551,7 +552,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); if (idTag == null || posTag == null || rotTag == null) { getLogger( - BukkitGetBlocks_1_16_4.class).debug("Unknown entity tag: " + nativeTag); + BukkitGetBlocks_1_16_5.class).debug("Unknown entity tag: " + nativeTag); continue; } final double x = posTag.getDouble(0); @@ -681,9 +682,17 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl } } + private char[] loadPrivately(int layer) { + if (super.sections[layer].isFull()) { + return super.blocks[layer]; + } else { + return BukkitGetBlocks_1_16_5.this.update(layer, null); + } + } + @Override public synchronized void send(int mask, boolean lighting) { - BukkitAdapter_1_16_4.sendChunk(world, chunkX, chunkZ, mask, lighting); + BukkitAdapter_1_16_5.sendChunk(world, chunkX, chunkZ, mask, lighting); } @Override @@ -699,7 +708,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl data = new char[4096]; Arrays.fill(data, (char) 1); } - DelegateLock lock = BukkitAdapter_1_16_4.applyLock(section); + DelegateLock lock = BukkitAdapter_1_16_5.applyLock(section); synchronized (lock) { lock.untilFree(); lock.setModified(false); @@ -708,10 +717,10 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl FAWE_Spigot_v1_16_R3 adapter = ((FAWE_Spigot_v1_16_R3) WorldEditPlugin.getInstance().getBukkitImplAdapter()); final DataPaletteBlock blocks = section.getBlocks(); - final DataBits bits = (DataBits) BukkitAdapter_1_16_4.fieldBits.get(blocks); - final DataPalette palette = (DataPalette) BukkitAdapter_1_16_4.fieldPalette.get(blocks); + final DataBits bits = (DataBits) BukkitAdapter_1_16_5.fieldBits.get(blocks); + final DataPalette palette = (DataPalette) BukkitAdapter_1_16_5.fieldPalette.get(blocks); - final int bitsPerEntry = (int) BukkitAdapter_1_16_4.fieldBitsPerEntry.get(bits); + final int bitsPerEntry = (int) BukkitAdapter_1_16_5.fieldBitsPerEntry.get(bits); final long[] blockStates = bits.a(); new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); @@ -878,7 +887,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl try { final DataPaletteBlock blocksExisting = existing.getBlocks(); - final DataPalette palette = (DataPalette) BukkitAdapter_1_16_4.fieldPalette.get(blocksExisting); + final DataPalette palette = (DataPalette) BukkitAdapter_1_16_5.fieldPalette.get(blocksExisting); int paletteSize; if (palette instanceof DataPaletteLinear) { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitGetBlocks_1_16_5_Copy.java similarity index 92% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitGetBlocks_1_16_5_Copy.java index 02149eaaa..52d9adc28 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/BukkitGetBlocks_1_16_5_Copy.java @@ -1,4 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_16_4; +package com.boydti.fawe.bukkit.adapter.mc1_16_5; import com.boydti.fawe.FaweCache; @@ -6,7 +6,7 @@ import com.boydti.fawe.beta.IBlocks; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.implementation.lighting.HeightMapType; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.nbt.LazyCompoundTag_1_16_5; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -35,7 +35,7 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.Future; -public class BukkitGetBlocks_1_16_4_Copy implements IChunkGet { +public class BukkitGetBlocks_1_16_5_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); @@ -43,13 +43,13 @@ public class BukkitGetBlocks_1_16_4_Copy implements IChunkGet { private final char[][] blocks = new char[16][]; private final WorldServer world; - protected BukkitGetBlocks_1_16_4_Copy(WorldServer world) { + protected BukkitGetBlocks_1_16_5_Copy(WorldServer world) { this.world = world; } protected void storeTile(TileEntity tile) { tiles.put(BlockVector3.at(tile.getPosition().getX(), tile.getPosition().getY(), tile.getPosition().getZ()), - new LazyCompoundTag_1_16_4(Suppliers.memoize(() -> tile.save(new NBTTagCompound())))); + new LazyCompoundTag_1_16_5(Suppliers.memoize(() -> tile.save(new NBTTagCompound())))); } @Override @@ -115,7 +115,7 @@ public class BukkitGetBlocks_1_16_4_Copy implements IChunkGet { public void setHeightmapToGet(HeightMapType type, int[] data) {} protected void storeBiomes(BiomeStorage biomeStorage) { - this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_4.getBiomeArray(biomeStorage).clone()); + this.biomeStorage = new BiomeStorage(biomeStorage.registry, BukkitAdapter_1_16_5.getBiomeArray(biomeStorage).clone()); } @Override diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/FAWEWorldNativeAccess_1_16_R3.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/FAWEWorldNativeAccess_1_16_R3.java similarity index 98% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/FAWEWorldNativeAccess_1_16_R3.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/FAWEWorldNativeAccess_1_16_R3.java index be1bd4082..2795bb0a2 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/FAWEWorldNativeAccess_1_16_R3.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/FAWEWorldNativeAccess_1_16_R3.java @@ -1,4 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_16_4; +package com.boydti.fawe.bukkit.adapter.mc1_16_5; import com.boydti.fawe.Fawe; import com.boydti.fawe.object.IntPair; @@ -214,7 +214,7 @@ public class FAWEWorldNativeAccess_1_16_R3 implements WorldNativeAccess cc.chunk.setType(cc.position, cc.blockData, sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE))); for (IntPair chunk : cachedChunksToSend) { - BukkitAdapter_1_16_4.sendChunk(getWorld().getWorld().getHandle(), chunk.x, chunk.z, 0, false); + BukkitAdapter_1_16_5.sendChunk(getWorld().getWorld().getHandle(), chunk.x, chunk.z, 0, false); } } }; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/MapChunkUtil_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/MapChunkUtil_1_16_5.java similarity index 85% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/MapChunkUtil_1_16_4.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/MapChunkUtil_1_16_5.java index 37993c9fe..f7369ed5f 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/MapChunkUtil_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/MapChunkUtil_1_16_5.java @@ -1,10 +1,10 @@ -package com.boydti.fawe.bukkit.adapter.mc1_16_4; +package com.boydti.fawe.bukkit.adapter.mc1_16_5; import com.boydti.fawe.bukkit.adapter.MapChunkUtil; import net.minecraft.server.v1_16_R3.PacketPlayOutMapChunk; -public class MapChunkUtil_1_16_4 extends MapChunkUtil { - public MapChunkUtil_1_16_4() throws NoSuchFieldException { +public class MapChunkUtil_1_16_5 extends MapChunkUtil { + public MapChunkUtil_1_16_5() throws NoSuchFieldException { fieldX = PacketPlayOutMapChunk.class.getDeclaredField("a"); fieldZ = PacketPlayOutMapChunk.class.getDeclaredField("b"); fieldBitMask = PacketPlayOutMapChunk.class.getDeclaredField("c"); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/nbt/LazyCompoundTag_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/nbt/LazyCompoundTag_1_16_5.java similarity index 93% rename from worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/nbt/LazyCompoundTag_1_16_4.java rename to worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/nbt/LazyCompoundTag_1_16_5.java index 73e416f35..ad1646216 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/nbt/LazyCompoundTag_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_5/nbt/LazyCompoundTag_1_16_5.java @@ -1,4 +1,4 @@ -package com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt; +package com.boydti.fawe.bukkit.adapter.mc1_16_5.nbt; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.ListTag; @@ -17,17 +17,17 @@ import java.util.List; import java.util.Map; import java.util.function.Supplier; -public class LazyCompoundTag_1_16_4 extends CompoundTag { +public class LazyCompoundTag_1_16_5 extends CompoundTag { private final Supplier nmsTag; private CompoundTag cachedValue; - public LazyCompoundTag_1_16_4(Supplier tag) { + public LazyCompoundTag_1_16_5(Supplier tag) { super(new HashMap<>()); this.nmsTag = tag; } - public LazyCompoundTag_1_16_4(NBTTagCompound tag) { + public LazyCompoundTag_1_16_5(NBTTagCompound tag) { this(() -> tag); } @@ -94,7 +94,7 @@ public class LazyCompoundTag_1_16_4 extends CompoundTag { NBTTagList nbtList = (NBTTagList) tag; for (NBTBase elem : nbtList) { if (elem instanceof NBTTagCompound) { - list.add(new LazyCompoundTag_1_16_4((NBTTagCompound) elem)); + list.add(new LazyCompoundTag_1_16_5((NBTTagCompound) elem)); } else { list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); } 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 dec7822ca..b7c5b93af 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 @@ -144,7 +144,7 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I } @Override - public BlockMaterial getMaterial(BlockState state) { + public synchronized BlockMaterial getMaterial(BlockState state) { IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); return new BlockMaterial_1_15_2(bs.getBlock(), bs); } 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 a9b95121f..f0a82bfab 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 @@ -144,7 +144,7 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I } @Override - public BlockMaterial getMaterial(BlockState state) { + public synchronized BlockMaterial getMaterial(BlockState state) { IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); return new BlockMaterial_1_16_1(bs.getBlock(), bs); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java index 681e4a7f0..690d8e2a7 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R2.java @@ -146,7 +146,7 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I } @Override - public BlockMaterial getMaterial(BlockState state) { + public synchronized BlockMaterial getMaterial(BlockState state) { IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); return new BlockMaterial_1_16_2(bs.getBlock(), bs); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java index 796379693..bad4e7b68 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_16_R3.java @@ -22,12 +22,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.implementation.packet.ChunkPacket; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.BlockMaterial_1_16_4; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.BukkitAdapter_1_16_4; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.BukkitGetBlocks_1_16_4; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.FAWEWorldNativeAccess_1_16_R3; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.MapChunkUtil_1_16_4; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.BlockMaterial_1_16_5; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.BukkitAdapter_1_16_5; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.BukkitGetBlocks_1_16_5; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.FAWEWorldNativeAccess_1_16_R3; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.MapChunkUtil_1_16_5; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.nbt.LazyCompoundTag_1_16_5; import com.google.common.base.Preconditions; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.StringTag; @@ -130,7 +130,7 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; - BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial(); + BlockMaterial_1_16_5 material = (BlockMaterial_1_16_5) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); char ordinal = state.getOrdinalChar(); ibdToStateOrdinal[id] = ordinal; @@ -142,13 +142,13 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I @Override public BlockMaterial getMaterial(BlockType blockType) { Block block = getBlock(blockType); - return new BlockMaterial_1_16_4(block); + return new BlockMaterial_1_16_5(block); } @Override - public BlockMaterial getMaterial(BlockState state) { + public synchronized BlockMaterial getMaterial(BlockState state) { IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new BlockMaterial_1_16_4(bs.getBlock(), bs); + return new BlockMaterial_1_16_5(bs.getBlock(), bs); } public Block getBlock(BlockType blockType) { @@ -195,14 +195,14 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I World nmsWorld = nmsChunk.getWorld(); BlockPosition blockPos = new BlockPosition(x, y, z); - IBlockData blockData = ((BlockMaterial_1_16_4) state.getMaterial()).getState(); + IBlockData blockData = ((BlockMaterial_1_16_5) state.getMaterial()).getState(); ChunkSection[] sections = nmsChunk.getSections(); int y4 = y >> 4; ChunkSection section = sections[y4]; IBlockData existing; if (section == null) { - existing = ((BlockMaterial_1_16_4) BlockTypes.AIR.getDefaultState().getMaterial()).getState(); + existing = ((BlockMaterial_1_16_5) BlockTypes.AIR.getDefaultState().getMaterial()).getState(); } else { existing = section.getType(x & 15, y & 15, z & 15); } @@ -303,7 +303,7 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I @Override public OptionalInt getInternalBlockStateId(BlockState state) { - BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial(); + BlockMaterial_1_16_5 material = (BlockMaterial_1_16_5) state.getMaterial(); IBlockData mcState = material.getCraftBlockData().getState(); return OptionalInt.of(Block.REGISTRY_ID.getId(mcState)); } @@ -366,16 +366,16 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I @Override public > BlockData adapt(B state) { - BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial(); + BlockMaterial_1_16_5 material = (BlockMaterial_1_16_5) state.getMaterial(); return material.getCraftBlockData(); } - private MapChunkUtil_1_16_4 mapUtil = new MapChunkUtil_1_16_4(); + private MapChunkUtil_1_16_5 mapUtil = new MapChunkUtil_1_16_5(); @Override public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) { WorldServer nmsWorld = ((CraftWorld) world).getHandle(); - PlayerChunk map = BukkitAdapter_1_16_4.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ()); + PlayerChunk map = BukkitAdapter_1_16_5.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ()); if (map != null && map.hasBeenLoaded()) { boolean flag = false; PlayerChunk.d players = map.players; @@ -428,8 +428,8 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I @Override public NBTBase fromNative(Tag foreign) { - if (foreign instanceof LazyCompoundTag_1_16_4) { - return ((LazyCompoundTag_1_16_4) foreign).get(); + if (foreign instanceof LazyCompoundTag_1_16_5) { + return ((LazyCompoundTag_1_16_5) foreign).get(); } return parent.fromNative(foreign); } @@ -441,7 +441,7 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I @Override public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new BukkitGetBlocks_1_16_4(world, chunkX, chunkZ); + return new BukkitGetBlocks_1_16_5(world, chunkX, chunkZ); } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/regen/Regen_v1_16_R3.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/regen/Regen_v1_16_R3.java index 542fd360d..312a3a51c 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/regen/Regen_v1_16_R3.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/regen/Regen_v1_16_R3.java @@ -3,7 +3,7 @@ package com.sk89q.worldedit.bukkit.adapter.impl.regen; import com.boydti.fawe.Fawe; import com.boydti.fawe.beta.IChunkCache; import com.boydti.fawe.beta.IChunkGet; -import com.boydti.fawe.bukkit.adapter.mc1_16_4.BukkitGetBlocks_1_16_4; +import com.boydti.fawe.bukkit.adapter.mc1_16_5.BukkitGetBlocks_1_16_5; import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; @@ -328,7 +328,7 @@ public class Regen_v1_16_R3 extends Regenerator initSourceQueueCache() { - return (chunkX, chunkZ) -> new BukkitGetBlocks_1_16_4(freshNMSWorld, chunkX, chunkZ) { + return (chunkX, chunkZ) -> new BukkitGetBlocks_1_16_5(freshNMSWorld, chunkX, chunkZ) { @Override public Chunk ensureLoaded(World nmsWorld, int x, int z) { return getChunkAt(x, z); diff --git a/worldedit-bukkit/src/main/resources/worldedit-adapters.jar b/worldedit-bukkit/src/main/resources/worldedit-adapters.jar index cc42ab3c0..21a08ec5c 100644 Binary files a/worldedit-bukkit/src/main/resources/worldedit-adapters.jar and b/worldedit-bukkit/src/main/resources/worldedit-adapters.jar differ diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index 4a10276e5..e656cdb9d 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -9,8 +9,6 @@ import org.jetbrains.annotations.Range; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.locks.ReentrantLock; - public abstract class CharBlocks implements IBlocks { public static final Logger logger = LoggerFactory.getLogger(CharBlocks.class); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java index cccda08c3..87f368f06 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NMSRelighter.java @@ -71,6 +71,7 @@ public class NMSRelighter implements Relighter { private final int maxY; private final boolean calculateHeightMaps; private final ReentrantLock lightingLock; + private final AtomicBoolean finished = new AtomicBoolean(false); private boolean removeFirst; public NMSRelighter(IQueueExtent queue, boolean calculateHeightMaps) { @@ -95,10 +96,15 @@ public class NMSRelighter implements Relighter { } @Override - public synchronized ReentrantLock getLock() { + public ReentrantLock getLock() { return lightingLock; } + @Override + public boolean isFinished() { + return finished.get(); + } + @Override public synchronized void removeAndRelight(boolean sky) { removeFirst = true; fixLightingSafe(sky); @@ -839,10 +845,12 @@ public class NMSRelighter implements Relighter { } if (Settings.IMP.LIGHTING.ASYNC) { queue.flush(); + finished.set(true); } else { TaskManager.IMP.sync(new RunnableVal() { @Override public void run(Object value) { queue.flush(); + finished.set(true); } }); } @@ -873,6 +881,7 @@ public class NMSRelighter implements Relighter { Fawe.imp().getPlatformAdapter().sendChunk(chunk.getOrCreateGet(), bitMask, true); iter.remove(); } + finished.set(true); } }; if (Settings.IMP.LIGHTING.ASYNC) { @@ -1000,7 +1009,7 @@ public class NMSRelighter implements Relighter { BlockMaterial material = state.getMaterial(); int opacity = material.getLightOpacity(); int brightness = material.getLightValue(); - if (brightness != iChunk.getEmmittedLight(x, y, z)) { + if (brightness > 0 && brightness != iChunk.getEmmittedLight(x, y, z)) { addLightUpdate(bx + x, y, bz + z); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NullRelighter.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NullRelighter.java index fe9eb28b3..1c345df1b 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NullRelighter.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/NullRelighter.java @@ -53,4 +53,9 @@ public class NullRelighter implements Relighter { public ReentrantLock getLock() { return null; } + + @Override + public boolean isFinished() { + return true; + } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/Relighter.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/Relighter.java index 99f809075..61fbc2d87 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/Relighter.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/lighting/Relighter.java @@ -70,6 +70,13 @@ public interface Relighter { ReentrantLock getLock(); + /** + * Returns true if the Relighter has been flushed + * + * @return true if finished + */ + boolean isFinished(); + class SkipReason { public static final byte NONE = 0; public static final byte AIR = 1; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java index 25c64cbcf..da9a517ff 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java @@ -16,11 +16,14 @@ import com.boydti.fawe.beta.implementation.processors.EmptyBatchProcessor; import com.boydti.fawe.beta.implementation.processors.ExtentBatchProcessorHolder; import com.boydti.fawe.beta.implementation.processors.ProcessorScope; import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MemUtil; import com.google.common.util.concurrent.Futures; import com.sk89q.worldedit.extent.Extent; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutionException; @@ -35,6 +38,9 @@ import java.util.concurrent.locks.ReentrantLock; */ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implements IQueueExtent { + // Don't bother with the full classpath. + private static final Logger log = LoggerFactory.getLogger("SingleThreadQueueExtent"); + // Pool discarded chunks for reuse (can safely be cleared by another thread) // private static final ConcurrentLinkedQueue CHUNK_POOL = new ConcurrentLinkedQueue<>(); // Chunks currently being queued / worked on @@ -108,7 +114,9 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen for (IChunk chunk : this.chunks.values()) { chunk.recycle(); } + getChunkLock.lock(); this.chunks.clear(); + getChunkLock.unlock(); } this.enabledQueue = true; this.lastChunk = null; @@ -157,7 +165,9 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen lastChunk = null; } final long index = MathMan.pairInt(chunk.getX(), chunk.getZ()); + getChunkLock.lock(); chunks.remove(index, chunk); + getChunkLock.unlock(); V future = submitUnchecked(chunk); submissions.add(future); return future; @@ -291,7 +301,15 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen while (future != null) { future = (Future) future.get(); } - } catch (InterruptedException | ExecutionException e) { + } catch (FaweException messageOnly) { + log.warn(messageOnly.getMessage()); + } catch (ExecutionException e) { + if (e.getCause() instanceof FaweException) { + log.warn(e.getCause().getClass().getCanonicalName() + ": " + e.getCause().getMessage()); + } else { + e.printStackTrace(); + } + } catch (InterruptedException e) { e.printStackTrace(); } } @@ -302,7 +320,15 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen while (first != null) { first = (Future) first.get(); } - } catch (InterruptedException | ExecutionException e) { + } catch (FaweException messageOnly) { + log.warn(messageOnly.getMessage()); + } catch (ExecutionException e) { + if (e.getCause() instanceof FaweException) { + log.warn(e.getCause().getClass().getCanonicalName() + ": " + e.getCause().getMessage()); + } else { + e.printStackTrace(); + } + } catch (InterruptedException e) { e.printStackTrace(); } } @@ -313,7 +339,15 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen if (next.isDone()) { try { next = (Future) next.get(); - } catch (InterruptedException | ExecutionException e) { + } catch (FaweException messageOnly) { + log.warn(messageOnly.getMessage()); + } catch (ExecutionException e) { + if (e.getCause() instanceof FaweException) { + log.warn(e.getCause().getClass().getCanonicalName() + ": " + e.getCause().getMessage()); + } else { + e.printStackTrace(); + } + } catch (InterruptedException e) { e.printStackTrace(); } } else { @@ -344,7 +378,9 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen } } } + getChunkLock.lock(); chunks.clear(); + getChunkLock.unlock(); } pollSubmissions(0, true); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java index 7edd24c78..ae335a8e8 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java @@ -389,7 +389,7 @@ public class Settings extends Config { }) public boolean ALLOW_TICK_EXISTING = true; @Comment({ - "Do not wait for a chunk's history to save before sending it", + "[SAFE] Do not wait for a chunk's history to save before sending it", " - Undo/redo commands will wait until the history has been written to disk before executing", " - Requires combine_stages = true" }) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java index 8fd3fd55a..8097f2104 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java @@ -4,7 +4,6 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.brush.visualization.VisualExtent; import com.boydti.fawe.object.mask.IdMask; import com.boydti.fawe.object.visitor.DFSRecursiveVisitor; -import com.boydti.fawe.util.MathMan; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.command.tool.brush.Brush; @@ -14,7 +13,6 @@ import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.math.MathUtils; import com.sk89q.worldedit.math.MutableVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.interpolation.Node; @@ -197,15 +195,15 @@ public class SplineBrush implements Brush, ResettableTool { if (det_max == det_x) { double a = (xz * yz - xy * zz) / det_x; double b = (xy * yz - xz * yy) / det_x; - dir = BlockVector3.at(1.0, (int) MathUtils.roundHalfUp(a), (int) MathUtils.roundHalfUp(b)); + dir = BlockVector3.at(1.0, a, b); } else if (det_max == det_y) { double a = (yz * xz - xy * zz) / det_y; double b = (xy * xz - yz * xx) / det_y; - dir = BlockVector3.at((int) MathUtils.roundHalfUp(a), 1.0, (int) MathUtils.roundHalfUp(b)); + dir = BlockVector3.at(a, 1.0, b); } else { double a = (yz * xy - xz * yy) / det_z; double b = (xz * xy - yz * xx) / det_z; - dir = BlockVector3.at((int) MathUtils.roundHalfUp(a), (int) MathUtils.roundHalfUp(b), 1.0); + dir = BlockVector3.at(a, b, 1.0); } return dir.normalize(); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/extent/PositionTransformExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/object/extent/PositionTransformExtent.java index 17f3215e3..f37f23eee 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/extent/PositionTransformExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/extent/PositionTransformExtent.java @@ -42,7 +42,7 @@ public class PositionTransformExtent extends ResettableExtent { mutable.mutY(pos.getY() - min.getY()); mutable.mutZ(pos.getZ() - min.getZ()); MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3())); - return min.add(tmp.toBlockPoint()); + return min.add(tmp.roundHalfUp().toBlockPoint()); } @Override 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 36870aeef..194eb697a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -1098,16 +1098,16 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { limit.set(originalLimit); try { if (relighter != null && !(relighter instanceof NullRelighter)) { - // Only relight once! - if (!relighter.getLock().tryLock()) { - relighter.getLock().lock(); - relighter.getLock().unlock(); - } else { - if (Settings.IMP.LIGHTING.REMOVE_FIRST) { - relighter.removeAndRelight(true); - } else { - relighter.fixSkyLighting(); - relighter.fixBlockLighting(); + // Don't relight twice! + if (!relighter.isFinished() && relighter.getLock().tryLock()) { + try { + if (Settings.IMP.LIGHTING.REMOVE_FIRST) { + relighter.removeAndRelight(true); + } else { + relighter.fixLightingSafe(true); + } + } finally { + relighter.getLock().unlock(); } } } @@ -1201,10 +1201,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { // Pick how we're going to visit blocks RecursiveVisitor visitor = new DirectionalVisitor(mask, replace, origin, direction, (int) (radius * 2 + 1)); - // With queue enabled, FAWE may start attempting to place chunks before the operation is finished. - // This is unnacceptable for recursive operations. - disableQueue(); - // Start at the origin visitor.visit(origin); @@ -1263,10 +1259,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { visitor = new DownwardVisitor(mask, replace, origin.getBlockY(), (int) (radius * 2 + 1)); } - // With queue enabled, FAWE may start attempting to place chunks before the operation is finished. - // This is unnacceptable for recursive operations. - disableQueue(); - // Start at the origin visitor.visit(origin); @@ -1747,10 +1739,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1)); - // With queue enabled, FAWE may start attempting to place chunks before the operation is finished. - // This is unnacceptable for recursive operations. - disableQueue(); - // Around the origin in a 3x3 block for (BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) { if (mask.test(position)) { @@ -1792,10 +1780,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { BlockReplace replace = new BlockReplace(this, fluid.getDefaultState()); NonRisingVisitor visitor = new NonRisingVisitor(mask, replace); - // With queue enabled, FAWE may start attempting to place chunks before the operation is finished. - // This is unnacceptable for recursive operations. - disableQueue(); - // Around the origin in a 3x3 block for (BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) { if (liquidMask.test(position)) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index be2a307b9..4a8c1840d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -36,6 +36,7 @@ import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.generator.FloraGenerator; +import com.sk89q.worldedit.function.mask.AbstractExtentMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.MaskIntersection; @@ -300,6 +301,9 @@ public class RegionCommands { if (from == null) { from = new ExistingBlockMask(editSession); } + if (from instanceof AbstractExtentMask) { + ((AbstractExtentMask) from).setExtent(editSession); + } int affected = editSession.replaceBlocks(region, from, to); actor.printInfo(TranslatableComponent.of("worldedit.replace.replaced", TextComponent.of(affected))); return affected; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java index 290dca4b6..974167c82 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java @@ -19,11 +19,17 @@ import org.enginehub.piston.exception.StopExecutionException; import org.enginehub.piston.inject.InjectAnnotation; import org.enginehub.piston.inject.InjectedValueAccess; import org.enginehub.piston.inject.Key; +import org.enginehub.piston.inject.MemoizingValueAccess; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -45,6 +51,9 @@ public @interface Confirm { REGION { @Override public boolean passes(Actor actor, InjectedValueAccess context, double value) { + if (checkExisting(context)) { + return true; + } Region region = context.injectedValue(Key.of(Region.class, Selection.class)).orElseThrow(IncompleteRegionException::new); BlockVector3 pos1 = region.getMinimumPoint(); BlockVector3 pos2 = region.getMaximumPoint(); @@ -62,6 +71,9 @@ public @interface Confirm { RADIUS { @Override public boolean passes(Actor actor, InjectedValueAccess context, double value) { + if (checkExisting(context)) { + return true; + } int max = WorldEdit.getInstance().getConfiguration().maxRadius; if (max != -1 && value > max) { actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.radius", @@ -74,6 +86,9 @@ public @interface Confirm { LIMIT { @Override public boolean passes(Actor actor, InjectedValueAccess context, double value) { + if (checkExisting(context)) { + return true; + } int max = 50; //TODO configurable, get Key.of(Method.class) @Limit if (max != -1 && value > max) { actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.limit", @@ -86,6 +101,9 @@ public @interface Confirm { ALWAYS { @Override public boolean passes(Actor actor, InjectedValueAccess context, double value) { + if (checkExisting(context)) { + return true; + } actor.print(TranslatableComponent.of("fawe.cancel.worldedit.cancel.reason.confirm")); return confirm(actor, context); } @@ -96,6 +114,13 @@ public @interface Confirm { } public T check(Actor actor, InjectedValueAccess context, T value) { + boolean isSuggestion = context.injectedValue(Key.of(boolean.class)).orElse(false); + if (isSuggestion) { + return value; + } + if (checkExisting(context)) { + return value; + } if (!passes(actor, context, value.doubleValue())) { throw new StopExecutionException(TextComponent.empty()); } @@ -130,6 +155,24 @@ public @interface Confirm { try { lock.lock(); actor.setMeta("cmdConfirm", wait); + try { + // This is really dumb but also stops the double //confirm requirement... + final MemoizingValueAccess memoizingValueAccess; + if (!(context instanceof MemoizingValueAccess)) { + if (!context.getClass().getSimpleName().contains("AutoValue_CommandParametersImpl")) { + LoggerFactory.getLogger(Confirm.class).warn("InjectedValueAccess " + context.getClass().getName() + " given to Confirm"); + return true; + } + memoizingValueAccess = (MemoizingValueAccess) Reflect.injectedValues.get(context); + } else { + memoizingValueAccess = (MemoizingValueAccess) context; + } + Map, Optional> memory = (Map, Optional>) Reflect.memory.get(memoizingValueAccess); + memory.put(Key.of(InterruptableCondition.class), Optional.of(wait)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + // Waits till 15 seconds then returns false unless awakened if (condition.await(15, TimeUnit.SECONDS)) { return true; } @@ -141,5 +184,39 @@ public @interface Confirm { } return false; } + + boolean checkExisting(InjectedValueAccess context) { + Optional lock = context.injectedValue(Key.of(InterruptableCondition.class)); + // lock if locked will be held by current thread unless something has gone REALLY wrong + // in which case this is the least of our worries... + return lock.isPresent(); + } + } + + class Reflect { + static final Field memory; + static final Field injectedValues; + static { + Field memoryField; + try { + memoryField = MemoizingValueAccess.class.getDeclaredField("memory"); + memoryField.setAccessible(true); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + memoryField = null; + } + memory = memoryField; + + Field injectedValuesField; + try { + Class c = Class.forName("org.enginehub.piston.impl.AutoValue_CommandParametersImpl"); + injectedValuesField = c.getDeclaredField("injectedValues"); + injectedValuesField.setAccessible(true); + } catch (NoSuchFieldException | ClassNotFoundException e) { + e.printStackTrace(); + injectedValuesField = null; + } + injectedValues = injectedValuesField; + } } } 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 dc4741215..3bb76fe2f 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 @@ -609,7 +609,7 @@ public final class PlatformCommandManager { if (actor == null) { context = globalInjectedValues; } else { - context = initializeInjectedValues(args::toString, actor, null); + context = initializeInjectedValues(args::toString, actor, null, false); } return parseCommand(args, context); } @@ -688,7 +688,7 @@ public final class PlatformCommandManager { } } - MemoizingValueAccess context = initializeInjectedValues(event::getArguments, actor, event); + MemoizingValueAccess context = initializeInjectedValues(event::getArguments, actor, event, false); ThrowableSupplier task = () -> commandManager.execute(context, ImmutableList.copyOf(split)); @@ -800,7 +800,7 @@ public final class PlatformCommandManager { getCommandManager(), actor, "//help"); } - private MemoizingValueAccess initializeInjectedValues(Arguments arguments, Actor actor, Event event) { + private MemoizingValueAccess initializeInjectedValues(Arguments arguments, Actor actor, Event event, boolean isSuggestions) { InjectedValueStore store = MapBackedValueStore.create(); store.injectValue(Key.of(Actor.class), ValueProvider.constant(actor)); if (actor instanceof Player) { @@ -817,6 +817,7 @@ public final class PlatformCommandManager { localSession.tellVersion(actor); return Optional.of(localSession); }); + store.injectValue(Key.of(boolean.class), context -> Optional.of(isSuggestions)); store.injectValue(Key.of(InjectedValueStore.class), ValueProvider.constant(store)); store.injectValue(Key.of(Event.class), ValueProvider.constant(event)); return MemoizingValueAccess.wrap( @@ -841,7 +842,7 @@ public final class PlatformCommandManager { List argStrings = split.stream() .map(Substring::getSubstring) .collect(Collectors.toList()); - MemoizingValueAccess access = initializeInjectedValues(() -> arguments, event.getActor(), event); + MemoizingValueAccess access = initializeInjectedValues(() -> arguments, event.getActor(), event, true); ImmutableSet suggestions; try { suggestions = commandManager.getSuggestions(access, argStrings); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/binding/Bindings.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/binding/Bindings.java index ba0916961..38f31c4a3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/binding/Bindings.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/binding/Bindings.java @@ -7,7 +7,9 @@ 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.exception.StopExecutionException; import org.enginehub.piston.inject.InjectedValueAccess; import org.enginehub.piston.inject.InjectedValueStore; import org.enginehub.piston.inject.Key; @@ -97,7 +99,11 @@ public class Bindings { @Override public ConversionResult convert(String s, InjectedValueAccess access) { - return SuccessfulConversion.fromSingle(invoke(s, argsFunc, access, method)); + Object o = invoke(s, argsFunc, access, method); + if (o == null) { + return FailedConversion.from(new NullPointerException()); + } + return SuccessfulConversion.fromSingle(o); } }); } @@ -118,7 +124,10 @@ public class Bindings { } return method.invoke(this, args); } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); + if (!(e.getCause() instanceof StopExecutionException)) { + throw new RuntimeException(e); + } + return null; } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java index 3d3b695c7..4b5e4c7cf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java @@ -120,7 +120,7 @@ public interface InputExtent { * @param position location * @return the light level at the location */ - default int getEmmittedLight(MutableBlockVector3 position) { + default int getEmmittedLight(BlockVector3 position) { return getEmmittedLight(position.getX(), position.getY(), position.getZ()); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java index 6dc337cb9..5fa40ca69 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java @@ -24,13 +24,21 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.LayerFunction; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.BooleanProperty; +import com.sk89q.worldedit.registry.state.EnumProperty; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; +import java.util.Locale; +import java.util.Map; + public class SnowSimulator implements LayerFunction { public static final BooleanProperty snowy = (BooleanProperty) (Property) BlockTypes.GRASS_BLOCK.getProperty("snowy"); + private static final EnumProperty slab = (EnumProperty) (Property) BlockTypes.SANDSTONE_SLAB.getProperty("type"); + private static final EnumProperty stair = (EnumProperty) (Property) BlockTypes.SANDSTONE_STAIRS.getProperty("half"); + private static final EnumProperty trapdoor = (EnumProperty) (Property) BlockTypes.ACACIA_TRAPDOOR.getProperty("half"); + private static final BooleanProperty trapdoorOpen = (BooleanProperty) (Property) BlockTypes.ACACIA_TRAPDOOR.getProperty("open"); private final BlockState ice = BlockTypes.ICE.getDefaultState(); private final BlockState snow = BlockTypes.SNOW.getDefaultState(); @@ -92,6 +100,7 @@ public class SnowSimulator implements LayerFunction { return false; } + // Can't put snow this far up if (position.getBlockY() == this.extent.getMaximumPoint().getBlockY()) { return false; @@ -103,6 +112,22 @@ public class SnowSimulator implements LayerFunction { // Can only replace air (or snow in stack mode) if (!above.getBlockType().getMaterial().isAir() && (!stack || above.getBlockType() != BlockTypes.SNOW)) { return false; + } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && this.extent.getEmmittedLight(abovePosition) > 10) { + return false; + } else if (!block.getBlockType().getMaterial().isFullCube()) { + Map, Object> states = block.getStates(); + if (states.containsKey(slab) && block.getState(slab).equalsIgnoreCase("bottom")) { + return false; + } else if (states.containsKey(trapdoorOpen) && states.containsKey(trapdoor) && (block.getState(trapdoorOpen) + || block.getState(trapdoor).equalsIgnoreCase("bottom"))) { + return false; + } else if (states.containsKey(stair) && block.getState(stair).equalsIgnoreCase("bottom")) { + return false; + } else { + return false; + } + } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && block.getBlockType().getMaterial().isTranslucent()) { + return false; } if (stack && above.getBlockType() == BlockTypes.SNOW) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java index 8189d583e..202efefec 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java @@ -34,9 +34,8 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Tests true if the biome at applied points is the same as the one given. */ -public class BiomeMask extends AbstractMask { +public class BiomeMask extends AbstractExtentMask { - private final Extent extent; private final Set biomes = new HashSet<>(); /** @@ -46,9 +45,8 @@ public class BiomeMask extends AbstractMask { * @param biomes a list of biomes to match */ public BiomeMask(Extent extent, Collection biomes) { - checkNotNull(extent); + super(extent); checkNotNull(biomes); - this.extent = extent; this.biomes.addAll(biomes); } @@ -92,7 +90,7 @@ public class BiomeMask extends AbstractMask { @Override public boolean test(BlockVector3 vector) { - BiomeType biome = extent.getBiome(vector); + BiomeType biome = getExtent().getBiome(vector); return biomes.contains(biome); } @@ -104,7 +102,12 @@ public class BiomeMask extends AbstractMask { @Override public Mask copy() { - return new BiomeMask(extent, new HashSet<>(biomes)); + return new BiomeMask(getExtent(), new HashSet<>(biomes)); } + @Override + public boolean test(Extent extent, BlockVector3 position) { + BiomeType biome = getExtent().getBiome(position); + return biomes.contains(biome); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/block/BlockStateIdAccess.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/block/BlockStateIdAccess.java index bcffdc98f..aa88cfe14 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/block/BlockStateIdAccess.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/block/BlockStateIdAccess.java @@ -20,37 +20,13 @@ package com.sk89q.worldedit.internal.block; import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.registry.BlockRegistry; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import java.util.BitSet; -import java.util.OptionalInt; import javax.annotation.Nullable; -import static com.google.common.base.Preconditions.checkState; - public final class BlockStateIdAccess { private static final int INVALID_ID = -1; - private static final int EXPECTED_BLOCK_COUNT = 2 << 13; - private static final Int2ObjectOpenHashMap TO_STATE = - new Int2ObjectOpenHashMap<>(EXPECTED_BLOCK_COUNT); - - static { - TO_STATE.defaultReturnValue(null); - } - - public interface BlockStateInternalId { - int getInternalId(BlockState blockState); - - void setInternalId(BlockState blockState, int internalId); - } - - private static BlockStateInternalId blockStateInternalId; - - public static void setBlockStateInternalId(BlockStateInternalId blockStateInternalId) { - BlockStateIdAccess.blockStateInternalId = blockStateInternalId; - } /** * An invalid internal ID, for verification purposes. @@ -65,8 +41,7 @@ public final class BlockStateIdAccess { } public static int getBlockStateId(BlockState holder) { - return holder.getOrdinal(); - //return blockStateInternalId.getInternalId(holder); + return holder.getInternalId(); } @Nullable @@ -74,39 +49,6 @@ public final class BlockStateIdAccess { return BlockState.getFromOrdinal(id); } - /** - * For platforms that don't have an internal ID system, - * {@link BlockRegistry#getInternalBlockStateId(BlockState)} will return - * {@link OptionalInt#empty()}. In those cases, we will use our own ID system, - * since it's useful for other entries as well. - * - * @return an unused ID in WorldEdit's ID tracker - */ - private static int provideUnusedWorldEditId() { - return usedIds.nextClearBit(0); - } - - private static final BitSet usedIds = new BitSet(); - - public static void register(BlockState blockState, int id) { - int i = isValidInternalId(id) ? id : provideUnusedWorldEditId(); - BlockState existing = getBlockStateById(id); - checkState(existing == null || existing == blockState, - "BlockState %s is using the same block ID (%s) as BlockState %s", - blockState, i, existing); - blockStateInternalId.setInternalId(blockState, i); - TO_STATE.put(i, blockState); - usedIds.set(i); - } - - public static void clear() { - for (BlockState value : TO_STATE.values()) { - blockStateInternalId.setInternalId(value, invalidId()); - } - TO_STATE.clear(); - usedIds.clear(); - } - private BlockStateIdAccess() { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java index 09f0387b3..2dd7a9598 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java @@ -83,16 +83,31 @@ public abstract class Vector3 { return YzxOrderComparator.YZX_ORDER; } + /** + * Gets the x coordinate rounded, accounting for negative coordinates + * + * @return the x coordinate + */ public int getBlockX() { - return (int) MathUtils.roundHalfUp(getX()); + return MathMan.roundInt(getX()); } + /** + * Gets the y coordinate rounded, accounting for negative coordinates + * + * @return the y coordinate + */ public int getBlockY() { - return (int) MathUtils.roundHalfUp(getY()); + return MathMan.roundInt(getY()); } + /** + * Gets the z coordinate rounded, accounting for negative coordinates + * + * @return the z coordinate + */ public int getBlockZ() { - return (int) MathUtils.roundHalfUp(getZ()); + return MathMan.roundInt(getZ()); } public MutableVector3 setComponents(Vector3 other) { @@ -487,6 +502,15 @@ public abstract class Vector3 { return Vector3.at(Math.floor(getX() + 0.5), Math.floor(getY() + 0.5), Math.floor(getZ() + 0.5)); } + /** + * Rounds all components using {@link MathUtils#roundHalfUp(double)} + * + * @return a new vector + */ + public Vector3 roundHalfUp() { + return Vector3.at(MathUtils.roundHalfUp(getX()), MathUtils.roundHalfUp(getY()), MathUtils.roundHalfUp(getZ())); + } + /** * Returns a vector with the absolute values of the components of * this vector. @@ -595,8 +619,7 @@ public abstract class Vector3 { * @return a new {@code BlockVector} */ public static BlockVector3 toBlockPoint(double x, double y, double z) { - return BlockVector3.at(MathUtils.roundHalfUp(x), MathUtils.roundHalfUp(y), MathUtils.roundHalfUp(z)); - //return BlockVector3.at(x, y, z); + return BlockVector3.at(x, y, z); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java index 05a29f2ec..35c259f31 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.util; -import com.boydti.fawe.util.MathMan; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; @@ -80,8 +79,7 @@ public enum Direction { } Direction(Vector3 vector, int flags, int left, int right) { - this.blockPoint = BlockVector3.at(MathMan.roundInt(Math.signum(vector.getX())), - MathMan.roundInt(Math.signum(vector.getY())), MathMan.roundInt(Math.signum(vector.getZ()))); + this.blockPoint = BlockVector3.at(Math.signum(vector.getX()), Math.signum(vector.getY()), Math.signum(vector.getZ())); this.direction = vector.normalize(); this.flags = flags; this.left = left; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index 6e020852f..26374e495 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -75,7 +75,6 @@ public class BlockState implements BlockStateHolder, Pattern { * @deprecated Magic Numbers * @return BlockState */ - @Deprecated public static BlockState getFromInternalId(int combinedId) throws InputParseException { return BlockTypes.getFromStateId(combinedId).withStateId(combinedId); @@ -408,11 +407,7 @@ public class BlockState implements BlockStateHolder, Pattern { } public boolean isAir() { - try { - return material.isAir(); - } catch (NullPointerException ignored) { - return getMaterial().isAir(); - } + return blockType.getMaterial().isAir(); } @Override