Skip to content

Commit ab79341

Browse files
authored
Merge pull request #2253 from Brokkonaut/bukkit-custombiomes
Allow custom biomes in bukkit
2 parents 474c191 + 6bbcf74 commit ab79341

7 files changed

Lines changed: 266 additions & 9 deletions

File tree

worldedit-bukkit/adapters/adapter-1.17.1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/v1_17_R1_2/PaperweightAdapter.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
import java.nio.file.Files;
143143
import java.nio.file.Path;
144144
import java.util.ArrayList;
145+
import java.util.Collection;
145146
import java.util.HashMap;
146147
import java.util.List;
147148
import java.util.Locale;
@@ -358,6 +359,44 @@ public BaseBlock getFullBlock(Location location) {
358359
return state.toBaseBlock();
359360
}
360361

362+
@Override
363+
public boolean hasCustomBiomeSupport() {
364+
return true;
365+
}
366+
367+
private static final HashMap<BiomeType, Biome> biomeTypeToNMSCache = new HashMap<>();
368+
private static final HashMap<Biome, BiomeType> biomeTypeFromNMSCache = new HashMap<>();
369+
370+
@Override
371+
public BiomeType getBiome(Location location) {
372+
checkNotNull(location);
373+
374+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
375+
int x = location.getBlockX();
376+
int y = location.getBlockY();
377+
int z = location.getBlockZ();
378+
379+
final ServerLevel handle = craftWorld.getHandle();
380+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
381+
return biomeTypeFromNMSCache.computeIfAbsent(chunk.getBiomes().getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getKey(b).toString()));
382+
}
383+
384+
@Override
385+
public void setBiome(Location location, BiomeType biome) {
386+
checkNotNull(location);
387+
checkNotNull(biome);
388+
389+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
390+
int x = location.getBlockX();
391+
int y = location.getBlockY();
392+
int z = location.getBlockZ();
393+
394+
final ServerLevel handle = craftWorld.getHandle();
395+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
396+
chunk.getBiomes().setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).get(ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation(b.getId())))));
397+
chunk.setUnsaved(true);
398+
}
399+
361400
@Override
362401
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
363402
return new PaperweightWorldNativeAccess(this,
@@ -799,6 +838,17 @@ public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3
799838
return false;
800839
}
801840

841+
@Override
842+
public void initializeRegistries() {
843+
DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer();
844+
// Biomes
845+
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).keySet()) {
846+
if (BiomeType.REGISTRY.get(name.toString()) == null) {
847+
BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString()));
848+
}
849+
}
850+
}
851+
802852
// ------------------------------------------------------------------------
803853
// Code that is less likely to break
804854
// ------------------------------------------------------------------------

worldedit-bukkit/adapters/adapter-1.18.2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/v1_18_R2/PaperweightAdapter.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import com.sk89q.worldedit.world.item.ItemType;
8080
import net.minecraft.Util;
8181
import net.minecraft.core.BlockPos;
82+
import net.minecraft.core.Holder;
8283
import net.minecraft.core.Registry;
8384
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
8485
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
@@ -142,6 +143,7 @@
142143
import java.nio.file.Files;
143144
import java.nio.file.Path;
144145
import java.util.ArrayList;
146+
import java.util.Collection;
145147
import java.util.HashMap;
146148
import java.util.List;
147149
import java.util.Locale;
@@ -349,6 +351,45 @@ public BaseBlock getFullBlock(Location location) {
349351
return state.toBaseBlock();
350352
}
351353

354+
@Override
355+
public boolean hasCustomBiomeSupport() {
356+
return true;
357+
}
358+
359+
private static final HashMap<BiomeType, Holder<Biome>> biomeTypeToNMSCache = new HashMap<>();
360+
private static final HashMap<Holder<Biome>, BiomeType> biomeTypeFromNMSCache = new HashMap<>();
361+
362+
@Override
363+
public BiomeType getBiome(Location location) {
364+
checkNotNull(location);
365+
366+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
367+
int x = location.getBlockX();
368+
int y = location.getBlockY();
369+
int z = location.getBlockZ();
370+
371+
final ServerLevel handle = craftWorld.getHandle();
372+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
373+
374+
return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString()));
375+
}
376+
377+
@Override
378+
public void setBiome(Location location, BiomeType biome) {
379+
checkNotNull(location);
380+
checkNotNull(biome);
381+
382+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
383+
int x = location.getBlockX();
384+
int y = location.getBlockY();
385+
int z = location.getBlockZ();
386+
387+
final ServerLevel handle = craftWorld.getHandle();
388+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
389+
chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getHolderOrThrow(ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation(b.getId())))));
390+
chunk.setUnsaved(true);
391+
}
392+
352393
@Override
353394
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
354395
return new PaperweightWorldNativeAccess(this,
@@ -788,6 +829,17 @@ public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3
788829
return false;
789830
}
790831

