#1393: Improve field rename handling and centralize conversion between bukkit and string more

By: DerFrZocker <derrieple@gmail.com>
This commit is contained in:
CraftBukkit/Spigot 2024-05-04 08:19:07 +10:00
parent f91094ddfd
commit acdb83379e
17 changed files with 313 additions and 90 deletions

View file

@ -1,6 +1,6 @@
--- a/net/minecraft/world/inventory/ContainerEnchantTable.java
+++ b/net/minecraft/world/inventory/ContainerEnchantTable.java
@@ -25,6 +25,21 @@
@@ -25,6 +25,22 @@
import net.minecraft.world.level.block.BlockEnchantmentTable;
import net.minecraft.world.level.block.Blocks;
@ -9,6 +9,7 @@
+import net.minecraft.world.item.enchantment.Enchantment;
+import org.bukkit.Location;
+import org.bukkit.NamespacedKey;
+import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
+import org.bukkit.craftbukkit.inventory.CraftInventoryEnchanting;
+import org.bukkit.craftbukkit.inventory.CraftInventoryView;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
@ -22,7 +23,7 @@
public class ContainerEnchantTable extends Container {
static final MinecraftKey EMPTY_SLOT_LAPIS_LAZULI = new MinecraftKey("item/empty_slot_lapis_lazuli");
@@ -35,6 +50,10 @@
@@ -35,6 +51,10 @@
public final int[] costs;
public final int[] enchantClue;
public final int[] levelClue;
@ -33,7 +34,7 @@
public ContainerEnchantTable(int i, PlayerInventory playerinventory) {
this(i, playerinventory, ContainerAccess.NULL);
@@ -48,6 +67,13 @@
@@ -48,6 +68,13 @@
super.setChanged();
ContainerEnchantTable.this.slotsChanged(this);
}
@ -47,7 +48,7 @@
};
this.random = RandomSource.create();
this.enchantmentSeed = ContainerProperty.standalone();
@@ -55,13 +81,13 @@
@@ -55,13 +82,13 @@
this.enchantClue = new int[]{-1, -1, -1};
this.levelClue = new int[]{-1, -1, -1};
this.access = containeraccess;
@ -63,7 +64,7 @@
@Override
public boolean mayPlace(ItemStack itemstack) {
return itemstack.is(Items.LAPIS_LAZULI);
@@ -95,6 +121,9 @@
@@ -95,6 +122,9 @@
this.addDataSlot(ContainerProperty.shared(this.levelClue, 0));
this.addDataSlot(ContainerProperty.shared(this.levelClue, 1));
this.addDataSlot(ContainerProperty.shared(this.levelClue, 2));
@ -73,7 +74,7 @@
}
@Override
@@ -102,7 +131,7 @@
@@ -102,7 +132,7 @@
if (iinventory == this.enchantSlots) {
ItemStack itemstack = iinventory.getItem(0);
@ -82,7 +83,7 @@
this.access.execute((world, blockposition) -> {
int i = 0;
Iterator iterator = BlockEnchantmentTable.BOOKSHELF_OFFSETS.iterator();
@@ -141,6 +170,41 @@
@@ -141,6 +171,41 @@
}
}
@ -90,7 +91,7 @@
+ CraftItemStack item = CraftItemStack.asCraftMirror(itemstack);
+ org.bukkit.enchantments.EnchantmentOffer[] offers = new EnchantmentOffer[3];
+ for (j = 0; j < 3; ++j) {
+ org.bukkit.enchantments.Enchantment enchantment = (this.enchantClue[j] >= 0) ? org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.ENCHANTMENT.getKey(BuiltInRegistries.ENCHANTMENT.byId(this.enchantClue[j])))) : null;
+ org.bukkit.enchantments.Enchantment enchantment = (this.enchantClue[j] >= 0) ? CraftEnchantment.minecraftToBukkit(Enchantment.byId(this.enchantClue[j])) : null;
+ offers[j] = (enchantment != null) ? new EnchantmentOffer(enchantment, this.levelClue[j], this.costs[j]) : null;
+ }
+
@ -111,7 +112,7 @@
+ EnchantmentOffer offer = event.getOffers()[j];
+ if (offer != null) {
+ this.costs[j] = offer.getCost();
+ this.enchantClue[j] = BuiltInRegistries.ENCHANTMENT.getId(BuiltInRegistries.ENCHANTMENT.get(CraftNamespacedKey.toMinecraft(offer.getEnchantment().getKey())));
+ this.enchantClue[j] = BuiltInRegistries.ENCHANTMENT.getId(CraftEnchantment.bukkitToMinecraft(offer.getEnchantment()));
+ this.levelClue[j] = offer.getEnchantmentLevel();
+ } else {
+ this.costs[j] = 0;
@ -124,7 +125,7 @@
this.broadcastChanges();
});
} else {
@@ -168,21 +232,46 @@
@@ -168,21 +233,46 @@
ItemStack itemstack2 = itemstack;
List<WeightedRandomEnchant> list = this.getEnchantmentList(world.enabledFeatures(), itemstack, i, this.costs[i]);
@ -135,11 +136,11 @@
+ // entityhuman.onEnchantmentPerformed(itemstack, j); // Moved down
+ Map<org.bukkit.enchantments.Enchantment, Integer> enchants = new java.util.HashMap<org.bukkit.enchantments.Enchantment, Integer>();
+ for (WeightedRandomEnchant instance : list) {
+ enchants.put(org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.ENCHANTMENT.getKey(instance.enchantment))), instance.level);
+ enchants.put(CraftEnchantment.minecraftToBukkit(instance.enchantment), instance.level);
+ }
+ CraftItemStack item = CraftItemStack.asCraftMirror(itemstack2);
+
+ org.bukkit.enchantments.Enchantment hintedEnchantment = org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.ENCHANTMENT.getKey(Enchantment.byId(enchantClue[i]))));
+ org.bukkit.enchantments.Enchantment hintedEnchantment = CraftEnchantment.minecraftToBukkit(Enchantment.byId(enchantClue[i]));
+ int hintedEnchantmentLevel = levelClue[i];
+ EnchantItemEvent event = new EnchantItemEvent((Player) entityhuman.getBukkitEntity(), this.getBukkitView(), access.getLocation().getBlock(), item, this.costs[i], enchants, hintedEnchantment, hintedEnchantmentLevel, i);
+ world.getCraftServer().getPluginManager().callEvent(event);
@ -177,7 +178,7 @@
if (!entityhuman.hasInfiniteMaterials()) {
itemstack1.shrink(j);
if (itemstack1.isEmpty()) {
@@ -245,6 +334,7 @@
@@ -245,6 +335,7 @@
@Override
public boolean stillValid(EntityHuman entityhuman) {
@ -185,7 +186,7 @@
return stillValid(this.access, entityhuman, Blocks.ENCHANTING_TABLE);
}
@@ -295,4 +385,17 @@
@@ -295,4 +386,17 @@
return itemstack;
}

View file

@ -38,6 +38,18 @@ public class CraftMusicInstrument extends MusicInstrument implements Handleable<
+ ", this can happen if a plugin creates its own instrument without properly registering it.");
}
public static String bukkitToString(MusicInstrument bukkit) {
Preconditions.checkArgument(bukkit != null);
return bukkit.getKey().toString();
}
public static MusicInstrument stringToBukkit(String string) {
Preconditions.checkArgument(string != null);
return Registry.INSTRUMENT.get(NamespacedKey.fromString(string));
}
private final NamespacedKey key;
private final Instrument handle;

