split direct holder support up from ctor accepting Holder

Enchantment shouldn't support direct holders despite the ctor
accepting a Holder type. We want to limit the types
to ones that are actually used as direct holders in the game
This commit is contained in:
Jake Potrebic
2025-01-13 20:12:13 -08:00
parent 6fde26d7f8
commit fe75eaf09a
12 changed files with 70 additions and 58 deletions

View File

@@ -32,7 +32,7 @@ public class CraftMusicInstrument extends MusicInstrument implements io.papermc.
public static Object bukkitToString(MusicInstrument bukkit) { // Paper - switch to Holder
Preconditions.checkArgument(bukkit != null);
return ((CraftMusicInstrument) bukkit).toBukkitSerializationObject(Instrument.CODEC); // Paper - switch to Holder
return ((CraftMusicInstrument) bukkit).toBukkitSerializationObject(Instrument.DIRECT_CODEC); // Paper - switch to Holder
}
public static MusicInstrument stringToBukkit(Object string) { // Paper - switch to Holder

View File

@@ -62,7 +62,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
final Registry<B> bukkitRegistry = RegistryAccess.registryAccess().getRegistry(PaperRegistries.registryFromNms(registryKey));
final java.util.Optional<ResourceKey<M>> resourceKey = registry.getResourceKey(minecraft);
if (resourceKey.isEmpty() && bukkitRegistry instanceof final CraftRegistry<?, ?> craftRegistry && craftRegistry.supportsDirectHolders()) {
return ((CraftRegistry<B, M>) bukkitRegistry).convertDirectHolder(Holder.direct(minecraft));
return ((CraftRegistry<B, M>) bukkitRegistry).createBukkit(Holder.direct(minecraft));
} else if (resourceKey.isEmpty()) {
throw new IllegalStateException(String.format("Cannot convert '%s' to bukkit representation, since it is not registered.", minecraft));
}
@@ -82,7 +82,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
if (!(bukkitRegistry instanceof final CraftRegistry<?, ?> craftRegistry) || !craftRegistry.supportsDirectHolders()) {
throw new IllegalArgumentException("Cannot convert direct holder to bukkit representation");
}
yield ((CraftRegistry<B, M>) bukkitRegistry).convertDirectHolder(direct);
yield ((CraftRegistry<B, M>) bukkitRegistry).createBukkit(direct);
}
case final Holder.Reference<M> reference -> bukkitRegistry.get(MCUtil.fromResourceKey(reference.key()));
default -> throw new IllegalArgumentException("Unknown holder: " + minecraft);
@@ -126,8 +126,8 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
// Paper start - fixup upstream being dum
public static <T extends Keyed, M> Optional<T> unwrapAndConvertHolder(final RegistryKey<T> registryKey, final Holder<M> value) {
final Registry<T> registry = RegistryAccess.registryAccess().getRegistry(registryKey);
if (registry instanceof CraftRegistry<?,?> craftRegistry && craftRegistry.supportsDirectHolders() && value.kind() == Holder.Kind.DIRECT) {
return Optional.of(((CraftRegistry<T, M>) registry).convertDirectHolder(value));
if (registry instanceof final CraftRegistry<?,?> craftRegistry && craftRegistry.supportsDirectHolders() && value.kind() == Holder.Kind.DIRECT) {
return Optional.of(((CraftRegistry<T, M>) registry).createBukkit(value));
}
return value.unwrapKey().map(key -> registry.get(CraftNamespacedKey.fromMinecraft(key.location())));
}
@@ -178,7 +178,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
this.minecraftRegistry = minecraftRegistry;
this.minecraftToBukkit = minecraftToBukkit;
this.serializationUpdater = serializationUpdater;
this.lockReferenceHolders = !this.minecraftToBukkit.supportsDirectHolders();
this.lockReferenceHolders = !this.minecraftToBukkit.constructorUsesHolder();
}
public void lockReferenceHolders() {
@@ -189,7 +189,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
} catch (final ClassNotFoundException e) {
throw new IllegalStateException("Failed to load class " + this.bukkitClass.getSimpleName(), e);
}
if (!this.minecraftToBukkit.supportsDirectHolders()) {
if (!this.minecraftToBukkit.constructorUsesHolder()) {
return;
}
Preconditions.checkState(!this.lockReferenceHolders, "Reference holders are already locked");
@@ -209,7 +209,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
final Holder.Reference<M> holder;
if (holderOptional.isPresent()) {
holder = holderOptional.get();
} else if (!this.lockReferenceHolders && this.minecraftToBukkit.supportsDirectHolders()) { // only works if its Holderable
} else if (!this.lockReferenceHolders && this.minecraftToBukkit.constructorUsesHolder()) { // only works if its Holderable
// we lock the reference holders after the preload class has been initialized
// this is to support the vanilla mechanic of preventing vanilla registry entries being loaded. We need
// to create something to fill the API constant fields, so we create a dummy reference holder.
@@ -217,7 +217,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
} else {
holder = null;
}
final B bukkit = this.createBukkit(namespacedKey, holder);
final B bukkit = this.createBukkit(holder);
if (bukkit == null) {
return null;
}
@@ -227,16 +227,6 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return bukkit;
}
@NotNull
@Override
public B getOrThrow(@NotNull NamespacedKey namespacedKey) {
B object = this.get(namespacedKey);
Preconditions.checkArgument(object != null, "No %s registry entry found for key %s.", this.minecraftRegistry.key(), namespacedKey);
return object;
}
@NotNull
@Override
public Stream<B> stream() {
@@ -248,24 +238,18 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return this.stream().iterator();
}
public B createBukkit(NamespacedKey namespacedKey, Holder<M> minecraft) { // Paper - switch to Holder
public B createBukkit(Holder<M> minecraft) {
if (minecraft == null) {
return null;
}
return this.minecraftToBukkit.createBukkit(namespacedKey, minecraft); // Paper - switch to Holder
return this.minecraftToBukkit.createBukkit(minecraft);
}
// Paper start - support Direct Holders
public boolean supportsDirectHolders() {
return this.minecraftToBukkit.supportsDirectHolders();
}
public B convertDirectHolder(Holder<M> holder) {
return this.minecraftToBukkit.convertDirectHolder(holder);
}
// Paper end - support Direct Holders
// Paper start - improve Registry
@Override
public NamespacedKey getKey(final B value) {

View File

@@ -36,7 +36,7 @@ public class CraftTrimMaterial implements TrimMaterial, io.papermc.paper.util.Ho
public static Object bukkitToObject(TrimMaterial bukkit) {
Preconditions.checkArgument(bukkit != null);
return ((CraftTrimMaterial) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimMaterial.CODEC); // Paper - switch to Holder
return ((CraftTrimMaterial) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimMaterial.DIRECT_CODEC); // Paper - switch to Holder
}
public static TrimMaterial objectToBukkit(Object object) {

View File

@@ -36,7 +36,7 @@ public class CraftTrimPattern implements TrimPattern, io.papermc.paper.util.Hold
public static Object bukkitToObject(TrimPattern bukkit) {
Preconditions.checkArgument(bukkit != null);
return ((CraftTrimPattern) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimPattern.CODEC); // Paper - switch to Holder
return ((CraftTrimPattern) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimPattern.DIRECT_CODEC); // Paper - switch to Holder
}
public static TrimPattern objectToBukkit(Object object) {