Paper/patches/server/0674-Implement-regenerateChunk.patch
Nassim Jahnke 6e71f41536
Updated Upstream (CraftBukkit/Spigot)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

CraftBukkit Changes:
65247583f SPIGOT-7857: Improve ItemMeta block data deserialization
05d80500d SPIGOT-7857: Fix spurious internal NBT tag when deserializing BlockStateMeta
cebb58e9a SPIGOT-7804: Fix written book serialization
efcdd5d38 SPIGOT-7794: Cancelling InventoryItemMoveEvent destroys items
b568ba572 SPIGOT-7789: Fix NPE in CraftMetaFirework applyToItem
f057cf449 Remove outdated build delay

Spigot Changes:
f6a48054 SPIGOT-7835: Fix issue with custom hopper settings
bb63b137 Rebuild patches
e1142b4d Rebuild patches
2024-08-24 11:23:57 +02:00

105 lines
5.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Mon, 31 Jan 2022 11:21:50 +0100
Subject: [PATCH] Implement regenerateChunk
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index a5121eb7fa8fccf7e742beea285c2f741ece513d..7e9344fdafb01030061458c55ccf6836bf643da3 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -151,6 +151,7 @@ import org.jetbrains.annotations.Nullable;
public class CraftWorld extends CraftRegionAccessor implements World {
public static final int CUSTOM_DIMENSION_OFFSET = 10;
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
+ private static final ChunkStatus[] REGEN_CHUNK_STATUSES = {ChunkStatus.BIOMES, ChunkStatus.NOISE, ChunkStatus.SURFACE, ChunkStatus.CARVERS, ChunkStatus.FEATURES, ChunkStatus.INITIALIZE_LIGHT}; // Paper - implement regenerate chunk method
private final ServerLevel world;
private WorldBorder worldBorder;
@@ -421,27 +422,70 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean regenerateChunk(int x, int z) {
org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot
- throw new UnsupportedOperationException("Not supported in this Minecraft version! Unless you can fix it, this is not a bug :)");
- /*
- if (!unloadChunk0(x, z, false)) {
- return false;
+ // Paper start - implement regenerateChunk method
+ final ServerLevel serverLevel = this.world;
+ final net.minecraft.server.level.ServerChunkCache serverChunkCache = serverLevel.getChunkSource();
+ final ChunkPos chunkPos = new ChunkPos(x, z);
+ final net.minecraft.world.level.chunk.LevelChunk levelChunk = serverChunkCache.getChunk(chunkPos.x, chunkPos.z, true);
+ for (final BlockPos blockPos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), serverLevel.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), serverLevel.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) {
+ levelChunk.removeBlockEntity(blockPos);
+ serverLevel.setBlock(blockPos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(), 16);
+ }
+
+ for (final ChunkStatus chunkStatus : REGEN_CHUNK_STATUSES) {
+ final List<ChunkAccess> list = new ArrayList<>();
+ final int range = Math.max(1, chunkStatus.getRange());
+ for (int chunkX = chunkPos.z - range; chunkX <= chunkPos.z + range; chunkX++) {
+ for (int chunkZ = chunkPos.x - range; chunkZ <= chunkPos.x + range; chunkZ++) {
+ ChunkAccess chunkAccess = serverChunkCache.getChunk(chunkZ, chunkX, chunkStatus.getParent(), true);
+ if (chunkAccess instanceof ImposterProtoChunk accessProtoChunk) {
+ chunkAccess = new ImposterProtoChunk(accessProtoChunk.getWrapped(), true);
+ } else if (chunkAccess instanceof net.minecraft.world.level.chunk.LevelChunk accessLevelChunk) {
+ chunkAccess = new ImposterProtoChunk(accessLevelChunk, true);
+ }
+ list.add(chunkAccess);
+ }
+ }
+
+ final java.util.concurrent.CompletableFuture<ChunkAccess> future = chunkStatus.generate(
+ new net.minecraft.world.level.chunk.status.WorldGenContext(
+ serverLevel,
+ serverChunkCache.getGenerator(),
+ serverLevel.getStructureManager(),
+ serverChunkCache.getLightEngine()
+ ),
+ Runnable::run,
+ chunk -> {
+ throw new UnsupportedOperationException("Not creating full chunks here");
+ },
+ list
+ );
+ serverChunkCache.mainThreadProcessor.managedBlock(future::isDone);
+ if (chunkStatus == ChunkStatus.NOISE) {
+ net.minecraft.world.level.levelgen.Heightmap.primeHeightmaps(future.join(), ChunkStatus.POST_FEATURES);
+ }
}
- final long chunkKey = ChunkCoordIntPair.pair(x, z);
- world.getChunkProvider().unloadQueue.remove(chunkKey);
+ for (final BlockPos blockPos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), serverLevel.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), serverLevel.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) {
+ serverChunkCache.blockChanged(blockPos);
+ }
- net.minecraft.server.Chunk chunk = world.getChunkProvider().generateChunk(x, z);
- PlayerChunk playerChunk = world.getPlayerChunkMap().getChunk(x, z);
- if (playerChunk != null) {
- playerChunk.chunk = chunk;
+ final Set<ChunkPos> chunksToRelight = new HashSet<>(9);
+ for (int chunkX = chunkPos.x - 1; chunkX <= chunkPos.x + 1 ; chunkX++) {
+ for (int chunkZ = chunkPos.z - 1; chunkZ <= chunkPos.z + 1 ; chunkZ++) {
+ chunksToRelight.add(new ChunkPos(chunkX, chunkZ));
+ }
}
- if (chunk != null) {
- refreshChunk(x, z);
+ for (final ChunkPos pos : chunksToRelight) {
+ final ChunkAccess chunk = serverChunkCache.getChunk(pos.x, pos.z, false);
+ if (chunk != null) {
+ serverChunkCache.getLightEngine().lightChunk(chunk, false);
+ }
}
- return chunk != null;
- */
+ return true;
+ // Paper end - implement regenerate chunk method
}
@Override