From 968799503f3932801498428e2c319778298cf77d Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 21 Jun 2022 14:52:02 +0100 Subject: [PATCH] Re-implement full Entity support in history, entity removal, entity creation, etc. (#1812) Co-authored-by: Alexander Brandes --- .../fawe/v1_17_R1_2/PaperweightGetBlocks.java | 106 +++++++++--------- .../v1_17_R1_2/PaperweightGetBlocks_Copy.java | 16 +-- .../PaperweightPlatformAdapter.java | 6 + .../fawe/v1_18_R2/PaperweightGetBlocks.java | 103 +++++++++-------- .../v1_18_R2/PaperweightGetBlocks_Copy.java | 16 +-- .../v1_18_R2/PaperweightPlatformAdapter.java | 5 + .../fawe/v1_19_R1/PaperweightGetBlocks.java | 104 ++++++++--------- .../v1_19_R1/PaperweightGetBlocks_Copy.java | 16 +-- .../v1_19_R1/PaperweightPlatformAdapter.java | 5 + .../resources/fastasyncworldedit-adapters.jar | Bin 434788 -> 434371 bytes .../cli/schematic/ClipboardWorld.java | 10 ++ .../core/configuration/Settings.java | 9 ++ .../core/extent/FaweRegionExtent.java | 13 +++ .../core/extent/HistoryExtent.java | 11 ++ .../core/extent/LimitExtent.java | 15 +++ .../core/extent/NullExtent.java | 7 ++ .../core/extent/ProcessedWEExtent.java | 14 +++ .../core/extent/StripNBTExtent.java | 7 ++ .../clipboard/CPUOptimizedClipboard.java | 25 ----- .../clipboard/DiskOptimizedClipboard.java | 47 -------- .../extent/clipboard/LinearClipboard.java | 53 +++++++++ .../clipboard/MemoryOptimizedClipboard.java | 36 ------ .../extent/clipboard/ReadOnlyClipboard.java | 13 +++ .../core/extent/transform/MultiTransform.java | 11 ++ .../core/extent/transform/ScaleTransform.java | 14 +++ .../extent/transform/SelectTransform.java | 8 ++ .../history/change/MutableEntityChange.java | 14 +-- .../core/queue/IChunkExtent.java | 23 ++-- .../implementation/chunk/ChunkHolder.java | 17 +-- .../core/wrappers/WorldWrapper.java | 7 ++ .../main/java/com/sk89q/jnbt/CompoundTag.java | 17 ++- .../main/java/com/sk89q/jnbt/NBTUtils.java | 28 +++++ .../java/com/sk89q/worldedit/EditSession.java | 9 ++ .../extent/AbstractDelegateExtent.java | 8 ++ .../worldedit/extent/ChangeSetExtent.java | 15 ++- .../com/sk89q/worldedit/extent/Extent.java | 15 +++ .../sk89q/worldedit/extent/NullExtent.java | 9 ++ .../sk89q/worldedit/extent/TracingExtent.java | 15 +++ .../extent/clipboard/BlockArrayClipboard.java | 12 ++ .../extent/world/WatchdogTickingExtent.java | 10 ++ .../function/entity/ExtentEntityCopy.java | 5 +- .../session/request/RequestExtent.java | 9 ++ .../com/sk89q/worldedit/world/NullWorld.java | 9 ++ 43 files changed, 556 insertions(+), 336 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java index b78b1987c..5554fe25b 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java @@ -14,7 +14,6 @@ import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.google.common.base.Suppliers; -import com.google.common.collect.Iterables; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.StringTag; @@ -64,9 +63,9 @@ import javax.annotation.Nonnull; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -79,7 +78,6 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.StreamSupport; public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { @@ -324,21 +322,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } @Override - @SuppressWarnings("unchecked") public CompoundTag getEntity(UUID uuid) { Entity entity = serverLevel.getEntity(uuid); if (entity != null) { org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); } - for (List entry : /*getChunk().getEntitySlices()*/ new List[0]) { - if (entry != null) { - for (Entity ent : entry) { - if (uuid.equals(ent.getUUID())) { - org.bukkit.entity.Entity bukkitEnt = ent.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - } + for (CompoundTag tag : getEntities()) { + if (uuid.equals(tag.getUUID())) { + return tag; } } return null; @@ -346,21 +338,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Override public Set getEntities() { - List[] slices = /*getChunk().getEntitySlices()*/ new List[0]; - int size = 0; - for (List slice : slices) { - if (slice != null) { - size += slice.size(); - } - } - if (slices.length == 0) { + List entities = PaperweightPlatformAdapter.getEntities(getChunk()); + if (entities.isEmpty()) { return Collections.emptySet(); } - int finalSize = size; - return new AbstractSet() { + int size = entities.size(); + return new AbstractSet<>() { @Override public int size() { - return finalSize; + return size; } @Override @@ -373,17 +359,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (!(get instanceof CompoundTag getTag)) { return false; } - Map value = getTag.getValue(); - CompoundTag getParts = (CompoundTag) value.get("UUID"); - UUID getUUID = new UUID(getParts.getLong("Most"), getParts.getLong("Least")); - for (List slice : slices) { - if (slice != null) { - for (Entity entity : slice) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } + UUID getUUID = getTag.getUUID(); + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (uuid.equals(getUUID)) { + return true; } } return false; @@ -392,9 +372,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Nonnull @Override public Iterator iterator() { - Iterable result = StreamSupport.stream(Iterables.concat(slices).spliterator(), false).map(input -> { + Iterable result = entities.stream().map(input -> { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - return (CompoundTag) adapter.toNative(input.saveWithoutId(tag)); + input.save(tag); + return (CompoundTag) adapter.toNative(tag); }).collect(Collectors.toList()); return result.iterator(); } @@ -630,23 +611,31 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } syncTasks[2] = () -> { - final List[] entities = /*nmsChunk.e()*/ new List[0]; + Set entitiesRemoved = new HashSet<>(); + final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - for (final Collection ents : entities) { - if (!ents.isEmpty()) { - final Iterator iter = ents.iterator(); - while (iter.hasNext()) { - final Entity entity = iter.next(); - if (entityRemoves.contains(entity.getUUID())) { - if (createCopy) { - copy.storeEntity(entity); - } - iter.remove(); - removeEntity(entity); - } + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (entityRemoves.contains(uuid)) { + if (createCopy) { + copy.storeEntity(entity); + } + removeEntity(entity); + entitiesRemoved.add(uuid); + entityRemoves.remove(uuid); + } + } + if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { + for (UUID uuid : entityRemoves) { + Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid); + if (entity != null) { + removeEntity(entity); } } } + // Only save entities that were actually removed to history + set.getEntityRemoves().clear(); + set.getEntityRemoves().addAll(entitiesRemoved); }; } @@ -657,7 +646,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } syncTasks[1] = () -> { - for (final CompoundTag nativeTag : entities) { + Iterator iterator = entities.iterator(); + while (iterator.hasNext()) { + final CompoundTag nativeTag = iterator.next(); final Map entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); @@ -684,12 +675,23 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } entity.load(tag); entity.absMoveTo(x, y, z, yaw, pitch); - nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); + entity.setUUID(nativeTag.getUUID()); + if (!nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { + LOGGER.warn( + "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", + id, + nmsWorld.getWorld().getName(), + x, + y, + z + ); + // Unsuccessful create should not be saved to history + iterator.remove(); + } } } } }; - } // set tiles diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java index 5d9c56092..de431c718 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java @@ -74,7 +74,8 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeEntity(Entity entity) { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - entities.add((CompoundTag) adapter.toNative(entity.save(compoundTag))); + entity.save(compoundTag); + entities.add((CompoundTag) adapter.toNative(compoundTag)); } @Override @@ -85,18 +86,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public CompoundTag getEntity(UUID uuid) { for (CompoundTag tag : entities) { - UUID tagUUID; - if (tag.containsKey("UUID")) { - int[] arr = tag.getIntArray("UUID"); - tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL)); - } else if (tag.containsKey("UUIDMost")) { - tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast")); - } else if (tag.containsKey("PersistentIDMSB")) { - tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB")); - } else { - return null; - } - if (uuid.equals(tagUUID)) { + if (uuid.equals(tag.getUUID())) { return tag; } } diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java index 8d76d9f7f..4b446d620 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java @@ -30,6 +30,7 @@ import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.BitStorage; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; @@ -53,6 +54,7 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -470,4 +472,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } } + static List getEntities(LevelChunk chunk) { + return chunk.level.entityManager.getEntities(new ChunkPos(chunk.locX, chunk.locZ)); + } + } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java index 9f44912cb..f225bd441 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java @@ -69,6 +69,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -315,21 +316,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } @Override - @SuppressWarnings("unchecked") public CompoundTag getEntity(UUID uuid) { Entity entity = serverLevel.getEntity(uuid); if (entity != null) { org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); } - for (List entry : /*getChunk().getEntitySlices()*/ new List[0]) { - if (entry != null) { - for (Entity ent : entry) { - if (uuid.equals(ent.getUUID())) { - org.bukkit.entity.Entity bukkitEnt = ent.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - } + for (CompoundTag tag : getEntities()) { + if (uuid.equals(tag.getUUID())) { + return tag; } } return null; @@ -337,21 +332,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Override public Set getEntities() { - List[] slices = /*getChunk().getEntitySlices()*/ new List[0]; - int size = 0; - for (List slice : slices) { - if (slice != null) { - size += slice.size(); - } - } - if (slices.length == 0) { + List entities = PaperweightPlatformAdapter.getEntities(getChunk()); + if (entities.isEmpty()) { return Collections.emptySet(); } - int finalSize = size; - return new AbstractSet() { + int size = entities.size(); + return new AbstractSet<>() { @Override public int size() { - return finalSize; + return size; } @Override @@ -364,17 +353,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (!(get instanceof CompoundTag getTag)) { return false; } - Map value = getTag.getValue(); - CompoundTag getParts = (CompoundTag) value.get("UUID"); - UUID getUUID = new UUID(getParts.getLong("Most"), getParts.getLong("Least")); - for (List slice : slices) { - if (slice != null) { - for (Entity entity : slice) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } + UUID getUUID = getTag.getUUID(); + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (uuid.equals(getUUID)) { + return true; } } return false; @@ -383,9 +366,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Nonnull @Override public Iterator iterator() { - Iterable result = StreamSupport.stream(Iterables.concat(slices).spliterator(), false).map(input -> { + Iterable result = entities.stream().map(input -> { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - return (CompoundTag) adapter.toNative(input.saveWithoutId(tag)); + input.save(tag); + return (CompoundTag) adapter.toNative(tag); }).collect(Collectors.toList()); return result.iterator(); } @@ -677,23 +661,31 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } syncTasks[2] = () -> { - final List[] entities = /*nmsChunk.e()*/ new List[0]; + Set entitiesRemoved = new HashSet<>(); + final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - for (final Collection ents : entities) { - if (!ents.isEmpty()) { - final Iterator iter = ents.iterator(); - while (iter.hasNext()) { - final Entity entity = iter.next(); - if (entityRemoves.contains(entity.getUUID())) { - if (createCopy) { - copy.storeEntity(entity); - } - iter.remove(); - removeEntity(entity); - } + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (entityRemoves.contains(uuid)) { + if (createCopy) { + copy.storeEntity(entity); + } + removeEntity(entity); + entitiesRemoved.add(uuid); + entityRemoves.remove(uuid); + } + } + if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { + for (UUID uuid : entityRemoves) { + Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid); + if (entity != null) { + removeEntity(entity); } } } + // Only save entities that were actually removed to history + set.getEntityRemoves().clear(); + set.getEntityRemoves().addAll(entitiesRemoved); }; } @@ -704,7 +696,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } syncTasks[1] = () -> { - for (final CompoundTag nativeTag : entities) { + Iterator iterator = entities.iterator(); + while (iterator.hasNext()) { + final CompoundTag nativeTag = iterator.next(); final Map entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); @@ -731,12 +725,23 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } entity.load(tag); entity.absMoveTo(x, y, z, yaw, pitch); - nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); + entity.setUUID(nativeTag.getUUID()); + if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { + LOGGER.warn( + "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", + id, + nmsWorld.getWorld().getName(), + x, + y, + z + ); + // Unsuccessful create should not be saved to history + iterator.remove(); + } } } } }; - } // set tiles diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks_Copy.java index 1404fd1c7..991c3d1f9 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks_Copy.java @@ -76,7 +76,8 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeEntity(Entity entity) { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - entities.add((CompoundTag) adapter.toNative(entity.save(compoundTag))); + entity.save(compoundTag); + entities.add((CompoundTag) adapter.toNative(compoundTag)); } @Override @@ -87,18 +88,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public CompoundTag getEntity(UUID uuid) { for (CompoundTag tag : entities) { - UUID tagUUID; - if (tag.containsKey("UUID")) { - int[] arr = tag.getIntArray("UUID"); - tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL)); - } else if (tag.containsKey("UUIDMost")) { - tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast")); - } else if (tag.containsKey("PersistentIDMSB")) { - tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB")); - } else { - return null; - } - if (uuid.equals(tagUUID)) { + if (uuid.equals(tag.getUUID())) { return tag; } } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java index 8316ae008..ad3205feb 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPlatformAdapter.java @@ -33,6 +33,7 @@ import net.minecraft.util.BitStorage; import net.minecraft.util.SimpleBitStorage; import net.minecraft.util.ThreadingDetector; import net.minecraft.util.ZeroBitStorage; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; @@ -599,6 +600,10 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } } + static List getEntities(LevelChunk chunk) { + return chunk.level.entityManager.getEntities(new ChunkPos(chunk.locX, chunk.locZ)); + } + record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java index b63875d82..3c543d2c7 100644 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java @@ -67,9 +67,9 @@ import javax.annotation.Nonnull; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -316,21 +316,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } @Override - @SuppressWarnings("unchecked") public CompoundTag getEntity(UUID uuid) { Entity entity = serverLevel.getEntity(uuid); if (entity != null) { org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); } - for (List entry : /*getChunk().getEntitySlices()*/ new List[0]) { - if (entry != null) { - for (Entity ent : entry) { - if (uuid.equals(ent.getUUID())) { - org.bukkit.entity.Entity bukkitEnt = ent.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - } + for (CompoundTag tag : getEntities()) { + if (uuid.equals(tag.getUUID())) { + return tag; } } return null; @@ -338,21 +332,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Override public Set getEntities() { - List[] slices = /*getChunk().getEntitySlices()*/ new List[0]; - int size = 0; - for (List slice : slices) { - if (slice != null) { - size += slice.size(); - } - } - if (slices.length == 0) { + List entities = PaperweightPlatformAdapter.getEntities(getChunk()); + if (entities.isEmpty()) { return Collections.emptySet(); } - int finalSize = size; - return new AbstractSet() { + int size = entities.size(); + return new AbstractSet<>() { @Override public int size() { - return finalSize; + return size; } @Override @@ -365,17 +353,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (!(get instanceof CompoundTag getTag)) { return false; } - Map value = getTag.getValue(); - CompoundTag getParts = (CompoundTag) value.get("UUID"); - UUID getUUID = new UUID(getParts.getLong("Most"), getParts.getLong("Least")); - for (List slice : slices) { - if (slice != null) { - for (Entity entity : slice) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } + UUID getUUID = getTag.getUUID(); + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (uuid.equals(getUUID)) { + return true; } } return false; @@ -384,9 +366,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Nonnull @Override public Iterator iterator() { - Iterable result = StreamSupport.stream(Iterables.concat(slices).spliterator(), false).map(input -> { + Iterable result = entities.stream().map(input -> { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - return (CompoundTag) adapter.toNative(input.saveWithoutId(tag)); + input.save(tag); + return (CompoundTag) adapter.toNative(tag); }).collect(Collectors.toList()); return result.iterator(); } @@ -677,23 +660,31 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } syncTasks[2] = () -> { - final List[] entities = /*nmsChunk.e()*/ new List[0]; + Set entitiesRemoved = new HashSet<>(); + final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - for (final Collection ents : entities) { - if (!ents.isEmpty()) { - final Iterator iter = ents.iterator(); - while (iter.hasNext()) { - final Entity entity = iter.next(); - if (entityRemoves.contains(entity.getUUID())) { - if (createCopy) { - copy.storeEntity(entity); - } - iter.remove(); - removeEntity(entity); - } + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (entityRemoves.contains(uuid)) { + if (createCopy) { + copy.storeEntity(entity); + } + removeEntity(entity); + entitiesRemoved.add(uuid); + entityRemoves.remove(uuid); + } + } + if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { + for (UUID uuid : entityRemoves) { + Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid); + if (entity != null) { + removeEntity(entity); } } } + // Only save entities that were actually removed to history + set.getEntityRemoves().clear(); + set.getEntityRemoves().addAll(entitiesRemoved); }; } @@ -704,7 +695,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } syncTasks[1] = () -> { - for (final CompoundTag nativeTag : entities) { + Iterator iterator = entities.iterator(); + while (iterator.hasNext()) { + final CompoundTag nativeTag = iterator.next(); final Map entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); @@ -731,12 +724,23 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } entity.load(tag); entity.absMoveTo(x, y, z, yaw, pitch); - nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); + entity.setUUID(nativeTag.getUUID()); + if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { + LOGGER.warn( + "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", + id, + nmsWorld.getWorld().getName(), + x, + y, + z + ); + // Unsuccessful create should not be saved to history + iterator.remove(); + } } } } }; - } // set tiles diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java index 33ff20dc1..c0b69ac80 100644 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java @@ -80,7 +80,8 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeEntity(Entity entity) { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - entities.add((CompoundTag) adapter.toNative(entity.save(compoundTag))); + entity.save(compoundTag); + entities.add((CompoundTag) adapter.toNative(compoundTag)); } @Override @@ -91,18 +92,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public CompoundTag getEntity(UUID uuid) { for (CompoundTag tag : entities) { - UUID tagUUID; - if (tag.containsKey("UUID")) { - int[] arr = tag.getIntArray("UUID"); - tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL)); - } else if (tag.containsKey("UUIDMost")) { - tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast")); - } else if (tag.containsKey("PersistentIDMSB")) { - tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB")); - } else { - return null; - } - if (uuid.equals(tagUUID)) { + if (uuid.equals(tag.getUUID())) { return tag; } } diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java index 75464bb61..9a7e73503 100644 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java @@ -33,6 +33,7 @@ import net.minecraft.util.BitStorage; import net.minecraft.util.SimpleBitStorage; import net.minecraft.util.ThreadingDetector; import net.minecraft.util.ZeroBitStorage; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; @@ -599,6 +600,10 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } } + static List getEntities(LevelChunk chunk) { + return chunk.level.entityManager.getEntities(new ChunkPos(chunk.locX, chunk.locZ)); + } + record FakeIdMapBlock(int size) implements IdMap { @Override diff --git a/worldedit-bukkit/adapters/adapter-legacy/src/main/resources/fastasyncworldedit-adapters.jar b/worldedit-bukkit/adapters/adapter-legacy/src/main/resources/fastasyncworldedit-adapters.jar index 83d4bb7b74266817320fcbe01168bc9a1bb48990..9000989ef76582a02074889aaf55ad7f3645347d 100644 GIT binary patch delta 56836 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�aEIGt2v1#|=Mi#_>?}i%-o&8W7&4gm7G|TNhA} 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 z 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 Y3vq}Jqi@9|2(|d{6`p&s!SuiX2bWPyi~s-t diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java index b164ecfa3..a8190234c 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java @@ -56,6 +56,7 @@ import java.io.IOException; import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.UUID; public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld { @@ -167,6 +168,15 @@ public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld return clipboard.createEntity(location, entity); } + //FAWE start + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + dirty = true; + return clipboard.createEntity(location, entity, uuid); + } + //FAWE end + @Override public BlockState getBlock(BlockVector3 position) { return clipboard.getBlock(position); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java index 7952a0883..976b8b62a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java @@ -621,6 +621,15 @@ public class Settings extends Config { }) public boolean KEEP_ENTITIES_IN_BLOCKS = false; + @Comment({ + "[SAFE] Attempt to remove entities from the world if they were not present in the expected chunk (default: true)", + " - Sometimes an entity may have moved into a different chunk to that which FAWE expected", + " - This option allows FAWE to attempt to remove the entity, even if present in a different chunk", + " - If the entity is in an unloaded or partially loaded chunk, this will fail", + " - If an entity cannot be removed, it is possible duplicate entities may be created when using undo and/or redo" + }) + public boolean REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL = true; + @Comment({ "Other experimental features" }) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java index ac869b630..ce49569ad 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java @@ -22,6 +22,7 @@ import com.sk89q.worldedit.world.block.BlockTypes; import javax.annotation.Nullable; import java.util.Collection; +import java.util.UUID; public abstract class FaweRegionExtent extends ResettableExtent implements IBatchProcessor { @@ -149,6 +150,18 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc return super.createEntity(location, entity); } + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + if (!contains(location.getBlockX(), location.getBlockY(), location.getBlockZ())) { + if (!limit.MAX_FAILS()) { + WEManager.weManager().cancelEditSafe(this, FaweCache.OUTSIDE_REGION); + } + return null; + } + return super.createEntity(location, entity, uuid); + } + @Override public ProcessorScope getScope() { return ProcessorScope.READING_SET_BLOCKS; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java index de29ff473..2fc5133c6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java @@ -18,6 +18,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import static com.google.common.base.Preconditions.checkNotNull; @@ -78,6 +79,16 @@ public class HistoryExtent extends AbstractDelegateExtent { return entity; } + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity state, UUID uuid) { + final Entity entity = super.createEntity(location, state, uuid); + if (state != null) { + this.changeSet.addEntityCreate(state.getNbtData()); + } + return entity; + } + @Override public List getEntities() { return this.wrapEntities(super.getEntities()); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java index e4f2bc2b3..e26f5c630 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java @@ -90,6 +90,21 @@ public class LimitExtent extends AbstractDelegateExtent { } } + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + limit.THROW_MAX_CHANGES(); + limit.THROW_MAX_ENTITIES(); + try { + return super.createEntity(location, entity, uuid); + } catch (FaweException e) { + if (!limit.MAX_FAILS()) { + throw e; + } + return null; + } + } + @Override public void removeEntity(int x, int y, int z, UUID uuid) { limit.THROW_MAX_CHANGES(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/NullExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/NullExtent.java index 07a9c4a49..4f0ad4960 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/NullExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/NullExtent.java @@ -36,6 +36,7 @@ import javax.annotation.Nullable; import java.util.Collection; import java.util.List; import java.util.Set; +import java.util.UUID; import java.util.concurrent.Future; //todo This should be removed in favor of com.sk89q.worldedit.extent.NullExtent @@ -87,6 +88,12 @@ public class NullExtent extends FaweRegionExtent implements IBatchProcessor { throw reason; } + @Nullable + @Override + public Entity createEntity(Location arg0, BaseEntity arg1, UUID arg2) { + throw reason; + } + @Override public BlockState getBlock(BlockVector3 position) { throw reason; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java index 9635497b2..5abe90348 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java @@ -16,6 +16,8 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypes; +import java.util.UUID; + public class ProcessedWEExtent extends AbstractDelegateExtent { private final FaweLimit limit; @@ -43,6 +45,18 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { return super.createEntity(location, entity); } + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + if (entity == null) { + return null; + } + if (!limit.MAX_ENTITIES()) { + WEManager.weManager().cancelEditSafe(this, FaweCache.MAX_ENTITIES); + return null; + } + return super.createEntity(location, entity, uuid); + } + @Override public BlockState getBlock(int x, int y, int z) { if (!limit.MAX_CHECKS()) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java index ea35cb424..ded96d5aa 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java @@ -28,6 +28,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; @@ -65,6 +66,12 @@ public class StripNBTExtent extends AbstractDelegateExtent implements IBatchProc return super.createEntity(location, stripEntityNBT(entity)); } + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + return super.createEntity(location, stripEntityNBT(entity), uuid); + } + @SuppressWarnings("unchecked") public > B stripBlockNBT(B block) { if (!(block instanceof BaseBlock localBlock)) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java index fc2122b07..6f566fcb9 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java @@ -5,23 +5,16 @@ import com.fastasyncworldedit.core.math.IntTriple; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.entity.Entity; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; -import javax.annotation.Nullable; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; public class CPUOptimizedClipboard extends LinearClipboard { @@ -209,22 +202,4 @@ public class CPUOptimizedClipboard extends LinearClipboard { return true; } - @Nullable - @Override - public Entity createEntity(Location location, BaseEntity entity) { - BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); - entities.add(ret); - return ret; - } - - @Override - public List getEntities() { - return new ArrayList<>(entities); - } - - @Override - public void removeEntity(Entity entity) { - this.entities.remove(entity); - } - } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java index f7cbc0531..acdf9fad7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java @@ -16,12 +16,10 @@ import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -30,7 +28,6 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypes; import org.apache.logging.log4j.Logger; -import javax.annotation.Nullable; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.File; @@ -48,7 +45,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.stream.Collectors; /** * A clipboard with disk backed storage. (lower memory + loads on crash) @@ -714,47 +710,4 @@ public class DiskOptimizedClipboard extends LinearClipboard { return false; } - @Nullable - @Override - public Entity createEntity(Location location, BaseEntity entity) { - BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); - entities.add(ret); - return ret; - } - - @Override - public List getEntities() { - return new ArrayList<>(entities); - } - - @Override - public List getEntities(Region region) { - return entities - .stream() - .filter(e -> region.contains(e.getLocation().toBlockPoint())).collect(Collectors.toList()); - } - - @Override - public void removeEntity(Entity entity) { - if (!(entity instanceof BlockArrayClipboard.ClipboardEntity)) { - Location loc = entity.getLocation(); - removeEntity(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), entity.getState().getNbtData().getUUID()); - } else { - this.entities.remove(entity); - } - } - - @Override - public void removeEntity(int x, int y, int z, UUID uuid) { - Iterator iter = this.entities.iterator(); - while (iter.hasNext()) { - BlockArrayClipboard.ClipboardEntity entity = iter.next(); - UUID entUUID = entity.getState().getNbtData().getUUID(); - if (uuid.equals(entUUID)) { - iter.remove(); - return; - } - } - } - } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java index 16d8acbf1..143168504 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java @@ -5,21 +5,33 @@ import com.fastasyncworldedit.core.function.visitor.Order; import com.fastasyncworldedit.core.jnbt.streamer.IntValueReader; import com.google.common.collect.ForwardingIterator; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.NBTUtils; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard.ClipboardEntity; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; public abstract class LinearClipboard extends SimpleClipboard { @@ -83,6 +95,25 @@ public abstract class LinearClipboard extends SimpleClipboard { } + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity) { + BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); + entities.add(ret); + return ret; + } + + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + Map map = new HashMap<>(entity.getNbtData().getValue()); + NBTUtils.addUUIDToMap(map, uuid); + entity.setNbtData(new CompoundTag(map)); + BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); + entities.add(ret); + return ret; + } + @Override public void removeEntity(int x, int y, int z, UUID uuid) { Iterator iter = this.entities.iterator(); @@ -96,6 +127,28 @@ public abstract class LinearClipboard extends SimpleClipboard { } } + @Override + public List getEntities() { + return new ArrayList<>(entities); + } + + @Override + public void removeEntity(Entity entity) { + if (!(entity instanceof BlockArrayClipboard.ClipboardEntity)) { + Location loc = entity.getLocation(); + removeEntity(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), entity.getState().getNbtData().getUUID()); + } else { + this.entities.remove(entity); + } + } + + @Override + public List getEntities(Region region) { + return entities + .stream() + .filter(e -> region.contains(e.getLocation().toBlockPoint())).collect(Collectors.toList()); + } + private class LinearFilter extends AbstractFilterBlock { private int index = -1; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java index 28dc1d3cc..ed76a9d1f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java @@ -7,13 +7,8 @@ import com.fastasyncworldedit.core.util.MainUtil; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.entity.Entity; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard.ClipboardEntity; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -22,14 +17,10 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; -import javax.annotation.Nullable; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; public class MemoryOptimizedClipboard extends LinearClipboard { @@ -293,31 +284,4 @@ public class MemoryOptimizedClipboard extends LinearClipboard { return true; } - @Nullable - @Override - public Entity createEntity(Location location, BaseEntity entity) { - BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); - entities.add(ret); - return ret; - } - - @Override - public List getEntities() { - return new ArrayList<>(entities); - } - - @Override - public List getEntities(Region region) { - return entities - .stream() - .filter(e -> region.contains(e.getLocation().toBlockPoint())).collect(Collectors.toList()); - } - - @Override - public void removeEntity(Entity entity) { - if (entity instanceof ClipboardEntity) { - this.entities.remove(entity); - } - } - } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java index e46c58c0e..4f7245d27 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java @@ -2,10 +2,13 @@ package com.fastasyncworldedit.core.extent.clipboard; import com.fastasyncworldedit.core.Fawe; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.NBTUtils; +import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.request.Request; @@ -14,7 +17,11 @@ import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockStateHolder; +import javax.annotation.Nullable; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.function.Supplier; public abstract class ReadOnlyClipboard extends SimpleClipboard { @@ -103,6 +110,12 @@ public abstract class ReadOnlyClipboard extends SimpleClipboard { throw new UnsupportedOperationException("Clipboard is immutable"); } + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + throw new UnsupportedOperationException("Clipboard is immutable"); + } + @Override public void removeEntity(Entity entity) { throw new UnsupportedOperationException("Clipboard is immutable"); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/MultiTransform.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/MultiTransform.java index edae11174..946ee8ae5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/MultiTransform.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/MultiTransform.java @@ -12,6 +12,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; import java.util.Collection; +import java.util.UUID; public class MultiTransform extends RandomTransform { @@ -90,4 +91,14 @@ public class MultiTransform extends RandomTransform { return created; } + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + Entity created = null; + for (AbstractDelegateExtent extent : extents) { + created = extent.createEntity(location, entity, uuid); + } + return created; + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java index fc7424868..29af87055 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java @@ -13,6 +13,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; +import java.util.UUID; public class ScaleTransform extends ResettableExtent { @@ -181,4 +182,17 @@ public class ScaleTransform extends ResettableExtent { return super.createEntity(newLoc, entity); } + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + Location newLoc = new Location(location.getExtent(), + getPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), + location.getYaw(), location.getPitch() + ); + if (!getExtent().contains(newLoc.toBlockPoint())) { + return null; + } + return super.createEntity(newLoc, entity, uuid); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java index c5cda5ff7..57f77b2fe 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java @@ -14,6 +14,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; +import java.util.UUID; public abstract class SelectTransform extends ResettableExtent { @@ -52,6 +53,13 @@ public abstract class SelectTransform extends ResettableExtent { .createEntity(position, entity); } + @Nullable + @Override + public Entity createEntity(Location position, BaseEntity entity, UUID uuid) { + return getExtent(position.getBlockX(), position.getBlockY(), position.getBlockZ()) + .createEntity(position, entity, uuid); + } + @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { return getExtent(position).setBiome(position, biome); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java index 2aeca60d3..b99c576ac 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java @@ -53,15 +53,8 @@ public class MutableEntityChange implements Change { @SuppressWarnings({"unchecked"}) public void delete(UndoContext context) { Map map = tag.getValue(); - long most; - long least; - if (map.containsKey("UUIDMost")) { - most = ((LongTag) map.get("UUIDMost")).getValue(); - least = ((LongTag) map.get("UUIDLeast")).getValue(); - } else if (map.containsKey("PersistentIDMSB")) { - most = ((LongTag) map.get("PersistentIDMSB")).getValue(); - least = ((LongTag) map.get("PersistentIDLSB")).getValue(); - } else { + UUID uuid = tag.getUUID(); + if (uuid == null) { LOGGER.info("Skipping entity without uuid."); return; } @@ -69,7 +62,6 @@ public class MutableEntityChange implements Change { int x = MathMan.roundInt(pos.get(0).getValue()); int y = MathMan.roundInt(pos.get(1).getValue()); int z = MathMan.roundInt(pos.get(2).getValue()); - UUID uuid = new UUID(most, least); context.getExtent().removeEntity(x, y, z, uuid); } @@ -89,7 +81,7 @@ public class MutableEntityChange implements Change { String id = tag.getString("Id"); EntityType type = EntityTypes.parse(id); BaseEntity entity = new BaseEntity(type, tag); - context.getExtent().createEntity(location, entity); + extent.createEntity(location, entity, tag.getUUID()); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java index e71680515..63c793ebd 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java @@ -5,6 +5,7 @@ import com.sk89q.jnbt.DoubleTag; import com.sk89q.jnbt.IntArrayTag; import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.LongTag; +import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.WorldEditException; @@ -119,6 +120,11 @@ public interface IChunkExtent extends Extent { @Override default Entity createEntity(Location location, BaseEntity entity) { + return createEntity(location, entity, UUID.randomUUID()); + } + + @Override + default Entity createEntity(Location location, BaseEntity entity, UUID uuid) { final IChunk chunk = getOrCreateChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4); Map map = new HashMap<>(entity.getNbtData().getValue()); //do not modify original entity data map.put("Id", new StringTag(entity.getType().getName())); @@ -130,23 +136,10 @@ public interface IChunkExtent extends Extent { posList.add(new DoubleTag(location.getZ())); map.put("Pos", new ListTag(DoubleTag.class, posList)); - //set new uuid - UUID newuuid = UUID.randomUUID(); - int[] uuidArray = new int[4]; - uuidArray[0] = (int) (newuuid.getMostSignificantBits() >> 32); - uuidArray[1] = (int) newuuid.getMostSignificantBits(); - uuidArray[2] = (int) (newuuid.getLeastSignificantBits() >> 32); - uuidArray[3] = (int) newuuid.getLeastSignificantBits(); - map.put("UUID", new IntArrayTag(uuidArray)); - - map.put("UUIDMost", new LongTag(newuuid.getMostSignificantBits())); - map.put("UUIDLeast", new LongTag(newuuid.getLeastSignificantBits())); - - map.put("PersistentIDMSB", new LongTag(newuuid.getMostSignificantBits())); - map.put("PersistentIDLSB", new LongTag(newuuid.getLeastSignificantBits())); + NBTUtils.addUUIDToMap(map, uuid); chunk.setEntity(new CompoundTag(map)); - return new IChunkEntity(this, location, newuuid, entity); + return new IChunkEntity(this, location, uuid, entity); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java index 763087c3b..39b4210ad 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java @@ -1056,14 +1056,17 @@ public class ChunkHolder> implements IQueueChunk { IChunkGet get = getOrCreateGet(); boolean postProcess = !(getExtent().getPostProcessor() instanceof EmptyBatchProcessor); get.setCreateCopy(postProcess); - set = getExtent().processSet(this, get, set); - try { - return get.call(set, finalize); - } finally { - if (postProcess) { - getExtent().postProcess(this, get.getCopy(), set); - } + final IChunkSet iChunkSet = getExtent().processSet(this, get, set); + Runnable finalizer; + if (postProcess) { + finalizer = () -> { + getExtent().postProcess(this, get.getCopy(), iChunkSet); + finalize.run(); + }; + } else { + finalizer = finalize; } + return get.call(set, finalizer); } return null; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java index 2893b7290..fc176a785 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java @@ -42,6 +42,7 @@ import javax.annotation.Nullable; import java.util.Collection; import java.util.List; import java.util.Set; +import java.util.UUID; public class WorldWrapper extends AbstractWorld { @@ -326,6 +327,12 @@ public class WorldWrapper extends AbstractWorld { return parent.createEntity(location, entity); } + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + return parent.createEntity(location, entity, uuid); + } + @Override public BlockState getBlock(BlockVector3 position) { return parent.getBlock(position); diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java index 451c4c679..d91aea8fe 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java @@ -340,9 +340,20 @@ public class CompoundTag extends Tag { //FAWE start public UUID getUUID() { - long most = getLong("UUIDMost"); - long least = getLong("UUIDLeast"); - return new UUID(most, least); + UUID uuid; + if (containsKey("UUID")) { + int[] arr = getIntArray("UUID"); + uuid = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL)); + } else if (containsKey("UUIDMost")) { + uuid = new UUID(getLong("UUIDMost"), getLong("UUIDLeast")); + } else if (containsKey("WorldUUIDMost")) { + uuid = new UUID(getLong("WorldUUIDMost"), getLong("WorldUUIDLeast")); + } else if (containsKey("PersistentIDMSB")) { + uuid = new UUID(getLong("PersistentIDMSB"), getLong("PersistentIDLSB")); + } else { + return null; + } + return uuid; } public Vector3 getEntityPosition() { diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java index f6217e8a7..09f87385e 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java @@ -24,6 +24,7 @@ import com.sk89q.worldedit.util.nbt.BinaryTagTypes; import com.sk89q.worldedit.world.storage.InvalidFormatException; import java.util.Map; +import java.util.UUID; import static com.google.common.base.Preconditions.checkNotNull; @@ -170,4 +171,31 @@ public final class NBTUtils { return expected.cast(tag); } + //FAWE start + /** + * Add a {@link UUID} to a map for use in a {@link CompoundTag} + * + * @param map Map to add uuid to + * @param uuid {@link UUID} to add + * @since TODO + */ + public static void addUUIDToMap(Map map, UUID uuid) { + int[] uuidArray = new int[4]; + uuidArray[0] = (int) (uuid.getMostSignificantBits() >> 32); + uuidArray[1] = (int) uuid.getMostSignificantBits(); + uuidArray[2] = (int) (uuid.getLeastSignificantBits() >> 32); + uuidArray[3] = (int) uuid.getLeastSignificantBits(); + map.put("UUID", new IntArrayTag(uuidArray)); + + map.put("UUIDMost", new LongTag(uuid.getMostSignificantBits())); + map.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits())); + + map.put("WorldUUIDMost", new LongTag(uuid.getMostSignificantBits())); + map.put("WorldUUIDLeast", new LongTag(uuid.getLeastSignificantBits())); + + map.put("PersistentIDMSB", new LongTag(uuid.getMostSignificantBits())); + map.put("PersistentIDLSB", new LongTag(uuid.getLeastSignificantBits())); + } + //FAWE end + } 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 0335a2e92..f4bb7bd6a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -3699,6 +3699,15 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } } + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + try { + return this.getExtent().createEntity(location, entity, uuid); + } catch (WorldEditException e) { + throw new RuntimeException("Unexpected exception", e); + } + } + @Override public void removeEntity(int x, int y, int z, UUID uuid) { try { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java index d3944a153..9dfd373ea 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java @@ -141,6 +141,14 @@ public class AbstractDelegateExtent implements Extent { return extent.createEntity(location, entity); } + //FAWE start + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + return extent.createEntity(location, entity, uuid); + } + //FAWE end + @Override @Nullable public Operation commit() { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java index 0239eb1ed..12ac9c428 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java @@ -37,6 +37,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import static com.google.common.base.Preconditions.checkNotNull; @@ -78,11 +79,23 @@ public class ChangeSetExtent extends AbstractDelegateExtent { public Entity createEntity(Location location, BaseEntity state) { Entity entity = super.createEntity(location, state); if (entity != null) { - changeSet.add(new EntityCreate(location, state, entity)); + changeSet.add(new EntityCreate(location, entity.getState(), entity)); } return entity; } + //FAWE start + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity state, UUID uuid) { + Entity entity = super.createEntity(location, state, uuid); + if (entity != null) { + changeSet.add(new EntityCreate(location, entity.getState(), entity)); + } + return entity; + } + //FAWE end + @Override public List getEntities() { return wrapEntities(super.getEntities()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java index fa53076eb..fc258893e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java @@ -148,6 +148,21 @@ public interface Extent extends InputExtent, OutputExtent { } //FAWE start + /** + * Create an entity at the given location, forcing a UUID onto the entity + * + * Only use if you are aware of the consequences of forcing a UUID to an entity. + * + * @param entity the entity + * @param location the location + * @param uuid UUID to force the entity to have + * @return a reference to the created entity, or null if the entity could not be created + * @since TODO + */ + @Nullable + default Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + return null; + } /** * Create an entity at the given location. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java index 6c51714c4..934b52204 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java @@ -38,6 +38,7 @@ import com.sk89q.worldedit.world.block.BlockTypes; import javax.annotation.Nullable; import java.util.Collections; import java.util.List; +import java.util.UUID; /** * An extent that returns air blocks for all blocks and does not @@ -73,6 +74,14 @@ public class NullExtent implements Extent { return null; } + //FAWE start + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + return null; + } + //FAWE end + @Override public BlockState getBlock(BlockVector3 position) { return BlockTypes.AIR.getDefaultState(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/TracingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/TracingExtent.java index b11278568..231daf9f7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/TracingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/TracingExtent.java @@ -34,6 +34,7 @@ import javax.annotation.Nullable; import java.util.Collections; import java.util.EnumSet; import java.util.Set; +import java.util.UUID; /** * An extent that can report back if an operation fails due to the extent(s) below it. @@ -106,6 +107,20 @@ public class TracingExtent extends AbstractDelegateExtent { return result; } + //FAWE start + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + BlockVector3 blockVector3 = location.toVector().toBlockPoint(); + touchedLocations.add(blockVector3); + Entity result = super.createEntity(location, entity, uuid); + if (result == null) { + failedActions.put(blockVector3, Action.CREATE_ENTITY); + } + return result; + } + //FAWE end + @Override public String toString() { return "TracingExtent{delegate=" + getExtent() + "}"; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java index 3625fed4a..ce935754f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java @@ -304,6 +304,18 @@ public class BlockArrayClipboard implements Clipboard { return getParent().createEntity(l, entity); } + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + Location l = new Location(location.getExtent(), + location.getX() - offset.getBlockX(), + location.getY() - offset.getBlockY(), + location.getZ() - offset.getBlockZ(), + location.getYaw(), location.getPitch() + ); + return getParent().createEntity(l, entity, uuid); + } + @Override public void removeEntity(int x, int y, int z, UUID uuid) { x -= offset.getX(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/WatchdogTickingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/WatchdogTickingExtent.java index da425b11a..fda1acdbb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/WatchdogTickingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/WatchdogTickingExtent.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; +import java.util.UUID; /** * Extent that ticks the watchdog before every world-affecting action. @@ -86,6 +87,15 @@ public class WatchdogTickingExtent extends AbstractDelegateExtent { return super.createEntity(location, entity); } + //FAWE start + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + onOperation(); + return super.createEntity(location, entity, uuid); + } + //FAWE end + @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { onOperation(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java index 4e3fdfd79..88f151e28 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.function.entity; +import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTagBuilder; import com.sk89q.jnbt.FloatTag; @@ -165,6 +166,8 @@ public class ExtentEntityCopy implements EntityFunction { uuid = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL)); } else if (tag.containsKey("UUIDMost")) { uuid = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast")); + } else if (tag.containsKey("WorldUUIDMost")) { + uuid = new UUID(tag.getLong("WorldUUIDMost"), tag.getLong("WorldUUIDLeast")); } else if (tag.containsKey("PersistentIDMSB")) { uuid = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB")); } @@ -177,8 +180,8 @@ public class ExtentEntityCopy implements EntityFunction { uuid ); } else { + TaskManager.taskManager().sync(entity::remove); //FAWE end - entity.remove(); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestExtent.java index 7f9db23fa..2af8232af 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestExtent.java @@ -36,6 +36,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; import java.util.List; +import java.util.UUID; public class RequestExtent implements Extent { @@ -75,6 +76,14 @@ public class RequestExtent implements Extent { return getExtent().createEntity(location, entity); } + //FAWE start + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + return getExtent().createEntity(location, entity, uuid); + } + //FAWE end + @Override public BlockState getBlock(BlockVector3 position) { return getExtent().getBlock(position); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java index 73d9110f0..908e0bac6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -52,6 +52,7 @@ import javax.annotation.Nullable; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.UUID; /** * A null implementation of {@link World} that drops all changes and @@ -229,6 +230,14 @@ public class NullWorld extends AbstractWorld { return null; } + //FAWE start + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { + return null; + } + //FAWE end + /** * Return an instance of this null world. *