From 7b903b41cbdd438e2f618e5ea46e6e133fcb22f3 Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Fri, 1 Nov 2024 08:05:35 +1100 Subject: [PATCH] #1501: Make Biome an interface By: DerFrZocker --- .../org/bukkit/craftbukkit/CraftRegistry.java | 8 +- .../bukkit/craftbukkit/block/CraftBiome.java | 99 +++++++++++++++---- .../craftbukkit/legacy/enums/EnumEvil.java | 2 + .../bukkit/craftbukkit/util/Commodore.java | 1 + .../craftbukkit/util/CraftMagicNumbers.java | 12 +++ .../provider/RegistriesArgumentProvider.java | 4 + 6 files changed, 105 insertions(+), 21 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index ac6e3a28e9..ba6a5eae95 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -24,6 +24,7 @@ import org.bukkit.block.Biome; import org.bukkit.block.BlockType; import org.bukkit.block.banner.PatternType; import org.bukkit.craftbukkit.attribute.CraftAttribute; +import org.bukkit.craftbukkit.block.CraftBiome; import org.bukkit.craftbukkit.block.CraftBlockType; import org.bukkit.craftbukkit.block.banner.CraftPatternType; import org.bukkit.craftbukkit.damage.CraftDamageType; @@ -136,6 +137,9 @@ public class CraftRegistry implements Registry { if (bukkitClass == Attribute.class) { return new CraftRegistry<>(Attribute.class, registryHolder.lookupOrThrow(Registries.ATTRIBUTE), CraftAttribute::new, FieldRename.ATTRIBUTE_RENAME); } + if (bukkitClass == Biome.class) { + return new CraftRegistry<>(Biome.class, registryHolder.lookupOrThrow(Registries.BIOME), CraftBiome::new, FieldRename.BIOME_RENAME); + } if (bukkitClass == Enchantment.class) { return new CraftRegistry<>(Enchantment.class, registryHolder.lookupOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME); } @@ -211,10 +215,6 @@ public class CraftRegistry implements Registry { if (bukkit instanceof Registry.SimpleRegistry simple) { Class bClass = simple.getType(); - if (bClass == Biome.class) { - return bukkit.get(FieldRename.BIOME_RENAME.apply(namespacedKey, apiVersion)); - } - if (bClass == EntityType.class) { return bukkit.get(FieldRename.ENTITY_TYPE_RENAME.apply(namespacedKey, apiVersion)); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java index 7a668c6b54..c463fb1dff 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java @@ -1,28 +1,23 @@ package org.bukkit.craftbukkit.block; -import com.google.common.base.Preconditions; +import java.util.Locale; import net.minecraft.core.Holder; import net.minecraft.core.IRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.biome.BiomeBase; +import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.CraftRegistry; -import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.Handleable; +import org.jetbrains.annotations.NotNull; -public class CraftBiome { +public class CraftBiome implements Biome, Handleable { + + private static int count = 0; public static Biome minecraftToBukkit(BiomeBase minecraft) { - Preconditions.checkArgument(minecraft != null); - - IRegistry registry = CraftRegistry.getMinecraftRegistry(Registries.BIOME); - Biome bukkit = Registry.BIOME.get(CraftNamespacedKey.fromMinecraft(registry.getResourceKey(minecraft).orElseThrow().location())); - - if (bukkit == null) { - return Biome.CUSTOM; - } - - return bukkit; + return CraftRegistry.minecraftToBukkit(minecraft, Registries.BIOME, Registry.BIOME); } public static Biome minecraftHolderToBukkit(Holder minecraft) { @@ -30,16 +25,15 @@ public class CraftBiome { } public static BiomeBase bukkitToMinecraft(Biome bukkit) { - if (bukkit == null || bukkit == Biome.CUSTOM) { + if (bukkit == Biome.CUSTOM) { return null; } - return CraftRegistry.getMinecraftRegistry(Registries.BIOME) - .getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow(); + return CraftRegistry.bukkitToMinecraft(bukkit); } public static Holder bukkitToMinecraftHolder(Biome bukkit) { - if (bukkit == null || bukkit == Biome.CUSTOM) { + if (bukkit == Biome.CUSTOM) { return null; } @@ -52,4 +46,75 @@ public class CraftBiome { throw new IllegalArgumentException("No Reference holder found for " + bukkit + ", this can happen if a plugin creates its own biome base with out properly registering it."); } + + private final NamespacedKey key; + private final BiomeBase biomeBase; + private final String name; + private final int ordinal; + + public CraftBiome(NamespacedKey key, BiomeBase biomeBase) { + this.key = key; + this.biomeBase = biomeBase; + // For backwards compatibility, minecraft values will stile return the uppercase name without the namespace, + // in case plugins use for example the name as key in a config file to receive biome specific values. + // Custom biomes will return the key with namespace. For a plugin this should look than like a new biome + // (which can always be added in new minecraft versions and the plugin should therefore handle it accordingly). + if (NamespacedKey.MINECRAFT.equals(key.getNamespace())) { + this.name = key.getKey().toUpperCase(Locale.ROOT); + } else { + this.name = key.toString(); + } + this.ordinal = count++; + } + + @Override + public BiomeBase getHandle() { + return biomeBase; + } + + @NotNull + @Override + public NamespacedKey getKey() { + return key; + } + + @Override + public int compareTo(@NotNull Biome biome) { + return ordinal - biome.ordinal(); + } + + @NotNull + @Override + public String name() { + return name; + } + + @Override + public int ordinal() { + return ordinal; + } + + @Override + public String toString() { + // For backwards compatibility + return name(); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (!(other instanceof CraftBiome otherBiome)) { + return false; + } + + return getKey().equals(otherBiome.getKey()); + } + + @Override + public int hashCode() { + return getKey().hashCode(); + } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java index 89987bafb7..ab1b970a0e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java @@ -19,6 +19,7 @@ import org.bukkit.Fluid; import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.attribute.Attribute; +import org.bukkit.block.Biome; import org.bukkit.block.banner.PatternType; import org.bukkit.craftbukkit.legacy.FieldRename; import org.bukkit.craftbukkit.legacy.reroute.DoNotReroute; @@ -47,6 +48,7 @@ public class EnumEvil { static { // Add Classes which got changed here REGISTRIES.put(Attribute.class, new LegacyRegistryData(Registry.ATTRIBUTE, Attribute::valueOf)); + REGISTRIES.put(Biome.class, new LegacyRegistryData(Registry.BIOME, Biome::valueOf)); REGISTRIES.put(Fluid.class, new LegacyRegistryData(Registry.FLUID, Fluid::valueOf)); REGISTRIES.put(Villager.Type.class, new LegacyRegistryData(Registry.VILLAGER_TYPE, Villager.Type::valueOf)); REGISTRIES.put(Villager.Profession.class, new LegacyRegistryData(Registry.VILLAGER_PROFESSION, Villager.Profession::valueOf)); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java index 86c557d501..0d1b18a8b7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java @@ -89,6 +89,7 @@ public class Commodore { "org/bukkit/map/MapCursor$Type", "NOP", "org/bukkit/block/banner/PatternType", "NOP", "org/bukkit/attribute/Attribute", "NOP", + "org/bukkit/block/Biome", "NOP", "org/bukkit/Fluid", "NOP" ); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index eda0a3dad7..c795b3f5bc 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -47,10 +47,12 @@ import org.bukkit.UnsafeValues; import org.bukkit.advancement.Advancement; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; +import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.CraftFeatureFlag; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.block.CraftBiome; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.damage.CraftDamageEffect; import org.bukkit.craftbukkit.damage.CraftDamageSourceBuilder; @@ -410,6 +412,16 @@ public final class CraftMagicNumbers implements UnsafeValues { return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT); } + private Biome customBiome; + @Override + public Biome getCustomBiome() { + if (customBiome == null) { + customBiome = new CraftBiome(NamespacedKey.minecraft("custom"), null); + } + + return customBiome; + } + /** * This helper class represents the different NBT Tags. *

