diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java index 8157c81eed..dabf55cffa 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java @@ -1,30 +1,94 @@ package org.bukkit.craftbukkit; -import com.google.common.base.Preconditions; -import net.minecraft.core.IRegistry; +import java.util.Locale; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.material.FluidType; import org.bukkit.Fluid; +import org.bukkit.NamespacedKey; import org.bukkit.Registry; -import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.Handleable; +import org.jetbrains.annotations.NotNull; -public class CraftFluid { +public class CraftFluid implements Fluid, Handleable { + + private static int count = 0; public static Fluid minecraftToBukkit(FluidType minecraft) { - Preconditions.checkArgument(minecraft != null); - - IRegistry registry = CraftRegistry.getMinecraftRegistry(Registries.FLUID); - Fluid bukkit = Registry.FLUID.get(CraftNamespacedKey.fromMinecraft(registry.getResourceKey(minecraft).orElseThrow().location())); - - Preconditions.checkArgument(bukkit != null); - - return bukkit; + return CraftRegistry.minecraftToBukkit(minecraft, Registries.FLUID, Registry.FLUID); } public static FluidType bukkitToMinecraft(Fluid bukkit) { - Preconditions.checkArgument(bukkit != null); + return CraftRegistry.bukkitToMinecraft(bukkit); + } - return CraftRegistry.getMinecraftRegistry(Registries.FLUID) - .getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow(); + private final NamespacedKey key; + private final FluidType fluidType; + private final String name; + private final int ordinal; + + public CraftFluid(NamespacedKey key, FluidType fluidType) { + this.key = key; + this.fluidType = fluidType; + // 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 fluid specific values. + // Custom fluids will return the key with namespace. For a plugin this should look than like a new fluid + // (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 FluidType getHandle() { + return fluidType; + } + + @NotNull + @Override + public NamespacedKey getKey() { + return key; + } + + @Override + public int compareTo(@NotNull Fluid fluid) { + return ordinal - fluid.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 CraftFluid otherFluid)) { + return false; + } + + return getKey().equals(otherFluid.getKey()); + } + + @Override + public int hashCode() { + return getKey().hashCode(); } } 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 c4326de93f..ac6e3a28e9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -11,6 +11,7 @@ import net.minecraft.core.IRegistry; import net.minecraft.core.IRegistryCustom; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; +import org.bukkit.Fluid; import org.bukkit.GameEvent; import org.bukkit.JukeboxSong; import org.bukkit.Keyed; @@ -138,6 +139,9 @@ public class CraftRegistry implements Registry { if (bukkitClass == Enchantment.class) { return new CraftRegistry<>(Enchantment.class, registryHolder.lookupOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME); } + if (bukkitClass == Fluid.class) { + return new CraftRegistry<>(Fluid.class, registryHolder.lookupOrThrow(Registries.FLUID), CraftFluid::new, FieldRename.NONE); + } if (bukkitClass == GameEvent.class) { return new CraftRegistry<>(GameEvent.class, registryHolder.lookupOrThrow(Registries.GAME_EVENT), CraftGameEvent::new, FieldRename.NONE); } 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 657d377ee4..89987bafb7 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 @@ -15,6 +15,7 @@ import java.util.Optional; import java.util.function.Function; import java.util.stream.Collector; import java.util.stream.Collectors; +import org.bukkit.Fluid; import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.attribute.Attribute; @@ -46,6 +47,7 @@ public class EnumEvil { static { // Add Classes which got changed here REGISTRIES.put(Attribute.class, new LegacyRegistryData(Registry.ATTRIBUTE, Attribute::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)); REGISTRIES.put(Frog.Variant.class, new LegacyRegistryData(Registry.FROG_VARIANT, Frog.Variant::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 c51e7a939b..86c557d501 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 @@ -88,7 +88,8 @@ public class Commodore { "org/bukkit/entity/Cat$Type", "NOP", "org/bukkit/map/MapCursor$Type", "NOP", "org/bukkit/block/banner/PatternType", "NOP", - "org/bukkit/attribute/Attribute", "NOP" + "org/bukkit/attribute/Attribute", "NOP", + "org/bukkit/Fluid", "NOP" ); private final List reroutes = new ArrayList<>(); // only for testing 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 6da72f19ed..dd5c76ad2a 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 @@ -15,13 +15,16 @@ import net.minecraft.world.entity.npc.VillagerType; import net.minecraft.world.inventory.Containers; import net.minecraft.world.item.Instrument; import net.minecraft.world.level.block.entity.EnumBannerPatternType; +import net.minecraft.world.level.material.FluidType; import net.minecraft.world.level.saveddata.maps.MapDecorationType; +import org.bukkit.Fluid; import org.bukkit.GameEvent; import org.bukkit.JukeboxSong; import org.bukkit.MusicInstrument; import org.bukkit.attribute.Attribute; import org.bukkit.block.BlockType; import org.bukkit.block.banner.PatternType; +import org.bukkit.craftbukkit.CraftFluid; import org.bukkit.craftbukkit.CraftGameEvent; import org.bukkit.craftbukkit.CraftJukeboxSong; import org.bukkit.craftbukkit.CraftMusicInstrument; @@ -68,6 +71,7 @@ public class RegistriesArgumentProvider implements ArgumentsProvider { // Order: Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class register(Attribute.class, Registries.ATTRIBUTE, CraftAttribute.class, AttributeBase.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); register(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class); register(MenuType.class, Registries.MENU, CraftMenuType.class, Containers.class);