#1275: Add internal ItemType and BlockType, delegate Material methods to them

By: Jishuna <joshl5324@gmail.com>
Also-by: Bjarne Koll <lynxplay101@gmail.com>
Also-by: DerFrZocker <derrieple@gmail.com>
Also-by: md_5 <git@md-5.net>
This commit is contained in:
CraftBukkit/Spigot 2024-05-05 10:08:54 +10:00
parent b4e6cc4dce
commit 8f55ed539f
14 changed files with 642 additions and 47 deletions

View File

@ -20,11 +20,14 @@ import org.bukkit.Particle;
import org.bukkit.Registry; import org.bukkit.Registry;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.BlockType;
import org.bukkit.craftbukkit.block.CraftBlockType;
import org.bukkit.craftbukkit.damage.CraftDamageType; import org.bukkit.craftbukkit.damage.CraftDamageType;
import org.bukkit.craftbukkit.enchantments.CraftEnchantment; import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
import org.bukkit.craftbukkit.entity.CraftWolf; import org.bukkit.craftbukkit.entity.CraftWolf;
import org.bukkit.craftbukkit.generator.structure.CraftStructure; import org.bukkit.craftbukkit.generator.structure.CraftStructure;
import org.bukkit.craftbukkit.generator.structure.CraftStructureType; import org.bukkit.craftbukkit.generator.structure.CraftStructureType;
import org.bukkit.craftbukkit.inventory.CraftItemType;
import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial; import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern; import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern;
import org.bukkit.craftbukkit.legacy.FieldRename; import org.bukkit.craftbukkit.legacy.FieldRename;
@ -38,6 +41,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Wolf; import org.bukkit.entity.Wolf;
import org.bukkit.generator.structure.Structure; import org.bukkit.generator.structure.Structure;
import org.bukkit.generator.structure.StructureType; import org.bukkit.generator.structure.StructureType;
import org.bukkit.inventory.ItemType;
import org.bukkit.inventory.meta.trim.TrimMaterial; import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.inventory.meta.trim.TrimPattern;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
@ -115,7 +119,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
* @param registryHolder the minecraft registry holder * @param registryHolder the minecraft registry holder
* @return the bukkit registry of the provided class * @return the bukkit registry of the provided class
*/ */
public static <B extends Keyed> Registry<?> createRegistry(Class<B> bukkitClass, IRegistryCustom registryHolder) { public static <B extends Keyed> Registry<?> createRegistry(Class<? super B> bukkitClass, IRegistryCustom registryHolder) {
if (bukkitClass == Enchantment.class) { if (bukkitClass == Enchantment.class) {
return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME); return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME);
} }
@ -146,6 +150,12 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
if (bukkitClass == Wolf.Variant.class) { if (bukkitClass == Wolf.Variant.class) {
return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, NONE); return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, NONE);
} }
if (bukkitClass == BlockType.class) {
return new CraftRegistry<>(BlockType.class, registryHolder.registryOrThrow(Registries.BLOCK), CraftBlockType::new, NONE);
}
if (bukkitClass == ItemType.class) {
return new CraftRegistry<>(ItemType.class, registryHolder.registryOrThrow(Registries.ITEM), CraftItemType::new, NONE);
}
return null; return null;
} }

View File

