385f313a8b
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 Bukkit Changes: d41796de SPIGOT-7071: Add Player#stopSound(SoundCategory category) 61dae5b2 SPIGOT-7011, SPIGOT-7065: Overhaul of structures CraftBukkit Changes: 991aeda12 SPIGOT-1729, SPIGOT-7090: Keep precision in teleportation between worlds 5c9a5f628 SPIGOT-7071: Add Player#stopSound(SoundCategory category) 68f888ded SPIGOT-7011, SPIGOT-7065: Overhaul of structures 0231a3746 Remove outdated build delay. Spigot Changes: 475f6008 Rebuild patches 8ce1761f Rebuild patches
98 Zeilen
5.4 KiB
Diff
98 Zeilen
5.4 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Nassim Jahnke <jahnke.nassim@gmail.com>
|
|
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 f68a1d5adac4d88c462371c484464bbea22d3147..6e36b6c722e647fe3672d782447a09030381137e 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
@@ -139,6 +139,7 @@ import org.bukkit.util.Vector;
|
|
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.LIQUID_CARVERS, ChunkStatus.FEATURES}; // Paper - implement regenerate chunk method
|
|
|
|
private final ServerLevel world;
|
|
private WorldBorder worldBorder;
|
|
@@ -431,27 +432,61 @@ 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;
|
|
- }
|
|
-
|
|
- final long chunkKey = ChunkCoordIntPair.pair(x, z);
|
|
- world.getChunkProvider().unloadQueue.remove(chunkKey);
|
|
+ // 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);
|
|
+ }
|
|
+ }
|
|
|
|
- net.minecraft.server.Chunk chunk = world.getChunkProvider().generateChunk(x, z);
|
|
- PlayerChunk playerChunk = world.getPlayerChunkMap().getChunk(x, z);
|
|
- if (playerChunk != null) {
|
|
- playerChunk.chunk = chunk;
|
|
+ final com.mojang.datafixers.util.Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = chunkStatus.generate(
|
|
+ Runnable::run,
|
|
+ serverLevel,
|
|
+ serverChunkCache.getGenerator(),
|
|
+ serverLevel.getStructureManager(),
|
|
+ serverChunkCache.getLightEngine(),
|
|
+ chunk -> {
|
|
+ throw new UnsupportedOperationException("Not creating full chunks here");
|
|
+ },
|
|
+ list,
|
|
+ true
|
|
+ ).join();
|
|
+ if (chunkStatus == ChunkStatus.NOISE) {
|
|
+ either.left().ifPresent(chunk -> net.minecraft.world.level.levelgen.Heightmap.primeHeightmaps(chunk, ChunkStatus.POST_FEATURES));
|
|
+ }
|
|
}
|
|
|
|
- if (chunk != null) {
|
|
- refreshChunk(x, z);
|
|
+ for (final BlockPos blockPos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), serverLevel.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), serverLevel.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) {
|
|
+ serverChunkCache.blockChanged(blockPos);
|
|
}
|
|
|
|
- return chunk != null;
|
|
- */
|
|
+ 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));
|
|
+ }
|
|
+ }
|
|
+ serverChunkCache.getLightEngine().relight(chunksToRelight, pos -> {}, relit -> {});
|
|
+ return true;
|
|
+ // Paper end
|
|
}
|
|
|
|
@Override
|