diff --git a/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java b/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java index dd5c76ad2a..90ec32cb9a 100644 --- a/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java +++ b/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java @@ -14,6 +14,7 @@ import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.entity.npc.VillagerType; import net.minecraft.world.inventory.Containers; import net.minecraft.world.item.Instrument; +import net.minecraft.world.level.biome.BiomeBase; import net.minecraft.world.level.block.entity.EnumBannerPatternType; import net.minecraft.world.level.material.FluidType; import net.minecraft.world.level.saveddata.maps.MapDecorationType; @@ -22,6 +23,7 @@ import org.bukkit.GameEvent; import org.bukkit.JukeboxSong; import org.bukkit.MusicInstrument; import org.bukkit.attribute.Attribute; +import org.bukkit.block.Biome; import org.bukkit.block.BlockType; import org.bukkit.block.banner.PatternType; import org.bukkit.craftbukkit.CraftFluid; @@ -29,6 +31,7 @@ import org.bukkit.craftbukkit.CraftGameEvent; import org.bukkit.craftbukkit.CraftJukeboxSong; import org.bukkit.craftbukkit.CraftMusicInstrument; import org.bukkit.craftbukkit.attribute.CraftAttribute; +import org.bukkit.craftbukkit.block.CraftBiome; import org.bukkit.craftbukkit.block.CraftBlockType; import org.bukkit.craftbukkit.block.banner.CraftPatternType; import org.bukkit.craftbukkit.damage.CraftDamageType; @@ -70,6 +73,7 @@ public class RegistriesArgumentProvider implements ArgumentsProvider { static { // Order: Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class register(Attribute.class, Registries.ATTRIBUTE, CraftAttribute.class, AttributeBase.class); + register(Biome.class, Registries.BIOME, CraftBiome.class, BiomeBase.class); register(Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class); register(Fluid.class, Registries.FLUID, CraftFluid.class, FluidType.class); register(GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class);