@ -121,6 +121,7 @@ import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Registry; import org.bukkit.Registry;
@ -2364,14 +2365,14 @@ public final class CraftServer implements Server {
public BlockData createBlockData(String data) throws IllegalArgumentException { public BlockData createBlockData(String data) throws IllegalArgumentException {
Preconditions.checkArgument(data != null, "data cannot be null"); Preconditions.checkArgument(data != null, "data cannot be null");
return createBlockData(null, data); return createBlockData((Material) null, data);
} }
@Override @Override
public BlockData createBlockData(org.bukkit.Material material, String data) { public BlockData createBlockData(org.bukkit.Material material, String data) {
Preconditions.checkArgument(material != null || data != null, "Must provide one of material or data"); Preconditions.checkArgument(material != null || data != null, "Must provide one of material or data");
return CraftBlockData.newData(material, data); return CraftBlockData.newData((material != null) ? material.asBlockType() : null, data);
} }
@Override @Override

View File

@ -1,10 +1,42 @@
package org.bukkit.craftbukkit.block; package org.bukkit.craftbukkit.block;
import com.google.common.base.Preconditions;
import java.util.function.Consumer;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.EnumHand;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.BlockAccessAir;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.BlockFalling;
import net.minecraft.world.level.block.BlockFire;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBase;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.phys.MovingObjectPositionBlock;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.World;
import org.bukkit.block.BlockType;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.inventory.CraftItemType;
import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.inventory.ItemType;
import org.jetbrains.annotations.NotNull;
public class CraftBlockType { public class CraftBlockType<B extends BlockData> implements BlockType.Typed<B>, Handleable<Block> {
private final NamespacedKey key;
private final Block block;
private final Class<B> blockDataClass;
private final boolean interactable;
public static Material minecraftToBukkit(Block block) { public static Material minecraftToBukkit(Block block) {
return CraftMagicNumbers.getMaterial(block); return CraftMagicNumbers.getMaterial(block);
@ -13,4 +45,184 @@ public class CraftBlockType {
public static Block bukkitToMinecraft(Material material) { public static Block bukkitToMinecraft(Material material) {
return CraftMagicNumbers.getBlock(material); return CraftMagicNumbers.getBlock(material);
} }
public static BlockType minecraftToBukkitNew(Block minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.BLOCK, Registry.BLOCK);
}
public static Block bukkitToMinecraftNew(BlockType bukkit) {
return CraftRegistry.bukkitToMinecraft(bukkit);
}
private static boolean hasMethod(Class<?> clazz, String methodName, Class<?>... params) {
boolean hasMethod;
try {
hasMethod = clazz.getDeclaredMethod(methodName, params) != null;
} catch (NoSuchMethodException ex) {
hasMethod = false;
}
return hasMethod;
}
private static boolean isInteractable(Block block) {
Class<?> clazz = block.getClass();
boolean hasMethod = hasMethod(clazz, "useWithoutItem", IBlockData.class, net.minecraft.world.level.World.class, BlockPosition.class, EntityHuman.class, MovingObjectPositionBlock.class)
|| hasMethod(clazz, "useItemOn", net.minecraft.world.item.ItemStack.class, IBlockData.class, net.minecraft.world.level.World.class, BlockPosition.class, EntityHuman.class, EnumHand.class, MovingObjectPositionBlock.class);
if (!hasMethod && clazz.getSuperclass() != BlockBase.class) {
clazz = clazz.getSuperclass();
hasMethod = hasMethod(clazz, "useWithoutItem", IBlockData.class, net.minecraft.world.level.World.class, BlockPosition.class, EntityHuman.class, MovingObjectPositionBlock.class)
|| hasMethod(clazz, "useItemOn", net.minecraft.world.item.ItemStack.class, IBlockData.class, net.minecraft.world.level.World.class, BlockPosition.class, EntityHuman.class, EnumHand.class, MovingObjectPositionBlock.class);
}
return hasMethod;
}
public CraftBlockType(NamespacedKey key, Block block) {
this.key = key;
this.block = block;
this.blockDataClass = (Class<B>) CraftBlockData.fromData(block.defaultBlockState()).getClass().getInterfaces()[0];
this.interactable = isInteractable(block);
}
@Override
public Block getHandle() {
return block;
}
@NotNull
@Override
public Typed<BlockData> typed() {
return this.typed(BlockData.class);
}
@NotNull
@Override
@SuppressWarnings("unchecked")
public <Other extends BlockData> Typed<Other> typed(@NotNull Class<Other> blockDataType) {
if (blockDataType.isAssignableFrom(this.blockDataClass)) return (Typed<Other>) this;
throw new IllegalArgumentException("Cannot type block type " + this.key.toString() + " to blockdata type " + blockDataType.getSimpleName());
}
@Override
public boolean hasItemType() {
if (this == AIR) {
return true;
}
return block.asItem() != Items.AIR;
}
@NotNull
@Override
public ItemType getItemType() {
if (this == AIR) {
return ItemType.AIR;
}
Item item = block.asItem();
Preconditions.checkArgument(item != Items.AIR, "The block type %s has no corresponding item type", getKey());
return CraftItemType.minecraftToBukkitNew(item);
}
@Override
public Class<B> getBlockDataClass() {
return blockDataClass;
}
@Override
public B createBlockData() {
return createBlockData((String) null);
}
@Override
public B createBlockData(Consumer<? super B> consumer) {
B data = createBlockData();
if (consumer != null) {
consumer.accept(data);
}
return data;
}
@Override
public B createBlockData(String data) {
return (B) CraftBlockData.newData(this, data);
}
@Override
public boolean isSolid() {
return block.defaultBlockState().blocksMotion();
}
@Override
public boolean isAir() {
return block.defaultBlockState().isAir();
}
@Override
public boolean isEnabledByFeature(@NotNull World world) {
Preconditions.checkNotNull(world, "World cannot be null");
return getHandle().isEnabled(((CraftWorld) world).getHandle().enabledFeatures());
}
@Override
public boolean isFlammable() {
return block.defaultBlockState().ignitedByLava();
}
@Override
public boolean isBurnable() {
return ((BlockFire) Blocks.FIRE).igniteOdds.getOrDefault(block, 0) > 0;
}
@Override
public boolean isOccluding() {
return block.defaultBlockState().isRedstoneConductor(BlockAccessAir.INSTANCE, BlockPosition.ZERO);
}
@Override
public boolean hasGravity() {
return block instanceof BlockFalling;
}
@Override
public boolean isInteractable() {
return interactable;
}
@Override
public float getHardness() {
return block.defaultBlockState().destroySpeed;
}
@Override
public float getBlastResistance() {
return block.getExplosionResistance();
}
@Override
public float getSlipperiness() {
return block.getFriction();
}
@NotNull
@Override
public String getTranslationKey() {
return block.getDescriptionId();
}
@Override
public NamespacedKey getKey() {
return key;
}
@Override
public Material asMaterial() {
return Registry.MATERIAL.get(this.key);
}
} }

View File

@ -31,6 +31,7 @@ import org.bukkit.SoundGroup;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.BlockSupport; import org.bukkit.block.BlockSupport;
import org.bukkit.block.BlockType;
import org.bukkit.block.PistonMoveReaction; import org.bukkit.block.PistonMoveReaction;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.structure.Mirror; import org.bukkit.block.structure.Mirror;
@ -540,11 +541,9 @@ public class CraftBlockData implements BlockData {
Preconditions.checkState(MAP.put(nms, bukkit) == null, "Duplicate mapping %s->%s", nms, bukkit); Preconditions.checkState(MAP.put(nms, bukkit) == null, "Duplicate mapping %s->%s", nms, bukkit);
} }
public static CraftBlockData newData(Material material, String data) { public static CraftBlockData newData(BlockType blockType, String data) {
Preconditions.checkArgument(material == null || material.isBlock(), "Cannot get data for not block %s", material);
IBlockData blockData; IBlockData blockData;
Block block = CraftBlockType.bukkitToMinecraft(material); Block block = blockType == null ? null : ((CraftBlockType<?>) blockType).getHandle();
Map<IBlockState<?>, Comparable<?>> parsed = null; Map<IBlockState<?>, Comparable<?>> parsed = null;
// Data provided, use it // Data provided, use it

View File

@ -1,10 +1,44 @@
package org.bukkit.craftbukkit.inventory; package org.bukkit.craftbukkit.inventory;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import java.util.function.Consumer;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemBlock;
import net.minecraft.world.item.ItemRecord;
import net.minecraft.world.item.component.ItemAttributeModifiers;
import net.minecraft.world.level.block.entity.TileEntityFurnace;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.World;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.block.BlockType;
import org.bukkit.craftbukkit.CraftEquipmentSlot;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.attribute.CraftAttribute;
import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
import org.bukkit.craftbukkit.block.CraftBlockType;
import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.inventory.CreativeCategory;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ItemType;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CraftItemType { public class CraftItemType<M extends ItemMeta> implements ItemType.Typed<M>, Handleable<Item> {
private final NamespacedKey key;
private final Item item;
private final Class<M> itemMetaClass;
public static Material minecraftToBukkit(Item item) { public static Material minecraftToBukkit(Item item) {
return CraftMagicNumbers.getMaterial(item); return CraftMagicNumbers.getMaterial(item);
@ -13,4 +47,183 @@ public class CraftItemType {
public static Item bukkitToMinecraft(Material material) { public static Item bukkitToMinecraft(Material material) {
return CraftMagicNumbers.getItem(material); return CraftMagicNumbers.getItem(material);
} }
public static ItemType minecraftToBukkitNew(Item minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.ITEM, Registry.ITEM);
}
public static Item bukkitToMinecraftNew(ItemType bukkit) {
return CraftRegistry.bukkitToMinecraft(bukkit);
}
public CraftItemType(NamespacedKey key, Item item) {
this.key = key;
this.item = item;
this.itemMetaClass = getItemMetaClass(item);
}
// Cursed, this should be refactored when possible
private Class<M> getItemMetaClass(Item item) {
ItemMeta meta = new ItemStack(asMaterial()).getItemMeta();
if (meta != null) {
if (CraftMetaEntityTag.class != meta.getClass() && CraftMetaArmorStand.class != meta.getClass()) {
return (Class<M>) meta.getClass().getInterfaces()[0];
}
}
return (Class<M>) ItemMeta.class;
}
@NotNull
@Override
public Typed<ItemMeta> typed() {
return this.typed(ItemMeta.class);
}
@NotNull
@Override
@SuppressWarnings("unchecked")
public <Other extends ItemMeta> Typed<Other> typed(@NotNull final Class<Other> itemMetaType) {
if (itemMetaType.isAssignableFrom(this.itemMetaClass)) return (Typed<Other>) this;
throw new IllegalArgumentException("Cannot type item type " + this.key.toString() + " to meta type " + itemMetaType.getSimpleName());
}
@NotNull
@Override
public ItemStack createItemStack() {
return this.createItemStack(1, null);
}
@NotNull
@Override
public ItemStack createItemStack(final int amount) {
return this.createItemStack(amount, null);
}
@NotNull
@Override
public ItemStack createItemStack(Consumer<? super M> metaConfigurator) {
return this.createItemStack(1, metaConfigurator);
}
@NotNull
@Override
public ItemStack createItemStack(final int amount, @Nullable final Consumer<? super M> metaConfigurator) {
final ItemStack itemStack = new ItemStack(this.asMaterial(), amount);
if (metaConfigurator != null) {
final ItemMeta itemMeta = itemStack.getItemMeta();
metaConfigurator.accept((M) itemMeta);
itemStack.setItemMeta(itemMeta);
}
return itemStack;
}
@Override
public Item getHandle() {
return item;
}
@Override
public boolean hasBlockType() {
return item instanceof ItemBlock;
}
@NotNull
@Override
public BlockType getBlockType() {
if (!(item instanceof ItemBlock block)) {
throw new IllegalStateException("The item type " + getKey() + " has no corresponding block type");
}
return CraftBlockType.minecraftToBukkitNew(block.getBlock());
}
@Override
public Class<M> getItemMetaClass() {
if (this == ItemType.AIR) {
throw new UnsupportedOperationException("Air does not have ItemMeta");
}
return itemMetaClass;
}
@Override
public int getMaxStackSize() {
// Based of the material enum air is only 0, in PerMaterialTest it is also set as special case
// the item info itself would return 64
if (this == AIR) {
return 0;
}
return item.components().getOrDefault(DataComponents.MAX_STACK_SIZE, 64);
}
@Override
public short getMaxDurability() {
return item.components().getOrDefault(DataComponents.MAX_DAMAGE, 0).shortValue();
}
@Override
public boolean isEdible() {
return item.components().has(DataComponents.FOOD);
}
@Override
public boolean isRecord() {
return item instanceof ItemRecord;
}
@Override
public boolean isFuel() {
return TileEntityFurnace.isFuel(new net.minecraft.world.item.ItemStack(item));
}
@Override
public ItemType getCraftingRemainingItem() {
Item expectedItem = item.getCraftingRemainingItem();
return expectedItem == null ? null : minecraftToBukkitNew(expectedItem);
}
// @Override
// public EquipmentSlot getEquipmentSlot() {
// return CraftEquipmentSlot.getSlot(EntityInsentient.getEquipmentSlotForItem(CraftItemStack.asNMSCopy(ItemStack.of(this))));
// }
@Override
public Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(EquipmentSlot slot) {
ImmutableMultimap.Builder<Attribute, AttributeModifier> defaultAttributes = ImmutableMultimap.builder();
ItemAttributeModifiers nmsDefaultAttributes = item.getDefaultAttributeModifiers();
nmsDefaultAttributes.forEach(CraftEquipmentSlot.getNMS(slot), (key, value) -> {
Attribute attribute = CraftAttribute.minecraftToBukkit(key.value());
defaultAttributes.put(attribute, CraftAttributeInstance.convert(value, slot));
});
return defaultAttributes.build();
}
@Override
public CreativeCategory getCreativeCategory() {
return CreativeCategory.BUILDING_BLOCKS;
}
@Override
public boolean isEnabledByFeature(@NotNull World world) {
Preconditions.checkNotNull(world, "World cannot be null");
return getHandle().isEnabled(((CraftWorld) world).getHandle().enabledFeatures());
}
@NotNull
@Override
public String getTranslationKey() {
return item.getDescriptionId();
}
@Override
public NamespacedKey getKey() {
return key;
}
@Override
public Material asMaterial() {
return Registry.MATERIAL.get(this.key);
}
} }

View File

@ -192,7 +192,7 @@ public final class CraftLegacy {
} }
} }
if (mappedData == null && material.isBlock()) { if (mappedData == null) {
// Try exact match first // Try exact match first
IBlockData iblock = materialToData.get(materialData); IBlockData iblock = materialToData.get(materialData);
if (iblock != null) { if (iblock != null) {

View File

@ -10,11 +10,13 @@ import net.minecraft.world.entity.EntityTypes;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.BlockType;
import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.block.CraftBlockType; import org.bukkit.craftbukkit.block.CraftBlockType;
import org.bukkit.craftbukkit.entity.CraftEntityType; import org.bukkit.craftbukkit.entity.CraftEntityType;
import org.bukkit.craftbukkit.inventory.CraftItemType; import org.bukkit.craftbukkit.inventory.CraftItemType;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemType;
import org.bukkit.packs.DataPack; import org.bukkit.packs.DataPack;
import org.bukkit.packs.DataPackManager; import org.bukkit.packs.DataPackManager;
@ -89,6 +91,24 @@ public class CraftDataPackManager implements DataPackManager {
return false; return false;
} }
@Override
public boolean isEnabledByFeature(ItemType itemType, World world) {
Preconditions.checkArgument(itemType != null, "itemType cannot be null");
Preconditions.checkArgument(world != null, "world cannot be null");
CraftWorld craftWorld = ((CraftWorld) world);
return CraftItemType.bukkitToMinecraftNew(itemType.typed()).isEnabled(craftWorld.getHandle().enabledFeatures());
}
@Override
public boolean isEnabledByFeature(BlockType blockType, World world) {
Preconditions.checkArgument(blockType != null, "blockType cannot be null");
Preconditions.checkArgument(world != null, "world cannot be null");
CraftWorld craftWorld = ((CraftWorld) world);
return CraftBlockType.bukkitToMinecraftNew(blockType.typed()).isEnabled(craftWorld.getHandle().enabledFeatures());
}
@Override @Override
public boolean isEnabledByFeature(EntityType entityType, World world) { public boolean isEnabledByFeature(EntityType entityType, World world) {
Preconditions.checkArgument(entityType != null, "entityType cannot be null"); Preconditions.checkArgument(entityType != null, "entityType cannot be null");

View File

@ -8,6 +8,7 @@ import net.minecraft.world.level.block.BlockCake;
import net.minecraft.world.level.block.BlockChest; import net.minecraft.world.level.block.BlockChest;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockType;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Cake; import org.bukkit.block.data.type.Cake;
import org.bukkit.block.data.type.Chest; import org.bukkit.block.data.type.Chest;
@ -21,7 +22,7 @@ public class BlockDataTest extends AbstractTestingBase {
public void testParsing() { public void testParsing() {
BlockData cakeTest = CraftBlockData.fromData(Blocks.CAKE.defaultBlockState().setValue(BlockCake.BITES, 3)); BlockData cakeTest = CraftBlockData.fromData(Blocks.CAKE.defaultBlockState().setValue(BlockCake.BITES, 3));
BlockData materialString = CraftBlockData.newData(Material.CAKE, "[bites=3]"); BlockData materialString = CraftBlockData.newData(BlockType.CAKE, "[bites=3]");
assertThat(materialString, is(cakeTest)); assertThat(materialString, is(cakeTest));
BlockData combined = CraftBlockData.newData(null, "cake[bites=3]"); BlockData combined = CraftBlockData.newData(null, "cake[bites=3]");
@ -46,19 +47,14 @@ public class BlockDataTest extends AbstractTestingBase {
@Test @Test
public void testDoubleMaterial() { public void testDoubleMaterial() {
assertThrows(IllegalArgumentException.class, () -> CraftBlockData.newData(Material.CAKE, "minecraft:cake[bites=3]")); assertThrows(IllegalArgumentException.class, () -> CraftBlockData.newData(BlockType.CAKE, "minecraft:cake[bites=3]"));
} }
@Test @Test
public void testMistake() { public void testMistake() {
BlockData cakeTest = CraftBlockData.fromData(Blocks.CAKE.defaultBlockState().setValue(BlockCake.BITES, 3)); BlockData cakeTest = CraftBlockData.fromData(Blocks.CAKE.defaultBlockState().setValue(BlockCake.BITES, 3));
assertThrows(IllegalArgumentException.class, () -> CraftBlockData.newData(Material.CAKE, cakeTest.toString())); assertThrows(IllegalArgumentException.class, () -> CraftBlockData.newData(BlockType.CAKE, cakeTest.toString()));
}
@Test
public void testItem() {
assertThrows(IllegalArgumentException.class, () -> CraftBlockData.newData(Material.DIAMOND_AXE, null));
} }
@Test @Test

View File

@ -0,0 +1,22 @@
package org.bukkit.craftbukkit.block;
import static org.bukkit.support.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import java.lang.reflect.Field;
import org.bukkit.block.BlockType;
import org.junit.jupiter.api.Test;
public class BlockTypeTest {
// Ensures all BlockType constants have the correct generics
@Test
public void testBlockDataClasses() throws Exception {
for (Field f : BlockType.class.getDeclaredFields()) {
BlockType type = (BlockType) f.get(null);
Class<?> expected = type.getBlockDataClass();
Class<?> actual = type.typed().createBlockData().getClass().getInterfaces()[0];
assertThat(actual, is(expected));
}
}
}

View File

@ -22,6 +22,7 @@ import org.bukkit.FireworkEffect.Type;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.MusicInstrument; import org.bukkit.MusicInstrument;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier; import org.bukkit.attribute.AttributeModifier;
import org.bukkit.block.banner.Pattern; import org.bukkit.block.banner.Pattern;
@ -35,6 +36,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Axolotl; import org.bukkit.entity.Axolotl;
import org.bukkit.entity.TropicalFish; import org.bukkit.entity.TropicalFish;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ItemType;
import org.bukkit.inventory.meta.ArmorMeta; import org.bukkit.inventory.meta.ArmorMeta;
import org.bukkit.inventory.meta.AxolotlBucketMeta; import org.bukkit.inventory.meta.AxolotlBucketMeta;
import org.bukkit.inventory.meta.BannerMeta; import org.bukkit.inventory.meta.BannerMeta;
@ -452,6 +454,29 @@ public class ItemMetaTest extends AbstractTestingBase {
assertThat(itemMeta.getBlockData(Material.CHEST), is(CraftBlockData.newData(null, "minecraft:chest[waterlogged=true]"))); assertThat(itemMeta.getBlockData(Material.CHEST), is(CraftBlockData.newData(null, "minecraft:chest[waterlogged=true]")));
} }
@Test
public void testMetaClasses() {
Registry.ITEM.forEach(itemType -> {
if (itemType == ItemType.AIR) {
return;
}
ItemMeta meta = new ItemStack(itemType.asMaterial()).getItemMeta();
Class<?> internal = meta == null ? CraftMetaItem.class : meta.getClass();
Class<?>[] interfaces = internal.getInterfaces();
Class<?> expected;
if (interfaces.length > 0) {
expected = interfaces[0];
} else {
expected = ItemMeta.class;
}
// Currently the expected and actual for AIR are ItemMeta rather than null
Class<?> actual = itemType.getItemMetaClass();
assertThat(actual, is(expected));
});
}
private void downCastTest(final StackWrapper provider) { private void downCastTest(final StackWrapper provider) {
final String name = provider.toString(); final String name = provider.toString();
final ItemStack blank = new ItemStack(Material.STONE); final ItemStack blank = new ItemStack(Material.STONE);

View File

@ -0,0 +1,76 @@
package org.bukkit.craftbukkit.inventory;
import static org.bukkit.support.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.lang.reflect.Field;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ItemType;
import org.bukkit.inventory.meta.ArmorMeta;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.trim.ArmorTrim;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern;
import org.bukkit.support.AbstractTestingBase;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class ItemTypeTest extends AbstractTestingBase {
// Ensures all ItemType constants have the correct generics
@Test
public void testItemMetaClasses() throws Exception {
for (Field f : ItemType.class.getDeclaredFields()) {
ItemType type = (ItemType) f.get(null);
if (type == ItemType.AIR) {
continue;
}
ItemMeta meta = new ItemStack(type.asMaterial()).getItemMeta();
Class<?> internal = meta == null ? CraftMetaItem.class : meta.getClass();
Class<?>[] interfaces = internal.getInterfaces();
Class<?> expected;
if (interfaces.length > 0) {
expected = interfaces[0];
} else {
expected = ItemMeta.class;
}
Class<?> actual = type.getItemMetaClass();
assertThat(actual, is(expected));
}
assertThrows(UnsupportedOperationException.class, () -> ItemType.AIR.getItemMetaClass());
}
@Test
public void testStaticItemTypeUsage() {
final ItemStack itemStack = ItemType.DIAMOND.createItemStack();
Assertions.assertEquals(itemStack.getType(), Material.DIAMOND);
Assertions.assertEquals(itemStack.getType().asItemType(), ItemType.DIAMOND);
}
@Test
public void testStaticItemTypeUsageBuilder() {
final ItemStack armor = ItemType.DIAMOND_LEGGINGS.createItemStack(a ->
a.setTrim(new ArmorTrim(TrimMaterial.EMERALD, TrimPattern.COAST))
);
final ItemMeta itemMeta = armor.getItemMeta();
Assertions.assertInstanceOf(ArmorMeta.class, itemMeta);
final ArmorTrim trim = ((ArmorMeta) itemMeta).getTrim();
Assertions.assertEquals(trim.getMaterial(), TrimMaterial.EMERALD);
Assertions.assertEquals(trim.getPattern(), TrimPattern.COAST);
}
@Test
public void testRetyping() {
final ItemType itemType = ItemType.ENCHANTED_BOOK;
Assertions.assertDoesNotThrow(() -> itemType.typed());
Assertions.assertDoesNotThrow(() -> itemType.typed(EnchantmentStorageMeta.class));
Assertions.assertThrows(IllegalArgumentException.class, () -> itemType.typed(ArmorMeta.class));
}
}

View File

@ -31,6 +31,9 @@ public class RegistryConversionTest extends AbstractTestingBase {
private static final String MINECRAFT_TO_BUKKIT = "minecraftToBukkit"; private static final String MINECRAFT_TO_BUKKIT = "minecraftToBukkit";
private static final String BUKKIT_TO_MINECRAFT = "bukkitToMinecraft"; private static final String BUKKIT_TO_MINECRAFT = "bukkitToMinecraft";
private static final String MINECRAFT_TO_BUKKIT_NEW = "minecraftToBukkitNew";
private static final String BUKKIT_TO_MINECRAFT_NEW = "bukkitToMinecraftNew";
private static final Map<Class<? extends Keyed>, Method> MINECRAFT_TO_BUKKIT_METHODS = new HashMap<>(); private static final Map<Class<? extends Keyed>, Method> MINECRAFT_TO_BUKKIT_METHODS = new HashMap<>();
private static final Map<Class<? extends Keyed>, Method> BUKKIT_TO_MINECRAFT_METHODS = new HashMap<>(); private static final Map<Class<? extends Keyed>, Method> BUKKIT_TO_MINECRAFT_METHODS = new HashMap<>();
@ -61,17 +64,18 @@ public class RegistryConversionTest extends AbstractTestingBase {
@Order(2) @Order(2)
@RegistriesTest @RegistriesTest
public void testMinecraftToBukkitPresent(Class<? extends Keyed> clazz, ResourceKey<IRegistry<?>> registryKey, public void testMinecraftToBukkitPresent(Class<? extends Keyed> clazz, ResourceKey<IRegistry<?>> registryKey,
Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) { Class<? extends Keyed> craftClazz, Class<?> minecraftClazz, boolean newMethod) {
String methodName = (newMethod) ? MINECRAFT_TO_BUKKIT_NEW : MINECRAFT_TO_BUKKIT;
Method method = null; Method method = null;
try { try {
method = craftClazz.getDeclaredMethod(MINECRAFT_TO_BUKKIT, minecraftClazz); method = craftClazz.getDeclaredMethod(methodName, minecraftClazz);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
fail(String.format(""" fail(String.format("""
The class %s does not have a public static method to convert a minecraft value to a bukkit value. The class %s does not have a public static method to convert a minecraft value to a bukkit value.
Following method should be add which, returns the bukkit value based on the minecraft value. Following method should be add which, returns the bukkit value based on the minecraft value.
%s %s
""", craftClazz, buildMinecraftToBukkitMethod(clazz, minecraftClazz))); """, craftClazz, buildMinecraftToBukkitMethod(clazz, methodName, minecraftClazz)));
} }
assertTrue(Modifier.isPublic(method.getModifiers()), String.format(""" assertTrue(Modifier.isPublic(method.getModifiers()), String.format("""
@ -79,47 +83,48 @@ public class RegistryConversionTest extends AbstractTestingBase {
The method should be made public, method structure: The method should be made public, method structure:
%s %s
""", MINECRAFT_TO_BUKKIT, craftClazz, buildMinecraftToBukkitMethod(clazz, minecraftClazz))); """, methodName, craftClazz, buildMinecraftToBukkitMethod(clazz, methodName, minecraftClazz)));
assertTrue(Modifier.isStatic(method.getModifiers()), String.format(""" assertTrue(Modifier.isStatic(method.getModifiers()), String.format("""
The method %s in class %s is not static. The method %s in class %s is not static.
The method should be made static, method structure: The method should be made static, method structure:
%s %s
""", MINECRAFT_TO_BUKKIT, craftClazz, buildMinecraftToBukkitMethod(clazz, minecraftClazz))); """, methodName, craftClazz, buildMinecraftToBukkitMethod(clazz, methodName, minecraftClazz)));
assertSame(clazz, method.getReturnType(), String.format(""" assertSame(clazz, method.getReturnType(), String.format("""
The method %s in class %s has the wrong return value. The method %s in class %s has the wrong return value.
The method should have the correct return value, method structure: The method should have the correct return value, method structure:
%s %s
""", MINECRAFT_TO_BUKKIT, craftClazz, buildMinecraftToBukkitMethod(clazz, minecraftClazz))); """, methodName, craftClazz, buildMinecraftToBukkitMethod(clazz, methodName, minecraftClazz)));
MINECRAFT_TO_BUKKIT_METHODS.put(clazz, method); MINECRAFT_TO_BUKKIT_METHODS.put(clazz, method);
} }
private String buildMinecraftToBukkitMethod(Class<? extends Keyed> clazz, Class<?> minecraftClazz) { private String buildMinecraftToBukkitMethod(Class<? extends Keyed> clazz, String methodName, Class<?> minecraftClazz) {
return String.format(""" return String.format("""
public static %s minecraftToBukkit(%s minecraft) { public static %s %s(%s minecraft) {
[...] [...]
} }
""", clazz.getSimpleName(), minecraftClazz.getName()); """, clazz.getSimpleName(), methodName, minecraftClazz.getName());
} }
@Order(2) @Order(2)
@RegistriesTest @RegistriesTest
public void testBukkitToMinecraftPresent(Class<? extends Keyed> clazz, ResourceKey<IRegistry<?>> registryKey, public void testBukkitToMinecraftPresent(Class<? extends Keyed> clazz, ResourceKey<IRegistry<?>> registryKey,
Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) { Class<? extends Keyed> craftClazz, Class<?> minecraftClazz, boolean newMethod) {
String methodName = (newMethod) ? BUKKIT_TO_MINECRAFT_NEW : BUKKIT_TO_MINECRAFT;
Method method = null; Method method = null;
try { try {
method = craftClazz.getDeclaredMethod(BUKKIT_TO_MINECRAFT, clazz); method = craftClazz.getDeclaredMethod(methodName, clazz);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
fail(String.format(""" fail(String.format("""
The class %s does not have a public static method to convert a bukkit value to a minecraft value. The class %s does not have a public static method to convert a bukkit value to a minecraft value.
Following method should be add which, returns the minecraft value based on the bukkit value. Following method should be add which, returns the minecraft value based on the bukkit value.
%s %s
""", craftClazz, buildBukkitToMinecraftMethod(clazz, minecraftClazz))); """, craftClazz, buildBukkitToMinecraftMethod(clazz, methodName, minecraftClazz)));
} }
assertTrue(Modifier.isPublic(method.getModifiers()), String.format(""" assertTrue(Modifier.isPublic(method.getModifiers()), String.format("""
@ -127,31 +132,31 @@ public class RegistryConversionTest extends AbstractTestingBase {
The method should be made public, method structure: The method should be made public, method structure:
%s %s
""", BUKKIT_TO_MINECRAFT, craftClazz, buildBukkitToMinecraftMethod(clazz, minecraftClazz))); """, methodName, craftClazz, buildBukkitToMinecraftMethod(clazz, methodName, minecraftClazz)));
assertTrue(Modifier.isStatic(method.getModifiers()), String.format(""" assertTrue(Modifier.isStatic(method.getModifiers()), String.format("""
The method %s in class %s is not static. The method %s in class %s is not static.
The method should be made static, method structure: The method should be made static, method structure:
%s %s
""", BUKKIT_TO_MINECRAFT, craftClazz, buildBukkitToMinecraftMethod(clazz, minecraftClazz))); """, methodName, craftClazz, buildBukkitToMinecraftMethod(clazz, methodName, minecraftClazz)));
assertSame(minecraftClazz, method.getReturnType(), String.format(""" assertSame(minecraftClazz, method.getReturnType(), String.format("""
The method %s in class %s has the wrong return value. The method %s in class %s has the wrong return value.
The method should have the correct return value, method structure: The method should have the correct return value, method structure:
%s %s
""", BUKKIT_TO_MINECRAFT, craftClazz, buildBukkitToMinecraftMethod(clazz, minecraftClazz))); """, methodName, craftClazz, buildBukkitToMinecraftMethod(clazz, methodName, minecraftClazz)));
BUKKIT_TO_MINECRAFT_METHODS.put(clazz, method); BUKKIT_TO_MINECRAFT_METHODS.put(clazz, method);
} }
private String buildBukkitToMinecraftMethod(Class<? extends Keyed> clazz, Class<?> minecraftClazz) { private String buildBukkitToMinecraftMethod(Class<? extends Keyed> clazz, String methodName, Class<?> minecraftClazz) {
return String.format(""" return String.format("""
public static %s bukkitToMinecraft(%s bukkit) { public static %s %s(%s bukkit) {
[...] [...]
} }
""", minecraftClazz.getName(), clazz.getSimpleName()); """, minecraftClazz.getName(), methodName, clazz.getSimpleName());
} }
@Order(2) @Order(2)

View File

@ -40,7 +40,7 @@ public final class DummyServer {
when(instance.getUnsafe()).then(mock -> CraftMagicNumbers.INSTANCE); when(instance.getUnsafe()).then(mock -> CraftMagicNumbers.INSTANCE);
when(instance.createBlockData(any(Material.class))).then(mock -> CraftBlockData.newData(mock.getArgument(0), null)); when(instance.createBlockData(any(Material.class))).then(mock -> CraftBlockData.newData(((Material) mock.getArgument(0)).asBlockType(), null));
when(instance.getLootTable(any())).then(mock -> new CraftLootTable(mock.getArgument(0), when(instance.getLootTable(any())).then(mock -> new CraftLootTable(mock.getArgument(0),
AbstractTestingBase.DATA_PACK.fullRegistries().getLootTable(ResourceKey.create(Registries.LOOT_TABLE, CraftNamespacedKey.toMinecraft(mock.getArgument(0)))))); AbstractTestingBase.DATA_PACK.fullRegistries().getLootTable(ResourceKey.create(Registries.LOOT_TABLE, CraftNamespacedKey.toMinecraft(mock.getArgument(0))))));

View File

@ -4,18 +4,22 @@ import com.google.common.collect.Lists;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.effect.MobEffectList; import net.minecraft.world.effect.MobEffectList;
import net.minecraft.world.entity.animal.WolfVariant; import net.minecraft.world.entity.animal.WolfVariant;
import net.minecraft.world.item.Instrument; import net.minecraft.world.item.Instrument;
import org.bukkit.GameEvent; import org.bukkit.GameEvent;
import org.bukkit.MusicInstrument; import org.bukkit.MusicInstrument;
import org.bukkit.block.BlockType;
import org.bukkit.craftbukkit.CraftGameEvent; import org.bukkit.craftbukkit.CraftGameEvent;
import org.bukkit.craftbukkit.CraftMusicInstrument; import org.bukkit.craftbukkit.CraftMusicInstrument;
import org.bukkit.craftbukkit.block.CraftBlockType;
import org.bukkit.craftbukkit.damage.CraftDamageType; import org.bukkit.craftbukkit.damage.CraftDamageType;
import org.bukkit.craftbukkit.enchantments.CraftEnchantment; import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
import org.bukkit.craftbukkit.entity.CraftWolf; import org.bukkit.craftbukkit.entity.CraftWolf;
import org.bukkit.craftbukkit.generator.structure.CraftStructure; import org.bukkit.craftbukkit.generator.structure.CraftStructure;
import org.bukkit.craftbukkit.generator.structure.CraftStructureType; import org.bukkit.craftbukkit.generator.structure.CraftStructureType;
import org.bukkit.craftbukkit.inventory.CraftItemType;
import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial; import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern; import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern;
import org.bukkit.craftbukkit.potion.CraftPotionEffectType; import org.bukkit.craftbukkit.potion.CraftPotionEffectType;
@ -24,6 +28,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Wolf; import org.bukkit.entity.Wolf;
import org.bukkit.generator.structure.Structure; import org.bukkit.generator.structure.Structure;
import org.bukkit.generator.structure.StructureType; import org.bukkit.generator.structure.StructureType;
import org.bukkit.inventory.ItemType;
import org.bukkit.inventory.meta.trim.TrimMaterial; import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.inventory.meta.trim.TrimPattern;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
@ -37,16 +42,27 @@ public class RegistriesArgumentProvider implements ArgumentsProvider {
static { static {
// Order: Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class // Order: Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class
DATA.add(Arguments.of(Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class)); register(Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class);
DATA.add(Arguments.of(GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class)); register(GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class);
DATA.add(Arguments.of(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class)); register(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class);
DATA.add(Arguments.of(PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffectList.class)); register(PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffectList.class);
DATA.add(Arguments.of(Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class)); register(Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class);
DATA.add(Arguments.of(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class)); register(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class);
DATA.add(Arguments.of(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class)); register(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class);
DATA.add(Arguments.of(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class)); register(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class);
DATA.add(Arguments.of(DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class)); register(DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class);
DATA.add(Arguments.of(Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class)); register(Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class);
register(ItemType.class, Registries.ITEM, CraftItemType.class, net.minecraft.world.item.Item.class, true);
register(BlockType.class, Registries.BLOCK, CraftBlockType.class, net.minecraft.world.level.block.Block.class, true);
}
private static void register(Class bukkit, ResourceKey registry, Class craft, Class minecraft) {
register(bukkit, registry, craft, minecraft, false);
}
private static void register(Class bukkit, ResourceKey registry, Class craft, Class minecraft, boolean newClass) {
DATA.add(Arguments.of(bukkit, registry, craft, minecraft, newClass));
} }
@Override @Override