13
0
geforkt von Mirrors/Paper

Switch Impl types to Holderable

Dieser Commit ist enthalten in:
Jake Potrebic 2024-11-24 15:08:19 -08:00
Ursprung d300c94ec2
Commit ca5499c7fa
8 geänderte Dateien mit 223 neuen und 93 gelöschten Zeilen

Datei anzeigen

@ -1,8 +1,21 @@
package io.papermc.paper.util;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import net.kyori.adventure.key.Key;
import net.minecraft.core.Holder;
import net.minecraft.resources.RegistryOps;
import org.bukkit.Keyed;
import org.bukkit.Registry;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.util.Handleable;
import org.intellij.lang.annotations.Subst;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
public interface Holderable<M> extends Handleable<M> {
Holder<M> getHolder();
@ -11,4 +24,55 @@ public interface Holderable<M> extends Handleable<M> {
default M getHandle() {
return this.getHolder().value();
}
static <T extends Keyed, M> @Nullable T fromBukkitSerializationObject(final Object deserialized, final Codec<? extends Holder<M>> codec, final Registry<T> registry) { // TODO remove Keyed
return switch (deserialized) {
case @Subst("key:value") final String string -> {
if (!(Key.parseable(string))) {
yield null;
}
yield registry.get(Key.key(string));
}
case JsonObjectWrapper(final JsonObject element) -> {
if (!(registry instanceof final CraftRegistry<?, ?> craftRegistry) || !craftRegistry.supportsDirectHolders()) {
throw new IllegalArgumentException("Cannot deserialize direct holders for " + registry);
}
final RegistryOps<JsonElement> ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE);
final Holder<M> holder = codec.decode(ops, element).getOrThrow().getFirst();
yield ((CraftRegistry<T, M>) registry).convertDirectHolder(holder);
}
default -> throw new IllegalArgumentException("Cannot deserialize " + deserialized);
};
}
default Object toBukkitSerializationObject(final Codec<? super Holder<M>> codec) {
return switch (this.getHolder()) {
case final Holder.Direct<M> direct -> {
final RegistryOps<JsonElement> ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE);
yield new JsonObjectWrapper(codec.encodeStart(ops, direct).getOrThrow().getAsJsonObject());
}
case final Holder.Reference<M> reference -> reference.key().location().toString();
default -> throw new IllegalArgumentException("Cannot serialize " + this.getHolder());
};
}
/**
* All implementations should use this as their hashCode implementation
*/
default int implHashCode() {
return this.getHolder().hashCode();
}
/**
* All implementations should use this as their equals implementation
*/
default boolean implEquals(final @Nullable Object o) {
if (o == null || this.getClass() != o.getClass()) return false;
final Holderable<?> that = (Holderable<?>) o;
return this.getHolder().equals(that.getHolder());
}
default String implToString() {
return "%s{holder=%s}".formatted(this.getClass().getSimpleName(), this.getHolder().toString());
}
}

Datei anzeigen

@ -0,0 +1,34 @@
package io.papermc.paper.util;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.Map;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.jspecify.annotations.NullMarked;
@NullMarked
public record JsonObjectWrapper(JsonObject element) implements ConfigurationSerializable {
private static final String KEY = "value";
private static final Gson GSON = new Gson();
static {
ConfigurationSerialization.registerClass(JsonObjectWrapper.class);
}
public JsonObjectWrapper(final JsonElement element) {
this(element.getAsJsonObject());
}
public JsonObjectWrapper(final Map<String, Object> input) {
this(JsonParser.parseString((String) input.get(KEY)).getAsJsonObject());
}
@Override
public Map<String, Object> serialize() {
return Map.of(KEY, GSON.toJson(this.element));
}
}

Datei anzeigen

