2021-03-15 23:00:00 +01:00
|
|
|
--- a/net/minecraft/server/level/PlayerChunk.java
|
|
|
|
+++ b/net/minecraft/server/level/PlayerChunk.java
|
2024-06-13 17:05:00 +02:00
|
|
|
@@ -28,6 +28,10 @@
|
2024-04-23 17:15:00 +02:00
|
|
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
2023-06-07 17:30:00 +02:00
|
|
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
2021-03-15 23:00:00 +01:00
|
|
|
|
|
|
|
+// CraftBukkit start
|
|
|
|
+import net.minecraft.server.MinecraftServer;
|
|
|
|
+// CraftBukkit end
|
|
|
|
+
|
2024-06-13 17:05:00 +02:00
|
|
|
public class PlayerChunk extends GenerationChunkHolder {
|
2021-03-15 23:00:00 +01:00
|
|
|
|
2024-06-13 17:05:00 +02:00
|
|
|
public static final ChunkResult<Chunk> UNLOADED_LEVEL_CHUNK = ChunkResult.error("Unloaded level chunk");
|
|
|
|
@@ -58,9 +62,9 @@
|
2021-06-11 07:00:00 +02:00
|
|
|
this.entityTickingChunkFuture = PlayerChunk.UNLOADED_LEVEL_CHUNK_FUTURE;
|
|
|
|
this.blockChangedLightSectionFilter = new BitSet();
|
|
|
|
this.skyChangedLightSectionFilter = new BitSet();
|
|
|
|
- this.pendingFullStateConfirmation = CompletableFuture.completedFuture((Object) null);
|
2023-09-21 18:40:00 +02:00
|
|
|
- this.sendSync = CompletableFuture.completedFuture((Object) null);
|
2024-06-13 17:05:00 +02:00
|
|
|
- this.saveSync = CompletableFuture.completedFuture((Object) null);
|
2021-06-11 07:00:00 +02:00
|
|
|
+ this.pendingFullStateConfirmation = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
|
2023-09-21 18:40:00 +02:00
|
|
|
+ this.sendSync = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
|
2024-06-13 17:05:00 +02:00
|
|
|
+ this.saveSync = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
|
2021-06-11 07:00:00 +02:00
|
|
|
this.levelHeightAccessor = levelheightaccessor;
|
2023-06-07 17:30:00 +02:00
|
|
|
this.lightEngine = levellightengine;
|
2024-06-13 17:05:00 +02:00
|
|
|
this.onLevelChange = playerchunk_a;
|
2024-06-15 08:47:43 +02:00
|
|
|
@@ -72,6 +76,18 @@
|
2022-03-27 07:24:06 +02:00
|
|
|
this.changedBlocksPerSection = new ShortSet[levelheightaccessor.getSectionsCount()];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ // CraftBukkit start
|
|
|
|
+ public Chunk getFullChunkNow() {
|
2024-06-15 08:47:43 +02:00
|
|
|
+ // Note: We use the oldTicketLevel for isLoaded checks.
|
|
|
|
+ if (!ChunkLevel.fullStatus(this.oldTicketLevel).isOrAfter(FullChunkStatus.FULL)) return null;
|
|
|
|
+ return this.getFullChunkNowUnchecked();
|
2022-03-27 07:24:06 +02:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public Chunk getFullChunkNowUnchecked() {
|
2024-06-13 17:05:00 +02:00
|
|
|
+ return (Chunk) this.getChunkIfPresentUnchecked(ChunkStatus.FULL);
|
2022-03-27 07:24:06 +02:00
|
|
|
+ }
|
|
|
|
+ // CraftBukkit end
|
|
|
|
+
|
2024-06-13 17:05:00 +02:00
|
|
|
public CompletableFuture<ChunkResult<Chunk>> getTickingChunkFuture() {
|
|
|
|
return this.tickingChunkFuture;
|
|
|
|
}
|
2024-06-15 08:47:43 +02:00
|
|
|
@@ -86,7 +102,7 @@
|
2022-03-27 07:24:06 +02:00
|
|
|
|
2019-04-23 04:00:00 +02:00
|
|
|
@Nullable
|
2021-11-21 23:00:00 +01:00
|
|
|
public Chunk getTickingChunk() {
|
2024-04-23 17:15:00 +02:00
|
|
|
- return (Chunk) ((ChunkResult) this.getTickingChunkFuture().getNow(PlayerChunk.UNLOADED_LEVEL_CHUNK)).orElse((Object) null);
|
|
|
|
+ return (Chunk) ((ChunkResult) this.getTickingChunkFuture().getNow(PlayerChunk.UNLOADED_LEVEL_CHUNK)).orElse(null); // CraftBukkit - decompile error
|
2019-04-23 04:00:00 +02:00
|
|
|
}
|
|
|
|
|
2024-06-13 17:05:00 +02:00
|
|
|
@Nullable
|
2024-06-15 08:47:43 +02:00
|
|
|
@@ -134,6 +150,7 @@
|
2020-08-20 10:48:38 +02:00
|
|
|
if (chunk != null) {
|
2021-06-11 07:00:00 +02:00
|
|
|
int i = this.levelHeightAccessor.getSectionIndex(blockposition.getY());
|
2020-08-20 10:48:38 +02:00
|
|
|
|
2021-06-11 07:00:00 +02:00
|
|
|
+ if (i < 0 || i >= this.changedBlocksPerSection.length) return; // CraftBukkit - SPIGOT-6086, SPIGOT-6296
|
|
|
|
if (this.changedBlocksPerSection[i] == null) {
|
|
|
|
this.hasChangedSections = true;
|
2021-11-21 23:00:00 +01:00
|
|
|
this.changedBlocksPerSection[i] = new ShortOpenHashSet();
|
2024-06-15 08:47:43 +02:00
|
|
|
@@ -208,8 +225,11 @@
|
2023-06-07 17:30:00 +02:00
|
|
|
PacketPlayOutMultiBlockChange packetplayoutmultiblockchange = new PacketPlayOutMultiBlockChange(sectionposition, shortset, chunksection);
|
|
|
|
|
|
|
|
this.broadcast(list, packetplayoutmultiblockchange);
|
|
|
|
+ // CraftBukkit start
|
|
|
|
+ List finalList = list;
|
|
|
|
packetplayoutmultiblockchange.runUpdates((blockposition1, iblockdata1) -> {
|
|
|
|
- this.broadcastBlockEntityIfNeeded(list, world, blockposition1, iblockdata1);
|
|
|
|
+ this.broadcastBlockEntityIfNeeded(finalList, world, blockposition1, iblockdata1);
|
|
|
|
+ // CraftBukkit end
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2024-06-15 08:47:43 +02:00
|
|
|
@@ -275,7 +295,7 @@
|
2021-06-11 07:00:00 +02:00
|
|
|
this.pendingFullStateConfirmation = completablefuture1;
|
2024-04-23 17:15:00 +02:00
|
|
|
completablefuture.thenAccept((chunkresult) -> {
|
|
|
|
chunkresult.ifSuccess((chunk) -> {
|
2021-06-11 07:00:00 +02:00
|
|
|
- completablefuture1.complete((Object) null);
|
|
|
|
+ completablefuture1.complete(null); // CraftBukkit - decompile error
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2024-06-15 08:47:43 +02:00
|
|
|
@@ -290,6 +310,30 @@
|
2023-06-07 17:30:00 +02:00
|
|
|
FullChunkStatus fullchunkstatus1 = ChunkLevel.fullStatus(this.ticketLevel);
|
2024-06-13 17:05:00 +02:00
|
|
|
boolean flag = fullchunkstatus.isOrAfter(FullChunkStatus.FULL);
|
|
|
|
boolean flag1 = fullchunkstatus1.isOrAfter(FullChunkStatus.FULL);
|
2019-05-16 01:11:20 +02:00
|
|
|
+ // CraftBukkit start
|
|
|
|
+ // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins.
|
2024-06-13 17:05:00 +02:00
|
|
|
+ if (flag && !flag1) {
|
|
|
|
+ this.getFullChunkFuture().thenAccept((either) -> {
|
2024-04-23 17:15:00 +02:00
|
|
|
+ Chunk chunk = (Chunk) either.orElse(null);
|
2020-03-03 02:19:06 +01:00
|
|
|
+ if (chunk != null) {
|
|
|
|
+ playerchunkmap.callbackExecutor.execute(() -> {
|
|
|
|
+ // Minecraft will apply the chunks tick lists to the world once the chunk got loaded, and then store the tick
|
|
|
|
+ // lists again inside the chunk once the chunk becomes inaccessible and set the chunk's needsSaving flag.
|
|
|
|
+ // These actions may however happen deferred, so we manually set the needsSaving flag already here.
|
2021-11-21 23:00:00 +01:00
|
|
|
+ chunk.setUnsaved(true);
|
2020-03-03 02:19:06 +01:00
|
|
|
+ chunk.unloadCallback();
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }).exceptionally((throwable) -> {
|
|
|
|
+ // ensure exceptions are printed, by default this is not the case
|
2022-02-28 16:00:00 +01:00
|
|
|
+ MinecraftServer.LOGGER.error("Failed to schedule unload callback for chunk " + PlayerChunk.this.pos, throwable);
|
2020-03-03 02:19:06 +01:00
|
|
|
+ return null;
|
|
|
|
+ });
|
2019-07-13 20:19:44 +02:00
|
|
|
+
|
|
|
|
+ // Run callback right away if the future was already done
|
|
|
|
+ playerchunkmap.callbackExecutor.run();
|
2019-05-16 01:11:20 +02:00
|
|
|
+ }
|
|
|
|
+ // CraftBukkit end
|
|
|
|
|
2024-06-13 17:05:00 +02:00
|
|
|
this.wasAccessibleSinceLastSave |= flag1;
|
|
|
|
if (!flag && flag1) {
|
2024-06-15 08:47:43 +02:00
|
|
|
@@ -341,6 +385,26 @@
|
2019-05-16 01:11:20 +02:00
|
|
|
|
2021-11-21 23:00:00 +01:00
|
|
|
this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel);
|
2019-05-16 01:11:20 +02:00
|
|
|
this.oldTicketLevel = this.ticketLevel;
|
|
|
|
+ // CraftBukkit start
|
|
|
|
+ // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins.
|
2023-06-07 17:30:00 +02:00
|
|
|
+ if (!fullchunkstatus.isOrAfter(FullChunkStatus.FULL) && fullchunkstatus1.isOrAfter(FullChunkStatus.FULL)) {
|
2024-06-13 17:05:00 +02:00
|
|
|
+ this.getFullChunkFuture().thenAccept((either) -> {
|
2024-04-23 17:15:00 +02:00
|
|
|
+ Chunk chunk = (Chunk) either.orElse(null);
|
2020-03-03 02:19:06 +01:00
|
|
|
+ if (chunk != null) {
|
|
|
|
+ playerchunkmap.callbackExecutor.execute(() -> {
|
|
|
|
+ chunk.loadCallback();
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }).exceptionally((throwable) -> {
|
|
|
|
+ // ensure exceptions are printed, by default this is not the case
|
2022-02-28 16:00:00 +01:00
|
|
|
+ MinecraftServer.LOGGER.error("Failed to schedule load callback for chunk " + PlayerChunk.this.pos, throwable);
|
2020-03-03 02:19:06 +01:00
|
|
|
+ return null;
|
|
|
|
+ });
|
2019-07-13 20:19:44 +02:00
|
|
|
+
|
|
|
|
+ // Run callback right away if the future was already done
|
|
|
|
+ playerchunkmap.callbackExecutor.run();
|
2019-05-16 01:11:20 +02:00
|
|
|
+ }
|
|
|
|
+ // CraftBukkit end
|
|
|
|
}
|
|
|
|
|
2023-06-07 17:30:00 +02:00
|
|
|
public boolean wasAccessibleSinceLastSave() {
|