Skip to content

Commit feb4f31

Browse files
committed
Resolve rare Folia-oriented chunk buffer crash that is incurred 1/100,000 pastes due to an unscheduled ClientboundLevelChunkWithLightPacket (and subsequent processes) operation by implementing region scheduling in this section
1 parent 7bfb60b commit feb4f31

10 files changed

Lines changed: 400 additions & 218 deletions

File tree

worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import net.minecraft.world.level.chunk.SingleValuePalette;
5858
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
5959
import org.apache.logging.log4j.Logger;
60+
import org.bukkit.Bukkit;
6061
import org.bukkit.Chunk;
6162
import org.bukkit.craftbukkit.v1_20_R2.CraftChunk;
6263

@@ -356,7 +357,6 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
356357
if (chunkHolder == null) {
357358
return;
358359
}
359-
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
360360
LevelChunk levelChunk;
361361
if (PaperLib.isPaper()) {
362362
// getChunkAtIfLoadedImmediately is paper only
@@ -378,29 +378,49 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
378378
return;
379379
}
380380
if (FoliaUtil.isFoliaServer()) {
381-
try {
382-
ClientboundLevelChunkWithLightPacket packet;
383-
if (PaperLib.isPaper()) {
384-
packet = new ClientboundLevelChunkWithLightPacket(
385-
levelChunk,
386-
nmsWorld.getChunkSource().getLightEngine(),
387-
null,
388-
null,
389-
false // last false is to not bother with x-ray
390-
);
391-
} else {
392-
// deprecated on paper - deprecation suppressed
393-
packet = new ClientboundLevelChunkWithLightPacket(
394-
levelChunk,
395-
nmsWorld.getChunkSource().getLightEngine(),
396-
null,
397-
null
398-
);
399-
}
400-
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
401-
} finally {
402-
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
403-
}
381+
Bukkit.getServer().getRegionScheduler().execute(
382+
WorldEditPlugin.getInstance(),
383+
nmsWorld.getWorld(),
384+
chunkX,
385+
chunkZ,
386+
() -> {
387+
try {
388+
LevelChunk regionChunk = nmsWorld.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
389+
if (regionChunk == null) {
390+
return;
391+
}
392+
ChunkPos coordIntPair = regionChunk.getPos();
393+
ClientboundLevelChunkWithLightPacket packet;
394+
if (PaperLib.isPaper()) {
395+
packet = new ClientboundLevelChunkWithLightPacket(
396+
regionChunk,
397+
nmsWorld.getChunkSource().getLightEngine(),
398+
null,
399+
null,
400+
false // last false is to not bother with x-ray
401+
);
402+
} else {
403+
// deprecated on paper - deprecation suppressed
404+
packet = new ClientboundLevelChunkWithLightPacket(
405+
regionChunk,
406+
nmsWorld.getChunkSource().getLightEngine(),
407+
null,
408+
null
409+
);
410+
}
411+
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
412+
} catch (IllegalStateException e) {
413+
LOGGER.warn(
414+
"Skipped sending chunk packet for chunk [{}, {}] due to concurrent section modification",
415+
chunkX,
416+
chunkZ,
417+
e
418+
);
419+
} finally {
420+
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
421+
}
422+
}
423+
);
404424
} else {
405425
MinecraftServer.getServer().execute(() -> {
406426
try {

worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import net.minecraft.world.level.chunk.SingleValuePalette;
5858
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
5959
import org.apache.logging.log4j.Logger;
60+
import org.bukkit.Bukkit;
6061
import org.bukkit.Chunk;
6162
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
6263

@@ -356,7 +357,6 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
356357
if (chunkHolder == null) {
357358
return;
358359
}
359-
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
360360
LevelChunk levelChunk;
361361
if (PaperLib.isPaper()) {
362362
// getChunkAtIfLoadedImmediately is paper only
@@ -378,29 +378,49 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
378378
return;
379379
}
380380
if (FoliaUtil.isFoliaServer()) {
381-
try {
382-
ClientboundLevelChunkWithLightPacket packet;
383-
if (PaperLib.isPaper()) {
384-
packet = new ClientboundLevelChunkWithLightPacket(
385-
levelChunk,
386-
nmsWorld.getChunkSource().getLightEngine(),
387-
null,
388-
null,
389-
false // last false is to not bother with x-ray
390-
);
391-
} else {
392-
// deprecated on paper - deprecation suppressed
393-
packet = new ClientboundLevelChunkWithLightPacket(
394-
levelChunk,
395-
nmsWorld.getChunkSource().getLightEngine(),
396-
null,
397-
null
398-
);
399-
}
400-
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
401-
} finally {
402-
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
403-
}
381+
Bukkit.getServer().getRegionScheduler().execute(
382+
WorldEditPlugin.getInstance(),
383+
nmsWorld.getWorld(),
384+
chunkX,
385+
chunkZ,
386+
() -> {
387+
try {
388+
LevelChunk regionChunk = nmsWorld.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
389+
if (regionChunk == null) {
390+
return;
391+
}
392+
ChunkPos coordIntPair = regionChunk.getPos();
393+
ClientboundLevelChunkWithLightPacket packet;
394+
if (PaperLib.isPaper()) {
395+
packet = new ClientboundLevelChunkWithLightPacket(
396+
regionChunk,
397+
nmsWorld.getChunkSource().getLightEngine(),
398+
null,
399+
null,
400+
false // last false is to not bother with x-ray
401+
);
402+
} else {
403+
// deprecated on paper - deprecation suppressed
404+
packet = new ClientboundLevelChunkWithLightPacket(
405+
regionChunk,
406+
nmsWorld.getChunkSource().getLightEngine(),
407+
null,
408+
null
409+
);
410+
}
411+
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
412+
} catch (IllegalStateException e) {
413+
LOGGER.warn(
414+
"Skipped sending chunk packet for chunk [{}, {}] due to concurrent section modification",
415+
chunkX,
416+
chunkZ,
417+
e
418+
);
419+
} finally {
420+
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
421+
}
422+
}
423+
);
404424
} else {
405425
MinecraftServer.getServer().execute(() -> {
406426
try {

worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import net.minecraft.world.level.chunk.status.ChunkStatus;
5858
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
5959
import org.apache.logging.log4j.Logger;
60+
import org.bukkit.Bukkit;
6061
import org.bukkit.Chunk;
6162
import org.bukkit.craftbukkit.CraftChunk;
6263

@@ -356,7 +357,6 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
356357
if (chunkHolder == null) {
357358
return;
358359
}
359-
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
360360
LevelChunk levelChunk;
361361
if (PaperLib.isPaper()) {
362362
// getChunkAtIfLoadedImmediately is paper only
@@ -373,29 +373,49 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
373373
return;
374374
}
375375
if (FoliaUtil.isFoliaServer()) {
376-
try {
377-
ClientboundLevelChunkWithLightPacket packet;
378-
if (PaperLib.isPaper()) {
379-
packet = new ClientboundLevelChunkWithLightPacket(
380-
levelChunk,
381-
nmsWorld.getChunkSource().getLightEngine(),
382-
null,
383-
null,
384-
false // last false is to not bother with x-ray
385-
);
386-
} else {
387-
// deprecated on paper - deprecation suppressed
388-
packet = new ClientboundLevelChunkWithLightPacket(
389-
levelChunk,
390-
nmsWorld.getChunkSource().getLightEngine(),
391-
null,
392-
null
393-
);
394-
}
395-
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
396-
} finally {
397-
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
398-
}
376+
Bukkit.getServer().getRegionScheduler().execute(
377+
WorldEditPlugin.getInstance(),
378+
nmsWorld.getWorld(),
379+
chunkX,
380+
chunkZ,
381+
() -> {
382+
try {
383+
LevelChunk regionChunk = nmsWorld.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
384+
if (regionChunk == null) {
385+
return;
386+
}
387+
ChunkPos coordIntPair = regionChunk.getPos();
388+
ClientboundLevelChunkWithLightPacket packet;
389+
if (PaperLib.isPaper()) {
390+
packet = new ClientboundLevelChunkWithLightPacket(
391+
regionChunk,
392+
nmsWorld.getChunkSource().getLightEngine(),
393+
null,
394+
null,
395+
false // last false is to not bother with x-ray
396+
);
397+
} else {
398+
// deprecated on paper - deprecation suppressed
399+
packet = new ClientboundLevelChunkWithLightPacket(
400+
regionChunk,
401+
nmsWorld.getChunkSource().getLightEngine(),
402+
null,
403+
null
404+
);
405+
}
406+
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
407+
} catch (IllegalStateException e) {
408+
LOGGER.warn(
409+
"Skipped sending chunk packet for chunk [{}, {}] due to concurrent section modification",
410+
chunkX,
411+
chunkZ,
412+
e
413+
);
414+
} finally {
415+
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
416+
}
417+
}
418+
);
399419
} else {
400420
MinecraftServer.getServer().execute(() -> {
401421
try {

worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import net.minecraft.world.level.chunk.status.ChunkStatus;
5858
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
5959
import org.apache.logging.log4j.Logger;
60+
import org.bukkit.Bukkit;
6061
import org.bukkit.Chunk;
6162
import org.bukkit.craftbukkit.CraftChunk;
6263

@@ -346,7 +347,6 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
346347
if (chunkHolder == null) {
347348
return;
348349
}
349-
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
350350
LevelChunk levelChunk;
351351
if (PaperLib.isPaper()) {
352352
// getChunkAtIfLoadedImmediately is paper only
@@ -363,29 +363,49 @@ public static void sendChunk(IntPair pair, ServerLevel nmsWorld, int chunkX, int
363363
return;
364364
}
365365
if (FoliaUtil.isFoliaServer()) {
366-
try {
367-
ClientboundLevelChunkWithLightPacket packet;
368-
if (PaperLib.isPaper()) {
369-
packet = new ClientboundLevelChunkWithLightPacket(
370-
levelChunk,
371-
nmsWorld.getChunkSource().getLightEngine(),
372-
null,
373-
null,
374-
false // last false is to not bother with x-ray
375-
);
376-
} else {
377-
// deprecated on paper - deprecation suppressed
378-
packet = new ClientboundLevelChunkWithLightPacket(
379-
levelChunk,
380-
nmsWorld.getChunkSource().getLightEngine(),
381-
null,
382-
null
383-
);
384-
}
385-
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
386-
} finally {
387-
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
388-
}
366+
Bukkit.getServer().getRegionScheduler().execute(
367+
WorldEditPlugin.getInstance(),
368+
nmsWorld.getWorld(),
369+
chunkX,
370+
chunkZ,
371+
() -> {
372+
try {
373+
LevelChunk regionChunk = nmsWorld.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
374+
if (regionChunk == null) {
375+
return;
376+
}
377+
ChunkPos coordIntPair = regionChunk.getPos();
378+
ClientboundLevelChunkWithLightPacket packet;
379+
if (PaperLib.isPaper()) {
380+
packet = new ClientboundLevelChunkWithLightPacket(
381+
regionChunk,
382+
nmsWorld.getChunkSource().getLightEngine(),
383+
null,
384+
null,
385+
false // last false is to not bother with x-ray
386+
);
387+
} else {
388+
// deprecated on paper - deprecation suppressed
389+
packet = new ClientboundLevelChunkWithLightPacket(
390+
regionChunk,
391+
nmsWorld.getChunkSource().getLightEngine(),
392+
null,
393+
null
394+
);
395+
}
396+
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
397+
} catch (IllegalStateException e) {
398+
LOGGER.warn(
399+
"Skipped sending chunk packet for chunk [{}, {}] due to concurrent section modification",
400+
chunkX,
401+
chunkZ,
402+
e
403+
);
404+
} finally {
405+
NMSAdapter.endChunkPacketSend(nmsWorld.getWorld().getName(), pair, lockHolder);
406+
}
407+
}
408+
);
389409
} else {
390410
MinecraftServer.getServer().execute(() -> {
391411
try {

0 commit comments

Comments
 (0)