@ -10,14 +10,14 @@ import org.bukkit.Registry;
import org.bukkit.craftbukkit.util.Handleable;
import org.jetbrains.annotations.NotNull;
public class CraftMusicInstrument extends MusicInstrument implements Handleable<Instrument> {
public class CraftMusicInstrument extends MusicInstrument implements io.papermc.paper.util.Holderable<Instrument> {
public static MusicInstrument minecraftToBukkit(Instrument minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.INSTRUMENT, Registry.INSTRUMENT);
}
public static MusicInstrument minecraftHolderToBukkit(Holder<Instrument> minecraft) {
return CraftMusicInstrument.minecraftToBukkit(minecraft.value());
return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.INSTRUMENT); // Paper - switch to Holder
}
public static Instrument bukkitToMinecraft(MusicInstrument bukkit) {
@ -25,41 +25,51 @@ public class CraftMusicInstrument extends MusicInstrument implements Handleable<
}
public static Holder<Instrument> bukkitToMinecraftHolder(MusicInstrument bukkit) {
Preconditions.checkArgument(bukkit != null);
net.minecraft.core.Registry<Instrument> registry = CraftRegistry.getMinecraftRegistry(Registries.INSTRUMENT);
if (registry.wrapAsHolder(CraftMusicInstrument.bukkitToMinecraft(bukkit)) instanceof Holder.Reference<Instrument> holder) {
return holder;
}
throw new IllegalArgumentException("No Reference holder found for " + bukkit
+ ", this can happen if a plugin creates its own instrument without properly registering it.");
return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.INSTRUMENT); // Paper - switch to Holder
}
public static String bukkitToString(MusicInstrument bukkit) {
public static Object bukkitToString(MusicInstrument bukkit) { // Paper - switch to Holder
Preconditions.checkArgument(bukkit != null);
return bukkit.getKey().toString();
return ((CraftMusicInstrument) bukkit).toBukkitSerializationObject(Instrument.CODEC); // Paper - switch to Holder
}
public static MusicInstrument stringToBukkit(String string) {
public static MusicInstrument stringToBukkit(Object string) { // Paper - switch to Holder
Preconditions.checkArgument(string != null);
return Registry.INSTRUMENT.get(NamespacedKey.fromString(string));
return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(string, Instrument.CODEC, Registry.INSTRUMENT); // Paper - switch to Holder
}
private final NamespacedKey key;
private final Instrument handle;
public CraftMusicInstrument(NamespacedKey key, Instrument handle) {
this.key = key;
this.handle = handle;
// Paper start - switch to Holder
@Override
public boolean equals(final Object o) {
return this.implEquals(o);
}
@Override
public Instrument getHandle() {
return this.handle;
public int hashCode() {
return this.implHashCode();
}
@Override
public String toString() {
return this.implToString();
}
private final Holder<Instrument> holder;
public CraftMusicInstrument(Holder<Instrument> holder) {
this.holder = holder;
this.key = holder.unwrapKey().map(io.papermc.paper.util.MCUtil::fromResourceKey).orElse(null);
this.handle = holder.value();
// Paper end - switch to Holder
}
@Override
public Holder<Instrument> getHolder() { // Paper - switch to Holder
return this.holder; // Paper - switch to Holder
}
@NotNull
@ -79,26 +89,5 @@ public class CraftMusicInstrument extends MusicInstrument implements Handleable<
}
// Paper end - add translationKey methods
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof CraftMusicInstrument)) {
return false;
}
return this.getKey().equals(((MusicInstrument) other).getKey());
}
@Override
public int hashCode() {
return this.getKey().hashCode();
}
@Override
public String toString() {
return "CraftMusicInstrument{key=" + this.key + "}";
}
// Paper - switch to Holder
}

Datei anzeigen