832+
@Override
833+
public void initializeRegistries() {
834+
DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer();
835+
// Biomes
836+
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).keySet()) {
837+
if (BiomeType.REGISTRY.get(name.toString()) == null) {
838+
BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString()));
839+
}
840+
}
841+
}
842+
791843
// ------------------------------------------------------------------------
792844
// Code that is less likely to break
793845
// ------------------------------------------------------------------------

worldedit-bukkit/adapters/adapter-1.19.3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/v1_19_R2/PaperweightAdapter.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import com.sk89q.worldedit.world.item.ItemType;
8080
import net.minecraft.Util;
8181
import net.minecraft.core.BlockPos;
82+
import net.minecraft.core.Holder;
8283
import net.minecraft.core.registries.Registries;
8384
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
8485
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
@@ -142,6 +143,7 @@
142143
import java.nio.file.Files;
143144
import java.nio.file.Path;
144145
import java.util.ArrayList;
146+
import java.util.Collection;
145147
import java.util.HashMap;
146148
import java.util.List;
147149
import java.util.Locale;
@@ -349,6 +351,45 @@ public BaseBlock getFullBlock(Location location) {
349351
return state.toBaseBlock();
350352
}
351353

354+
@Override
355+
public boolean hasCustomBiomeSupport() {
356+
return true;
357+
}
358+
359+
private static final HashMap<BiomeType, Holder<Biome>> biomeTypeToNMSCache = new HashMap<>();
360+
private static final HashMap<Holder<Biome>, BiomeType> biomeTypeFromNMSCache = new HashMap<>();
361+
362+
@Override
363+
public BiomeType getBiome(Location location) {
364+
checkNotNull(location);
365+
366+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
367+
int x = location.getBlockX();
368+
int y = location.getBlockY();
369+
int z = location.getBlockZ();
370+
371+
final ServerLevel handle = craftWorld.getHandle();
372+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
373+
374+
return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString()));
375+
}
376+
377+
@Override
378+
public void setBiome(Location location, BiomeType biome) {
379+
checkNotNull(location);
380+
checkNotNull(biome);
381+
382+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
383+
int x = location.getBlockX();
384+
int y = location.getBlockY();
385+
int z = location.getBlockZ();
386+
387+
final ServerLevel handle = craftWorld.getHandle();
388+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
389+
chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(ResourceKey.create(Registries.BIOME, new ResourceLocation(b.getId())))));
390+
chunk.setUnsaved(true);
391+
}
392+
352393
@Override
353394
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
354395
return new PaperweightWorldNativeAccess(this,
@@ -802,6 +843,17 @@ public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3
802843
return false;
803844
}
804845

846+
@Override
847+
public void initializeRegistries() {
848+
DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer();
849+
// Biomes
850+
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.BIOME).keySet()) {
851+
if (BiomeType.REGISTRY.get(name.toString()) == null) {
852+
BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString()));
853+
}
854+
}
855+
}
856+
805857
// ------------------------------------------------------------------------
806858
// Code that is less likely to break
807859
// ------------------------------------------------------------------------

worldedit-bukkit/adapters/adapter-1.19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/v1_19_R1/PaperweightAdapter.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import com.sk89q.worldedit.world.item.ItemType;
8080
import net.minecraft.Util;
8181
import net.minecraft.core.BlockPos;
82+
import net.minecraft.core.Holder;
8283
import net.minecraft.core.Registry;
8384
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
8485
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
@@ -142,6 +143,7 @@
142143
import java.nio.file.Files;
143144
import java.nio.file.Path;
144145
import java.util.ArrayList;
146+
import java.util.Collection;
145147
import java.util.HashMap;
146148
import java.util.List;
147149
import java.util.Locale;
@@ -348,6 +350,45 @@ public BaseBlock getFullBlock(Location location) {
348350
return state.toBaseBlock();
349351
}
350352