View file

@ -31,6 +31,7 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.util.CraftLocation;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
@ -207,7 +208,7 @@ public abstract class CraftParticle<D> implements Keyed {
}
public CraftParticleRegistry(IRegistry<net.minecraft.core.particles.Particle<?>> minecraftRegistry) {
super(CraftParticle.class, minecraftRegistry, null);
super(CraftParticle.class, minecraftRegistry, null, FieldRename.PARTICLE_TYPE_RENAME);
}
@Override

View file

@ -16,7 +16,10 @@ import org.bukkit.GameEvent;
import org.bukkit.Keyed;
import org.bukkit.MusicInstrument;
import org.bukkit.NamespacedKey;
import org.bukkit.Particle;
import org.bukkit.Registry;
import org.bukkit.attribute.Attribute;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.damage.CraftDamageType;
import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
import org.bukkit.craftbukkit.entity.CraftWolf;
@ -24,11 +27,14 @@ import org.bukkit.craftbukkit.generator.structure.CraftStructure;
import org.bukkit.craftbukkit.generator.structure.CraftStructureType;
import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.potion.CraftPotionEffectType;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.damage.DamageType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Wolf;
import org.bukkit.generator.structure.Structure;
import org.bukkit.generator.structure.StructureType;
@ -39,6 +45,7 @@ import org.jetbrains.annotations.NotNull;
public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
private static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> NONE = (namespacedKey, apiVersion) -> namespacedKey;
private static IRegistryCustom registry;
public static void setMinecraftRegistry(IRegistryCustom registry) {
@ -110,49 +117,83 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
*/
public static <B extends Keyed> Registry<?> createRegistry(Class<B> bukkitClass, IRegistryCustom registryHolder) {
if (bukkitClass == Enchantment.class) {
return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new);
return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME);
}
if (bukkitClass == GameEvent.class) {
return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new);
return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new, NONE);
}
if (bukkitClass == MusicInstrument.class) {
return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new);
return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new, NONE);
}
if (bukkitClass == PotionEffectType.class) {
return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new);
return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, NONE);
}
if (bukkitClass == Structure.class) {
return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new);
return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new, NONE);
}
if (bukkitClass == StructureType.class) {
return new CraftRegistry<>(StructureType.class, BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new);
return new CraftRegistry<>(StructureType.class, BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new, NONE);
}
if (bukkitClass == TrimMaterial.class) {
return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new);
return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new, NONE);
}
if (bukkitClass == TrimPattern.class) {
return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new);
return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new, NONE);
}
if (bukkitClass == DamageType.class) {
return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new);
return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new, NONE);
}
if (bukkitClass == Wolf.Variant.class) {
return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new);
return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, NONE);
}
return null;
}
public static <B extends Keyed> B get(Registry<B> bukkit, NamespacedKey namespacedKey, ApiVersion apiVersion) {
if (bukkit instanceof CraftRegistry<B, ?> craft) {
return craft.get(namespacedKey, apiVersion);
}
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));
}
if (bClass == Particle.class) {
return bukkit.get(FieldRename.PARTICLE_TYPE_RENAME.apply(namespacedKey, apiVersion));
}
if (bClass == Attribute.class) {
return bukkit.get(FieldRename.ATTRIBUTE_RENAME.apply(namespacedKey, apiVersion));
}
}
return bukkit.get(namespacedKey);
}
private final Class<? super B> bukkitClass;
private final Map<NamespacedKey, B> cache = new HashMap<>();
private final IRegistry<M> minecraftRegistry;
private final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater;
private boolean init;
public CraftRegistry(Class<? super B> bukkitClass, IRegistry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit) {
public CraftRegistry(Class<? super B> bukkitClass, IRegistry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater) {
this.bukkitClass = bukkitClass;
this.minecraftRegistry = minecraftRegistry;
this.minecraftToBukkit = minecraftToBukkit;
this.updater = updater;
}
public B get(NamespacedKey namespacedKey, ApiVersion apiVersion) {
return get(updater.apply(namespacedKey, apiVersion));
}
@Override

View file

@ -1,6 +1,7 @@
package org.bukkit.craftbukkit.attribute;
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;
@ -9,6 +10,8 @@ import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.attribute.Attribute;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
public class CraftAttribute {
@ -28,10 +31,17 @@ public class CraftAttribute {
return minecraftToBukkit(minecraft.value());
}
public static Attribute stringToBukkit(String bukkit) {
Preconditions.checkArgument(bukkit != null);
public static Attribute stringToBukkit(String string) {
Preconditions.checkArgument(string != null);
return Registry.ATTRIBUTE.get(NamespacedKey.fromString(bukkit));
// We currently do not have any version-dependent remapping, so we can use current version
// First convert from when only the names where saved
string = FieldRename.convertAttributeName(ApiVersion.CURRENT, string);
string = string.toLowerCase(Locale.ROOT);
NamespacedKey key = NamespacedKey.fromString(string);
// Now also convert from when keys where saved
return CraftRegistry.get(Registry.ATTRIBUTE, key, ApiVersion.CURRENT);
}
public static AttributeBase bukkitToMinecraft(Attribute bukkit) {
@ -53,4 +63,10 @@ public class CraftAttribute {
throw new IllegalArgumentException("No Reference holder found for " + bukkit
+ ", this can happen if a plugin creates its own sound effect with out properly registering it.");
}
public static String bukkitToString(Attribute bukkit) {
Preconditions.checkArgument(bukkit != null);
return bukkit.getKey().toString();
}
}

View file

@ -143,13 +143,13 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<TileEntityMobSpa
}
Optional<EntityTypes<?>> type = EntityTypes.by(spawnData.getEntityToSpawn());
return type.map(entityTypes -> EntityTypes.getKey(entityTypes).getPath()).orElse(null);
return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
}
@Override
public void setCreatureTypeByName(String creatureType) {
// Verify input
EntityType type = EntityType.fromName(creatureType);
EntityType type = CraftEntityType.stringToBukkit(creatureType);
if (type == null) {
setSpawnedType(null);
return;

View file

@ -1,5 +1,7 @@
package org.bukkit.craftbukkit.enchantments;
import com.google.common.base.Preconditions;
import java.util.Locale;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
@ -9,6 +11,8 @@ import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
@ -29,6 +33,25 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
return CraftRegistry.bukkitToMinecraft(bukkit);
}
public static String bukkitToString(Enchantment bukkit) {
Preconditions.checkArgument(bukkit != null);
return bukkit.getKey().toString();
}
public static Enchantment stringToBukkit(String string) {
Preconditions.checkArgument(string != null);
// We currently do not have any version-dependent remapping, so we can use current version
// First convert from when only the names where saved
string = FieldRename.convertEnchantmentName(ApiVersion.CURRENT, string);
string = string.toLowerCase(Locale.ROOT);
NamespacedKey key = NamespacedKey.fromString(string);
// Now also convert from when keys where saved
return CraftRegistry.get(Registry.ENCHANTMENT, key, ApiVersion.CURRENT);
}
private final NamespacedKey key;
private final net.minecraft.world.item.enchantment.Enchantment handle;
private final int id;

View file

@ -1,11 +1,15 @@
package org.bukkit.craftbukkit.entity;
import com.google.common.base.Preconditions;
import java.util.Locale;
import net.minecraft.core.IRegistry;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.entity.EntityTypes;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.entity.EntityType;
@ -28,4 +32,23 @@ public class CraftEntityType {
return CraftRegistry.getMinecraftRegistry(Registries.ENTITY_TYPE)
.getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow();
}
public static String bukkitToString(EntityType bukkit) {
Preconditions.checkArgument(bukkit != null);
return bukkit.getKey().toString();
}
public static EntityType stringToBukkit(String string) {
Preconditions.checkArgument(string != null);
// We currently do not have any version-dependent remapping, so we can use current version
// First convert from when only the names where saved
string = FieldRename.convertEntityTypeName(ApiVersion.CURRENT, string);
string = string.toLowerCase(Locale.ROOT);
NamespacedKey key = NamespacedKey.fromString(string);
// Now also convert from when keys where saved
return CraftRegistry.get(Registry.ENTITY_TYPE, key, ApiVersion.CURRENT);
}
}

View file

@ -0,0 +1,23 @@
package org.bukkit.craftbukkit.inventory;
import com.google.common.base.Preconditions;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.inventory.ItemFlag;
public class CraftItemFlag {
public static String bukkitToString(ItemFlag bukkit) {
Preconditions.checkArgument(bukkit != null);
return bukkit.name();
}
public static ItemFlag stringToBukkit(String string) {
Preconditions.checkArgument(string != null);
// We currently do not have any version-dependent remapping, so we can use current version
string = FieldRename.convertItemFlagName(ApiVersion.CURRENT, string);
return ItemFlag.valueOf(string);
}
}

View file

@ -62,7 +62,6 @@ import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.item.component.Unbreakable;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.minecraft.world.level.block.state.IBlockData;
import org.apache.commons.lang3.EnumUtils;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
@ -493,7 +492,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
for (Object hideFlagObject : hideFlags) {
String hideFlagString = (String) hideFlagObject;
try {
ItemFlag hideFlatEnum = ItemFlag.valueOf(hideFlagString);
ItemFlag hideFlatEnum = CraftItemFlag.stringToBukkit(hideFlagString);
addItemFlags(hideFlatEnum);
} catch (IllegalArgumentException ex) {
// Ignore when we got a old String which does not map to a Enum value anymore
@ -656,13 +655,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
Map<Enchantment, Integer> enchantments = new LinkedHashMap<Enchantment, Integer>(ench.size());
for (Map.Entry<?, ?> entry : ench.entrySet()) {
// Doctor older enchants
String enchantKey = entry.getKey().toString();
if (enchantKey.equals("SWEEPING")) {
enchantKey = "SWEEPING_EDGE";
}
Enchantment enchantment = Enchantment.getByName(enchantKey);
Enchantment enchantment = CraftEnchantment.stringToBukkit(entry.getKey().toString());
if ((enchantment != null) && (entry.getValue() instanceof Integer)) {
enchantments.put(enchantment, (Integer) entry.getValue());
}
@ -696,7 +689,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
continue;
}
AttributeModifier modifier = (AttributeModifier) o;
Attribute attribute = EnumUtils.getEnum(Attribute.class, attributeName.toUpperCase(Locale.ROOT));
Attribute attribute = CraftAttribute.stringToBukkit(attributeName);
if (attribute == null) {
continue;
}
@ -1520,7 +1513,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
List<String> hideFlags = new ArrayList<String>();
for (ItemFlag hideFlagEnum : getItemFlags()) {
hideFlags.add(hideFlagEnum.name());
hideFlags.add(CraftItemFlag.bukkitToString(hideFlagEnum));
}
if (!hideFlags.isEmpty()) {
builder.put(HIDEFLAGS.BUKKIT, hideFlags);
@ -1620,7 +1613,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
ImmutableMap.Builder<String, Integer> enchants = ImmutableMap.builder();
for (Map.Entry<? extends Enchantment, Integer> enchant : enchantments.entrySet()) {
enchants.put(enchant.getKey().getName(), enchant.getValue());
enchants.put(CraftEnchantment.bukkitToString(enchant.getKey()), enchant.getValue());
}
builder.put(key.BUKKIT, enchants.build());
@ -1640,7 +1633,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
if (modCollection == null || modCollection.isEmpty()) {
continue;
}
mods.put(entry.getKey().name(), new ArrayList<>(modCollection));
mods.put(CraftAttribute.bukkitToString(entry.getKey()), new ArrayList<>(modCollection));
}
builder.put(key.BUKKIT, mods);
}

View file

@ -8,8 +8,6 @@ import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.Instrument;
import org.bukkit.Material;
import org.bukkit.MusicInstrument;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.configuration.serialization.DelegateDeserialization;
import org.bukkit.craftbukkit.CraftMusicInstrument;
import org.bukkit.inventory.meta.MusicInstrumentMeta;
@ -42,7 +40,7 @@ public class CraftMetaMusicInstrument extends CraftMetaItem implements MusicInst
String instrumentString = SerializableMeta.getString(map, GOAT_HORN_INSTRUMENT.BUKKIT, true);
if (instrumentString != null) {
this.instrument = Registry.INSTRUMENT.get(NamespacedKey.fromString(instrumentString));
this.instrument = CraftMusicInstrument.stringToBukkit(instrumentString);
}
}
@ -110,7 +108,7 @@ public class CraftMetaMusicInstrument extends CraftMetaItem implements MusicInst
super.serialize(builder);
if (hasInstrument()) {
builder.put(GOAT_HORN_INSTRUMENT.BUKKIT, instrument.getKey().toString());
builder.put(GOAT_HORN_INSTRUMENT.BUKKIT, CraftMusicInstrument.bukkitToString(instrument));
}
return builder;

View file

@ -9,11 +9,11 @@ import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.world.item.component.CustomData;
import org.bukkit.Material;
import org.bukkit.configuration.serialization.DelegateDeserialization;
import org.bukkit.craftbukkit.entity.CraftEntitySnapshot;
import org.bukkit.craftbukkit.entity.CraftEntityType;
import org.bukkit.craftbukkit.util.CraftLegacy;
import org.bukkit.entity.EntitySnapshot;
import org.bukkit.entity.EntityType;
@ -138,7 +138,7 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta {
String entityType = SerializableMeta.getString(map, ENTITY_ID.BUKKIT, true);
if (entityType != null) {
this.spawnedType = EntityType.fromName(entityType);
this.spawnedType = CraftEntityType.stringToBukkit(entityType);
}
}
@ -155,7 +155,7 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta {
// Duplicated from constructor
String entityType = SerializableMeta.getString(map, ENTITY_ID.BUKKIT, true);
if (entityType != null) {
this.spawnedType = EntityType.fromName(entityType);
this.spawnedType = CraftEntityType.stringToBukkit(entityType);
}
}
@ -172,7 +172,7 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta {
// See if we can read a converted ID tag
if (entityTag.contains(ENTITY_ID.NBT)) {
this.spawnedType = EntityType.fromName(new MinecraftKey(entityTag.getString(ENTITY_ID.NBT)).getPath());
this.spawnedType = CraftEntityType.stringToBukkit(entityTag.getString(ENTITY_ID.NBT));
}
}
}