@ -54,21 +54,17 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta {
Map<?, ?> trimData = SerializableMeta.getObject(Map.class, map, CraftMetaArmor.TRIM.BUKKIT, true);
if (trimData != null) {
String materialKeyString = SerializableMeta.getString(trimData, CraftMetaArmor.TRIM_MATERIAL.BUKKIT, true);
String patternKeyString = SerializableMeta.getString(trimData, CraftMetaArmor.TRIM_PATTERN.BUKKIT, true);
Object materialKeyString = SerializableMeta.getObject(Object.class, trimData, CraftMetaArmor.TRIM_MATERIAL.BUKKIT, true); // Paper - switch to Holder
Object patternKeyString = SerializableMeta.getObject(Object.class, trimData, CraftMetaArmor.TRIM_PATTERN.BUKKIT, true); // Paper - switch to Holder
if (materialKeyString != null && patternKeyString != null) {
NamespacedKey materialKey = NamespacedKey.fromString(materialKeyString);
NamespacedKey patternKey = NamespacedKey.fromString(patternKeyString);
if (materialKey != null && patternKey != null) {
TrimMaterial trimMaterial = Registry.TRIM_MATERIAL.get(materialKey);
TrimPattern trimPattern = Registry.TRIM_PATTERN.get(patternKey);
if (trimMaterial != null && trimPattern != null) {
this.trim = new ArmorTrim(trimMaterial, trimPattern);
}
// Paper start - switch to Holder
TrimMaterial trimMaterial = CraftTrimMaterial.objectToBukkit(materialKeyString);
TrimPattern trimPattern = CraftTrimPattern.objectToBukkit(patternKeyString);
if (trimMaterial != null && trimPattern != null) {
this.trim = new ArmorTrim(trimMaterial, trimPattern);
}
// Paper end - switch to Holder
}
}
}
@ -133,9 +129,9 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta {
super.serialize(builder);
if (this.hasTrim()) {
Map<String, String> trimData = new HashMap<>();
trimData.put(CraftMetaArmor.TRIM_MATERIAL.BUKKIT, this.trim.getMaterial().getKey().toString());
trimData.put(CraftMetaArmor.TRIM_PATTERN.BUKKIT, this.trim.getPattern().getKey().toString());
Map<String, Object> trimData = new HashMap<>(); // Paper - switch to Holder
trimData.put(CraftMetaArmor.TRIM_MATERIAL.BUKKIT, CraftTrimMaterial.bukkitToObject(this.trim.getMaterial())); // Paper - switch to Holder
trimData.put(CraftMetaArmor.TRIM_PATTERN.BUKKIT, CraftTrimPattern.bukkitToObject(this.trim.getPattern())); // Paper - switch to Holder
builder.put(CraftMetaArmor.TRIM.BUKKIT, trimData);
}

Datei anzeigen

@ -37,7 +37,7 @@ public class CraftMetaMusicInstrument extends CraftMetaItem implements MusicInst
CraftMetaMusicInstrument(Map<String, Object> map) {
super(map);
String instrumentString = SerializableMeta.getString(map, CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.BUKKIT, true);
Object instrumentString = SerializableMeta.getObject(Object.class, map, CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.BUKKIT, true); // Paper - switch to Holder
if (instrumentString != null) {
this.instrument = CraftMusicInstrument.stringToBukkit(instrumentString);
}

Datei anzeigen

@ -11,14 +11,14 @@ import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.jetbrains.annotations.NotNull;
public class CraftTrimMaterial implements TrimMaterial, Handleable<net.minecraft.world.item.equipment.trim.TrimMaterial> {
public class CraftTrimMaterial implements TrimMaterial, io.papermc.paper.util.Holderable<net.minecraft.world.item.equipment.trim.TrimMaterial> { // Paper - switch to Holder
public static TrimMaterial minecraftToBukkit(net.minecraft.world.item.equipment.trim.TrimMaterial minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_MATERIAL, Registry.TRIM_MATERIAL);
}
public static TrimMaterial minecraftHolderToBukkit(Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> minecraft) {
return CraftTrimMaterial.minecraftToBukkit(minecraft.value());
return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.TRIM_MATERIAL); // Paper - switch to Holder
}
public static net.minecraft.world.item.equipment.trim.TrimMaterial bukkitToMinecraft(TrimMaterial bukkit) {
@ -26,29 +26,52 @@ public class CraftTrimMaterial implements TrimMaterial, Handleable<net.minecraft
}
public static Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> bukkitToMinecraftHolder(TrimMaterial bukkit) {
Preconditions.checkArgument(bukkit != null);
net.minecraft.core.Registry<net.minecraft.world.item.equipment.trim.TrimMaterial> registry = CraftRegistry.getMinecraftRegistry(Registries.TRIM_MATERIAL);
if (registry.wrapAsHolder(CraftTrimMaterial.bukkitToMinecraft(bukkit)) instanceof Holder.Reference<net.minecraft.world.item.equipment.trim.TrimMaterial> holder) {
return holder;
}
throw new IllegalArgumentException("No Reference holder found for " + bukkit
+ ", this can happen if a plugin creates its own trim material without properly registering it.");
return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.TRIM_MATERIAL); // Paper - switch to Holder
}
private final NamespacedKey key;
private final net.minecraft.world.item.equipment.trim.TrimMaterial handle;
public CraftTrimMaterial(NamespacedKey key, net.minecraft.world.item.equipment.trim.TrimMaterial handle) {
this.key = key;
this.handle = handle;
// Paper start - switch to Holder
private final Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> holder;
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
}
public static TrimMaterial objectToBukkit(Object object) {
Preconditions.checkArgument(object != null);
return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(object, net.minecraft.world.item.equipment.trim.TrimMaterial.CODEC, Registry.TRIM_MATERIAL); // Paper - switch to Holder
}
@Override
public net.minecraft.world.item.equipment.trim.TrimMaterial getHandle() {
return this.handle;
public boolean equals(final Object o) {
return this.implEquals(o);
}
@Override
public int hashCode() {
return this.implHashCode();
}
@Override
public String toString() {
return this.implToString();
}
public CraftTrimMaterial(final Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> holder) {
this.key = holder.unwrapKey().map(io.papermc.paper.util.MCUtil::fromResourceKey).orElse(null);
this.handle = holder.value();
this.holder = holder;
// Paper end - switch to Holder
}
@Override
public Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> getHolder() { // Paper - switch to Holder
return this.holder; // Paper - switch to Holder
}
@Override

Datei anzeigen

@ -11,14 +11,14 @@ import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.inventory.meta.trim.TrimPattern;
import org.jetbrains.annotations.NotNull;
public class CraftTrimPattern implements TrimPattern, Handleable<net.minecraft.world.item.equipment.trim.TrimPattern> {
public class CraftTrimPattern implements TrimPattern, io.papermc.paper.util.Holderable<net.minecraft.world.item.equipment.trim.TrimPattern> { // Paper - switch to Holder
public static TrimPattern minecraftToBukkit(net.minecraft.world.item.equipment.trim.TrimPattern minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_PATTERN, Registry.TRIM_PATTERN);
}
public static TrimPattern minecraftHolderToBukkit(Holder<net.minecraft.world.item.equipment.trim.TrimPattern> minecraft) {
return CraftTrimPattern.minecraftToBukkit(minecraft.value());
return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.TRIM_PATTERN); // Paper - switch to Holder
}
public static net.minecraft.world.item.equipment.trim.TrimPattern bukkitToMinecraft(TrimPattern bukkit) {
@ -26,29 +26,52 @@ public class CraftTrimPattern implements TrimPattern, Handleable<net.minecraft.w
}
public static Holder<net.minecraft.world.item.equipment.trim.TrimPattern> bukkitToMinecraftHolder(TrimPattern bukkit) {
Preconditions.checkArgument(bukkit != null);
net.minecraft.core.Registry<net.minecraft.world.item.equipment.trim.TrimPattern> registry = CraftRegistry.getMinecraftRegistry(Registries.TRIM_PATTERN);
if (registry.wrapAsHolder(CraftTrimPattern.bukkitToMinecraft(bukkit)) instanceof Holder.Reference<net.minecraft.world.item.equipment.trim.TrimPattern> holder) {
return holder;
}
throw new IllegalArgumentException("No Reference holder found for " + bukkit
+ ", this can happen if a plugin creates its own trim pattern without properly registering it.");
return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.TRIM_PATTERN); // Paper - switch to Holder
}
private final NamespacedKey key;
private final net.minecraft.world.item.equipment.trim.TrimPattern handle;
public CraftTrimPattern(NamespacedKey key, net.minecraft.world.item.equipment.trim.TrimPattern handle) {
this.key = key;
this.handle = handle;
// Paper start - switch to Holder
private final Holder<net.minecraft.world.item.equipment.trim.TrimPattern> holder; // Paper - switch to Holder
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
}
public static TrimPattern objectToBukkit(Object object) {
Preconditions.checkArgument(object != null);
return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(object, net.minecraft.world.item.equipment.trim.TrimPattern.CODEC, Registry.TRIM_PATTERN); // Paper - switch to Holder
}
@Override
public net.minecraft.world.item.equipment.trim.TrimPattern getHandle() {
return this.handle;
public boolean equals(final Object o) {
return this.implEquals(o);
}
@Override
public int hashCode() {
return this.implHashCode();
}
@Override
public String toString() {
return this.implToString();
}
public CraftTrimPattern(Holder<net.minecraft.world.item.equipment.trim.TrimPattern> handle) {
this.key = handle.unwrapKey().map(io.papermc.paper.util.MCUtil::fromResourceKey).orElse(null);
this.handle = handle.value();
this.holder = handle;
// Paper end - switch to Holder
}
@Override
public Holder<net.minecraft.world.item.equipment.trim.TrimPattern> getHolder() { // Paper - switch to Holder
return this.holder; // Paper - switch to Holder
}
@Override

Datei anzeigen

@ -269,6 +269,7 @@ public class RegistryConversionTest {
Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) throws IllegalAccessException {
this.checkValidMinecraftToBukkit(clazz);
if (type == io.papermc.paper.registry.RegistryKey.TRIM_MATERIAL || type == io.papermc.paper.registry.RegistryKey.TRIM_PATTERN || type == io.papermc.paper.registry.RegistryKey.INSTRUMENT) return; // Paper - manually skip for now
try {
Object minecraft = mock(minecraftClazz);