Skip to content

Commit 6ad2605

Browse files
PierreSchwangMattBDevNotMyFault
authored
fix: synchronize entity removal when needed (#3325)
Co-authored-by: Matt <[email protected]> Co-authored-by: Alexander Brandes <[email protected]>
1 parent baf46e0 commit 6ad2605

File tree

4 files changed

+38
-14
lines changed

4 files changed

+38
-14
lines changed

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package com.sk89q.worldedit.bukkit;
2121

22+
import com.fastasyncworldedit.core.util.TaskManager;
2223
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
2324
import com.sk89q.worldedit.entity.BaseEntity;
2425
import com.sk89q.worldedit.entity.Entity;
@@ -110,17 +111,21 @@ public BaseEntity getState() {
110111

111112
@Override
112113
public boolean remove() {
113-
org.bukkit.entity.Entity entity = entityRef.get();
114-
if (entity != null) {
115-
try {
116-
entity.remove();
117-
} catch (UnsupportedOperationException e) {
118-
return false;
114+
// synchronize the whole method, not just the remove operation as we always need to synchronize and
115+
// can make sure the entity reference was not invalidated in the few milliseconds between the next available tick (lol)
116+
return TaskManager.taskManager().sync(() -> {
117+
org.bukkit.entity.Entity entity = entityRef.get();
118+
if (entity != null) {
119+
try {
120+
entity.remove();
121+
} catch (UnsupportedOperationException e) {
122+
return false;
123+
}
124+
return entity.isDead();
125+
} else {
126+
return true;
119127
}
120-
return entity.isDead();
121-
} else {
122-
return true;
123-
}
128+
});
124129
}
125130

126131
@SuppressWarnings("unchecked")

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ public List<com.sk89q.worldedit.entity.Entity> getEntities() {
167167
return list;
168168
}
169169

170+
@Override
171+
public int removeEntities(final Region region) {
172+
List<com.sk89q.worldedit.entity.Entity> entities = getEntities(region);
173+
return TaskManager.taskManager().sync(() -> entities.stream()
174+
.mapToInt(entity -> entity.remove() ? 1 : 0).sum()
175+
);
176+
}
177+
170178
//FAWE: createEntity was moved to IChunkExtent to prevent issues with Async Entity Add.
171179

172180
/**

worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
import com.sk89q.worldedit.command.util.annotation.Confirm;
5151
import com.sk89q.worldedit.command.util.annotation.Preload;
5252
import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected;
53-
import com.sk89q.worldedit.entity.Entity;
5453
import com.sk89q.worldedit.extension.platform.Actor;
5554
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
5655
import com.sk89q.worldedit.extent.clipboard.Clipboard;
@@ -479,7 +478,7 @@ public void place(
479478
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())
480479
.toBlockPoint());
481480
if (removeEntities) {
482-
editSession.getEntities(new CuboidRegion(realTo, max)).forEach(Entity::remove);
481+
editSession.removeEntities(new CuboidRegion(realTo, max));
483482
}
484483
if (selectPasted || onlySelect) {
485484
RegionSelector selector = new CuboidRegionSelector(world, realTo, max);
@@ -569,9 +568,9 @@ public void paste(
569568
Vector3 realTo = to.toVector3().add(transform.apply(clipboardOffset.toVector3()));
570569
Vector3 max = realTo.add(transform.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()));
571570

572-
// FAWE start - entity remova;l
571+
// FAWE start - entity removal
573572
if (removeEntities) {
574-
editSession.getEntities(new CuboidRegion(realTo.toBlockPoint(), max.toBlockPoint())).forEach(Entity::remove);
573+
editSession.removeEntities(new CuboidRegion(realTo.toBlockPoint(), max.toBlockPoint()));
575574
}
576575
if (selectPasted || onlySelect) {
577576
//FAWE end

worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,18 @@ default Entity createEntity(Location location, BaseEntity entity, UUID uuid) {
176176
default void removeEntity(int x, int y, int z, UUID uuid) {
177177
}
178178

179+
/**
180+
* Removes all entities in the given region.
181+
*
182+
* @param region the region
183+
* @return the number of entities removed
184+
*/
185+
default int removeEntities(Region region) {
186+
return this.getEntities(region).stream()
187+
.mapToInt(entity -> entity.remove() ? 1 : 0)
188+
.sum();
189+
}
190+
179191
/*
180192
Queue based methods
181193
TODO NOT IMPLEMENTED:

0 commit comments

Comments
 (0)