View file

@ -1,9 +1,14 @@
package org.bukkit.craftbukkit.legacy;
import java.util.function.BiFunction;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Particle;
import org.bukkit.Registry;
import org.bukkit.attribute.Attribute;
import org.bukkit.block.Biome;
import org.bukkit.block.banner.PatternType;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.legacy.fieldrename.FieldRenameData;
import org.bukkit.craftbukkit.legacy.reroute.DoNotReroute;
import org.bukkit.craftbukkit.legacy.reroute.InjectPluginVersion;
@ -36,13 +41,23 @@ public class FieldRename {
case "org/bukkit/MusicInstrument" -> convertMusicInstrumentName(apiVersion, from);
case "org/bukkit/Particle" -> convertParticleName(apiVersion, from);
case "org/bukkit/loot/LootTables" -> convertLootTablesName(apiVersion, from);
case "org/bukkit/attribute/Attribute" -> convertAttributeName(apiVersion, from);
case "org/bukkit/attribute/Attribute" -> convertAttributeName(apiVersion, from).replace('.', '_');
case "org/bukkit/map/MapCursor$Type" -> convertMapCursorTypeName(apiVersion, from);
case "org/bukkit/inventory/ItemFlag" -> convertItemFlagName(apiVersion, from);
default -> from;
};
}
@RerouteStatic("java/lang/Enum")
public static <T extends Enum<T>> T valueOf(Class<T> enumClass, String name, @InjectPluginVersion ApiVersion apiVersion) {
return Enum.valueOf(enumClass, rename(apiVersion, enumClass.getName().replace('.', '/'), name));
}
public static <T extends Keyed> T get(Registry<T> registry, NamespacedKey namespacedKey) {
// We don't have version-specific changes, so just use current, and don't inject a version
return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
}
// PatternType
private static final FieldRenameData PATTERN_TYPE_DATA = FieldRenameData.Builder.newBuilder()
.forVersionsBefore(ApiVersion.FIELD_NAME_PARITY)
@ -82,17 +97,20 @@ public class FieldRename {
.change("DAMAGE_UNDEAD", "SMITE")
.change("DAMAGE_ARTHROPODS", "BANE_OF_ARTHROPODS")
.change("LOOT_BONUS_MOBS", "LOOTING")
.change("SWEEPING_EDGE", "SWEEPING")
.change("DIG_SPEED", "EFFICIENCY")
.change("DURABILITY", "UNBREAKING")
.change("LOOT_BONUS_BLOCKS", "FORTUNE")
.change("ARROW_DAMAGE", "POWER")
.change("ARROW_KNOCKBACK", "PUNCH")
.change("ARROW_FIRE", "FLAME")
.change("ARROW_INFINITY", "INFINITY")
.change("ARROW_INFINITE", "INFINITY")
.change("LUCK", "LUCK_OF_THE_SEA")
.withKeyRename()
.change("SWEEPING", "SWEEPING_EDGE")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> ENCHANTMENT_RENAME = ENCHANTMENT_DATA::getReplacement;
@DoNotReroute
public static String convertEnchantmentName(ApiVersion version, String from) {
return ENCHANTMENT_DATA.getReplacement(version, from);
@ -108,6 +126,7 @@ public class FieldRename {
// Biome
private static final FieldRenameData BIOME_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.withKeyRename()
.change("NETHER", "NETHER_WASTES")
.change("TALL_BIRCH_FOREST", "OLD_GROWTH_BIRCH_FOREST")
.change("GIANT_TREE_TAIGA", "OLD_GROWTH_PINE_TAIGA")
@ -122,6 +141,8 @@ public class FieldRename {
.change("WOODED_BADLANDS_PLATEAU", "WOODED_BADLANDS")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> BIOME_RENAME = BIOME_DATA::getReplacement;
@DoNotReroute
public static String convertBiomeName(ApiVersion version, String from) {
return BIOME_DATA.getReplacement(version, from);
@ -134,23 +155,9 @@ public class FieldRename {
return Biome.valueOf(convertBiomeName(ApiVersion.CURRENT, name));
}
// EntityType
private static final FieldRenameData ENTITY_TYPE_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.change("XP_ORB", "EXPERIENCE_ORB")
.change("EYE_OF_ENDER_SIGNAL", "EYE_OF_ENDER")
.change("XP_BOTTLE", "EXPERIENCE_BOTTLE")
.change("FIREWORKS_ROCKET", "FIREWORK_ROCKET")
.change("EVOCATION_FANGS", "EVOKER_FANGS")
.change("EVOCATION_ILLAGER", "EVOKER")
.change("VINDICATION_ILLAGER", "VINDICATOR")
.change("ILLUSION_ILLAGER", "ILLUSIONER")
.change("COMMANDBLOCK_MINECART", "COMMAND_BLOCK_MINECART")
.change("SNOWMAN", "SNOW_GOLEM")
.change("VILLAGER_GOLEM", "IRON_GOLEM")
.change("ENDER_CRYSTAL", "END_CRYSTAL")
.change("ZOMBIE_PIGMAN", "ZOMBIFIED_PIGLIN")
.change("PIG_ZOMBIE", "ZOMBIFIED_PIGLIN")
.change("DROPPED_ITEM", "ITEM")
.change("LEASH_HITCH", "LEASH_KNOT")
@ -167,11 +174,26 @@ public class FieldRename {
.change("MINECART_MOB_SPAWNER", "SPAWNER_MINECART")
.change("MUSHROOM_COW", "MOOSHROOM")
.change("SNOWMAN", "SNOW_GOLEM")
.change("ENDER_CRYSTAL", "END_CRYSTAL")
.change("FISHING_HOOK", "FISHING_BOBBER")
.change("LIGHTNING", "LIGHTNING_BOLT")
.withKeyRename()
.change("XP_ORB", "EXPERIENCE_ORB")
.change("EYE_OF_ENDER_SIGNAL", "EYE_OF_ENDER")
.change("XP_BOTTLE", "EXPERIENCE_BOTTLE")
.change("FIREWORKS_ROCKET", "FIREWORK_ROCKET")
.change("EVOCATION_FANGS", "EVOKER_FANGS")
.change("EVOCATION_ILLAGER", "EVOKER")
.change("VINDICATION_ILLAGER", "VINDICATOR")
.change("ILLUSION_ILLAGER", "ILLUSIONER")
.change("COMMANDBLOCK_MINECART", "COMMAND_BLOCK_MINECART")
.change("SNOWMAN", "SNOW_GOLEM")
.change("VILLAGER_GOLEM", "IRON_GOLEM")
.change("ENDER_CRYSTAL", "END_CRYSTAL")
.change("ZOMBIE_PIGMAN", "ZOMBIFIED_PIGLIN")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> ENTITY_TYPE_RENAME = ENTITY_TYPE_DATA::getReplacement;
@DoNotReroute
public static String convertEntityTypeName(ApiVersion version, String from) {
return ENTITY_TYPE_DATA.getReplacement(version, from);
@ -220,7 +242,6 @@ public class FieldRename {
// PotionType
private static final FieldRenameData POTION_TYPE_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.change("UNCRAFTABLE", "EMPTY")
.change("JUMP", "LEAPING")
.change("SPEED", "SWIFTNESS")
.change("INSTANT_HEAL", "HEALING")
@ -292,8 +313,12 @@ public class FieldRename {
.change("WATER_DROP", "RAIN")
.change("MOB_APPEARANCE", "ELDER_GUARDIAN")
.change("TOTEM", "TOTEM_OF_UNDYING")
.withKeyRename()
.change("GUST_EMITTER", "GUST_EMITTER_LARGE")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> PARTICLE_TYPE_RENAME = PARTICLE_DATA::getReplacement;
@DoNotReroute
public static String convertParticleName(ApiVersion version, String from) {
return PARTICLE_DATA.getReplacement(version, from);
@ -327,9 +352,12 @@ public class FieldRename {
// Attribute
private static final FieldRenameData ATTRIBUTE_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.change("HORSE_JUMP_STRENGTH", "GENERIC_JUMP_STRENGTH")
.withKeyRename()
.change("HORSE.JUMP_STRENGTH", "GENERIC.JUMP_STRENGTH")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> ATTRIBUTE_RENAME = ATTRIBUTE_DATA::getReplacement;
@DoNotReroute
public static String convertAttributeName(ApiVersion version, String from) {
return ATTRIBUTE_DATA.getReplacement(version, from);
@ -339,7 +367,7 @@ public class FieldRename {
@RerouteStatic("org/bukkit/attribute/Attribute")
public static Attribute valueOf_Attribute(String name) {
// We don't have version-specific changes, so just use current, and don't inject a version
return Attribute.valueOf(convertAttributeName(ApiVersion.CURRENT, name));
return Attribute.valueOf(convertAttributeName(ApiVersion.CURRENT, name).replace('.', '_'));
}
// MapCursor Type

View file

@ -5,9 +5,10 @@ import java.util.Locale;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.util.ApiVersion;
public record FieldRenameData(NavigableMap<ApiVersion, Map<String, String>> versionData, Map<String, String> data) {
public record FieldRenameData(RenameData<String> renameData, RenameData<NamespacedKey> keyRenameData) {
public String getReplacement(ApiVersion apiVersion, String from) {
if (from == null) {
@ -15,24 +16,25 @@ public record FieldRenameData(NavigableMap<ApiVersion, Map<String, String>> vers
}
from = from.toUpperCase(Locale.ROOT);
from = data.getOrDefault(from, from);
return renameData.getReplacement(apiVersion, from);
}
for (Map.Entry<ApiVersion, Map<String, String>> entry : versionData.entrySet()) {
if (apiVersion.isNewerThanOrSameAs(entry.getKey())) {
continue;
}
from = entry.getValue().getOrDefault(from, from);
public NamespacedKey getReplacement(NamespacedKey from, ApiVersion apiVersion) {
if (from == null) {
return null;
}
return from;
return keyRenameData.getReplacement(apiVersion, from);
}
public static class Builder {
private final Map<String, String> data = new HashMap<>();
private final NavigableMap<ApiVersion, Map<String, String>> versionData = new TreeMap<>();
private final Map<NamespacedKey, NamespacedKey> keyData = new HashMap<>();
private final NavigableMap<ApiVersion, Map<NamespacedKey, NamespacedKey>> versionKeyData = new TreeMap<>();
private ApiVersion currentVersion;
private boolean keyRename = false;
public static Builder newBuilder() {
return new Builder();
@ -40,25 +42,58 @@ public record FieldRenameData(NavigableMap<ApiVersion, Map<String, String>> vers
public Builder forVersionsBefore(ApiVersion apiVersion) {
this.currentVersion = apiVersion;
this.keyRename = false;
return this;
}
public Builder forAllVersions() {
this.currentVersion = null;
this.keyRename = false;
return this;
}
public Builder withKeyRename() {
this.keyRename = true;
return this;
}
public Builder change(String from, String to) {
if (currentVersion != null) {
versionData.computeIfAbsent(currentVersion, d -> new HashMap<>()).put(from, to);
versionData.computeIfAbsent(currentVersion, d -> new HashMap<>()).put(from.replace('.', '_'), to);
} else {
data.put(from, to);
data.put(from.replace('.', '_'), to);
}
if (keyRename) {
NamespacedKey fromKey = NamespacedKey.minecraft(from.toLowerCase(Locale.ROOT));
NamespacedKey toKey = NamespacedKey.minecraft(to.toLowerCase(Locale.ROOT));
if (currentVersion != null) {
versionKeyData.computeIfAbsent(currentVersion, d -> new HashMap<>()).put(fromKey, toKey);
} else {
keyData.put(fromKey, toKey);
}
}
return this;
}
public FieldRenameData build() {
return new FieldRenameData(versionData, data);
return new FieldRenameData(new RenameData<>(versionData, data), new RenameData<>(versionKeyData, keyData));
}
}
private record RenameData<T>(NavigableMap<ApiVersion, Map<T, T>> versionData, Map<T, T> data) {
public T getReplacement(ApiVersion apiVersion, T from) {
from = data.getOrDefault(from, from);
for (Map.Entry<ApiVersion, Map<T, T>> entry : versionData.entrySet()) {
if (apiVersion.isNewerThanOrSameAs(entry.getKey())) {
continue;
}
from = entry.getValue().getOrDefault(from, from);
}
return from;
}
}
}

View file

@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.potion;
import com.google.common.base.Preconditions;
import com.google.common.base.Suppliers;
import java.util.List;
import java.util.Locale;
import java.util.function.Supplier;
import net.minecraft.core.Holder;
import net.minecraft.core.IRegistry;
@ -11,6 +12,8 @@ import net.minecraft.world.item.alchemy.PotionRegistry;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@ -53,16 +56,23 @@ public class CraftPotionType implements PotionType.InternalPotionData {
+ ", this can happen if a plugin creates its own sound effect with out properly registering it.");
}
public static String bukkitToString(PotionType potionType) {
Preconditions.checkArgument(potionType != null);
public static String bukkitToString(PotionType bukkit) {
Preconditions.checkArgument(bukkit != null);
return potionType.getKey().toString();
return bukkit.getKey().toString();
}
public static PotionType stringToBukkit(String string) {
Preconditions.checkArgument(string != null);
return Registry.POTION.get(NamespacedKey.fromString(string));
// We currently do not have any version-dependent remapping, so we can use current version
// First convert from when only the names where saved
string = FieldRename.convertPotionTypeName(ApiVersion.CURRENT, string);
string = string.toLowerCase(Locale.ROOT);
NamespacedKey key = NamespacedKey.fromString(string);
// Now also convert from when keys where saved
return CraftRegistry.get(Registry.POTION, key, ApiVersion.CURRENT);
}
private final NamespacedKey key;

View file

@ -41,8 +41,10 @@ import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.storage.SavedFile;
import org.bukkit.Bukkit;
import org.bukkit.FeatureFlag;
import org.bukkit.Keyed;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.UnsafeValues;
import org.bukkit.advancement.Advancement;
import org.bukkit.attribute.Attribute;
@ -58,10 +60,12 @@ import org.bukkit.craftbukkit.damage.CraftDamageEffect;
import org.bukkit.craftbukkit.damage.CraftDamageSourceBuilder;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.legacy.CraftLegacy;
import org.bukkit.craftbukkit.legacy.FieldRename;
import org.bukkit.craftbukkit.potion.CraftPotionType;
import org.bukkit.damage.DamageEffect;
import org.bukkit.damage.DamageSource;
import org.bukkit.damage.DamageType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.CreativeCategory;
import org.bukkit.inventory.EquipmentSlot;
@ -399,6 +403,21 @@ public final class CraftMagicNumbers implements UnsafeValues {
return new CraftDamageSourceBuilder(damageType);
}
@Override
public String get(Class<?> aClass, String s) {
if (aClass == Enchantment.class) {
// We currently do not have any version-dependent remapping, so we can use current version
return FieldRename.convertEnchantmentName(ApiVersion.CURRENT, s);
}
return s;
}
@Override
public <B extends Keyed> B get(Registry<B> registry, NamespacedKey namespacedKey) {
// We currently do not have any version-dependent remapping, so we can use current version
return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
}
/**
* This helper class represents the different NBT Tags.
* <p>

View file

@ -58,7 +58,7 @@ public class RegistryLoadOrderTest extends AbstractTestingBase {
minecraftRegistry.register(ResourceKey.create(resourceKey, MinecraftKey.tryBuild("bukkit", "test-two")), new MinecraftTestType(), new RegistrationInfo(Optional.empty(), Lifecycle.experimental()));
minecraftRegistry.freeze();
registry = new CraftRegistry<>(keyedClass, minecraftRegistry, minecraftToBukkit);
registry = new CraftRegistry<>(keyedClass, minecraftRegistry, minecraftToBukkit, (namespacedKey, apiVersion) -> namespacedKey);
testClassNotLoaded(init.get());
Object testOne = registry.get(new NamespacedKey("bukkit", "test-one"));