2022-01-08 00:35:32 +01:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Thu, 6 Jan 2022 15:59:06 -0800
Subject: [PATCH] Expose vanilla BiomeProvider from WorldInfo
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
2024-12-03 19:54:10 +01:00
index edd2e83df282b0e24d4c7e3a34776a5b039c2c6b..c133a646baf88e0489d358e302d67f21f76b47c3 100644
2022-01-08 00:35:32 +01:00
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
2024-10-31 22:30:18 +01:00
@@ -625,7 +625,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2022-12-07 22:35:34 +01:00
List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver));
2024-10-23 22:52:43 +02:00
LevelStem worlddimension = (LevelStem) dimensions.getValue(dimensionKey);
2022-01-08 00:35:32 +01:00
2022-12-07 22:35:34 +01:00
- org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value());
2024-01-18 22:00:40 +01:00
+ org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value(), worlddimension.generator(), this.registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
2022-01-08 00:35:32 +01:00
if (biomeProvider == null && gen != null) {
biomeProvider = gen.getDefaultBiomeProvider(worldInfo);
}
2024-08-31 19:59:17 +02:00
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
2024-12-05 11:18:29 +01:00
index 3ed78515fed78f5a679b9002e2e3a0aa6984aa70..8ca9a5d274a28f5feab492a446afea6b187b5d6a 100644
2024-08-31 19:59:17 +02:00
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
2024-12-03 19:54:10 +01:00
@@ -363,7 +363,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
2024-08-31 19:59:17 +02:00
this.serverLevelData.setWorld(this);
if (biomeProvider != null) {
2024-10-23 22:52:43 +02:00
- BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().lookupOrThrow(Registries.BIOME));
+ BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().lookupOrThrow(Registries.BIOME), chunkgenerator.getBiomeSource()); // Paper - add vanillaBiomeProvider
2024-08-31 19:59:17 +02:00
if (chunkgenerator instanceof NoiseBasedChunkGenerator cga) {
chunkgenerator = new NoiseBasedChunkGenerator(worldChunkManager, cga.settings);
} else if (chunkgenerator instanceof FlatLevelSource cpf) {
2022-01-08 00:35:32 +01:00
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
Rework async chunk api implementation
Firstly, the old methods all routed to the CompletableFuture method.
However, the CF method could not guarantee that if the caller
was off-main that the future would be "completed" on-main. Since
the callback methods used the CF one, this meant that the callback
methods did not guarantee that the callbacks were to be called on
the main thread.
Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb)
so that the methods with the callback are guaranteed to invoke
the callback on the main thread. The CF behavior remains unchanged;
it may still appear to complete on main if invoked off-main.
Secondly, remove the scheduleOnMain invocation in the async
chunk completion. This unnecessarily delays the callback
by 1 tick.
Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which
will load chunks within an area. This method is provided as a helper
as keeping all chunks loaded within an area can be complicated to
implement for plugins (due to the lacking ticket API), and is
already implemented internally anyways.
Fourthly, remove the ticket addition that occured with getChunkAt
and getChunkAtAsync. The ticket addition may delay the unloading
of the chunk unnecessarily. It also fixes a very rare timing bug
where the future/callback would be completed after the chunk
unloads.
2024-11-19 07:34:32 +01:00
index 33d9f3778996eedc83064332a2fbbdc7c6a8ba90..62ab88e022230d25ffb359981ce7da4e64a9be5a 100644
2022-01-08 00:35:32 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
2024-10-27 18:11:15 +01:00
@@ -1310,7 +1310,7 @@ public final class CraftServer implements Server {
2022-12-07 22:35:34 +01:00
List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata));
2024-10-23 22:52:43 +02:00
LevelStem worlddimension = iregistry.getValue(actualDimension);
2022-01-08 00:35:32 +01:00
2022-12-07 22:35:34 +01:00
- WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value());
2024-01-18 22:00:40 +01:00
+ WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value(), worlddimension.generator(), this.getHandle().getServer().registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
2022-01-08 00:35:32 +01:00
if (biomeProvider == null && generator != null) {
biomeProvider = generator.getDefaultBiomeProvider(worldInfo);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
2024-12-03 19:54:10 +01:00
index 744e3631cd2d5c157c9b6023ca813e57c6f860d6..66778ebd82563823f692c7151f40a373e8d7427a 100644
2022-01-08 00:35:32 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
2024-12-03 15:47:48 +01:00
@@ -209,6 +209,39 @@ public class CraftWorld extends CraftRegionAccessor implements World {
2022-06-05 22:51:44 +02:00
public int getPlayerCount() {
return world.players().size();
2022-01-08 00:35:32 +01:00
}
+
+ @Override
+ public BiomeProvider vanillaBiomeProvider() {
2022-06-08 15:57:04 +02:00
+ net.minecraft.server.level.ServerChunkCache serverCache = this.getHandle().chunkSource;
+
2024-08-31 19:59:17 +02:00
+ final net.minecraft.world.level.chunk.ChunkGenerator gen = serverCache.getGenerator();
+ net.minecraft.world.level.biome.BiomeSource biomeSource;
+ if (gen instanceof org.bukkit.craftbukkit.generator.CustomChunkGenerator custom) {
+ biomeSource = custom.getDelegate().getBiomeSource();
+ } else {
+ biomeSource = gen.getBiomeSource();
+ }
+ if (biomeSource instanceof org.bukkit.craftbukkit.generator.CustomWorldChunkManager customBiomeSource) {
+ biomeSource = customBiomeSource.vanillaBiomeSource;
+ }
+ final net.minecraft.world.level.biome.BiomeSource finalBiomeSource = biomeSource;
2022-06-08 15:57:04 +02:00
+ final net.minecraft.world.level.biome.Climate.Sampler sampler = serverCache.randomState().sampler();
+
2024-08-31 19:59:17 +02:00
+ final List<Biome> possibleBiomes = finalBiomeSource.possibleBiomes().stream()
+ .map(CraftBiome::minecraftHolderToBukkit)
2022-01-08 00:35:32 +01:00
+ .toList();
+ return new BiomeProvider() {
+ @Override
+ public Biome getBiome(final org.bukkit.generator.WorldInfo worldInfo, final int x, final int y, final int z) {
2024-08-31 19:59:17 +02:00
+ return CraftBiome.minecraftHolderToBukkit(finalBiomeSource.getNoiseBiome(x >> 2, y >> 2, z >> 2, sampler));
2022-01-08 00:35:32 +01:00
+ }
+
+ @Override
+ public List<Biome> getBiomes(final org.bukkit.generator.WorldInfo worldInfo) {
+ return possibleBiomes;
+ }
+ };
+ }
// Paper end
private static final Random rand = new Random();
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java
2024-09-07 22:35:11 +02:00
index 5d655d6cd3e23e0287069f8bdf77601487e862fd..c81455a4ee9a3185f125ebf8cec325f4ed2e501d 100644
2022-01-08 00:35:32 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftWorldInfo.java
2022-06-08 16:46:39 +02:00
@@ -17,8 +17,14 @@ public class CraftWorldInfo implements WorldInfo {
2022-01-08 00:35:32 +01:00
private final long seed;
private final int minHeight;
private final int maxHeight;
+ // Paper start
+ private final net.minecraft.world.level.chunk.ChunkGenerator vanillaChunkGenerator;
2022-06-08 16:46:39 +02:00
+ private final net.minecraft.core.RegistryAccess.Frozen registryAccess;
2022-01-08 00:35:32 +01:00
2022-06-08 16:46:39 +02:00
- public CraftWorldInfo(ServerLevelData worldDataServer, LevelStorageSource.LevelStorageAccess session, World.Environment environment, DimensionType dimensionManager) {
2024-09-07 22:35:11 +02:00
+ public CraftWorldInfo(PrimaryLevelData worldDataServer, LevelStorageSource.LevelStorageAccess session, World.Environment environment, DimensionType dimensionManager, net.minecraft.world.level.chunk.ChunkGenerator chunkGenerator, net.minecraft.core.RegistryAccess.Frozen registryAccess) {
2022-06-08 16:46:39 +02:00
+ this.registryAccess = registryAccess;
2022-01-08 00:35:32 +01:00
+ this.vanillaChunkGenerator = chunkGenerator;
+ // Paper end
this.name = worldDataServer.getLevelName();
2022-06-08 14:33:46 +02:00
this.uuid = WorldUUID.getUUID(session.levelDirectory.path().toFile());
2022-01-08 00:35:32 +01:00
this.environment = environment;
2022-06-08 16:46:39 +02:00
@@ -27,15 +33,6 @@ public class CraftWorldInfo implements WorldInfo {
this.maxHeight = dimensionManager.minY() + dimensionManager.height();
2022-01-08 00:35:32 +01:00
}
2022-06-08 16:46:39 +02:00
- public CraftWorldInfo(String name, UUID uuid, World.Environment environment, long seed, int minHeight, int maxHeight) {
- this.name = name;
- this.uuid = uuid;
- this.environment = environment;
- this.seed = seed;
- this.minHeight = minHeight;
- this.maxHeight = maxHeight;
- }
-
@Override
public String getName() {
return this.name;
2023-09-23 04:06:03 +02:00
@@ -65,4 +62,34 @@ public class CraftWorldInfo implements WorldInfo {
2022-01-08 00:35:32 +01:00
public int getMaxHeight() {
return this.maxHeight;
}
+
+ // Paper start
+ @Override
+ public org.bukkit.generator.BiomeProvider vanillaBiomeProvider() {
2022-06-08 16:46:39 +02:00
+ final net.minecraft.world.level.levelgen.RandomState randomState;
+ if (vanillaChunkGenerator instanceof net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
+ randomState = net.minecraft.world.level.levelgen.RandomState.create(noiseBasedChunkGenerator.generatorSettings().value(),
2022-12-08 04:24:00 +01:00
+ registryAccess.lookupOrThrow(net.minecraft.core.registries.Registries.NOISE), getSeed());
2022-06-08 16:46:39 +02:00
+ } else {
+ randomState = net.minecraft.world.level.levelgen.RandomState.create(net.minecraft.world.level.levelgen.NoiseGeneratorSettings.dummy(),
2022-12-08 04:24:00 +01:00
+ registryAccess.lookupOrThrow(net.minecraft.core.registries.Registries.NOISE), getSeed());
2022-06-08 16:46:39 +02:00
+ }
+
2022-01-08 00:35:32 +01:00
+ final java.util.List<org.bukkit.block.Biome> possibleBiomes = CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().possibleBiomes().stream()
2023-09-23 04:06:03 +02:00
+ .map(biome -> org.bukkit.craftbukkit.block.CraftBiome.minecraftHolderToBukkit(biome))
2022-01-08 00:35:32 +01:00
+ .toList();
+ return new org.bukkit.generator.BiomeProvider() {
+ @Override
+ public org.bukkit.block.Biome getBiome(final WorldInfo worldInfo, final int x, final int y, final int z) {
2023-09-23 04:06:03 +02:00
+ return org.bukkit.craftbukkit.block.CraftBiome.minecraftHolderToBukkit(
2022-06-08 16:46:39 +02:00
+ CraftWorldInfo.this.vanillaChunkGenerator.getBiomeSource().getNoiseBiome(x >> 2, y >> 2, z >> 2, randomState.sampler()));
2022-01-08 00:35:32 +01:00
+ }
+
+ @Override
+ public java.util.List<org.bukkit.block.Biome> getBiomes(final org.bukkit.generator.WorldInfo worldInfo) {
+ return possibleBiomes;
+ }
+ };
+ }
+ // Paper end
}
2024-08-31 19:59:17 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java
index 0063c4c17d05a77adf81164fb9307a29860cbe12..0bac128d6faff0063b03f595b82deea78d1ae161 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomWorldChunkManager.java
@@ -31,7 +31,11 @@ public class CustomWorldChunkManager extends BiomeSource {
return biomeBases;
}
- public CustomWorldChunkManager(WorldInfo worldInfo, BiomeProvider biomeProvider, Registry<net.minecraft.world.level.biome.Biome> registry) {
+ // Paper start - add vanillaBiomeProvider
+ public final BiomeSource vanillaBiomeSource;
+ public CustomWorldChunkManager(WorldInfo worldInfo, BiomeProvider biomeProvider, Registry<net.minecraft.world.level.biome.Biome> registry, BiomeSource vanillaBiomeSource) {
+ this.vanillaBiomeSource = vanillaBiomeSource;
+ // Paper end - add vanillaBiomeProvider
this.worldInfo = worldInfo;
this.biomeProvider = biomeProvider;
this.registry = registry;