diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle index be0cc651e..b915d4e92 100644 --- a/worldedit-bukkit/build.gradle +++ b/worldedit-bukkit/build.gradle @@ -8,7 +8,7 @@ repositories { maven { url "https://repo.codemc.org/repository/maven-public" } maven { url "https://papermc.io/repo/repository/maven-public/" } flatDir { - dirs 'lib' + dirs "$rootProject.projectDir/lib" } } @@ -26,6 +26,7 @@ task downloadJarsToLibs(){ } dependencies { + compile ('net.milkbowl.vault:VaultAPI:1.7') api project(':worldedit-core') api project(':worldedit-libs:bukkit') compileOnly 'com.sk89q:dummypermscompat:1.10' @@ -38,7 +39,6 @@ dependencies { // compile([fileTree(dir: 'lib', include: ['*.jar']),'commons-validator:commons-validator:1.4.1']) implementation('com.sk89q.worldguard:worldguard-core:7.0.0-20190215.210421-39'){transitive = false} implementation('com.sk89q.worldguard:worldguard-legacy:7.0.0-20190215.210421-39'){transitive = false} - implementation('net.milkbowl.vault:VaultAPI:1.7'){transitive = false} implementation('com.massivecraft:factions:2.8.0'){transitive = false} implementation('com.drtshock:factions:1.6.9.5'){transitive = false} implementation('com.factionsone:FactionsOne:1.2.2'){transitive = false} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitChunkHolder.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitChunkHolder.java index 3987e02de..919da1b05 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitChunkHolder.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitChunkHolder.java @@ -7,7 +7,7 @@ import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.implementation.QueueHandler; import com.boydti.fawe.beta.implementation.holder.ChunkHolder; import com.boydti.fawe.bukkit.v0.BukkitQueue_0; -import com.boydti.fawe.bukkit.v1_13.BukkitQueue_1_13; +import com.boydti.fawe.bukkit.v1_14.BukkitQueue_1_14; import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.ReflectionUtils; import com.sk89q.jnbt.CompoundTag; @@ -71,6 +71,11 @@ public class BukkitChunkHolder> extends ChunkHolder { } } + private void removeEntity(Entity entity) { + entity.die(); + entity.valid = false; + } + @Override public synchronized T call() { try { @@ -99,7 +104,7 @@ public class BukkitChunkHolder> extends ChunkHolder { } if (set.getBlock(lx, ly, lz).getOrdinal() != 0) { TileEntity tile = entry.getValue(); - tile.z(); + tile.n(); tile.invalidateBlockCache(); } } @@ -121,7 +126,7 @@ public class BukkitChunkHolder> extends ChunkHolder { ChunkSection newSection; ChunkSection existingSection = sections[layer]; if (existingSection == null) { - newSection = extent.newChunkSection(layer, hasSky, setArr); + newSection = extent.newChunkSection(layer, setArr); if (BukkitQueue.setSectionAtomic(sections, null, newSection, layer)) { updateGet(get, nmsChunk, sections, newSection, setArr, layer); continue; @@ -159,7 +164,7 @@ public class BukkitChunkHolder> extends ChunkHolder { getArr[i] = value; } } - newSection = extent.newChunkSection(layer, hasSky, getArr); + newSection = extent.newChunkSection(layer, getArr); if (!BukkitQueue.setSectionAtomic(sections, existingSection, newSection, layer)) { System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer); continue; @@ -207,9 +212,7 @@ public class BukkitChunkHolder> extends ChunkHolder { final Entity entity = iter.next(); if (entityRemoves.contains(entity.getUniqueID())) { iter.remove(); - entity.b(false); - entity.die(); - entity.valid = false; + removeEntity(entity); } } } @@ -240,20 +243,24 @@ public class BukkitChunkHolder> extends ChunkHolder { final float yaw = rotTag.getFloat(0); final float pitch = rotTag.getFloat(1); final String id = idTag.getValue(); - final Entity entity = EntityTypes.a(nmsWorld, new MinecraftKey(id)); - if (entity != null) { - final UUID uuid = entity.getUniqueID(); - entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits())); - entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits())); - if (nativeTag != null) { - final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_13.fromNative(nativeTag); - for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); + + 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) { + final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_14.fromNative(nativeTag); + for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { + tag.remove(name); + } + entity.f(tag); } - entity.f(tag); + entity.setLocation(x, y, z, yaw, pitch); + nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); } - entity.setLocation(x, y, z, yaw, pitch); - nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); } } } @@ -278,12 +285,12 @@ public class BukkitChunkHolder> extends ChunkHolder { final BlockPosition pos = new BlockPosition(x, y, z); synchronized (BukkitQueue_0.class) { TileEntity tileEntity = nmsWorld.getTileEntity(pos); - if (tileEntity == null || tileEntity.x()) { - nmsWorld.n(pos); + if (tileEntity == null || tileEntity.isRemoved()) { + nmsWorld.removeTileEntity(pos); tileEntity = nmsWorld.getTileEntity(pos); } if (tileEntity != null) { - final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_13.fromNative(nativeTag); + final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_14.fromNative(nativeTag); tag.set("x", new NBTTagInt(x)); tag.set("y", new NBTTagInt(y)); tag.set("z", new NBTTagInt(z)); @@ -302,8 +309,8 @@ public class BukkitChunkHolder> extends ChunkHolder { int finalMask = bitMask; callback = () -> { // Set Modified - nmsChunk.f(true); - nmsChunk.mustSave = true; + nmsChunk.d(true); // Set Modified + nmsChunk.mustNotSave = false; nmsChunk.markDirty(); // send to player extent.sendChunk(X, Z, finalMask); diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitGetBlocks.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitGetBlocks.java index da1506fd7..256268ec5 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitGetBlocks.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitGetBlocks.java @@ -9,6 +9,7 @@ import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.TaskManager; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockTypes; import net.minecraft.server.v1_14_R1.BiomeBase; @@ -84,6 +85,8 @@ public class BukkitGetBlocks extends CharGetBlocks { lock.setModified(false); // Efficiently convert ChunkSection to raw data try { + Spigot_v1_14_R1 adapter = ((Spigot_v1_14_R1) WorldEditPlugin.getInstance().getBukkitImplAdapter()); + final DataPaletteBlock blocks = section.getBlocks(); final DataBits bits = (DataBits) BukkitQueue_1_14.fieldBits.get(blocks); final DataPalette palette = (DataPalette) BukkitQueue_1_14.fieldPalette.get(blocks); @@ -112,7 +115,7 @@ public class BukkitGetBlocks extends CharGetBlocks { if (ibd == null) { ordinal = BlockTypes.AIR.getDefaultState().getOrdinalChar(); } else { - ordinal = ((Spigot_v1_14_R1) getAdapter()).adaptToChar(ibd); + ordinal = adapter.adaptToChar(ibd); } paletteToBlockChars[paletteVal] = ordinal; } @@ -132,7 +135,7 @@ public class BukkitGetBlocks extends CharGetBlocks { final int size = num_palette; if (size != 1) { for (int i = 0; i < size; i++) { - char ordinal = ordinal(palette.a(i)); + char ordinal = ordinal(palette.a(i), adapter); paletteToBlockChars[i] = ordinal; } for (int i = 0; i < 4096; i++) { @@ -141,7 +144,7 @@ public class BukkitGetBlocks extends CharGetBlocks { data[i] = val; } } else { - char ordinal = ordinal(palette.a(0)); + char ordinal = ordinal(palette.a(0), adapter); Arrays.fill(data, ordinal); } } finally { @@ -157,11 +160,11 @@ public class BukkitGetBlocks extends CharGetBlocks { } } - private final char ordinal(IBlockData ibd) { + private final char ordinal(IBlockData ibd, Spigot_v1_14_R1 adapter) { if (ibd == null) { return BlockTypes.AIR.getDefaultState().getOrdinalChar(); } else { - return ((Spigot_v1_14_R1) getAdapter()).adaptToChar(ibd); + return adapter.adaptToChar(ibd); } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitQueue.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitQueue.java index 79b37e1eb..2e48d7329 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitQueue.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/beta/BukkitQueue.java @@ -7,6 +7,7 @@ import com.boydti.fawe.beta.implementation.SimpleCharQueueExtent; import com.boydti.fawe.beta.implementation.SingleThreadQueueExtent; import com.boydti.fawe.beta.implementation.WorldChunkCache; import com.boydti.fawe.bukkit.adapter.v1_13_1.BlockMaterial_1_13; +import com.boydti.fawe.bukkit.v1_14.adapter.BlockMaterial_1_14; import com.boydti.fawe.config.Settings; import com.boydti.fawe.jnbt.anvil.BitArray4096; import com.boydti.fawe.object.collection.IterableThreadLocal; @@ -234,14 +235,11 @@ public class BukkitQueue extends SimpleCharQueueExtent { } private PlayerChunk getPlayerChunk(final int cx, final int cz) { - final PlayerChunkMap chunkMap = nmsWorld.getPlayerChunkMap(); - final PlayerChunk playerChunk = chunkMap.getChunk(cx, cz); + PlayerChunkMap chunkMap = nmsWorld.getChunkProvider().playerChunkMap; + PlayerChunk playerChunk = chunkMap.visibleChunks.get(ChunkCoordIntPair.pair(cx, cz)); if (playerChunk == null) { return null; } - if (playerChunk.players.isEmpty()) { - return null; - } return playerChunk; } @@ -250,14 +248,20 @@ public class BukkitQueue extends SimpleCharQueueExtent { if (playerChunk == null) { return false; } - if (playerChunk.e()) { +// ChunkSection[] sections = nmsChunk.getSections(); +// for (int layer = 0; layer < 16; layer++) { +// if (sections[layer] == null && (mask & (1 << layer)) != 0) { +// sections[layer] = new ChunkSection(layer << 4); +// } +// } + if (playerChunk.hasBeenLoaded()) { TaskManager.IMP.sync(new Supplier() { @Override public Object get() { try { int dirtyBits = fieldDirtyBits.getInt(playerChunk); if (dirtyBits == 0) { - nmsWorld.getPlayerChunkMap().a(playerChunk); + nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); } if (mask == 0) { dirtyBits = 65535; @@ -267,14 +271,15 @@ public class BukkitQueue extends SimpleCharQueueExtent { fieldDirtyBits.set(playerChunk, dirtyBits); fieldDirtyCount.set(playerChunk, 64); - } catch (final IllegalAccessException e) { + } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } }); + return true; } - return true; + return false; } /* @@ -342,7 +347,7 @@ public class BukkitQueue extends SimpleCharQueueExtent { final int ordinal = paletteToBlock[i]; blockToPalette[ordinal] = Integer.MAX_VALUE; final BlockState state = BlockTypes.states[ordinal]; - final IBlockData ibd = ((BlockMaterial_1_13) state.getMaterial()).getState(); + final IBlockData ibd = ((BlockMaterial_1_14) state.getMaterial()).getState(); palette.a(ibd); } try { diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/BukkitQueue_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/BukkitQueue_1_14.java index b6ddf06de..bdeaca902 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/BukkitQueue_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/BukkitQueue_1_14.java @@ -72,8 +72,8 @@ import java.util.function.Supplier; public class BukkitQueue_1_14 extends BukkitQueue_0 { - protected final static Field fieldBits; - protected final static Field fieldPalette; + public final static Field fieldBits; + public final static Field fieldPalette; protected final static Field fieldSize; protected final static Field fieldHashBlocks; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/adapter/Spigot_v1_14_R1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/adapter/Spigot_v1_14_R1.java index 717cac214..6aa146a24 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/adapter/Spigot_v1_14_R1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_14/adapter/Spigot_v1_14_R1.java @@ -20,7 +20,6 @@ package com.boydti.fawe.bukkit.v1_14.adapter; import com.boydti.fawe.Fawe; -import com.boydti.fawe.bukkit.adapter.v1_13_1.BlockMaterial_1_13; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.sk89q.jnbt.ByteArrayTag; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/ChunkBitSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/ChunkBitSet.java new file mode 100644 index 000000000..33e3988ab --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/ChunkBitSet.java @@ -0,0 +1,152 @@ +package com.boydti.fawe.object.collection; + +import java.util.Arrays; + +public class ChunkBitSet { + private final static int CHUNK_LAYERS = 16; + private final static int BITS_PER_LAYER = 4096; + private final static int BITS_PER_WORD = 6; + private final static int WORDS = BITS_PER_LAYER >> BITS_PER_WORD; + private final static IRow NULL_ROW_X = new NullRowX(); + private final static IRow NULL_ROW_Z = new NullRowZ(); + private final static IRow NULL_ROW_Y = new NullRowY(); + + private final IRow[] rows; + + public ChunkBitSet() { + this(16); + } + + public ChunkBitSet(int size) { + this.rows = new IRow[size]; + for (int i = 0; i < size; i++) rows[i] = NULL_ROW_X; + } + + public boolean get(int x, int y, int z) { + return rows[x >> 4].get(this.rows, x, y, z); + } + + public void set(int x, int y, int z) { + rows[x >> 4].set(this.rows, x, y, z); + } + + public void clear(int x, int y, int z) { + rows[x >> 4].clear(this.rows, x, y, z); + } + + private interface IRow { + default boolean get(IRow[] rows, int x, int y, int z) { return false; } + void set(IRow[] rows, int x, int y, int z); + default void clear(IRow[] rows, int x, int y, int z) { return; } + } + + private static class NullRowX implements IRow { + @Override + public void set(IRow[] parent, int x, int y, int z) { + IRow row = new RowX(parent.length); + parent[x >> 4] = row; + row.set(parent, x, y, z); + } + } + + private static class NullRowZ implements IRow { + @Override + public void set(IRow[] parent, int x, int y, int z) { + IRow row = new RowZ(); + parent[z >> 4] = row; + row.set(parent, x, y, z); + } + } + + private static class NullRowY implements IRow { + @Override + public void set(IRow[] parent, int x, int y, int z) { + IRow row = new RowY(); + parent[y >> 4] = row; + row.set(parent, x, y, z); + } + } + + private static class RowX implements IRow { + private final IRow[] rows; + + public RowX(int size) { + this.rows = new IRow[size]; + for (int i = 0; i < size; i++) rows[i] = NULL_ROW_Z; + } + + @Override + public boolean get(IRow[] parent, int x, int y, int z) { + return rows[z >> 4].get(this.rows, x, y, z); + } + + @Override + public void set(IRow[] parent, int x, int y, int z) { + this.rows[z >> 4].set(this.rows, x, y, z); + } + + @Override + public void clear(IRow[] parent, int x, int y, int z) { + this.rows[z >> 4].clear(this.rows, x, y, z); + } + } + + private static class RowZ implements IRow { + private final IRow[] rows; + + public RowZ() { + this.rows = new IRow[CHUNK_LAYERS]; + for (int i = 0; i < CHUNK_LAYERS; i++) rows[i] = NULL_ROW_Y; + } + + @Override + public boolean get(IRow[] parent, int x, int y, int z) { + return rows[y >> 4].get(this.rows, x, y, z); + } + + @Override + public void set(IRow[] parent, int x, int y, int z) { + this.rows[y >> 4].set(this.rows, x, y, z); + } + + @Override + public void clear(IRow[] parent, int x, int y, int z) { + this.rows[y >> 4].set(this.rows, x, y, z); + } + } + + private static class RowY implements IRow { + private final long[] bits; + + public RowY() { + this.bits = new long[WORDS]; + } + + @Override + public boolean get(IRow[] parent, int x, int y, int z) { + int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15); + return (bits[i >> 6] & (1L << (i & 0x3F))) != 0; + } + + @Override + public void set(IRow[] parent, int x, int y, int z) { + int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15); + bits[i >> 6] |= (1L << (i & 0x3F)); + } + + @Override + public void clear(IRow[] parent, int x, int y, int z) { + int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15); + bits[i >> 6] &= ~(1L << (i & 0x3F)); + } + } + + private static IRow[] resize(IRow[] arr, IRow def) { + int len = arr.length; + int newLen = len == 1 ? 1 : Integer.highestOneBit(len - 1) * 2; + IRow[] copy = Arrays.copyOf(arr, newLen, IRow[].class); + for (int i = len; i < newLen; i++) copy[i] = def; + return copy; + } +} +