Switch Impl types to Holderable
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user