9147456fc9
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: ab8ace685 SPIGOT-7236: Bone meal doesn't increase use statistic 7dcb59b8e Avoid switch on material in previous commit Spigot Changes: 19641c75 SPIGOT-7235: World.Spigot#strikeLightningEffect doesn't do anything
99 Zeilen
5.6 KiB
Diff
99 Zeilen
5.6 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 bbef20b0be264b429bcb037ae6740120d4113bb0..36bdc4aa5356ddcf9353c28a6ef15cd8c6aa4a47 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
@@ -138,6 +138,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;
|
|
@@ -418,27 +419,62 @@ 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 java.util.concurrent.CompletableFuture<com.mojang.datafixers.util.Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = chunkStatus.generate(
|
|
+ Runnable::run,
|
|
+ serverLevel,
|
|
+ serverChunkCache.getGenerator(),
|
|
+ serverLevel.getStructureManager(),
|
|
+ serverChunkCache.getLightEngine(),
|
|
+ chunk -> {
|
|
+ throw new UnsupportedOperationException("Not creating full chunks here");
|
|
+ },
|
|
+ list,
|
|
+ true
|
|
+ );
|
|
+ serverChunkCache.mainThreadProcessor.managedBlock(future::isDone);
|
|
+ if (chunkStatus == ChunkStatus.NOISE) {
|
|
+ future.join().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
|