From df6f3dc8b6c10d7f4ee303baa89619627e694765 Mon Sep 17 00:00:00 2001 From: SirYwell Date: Thu, 20 Mar 2025 20:12:19 +0100 Subject: [PATCH] Fix crash due to data race when removing block entity --- .../fawe/v1_20_R2/PaperweightGetBlocks.java | 58 ++++++++-------- .../fawe/v1_20_R3/PaperweightGetBlocks.java | 58 ++++++++-------- .../fawe/v1_20_R4/PaperweightGetBlocks.java | 58 ++++++++-------- .../fawe/v1_21_R1/PaperweightGetBlocks.java | 58 ++++++++-------- .../fawe/v1_21_3/PaperweightGetBlocks.java | 58 ++++++++-------- .../fawe/v1_21_4/PaperweightGetBlocks.java | 66 ++++++++++--------- 6 files changed, 189 insertions(+), 167 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java index 3b4713dcfe..1071170335 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java @@ -13,6 +13,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitEntity; @@ -340,38 +341,41 @@ protected > T internalCall( } copies.put(copyKey, copy); } - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + List beacons = TaskManager.taskManager().sync(() -> { + // Remove existing tiles. Create a copy so that we can remove blocks + Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); + List beaconEntities = null; + if (!chunkTiles.isEmpty()) { + for (Map.Entry entry : chunkTiles.entrySet()) { + final BlockPos pos = entry.getKey(); + final int lx = pos.getX() & 15; + final int ly = pos.getY(); + final int lz = pos.getZ() & 15; + final int layer = ly >> 4; + if (!set.hasSection(layer)) { continue; } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { + BlockEntity tile = entry.getValue(); + if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { + if (beaconEntities == null) { + beaconEntities = new ArrayList<>(); + } + beaconEntities.add(tile); + PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + continue; + } + nmsChunk.removeBlockEntity(tile.getBlockPos()); + if (createCopy) { + copy.storeTile(tile); + } } } } - } + return beaconEntities; + }); final BiomeType[][] biomes = set.getBiomes(); int bitMask = 0; diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java index 418110067c..cf9df8266f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java @@ -13,6 +13,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitEntity; @@ -340,38 +341,41 @@ protected > T internalCall( } copies.put(copyKey, copy); } - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + List beacons = TaskManager.taskManager().sync(() -> { + // Remove existing tiles. Create a copy so that we can remove blocks + Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); + List beaconEntities = null; + if (!chunkTiles.isEmpty()) { + for (Map.Entry entry : chunkTiles.entrySet()) { + final BlockPos pos = entry.getKey(); + final int lx = pos.getX() & 15; + final int ly = pos.getY(); + final int lz = pos.getZ() & 15; + final int layer = ly >> 4; + if (!set.hasSection(layer)) { continue; } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { + BlockEntity tile = entry.getValue(); + if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { + if (beaconEntities == null) { + beaconEntities = new ArrayList<>(); + } + beaconEntities.add(tile); + PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + continue; + } + nmsChunk.removeBlockEntity(tile.getBlockPos()); + if (createCopy) { + copy.storeTile(tile); + } } } } - } + return beaconEntities; + }); final BiomeType[][] biomes = set.getBiomes(); int bitMask = 0; diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java index fe247efb06..22bb83a504 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java @@ -13,6 +13,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitEntity; @@ -341,38 +342,41 @@ protected > T internalCall( } copies.put(copyKey, copy); } - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + List beacons = TaskManager.taskManager().sync(() -> { + // Remove existing tiles. Create a copy so that we can remove blocks + Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); + List beaconEntities = null; + if (!chunkTiles.isEmpty()) { + for (Map.Entry entry : chunkTiles.entrySet()) { + final BlockPos pos = entry.getKey(); + final int lx = pos.getX() & 15; + final int ly = pos.getY(); + final int lz = pos.getZ() & 15; + final int layer = ly >> 4; + if (!set.hasSection(layer)) { continue; } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { + BlockEntity tile = entry.getValue(); + if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { + if (beaconEntities == null) { + beaconEntities = new ArrayList<>(); + } + beaconEntities.add(tile); + PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + continue; + } + nmsChunk.removeBlockEntity(tile.getBlockPos()); + if (createCopy) { + copy.storeTile(tile); + } } } } - } + return beaconEntities; + }); final BiomeType[][] biomes = set.getBiomes(); int bitMask = 0; diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java index 6fe163d281..8a87c45d68 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java @@ -15,6 +15,7 @@ import com.fastasyncworldedit.core.queue.implementation.QueueHandler; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitEntity; @@ -344,38 +345,41 @@ protected > T internalCall( } copies.put(copyKey, copy); } - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + List beacons = TaskManager.taskManager().sync(() -> { + // Remove existing tiles. Create a copy so that we can remove blocks + Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); + List beaconEntities = null; + if (!chunkTiles.isEmpty()) { + for (Map.Entry entry : chunkTiles.entrySet()) { + final BlockPos pos = entry.getKey(); + final int lx = pos.getX() & 15; + final int ly = pos.getY(); + final int lz = pos.getZ() & 15; + final int layer = ly >> 4; + if (!set.hasSection(layer)) { continue; } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { + BlockEntity tile = entry.getValue(); + if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { + if (beaconEntities == null) { + beaconEntities = new ArrayList<>(); + } + beaconEntities.add(tile); + PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + continue; + } + nmsChunk.removeBlockEntity(tile.getBlockPos()); + if (createCopy) { + copy.storeTile(tile); + } } } } - } + return beaconEntities; + }); final BiomeType[][] biomes = set.getBiomes(); int bitMask = 0; diff --git a/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightGetBlocks.java index 1ec6968a89..c942040dc0 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightGetBlocks.java @@ -13,6 +13,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitEntity; @@ -342,38 +343,41 @@ protected > T internalCall( } copies.put(copyKey, copy); } - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + List beacons = TaskManager.taskManager().sync(() -> { + // Remove existing tiles. Create a copy so that we can remove blocks + Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); + List beaconEntities = null; + if (!chunkTiles.isEmpty()) { + for (Map.Entry entry : chunkTiles.entrySet()) { + final BlockPos pos = entry.getKey(); + final int lx = pos.getX() & 15; + final int ly = pos.getY(); + final int lz = pos.getZ() & 15; + final int layer = ly >> 4; + if (!set.hasSection(layer)) { continue; } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { + BlockEntity tile = entry.getValue(); + if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { + if (beaconEntities == null) { + beaconEntities = new ArrayList<>(); + } + beaconEntities.add(tile); + PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + continue; + } + nmsChunk.removeBlockEntity(tile.getBlockPos()); + if (createCopy) { + copy.storeTile(tile); + } } } } - } + return beaconEntities; + }); final BiomeType[][] biomes = set.getBiomes(); int bitMask = 0; diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java index 78ea5ce2ee..62319e76b8 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java @@ -13,6 +13,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; +import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.collection.AdaptedMap; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitEntity; @@ -69,9 +70,7 @@ import org.enginehub.linbus.tree.LinStringTag; import org.enginehub.linbus.tree.LinTagType; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -344,38 +343,41 @@ protected > T internalCall( } copies.put(copyKey, copy); } - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + List beacons = TaskManager.taskManager().sync(() -> { + // Remove existing tiles. Create a copy so that we can remove blocks + Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); + List beaconEntities = null; + if (!chunkTiles.isEmpty()) { + for (Map.Entry entry : chunkTiles.entrySet()) { + final BlockPos pos = entry.getKey(); + final int lx = pos.getX() & 15; + final int ly = pos.getY(); + final int lz = pos.getZ() & 15; + final int layer = ly >> 4; + if (!set.hasSection(layer)) { continue; } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { + BlockEntity tile = entry.getValue(); + if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { + if (beaconEntities == null) { + beaconEntities = new ArrayList<>(); + } + beaconEntities.add(tile); + PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + continue; + } + nmsChunk.removeBlockEntity(tile.getBlockPos()); + if (createCopy) { + copy.storeTile(tile); + } } } } - } + return beaconEntities; + }); final BiomeType[][] biomes = set.getBiomes(); int bitMask = 0; @@ -574,14 +576,14 @@ protected > T internalCall( Map heightMaps = set.getHeightMaps(); for (Map.Entry entry : heightMaps.entrySet()) { - PaperweightGetBlocks.this.setHeightmapToGet(entry.getKey(), entry.getValue()); + this.setHeightmapToGet(entry.getKey(), entry.getValue()); } - PaperweightGetBlocks.this.setLightingToGet( + this.setLightingToGet( set.getLight(), set.getMinSectionPosition(), set.getMaxSectionPosition() ); - PaperweightGetBlocks.this.setSkyLightingToGet( + this.setSkyLightingToGet( set.getSkyLight(), set.getMinSectionPosition(), set.getMaxSectionPosition()