Skip to content

Commit

Permalink
Use final vars for lambdas to avoid them changing async
Browse files Browse the repository at this point in the history
The processes could run async, especially when chunk loading took a
while, so using fields that could change would result in blocks being
missed, especially in the nether or end. Switching to final vars avoids
this.

Fixes #1840
  • Loading branch information
tastybento committed Sep 9, 2021
1 parent 6bff4c8 commit b24c1fd
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions src/main/java/world/bentobox/bentobox/util/DeleteIslandChunks.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,15 @@ private void regenerateChunks() {
inDelete = true;
for (int i = 0; i < plugin.getSettings().getDeleteSpeed(); i++) {
boolean last = i == plugin.getSettings().getDeleteSpeed() -1;
final int x = chunkX;
final int z = chunkZ;
plugin.getIWM().getAddon(di.getWorld()).ifPresent(gm ->
// Overworld
processChunk(gm, di.getWorld(), chunkX, chunkZ).thenRun(() ->
processChunk(gm, di.getWorld(), x, z).thenRun(() ->
// Nether
processChunk(gm, netherWorld, chunkX, chunkZ).thenRun(() ->
processChunk(gm, netherWorld, x, z).thenRun(() ->
// End
processChunk(gm, endWorld, chunkX, chunkZ).thenRun(() -> finish(last)))));
processChunk(gm, endWorld, x, z).thenRun(() -> finish(last, x)))));
chunkZ++;
if (chunkZ > di.getMaxZChunk()) {
chunkZ = di.getMinZChunk();
Expand All @@ -94,8 +96,8 @@ private void regenerateChunks() {

}

private void finish(boolean last) {
if (chunkX > di.getMaxXChunk()) {
private void finish(boolean last, int x) {
if (x > di.getMaxXChunk()) {
// Fire event
IslandEvent.builder().deletedIslandInfo(di).reason(Reason.DELETED).build();
// We're done
Expand All @@ -107,19 +109,25 @@ private void finish(boolean last) {
}

private CompletableFuture<Boolean> processChunk(GameModeAddon gm, World world, int x, int z) {
if (world != null && PaperLib.isChunkGenerated(world, x, z)) {
if (world != null) {
CompletableFuture<Boolean> r = new CompletableFuture<>();
PaperLib.getChunkAtAsync(world, x, z).thenAccept(chunk -> regenerateChunk(r, gm, chunk));
PaperLib.getChunkAtAsync(world, x, z).thenAccept(chunk -> regenerateChunk(r, gm, chunk, x, z));
return r;
}
return CompletableFuture.completedFuture(false);
}

private void regenerateChunk(CompletableFuture<Boolean> r, GameModeAddon gm, Chunk chunk) {
private void regenerateChunk(CompletableFuture<Boolean> r, GameModeAddon gm, Chunk chunk, int x, int z) {
// Clear all inventories
Arrays.stream(chunk.getTileEntities()).filter(te -> (te instanceof InventoryHolder))
.filter(te -> di.inBounds(te.getLocation().getBlockX(), te.getLocation().getBlockZ()))
.forEach(te -> ((InventoryHolder)te).getInventory().clear());
// Remove all entities
for (Entity e : chunk.getEntities()) {
if (!(e instanceof Player)) {
e.remove();
}
}
// Reset blocks
MyBiomeGrid grid = new MyBiomeGrid(chunk.getWorld().getEnvironment());
ChunkGenerator cg = gm.getDefaultWorldGenerator(chunk.getWorld().getName(), "delete");
Expand Down

0 comments on commit b24c1fd

Please sign in to comment.