353+
@Override
354+
public boolean hasCustomBiomeSupport() {
355+
return true;
356+
}
357+
358+
private static final HashMap<BiomeType, Holder<Biome>> biomeTypeToNMSCache = new HashMap<>();
359+
private static final HashMap<Holder<Biome>, BiomeType> biomeTypeFromNMSCache = new HashMap<>();
360+
361+
@Override
362+
public BiomeType getBiome(Location location) {
363+
checkNotNull(location);
364+
365+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
366+
int x = location.getBlockX();
367+
int y = location.getBlockY();
368+
int z = location.getBlockZ();
369+
370+
final ServerLevel handle = craftWorld.getHandle();
371+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
372+
373+
return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString()));
374+
}
375+
376+
@Override
377+
public void setBiome(Location location, BiomeType biome) {
378+
checkNotNull(location);
379+
checkNotNull(biome);
380+
381+
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
382+
int x = location.getBlockX();
383+
int y = location.getBlockY();
384+
int z = location.getBlockZ();
385+
386+
final ServerLevel handle = craftWorld.getHandle();
387+
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
388+
chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getHolderOrThrow(ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation(b.getId())))));
389+
chunk.setUnsaved(true);
390+
}
391+
351392
@Override
352393
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
353394
return new PaperweightWorldNativeAccess(this,
@@ -790,6 +831,17 @@ public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3
790831
return false;
791832
}
792833

834+
@Override
835+
public void initializeRegistries() {
836+
DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer();
837+
// Biomes
838+
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).keySet()) {
839+
if (BiomeType.REGISTRY.get(name.toString()) == null) {
840+
BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString()));
841+
}
842+
}
843+
}
844+
793845
// ------------------------------------------------------------------------
794846
// Code that is less likely to break
795847
// ------------------------------------------------------------------------

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,20 +525,30 @@ public boolean fullySupports3DBiomes() {
525525
@SuppressWarnings("deprecation")
526526
@Override
527527
public BiomeType getBiome(BlockVector3 position) {
528-
if (HAS_3D_BIOMES) {
529-
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ()));
528+
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
529+
if (adapter != null && adapter.hasCustomBiomeSupport()) {
530+
return adapter.getBiome(BukkitAdapter.adapt(getWorld(), position));
530531
} else {
531-
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
532+
if (HAS_3D_BIOMES) {
533+
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ()));
534+
} else {
535+
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
536+
}
532537
}
533538
}
534539

535540
@SuppressWarnings("deprecation")
536541
@Override
537542
public boolean setBiome(BlockVector3 position, BiomeType biome) {
538-
if (HAS_3D_BIOMES) {
539-
getWorld().setBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ(), BukkitAdapter.adapt(biome));
543+
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
544+
if (adapter != null && adapter.hasCustomBiomeSupport()) {
545+
adapter.setBiome(BukkitAdapter.adapt(getWorld(), position), biome);
540546
} else {
541-
getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome));
547+
if (HAS_3D_BIOMES) {
548+
getWorld().setBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ(), BukkitAdapter.adapt(biome));
549+
} else {
550+
getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome));
551+
}
542552
}
543553
return true;
544554
}

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ public void onEnable() {
172172
getServer().getPluginManager().registerEvents(new AsyncTabCompleteListener(), this);
173173
}
174174

175-
initializeRegistries(); // this creates the objects matching Bukkit's enums - but doesn't fill them with data yet
176175
if (Bukkit.getWorlds().isEmpty()) {
177176
setupPreWorldData();
178177
// register this so we can load world-dependent data right as the first world is loading
@@ -194,6 +193,7 @@ public void onEnable() {
194193

195194
private void setupPreWorldData() {
196195
loadAdapter();
196+
initializeRegistries(); // this creates the objects matching Bukkit's enums - but doesn't fill them with data yet
197197
config.load();
198198
WorldEdit.getInstance().loadMappings();
199199
}
@@ -210,8 +210,10 @@ private void setupWorldData() {
210210
private void initializeRegistries() {
211211
// Biome
212212
for (Biome biome : Biome.values()) {
213-
String lowerCaseBiomeName = biome.name().toLowerCase(Locale.ROOT);
214-
BiomeType.REGISTRY.register("minecraft:" + lowerCaseBiomeName, new BiomeType("minecraft:" + lowerCaseBiomeName));
213+
if (!biome.name().equals("CUSTOM")) {
214+
String lowerCaseBiomeName = biome.name().toLowerCase(Locale.ROOT);
215+
BiomeType.REGISTRY.register("minecraft:" + lowerCaseBiomeName, new BiomeType("minecraft:" + lowerCaseBiomeName));
216+
}
215217
}
216218
// Block & Item
217219
for (Material material : Material.values()) {
@@ -253,6 +255,11 @@ private void initializeRegistries() {
253255
// ... :|
254256
GameModes.get("");
255257
WeatherTypes.get("");
258+
259+
BukkitImplAdapter adapter = getBukkitImplAdapter();
260+
if (adapter != null) {
261+
adapter.initializeRegistries();
262+
}
256263
}
257264

258265
private void setupTags() {

0 commit comments

Comments
 (0)