Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
@NullMarked
module net.kyori.adventure.api {
requires transitive net.kyori.adventure.key;
requires transitive org.jspecify;
requires transitive org.jetbrains.annotations;
requires static transitive org.jspecify;
requires static transitive org.jetbrains.annotations;

exports net.kyori.adventure;
exports net.kyori.adventure.audience;
Expand Down
6 changes: 3 additions & 3 deletions serializer-configurate4/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
module net.kyori.adventure.serializer.configurate4 {
requires transitive net.kyori.adventure.api;
requires net.kyori.adventure.text.serializer.commons;
requires io.leangen.geantyref;
requires org.spongepowered.configurate;
requires static org.checkerframework.checker.qual;
requires transitive io.leangen.geantyref;
requires transitive org.spongepowered.configurate;
requires static transitive org.checkerframework.checker.qual;

exports net.kyori.adventure.serializer.configurate4;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2025 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.serializer.configurate4;

import io.leangen.geantyref.GenericTypeReflector;
import java.lang.reflect.Type;
import net.kyori.adventure.text.event.ClickEvent;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;

final class ClickEventPayloadSerializer implements TypeSerializer<ClickEvent.Payload> {
static final TypeSerializer<ClickEvent.Payload> INSTANCE = new ClickEventPayloadSerializer();

private ClickEventPayloadSerializer() {
}

@Override
public ClickEvent.Payload deserialize(final Type type, final ConfigurationNode node) throws SerializationException {
final Class<? extends ClickEvent.Payload> raw = GenericTypeReflector.erase(type).asSubclass(ClickEvent.Payload.class);
if (ClickEvent.Payload.Custom.class.equals(raw) || ClickEvent.Payload.Dialog.class.equals(raw)) {
throw new SerializationException("Do not know how to deserialize a " + raw.getSimpleName() + " payload");
} else if (ClickEvent.Payload.Int.class.equals(raw)) {
return ClickEvent.Payload.integer(node.getInt());
} else if (ClickEvent.Payload.Text.class.equals(raw)) {
return ClickEvent.Payload.string(node.getString());
} else {
throw new SerializationException("Do not know how to deserialize a " + raw.getSimpleName() + " payload!");
}
}

@Override
public void serialize(final Type type, final ClickEvent.@Nullable Payload obj, final ConfigurationNode node) throws SerializationException {
switch (obj) {
case null -> node.set(null);
case ClickEvent.Payload.Custom c -> throw new SerializationException("Do not know how to serialize a custom payload");
case ClickEvent.Payload.Dialog d -> throw new SerializationException("Do not know how to serialize a dialog");
case ClickEvent.Payload.Int i -> node.set(i.integer());
case ClickEvent.Payload.Text s -> node.set(s.value());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,25 +97,21 @@ public Component deserialize(final Type type, final ConfigurationNode value) thr
return this.deserialize0(value);
}

private BuildableComponent<?, ?> deserialize0(final ConfigurationNode value) throws SerializationException {
private Component deserialize0(final ConfigurationNode value) throws SerializationException {
// Try to read as a string
if (!value.isList() && !value.isMap()) {
final String str = value.getString();
if (str != null) {
if (this.stringSerial != null) {
final Component ret = this.stringSerial.deserialize(str);
if (!(ret instanceof BuildableComponent<?, ?>)) {
throw new SerializationException("Result " + ret + " is not builable");
}
return (BuildableComponent<?, ?>) ret;
return this.stringSerial.deserialize(str);
} else {
return Component.text(str);
}
}
} else if (value.isList()) {
ComponentBuilder<?, ?> parent = null;
for (final ConfigurationNode childElement : value.childrenList()) {
final BuildableComponent<?, ?> child = this.deserialize0(childElement);
final Component child = this.deserialize0(childElement);
if (parent == null) {
parent = child.toBuilder();
} else {
Expand Down Expand Up @@ -278,13 +274,13 @@ public void serialize(final Type type, final @Nullable Component src, final Conf
score.node(SCORE_OBJECTIVE).set(sc.objective());
// score component value is optional
@SuppressWarnings("deprecation")
final @Nullable String scoreValue = sc.value();
final String scoreValue = sc.value();
if (scoreValue != null) score.node(SCORE_VALUE).set(scoreValue);
} else if (src instanceof SelectorComponent) {
value.node(SELECTOR).set(((SelectorComponent) src).pattern());
} else if (src instanceof KeybindComponent) {
value.node(KEYBIND).set(((KeybindComponent) src).keybind());
} else if (src instanceof final NBTComponent<?, ?> nc) {
} else if (src instanceof final NBTComponent<?> nc) {
value.node(NBT).set(nc.nbtPath());
value.node(NBT_INTERPRET).set(nc.interpret());
switch (src) {
Expand All @@ -293,17 +289,14 @@ public void serialize(final Type type, final @Nullable Component src, final Conf
case StorageNBTComponent storageNBTComponent -> value.node(NBT_STORAGE).set(KeySerializer.INSTANCE.type(), storageNBTComponent.storage());
default -> throw notSureHowToSerialize(src);
}
} else if (src instanceof ObjectComponent) {
final ObjectComponent objectComponent = (ObjectComponent) src;
} else if (src instanceof final ObjectComponent objectComponent) {
final ObjectContents contents = objectComponent.contents();
if (contents instanceof SpriteObjectContents) {
final SpriteObjectContents spriteContents = (SpriteObjectContents) contents;
if (contents instanceof final SpriteObjectContents spriteContents) {
if (!spriteContents.atlas().equals(SpriteObjectContents.DEFAULT_ATLAS)) {
value.node(OBJECT_ATLAS).set(KeySerializer.INSTANCE.type(), spriteContents.atlas());
}
value.node(OBJECT_SPRITE).set(KeySerializer.INSTANCE.type(), spriteContents.sprite());
} else if (contents instanceof PlayerHeadObjectContents) {
final PlayerHeadObjectContents playerHeadContents = (PlayerHeadObjectContents) contents;
} else if (contents instanceof final PlayerHeadObjectContents playerHeadContents) {
value.node(OBJECT_HAT).set(playerHeadContents.hat());
final String playerName = playerHeadContents.name();
final UUID playerId = playerHeadContents.id();
Expand Down Expand Up @@ -348,7 +341,7 @@ public void serialize(final Type type, final @Nullable Component src, final Conf
}
}

private static <C extends NBTComponent<C, B>, B extends NBTComponentBuilder<C, B>> B nbt(final B builder, final String nbt, final boolean interpret) {
private static <C extends NBTComponent<C>, B extends NBTComponentBuilder<C, B>> B nbt(final B builder, final String nbt, final boolean interpret) {
return builder
.nbtPath(nbt)
.interpret(interpret);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
import net.kyori.adventure.sound.SoundStop;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslationArgument;
import net.kyori.adventure.text.event.ClickEventImpl;
import net.kyori.adventure.text.event.HoverEventImpl;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.ShadowColor;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextDecoration;
Expand Down Expand Up @@ -66,7 +66,7 @@ private ConfigurateComponentSerializerImpl(final Builder builder) {
@Override
public Component deserialize(final ConfigurationNode input) {
try {
final @Nullable Component deserialized = input.get(Component.class);
final Component deserialized = input.get(Component.class);
if (deserialized != null) {
return deserialized;
}
Expand Down Expand Up @@ -102,12 +102,13 @@ private TypeSerializerCollection makeSerializers(final TypeSerializerCollection.
.register(TextColorSerializer.INSTANCE)
.register(BlockNBTPosSerializer.INSTANCE)
.register(TranslationArgument.class, TranslationArgumentTypeSerializer.INSTANCE)
.registerExact(new IndexSerializer<>(TypeToken.get(ClickEventImpl.Action.class), ClickEventImpl.Action.NAMES))
.registerExact(new IndexSerializer<>(new TypeToken<HoverEventImpl.Action<?>>() {}, HoverEventImpl.Action.NAMES))
.register(ClickEvent.Payload.class, ClickEventPayloadSerializer.INSTANCE)
.registerExact(new IndexSerializer<>(new TypeToken<ClickEvent.Action<?>>() {}, ClickEvent.Action.NAMES))
.registerExact(new IndexSerializer<>(new TypeToken<HoverEvent.Action<?>>() {}, HoverEvent.Action.NAMES))
.registerExact(new IndexSerializer<>(TypeToken.get(Sound.Source.class), Sound.Source.NAMES))
.registerExact(new IndexSerializer<>(TypeToken.get(TextDecoration.class), TextDecoration.NAMES))
.registerExact(HoverEventImpl.ShowEntity.class, HoverEventShowEntitySerializer.INSTANCE)
.registerExact(HoverEventImpl.ShowItem.class, HoverEventShowItemSerializer.INSTANCE)
.registerExact(HoverEvent.ShowEntity.class, HoverEventShowEntitySerializer.INSTANCE)
.registerExact(HoverEvent.ShowItem.class, HoverEventShowItemSerializer.INSTANCE)
.register(ConfigurateDataComponentValue.class, ConfigurateDataComponentValueTypeSerializer.INSTANCE)
.register(ShadowColor.class, ShadowColorSerializer.INSTACE)
.register(PlayerHeadObjectContents.ProfileProperty.class, ProfilePropertySerializer.INSTANCE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*
* @since 4.17.0
*/
public interface ConfigurateDataComponentValue extends DataComponentValue {
public sealed interface ConfigurateDataComponentValue extends DataComponentValue permits SnapshottingConfigurateDataComponentValue {
/**
* Create a data component value capturing the value of an existing node.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,33 @@
import java.util.UUID;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEventImpl;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants;
import org.jspecify.annotations.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;

final class HoverEventShowEntitySerializer implements TypeSerializer<HoverEventImpl.ShowEntity> {
final class HoverEventShowEntitySerializer implements TypeSerializer<HoverEvent.ShowEntity> {
static final HoverEventShowEntitySerializer INSTANCE = new HoverEventShowEntitySerializer();

private HoverEventShowEntitySerializer() {
}

@Override
public HoverEventImpl.ShowEntity deserialize(final Type type, final ConfigurationNode value) throws SerializationException {
public HoverEvent.ShowEntity deserialize(final Type type, final ConfigurationNode value) throws SerializationException {
final Key typeId = value.node(ComponentTreeConstants.SHOW_ENTITY_TYPE).get(Key.class);
final UUID id = value.node(ComponentTreeConstants.SHOW_ENTITY_ID).get(UUID.class);
if (typeId == null || id == null) {
throw new SerializationException("A show entity hover event needs type and id fields to be deserialized");
}
final @Nullable Component name = value.node(ComponentTreeConstants.SHOW_ENTITY_NAME).get(Component.class);
final Component name = value.node(ComponentTreeConstants.SHOW_ENTITY_NAME).get(Component.class);

return HoverEventImpl.ShowEntity.showEntity(typeId, id, name);
return HoverEvent.ShowEntity.showEntity(typeId, id, name);
}

@Override
public void serialize(final Type type, final HoverEventImpl.@Nullable ShowEntity obj, final ConfigurationNode value) throws SerializationException {
public void serialize(final Type type, final HoverEvent.@Nullable ShowEntity obj, final ConfigurationNode value) throws SerializationException {
if (obj == null) {
value.set(null);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
import java.util.Map;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.text.event.HoverEventImpl;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants;
import org.jspecify.annotations.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;

final class HoverEventShowItemSerializer implements TypeSerializer<HoverEventImpl.ShowItem> {
final class HoverEventShowItemSerializer implements TypeSerializer<HoverEvent.ShowItem> {
static final HoverEventShowItemSerializer INSTANCE = new HoverEventShowItemSerializer();

private static final TypeToken<Map<Key, ConfigurateDataComponentValue>> COMPONENT_MAP_TYPE = new TypeToken<Map<Key, ConfigurateDataComponentValue>>() {
Expand All @@ -46,7 +46,7 @@ private HoverEventShowItemSerializer() {
}

@Override
public HoverEventImpl.ShowItem deserialize(final Type type, final ConfigurationNode value) throws SerializationException {
public HoverEvent.ShowItem deserialize(final Type type, final ConfigurationNode value) throws SerializationException {
final Key id = value.node(ComponentTreeConstants.SHOW_ITEM_ID).get(Key.class);
if (id == null) {
throw new SerializationException("An id is required to deserialize the show_item hover event");
Expand All @@ -56,17 +56,17 @@ public HoverEventImpl.ShowItem deserialize(final Type type, final ConfigurationN
if (!components.virtual()) {
final Map<Key, ConfigurateDataComponentValue> componentsMap = components.require(COMPONENT_MAP_TYPE);

return HoverEventImpl.ShowItem.showItem(id, count, new HashMap<>(componentsMap));
return HoverEvent.ShowItem.showItem(id, count, new HashMap<>(componentsMap));
} else {
// legacy (pre-1.20.5)
@SuppressWarnings("deprecation")
final String tag = value.node(ComponentTreeConstants.SHOW_ITEM_TAG).getString();
return HoverEventImpl.ShowItem.showItem(id, count, tag == null ? null : BinaryTagHolder.binaryTagHolder(tag));
return HoverEvent.ShowItem.showItem(id, count, tag == null ? null : BinaryTagHolder.binaryTagHolder(tag));
}
}

@Override
public void serialize(final Type type, final HoverEventImpl.@Nullable ShowItem obj, final ConfigurationNode value) throws SerializationException {
public void serialize(final Type type, final HoverEvent.@Nullable ShowItem obj, final ConfigurationNode value) throws SerializationException {
if (obj == null) {
value.set(null);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
final class ShadowColorSerializer implements TypeSerializer<ShadowColor> {
static final TypeSerializer<ShadowColor> INSTACE = new ShadowColorSerializer(false);

private boolean emitFloats;
private final boolean emitFloats;

private ShadowColorSerializer(final boolean emitFloats) {
this.emitFloats = emitFloats;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,12 @@
*/
package net.kyori.adventure.serializer.configurate4;

import java.util.stream.Stream;
import net.kyori.examination.ExaminableProperty;
import org.spongepowered.configurate.AttributedConfigurationNode;
import org.spongepowered.configurate.BasicConfigurationNode;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurationNode;

final class SnapshottingConfigurateDataComponentValue implements ConfigurateDataComponentValue {
private final ConfigurationNode ownedNode;

record SnapshottingConfigurateDataComponentValue(ConfigurationNode ownedNode) implements ConfigurateDataComponentValue {
// capture the value of an existing node without exposing any mutable state
static SnapshottingConfigurateDataComponentValue create(final ConfigurationNode existing) {
final ConfigurationNode owned;
Expand All @@ -49,19 +45,8 @@ static SnapshottingConfigurateDataComponentValue create(final ConfigurationNode
return new SnapshottingConfigurateDataComponentValue(owned);
}

private SnapshottingConfigurateDataComponentValue(final ConfigurationNode owned) {
this.ownedNode = owned;
}

@Override
public void applyTo(final ConfigurationNode node) {
node.from(this.ownedNode);
}

@Override
public Stream<? extends ExaminableProperty> examinableProperties() {
return Stream.of(
ExaminableProperty.of("ownedNode", this.ownedNode)
);
}
}
Loading
Loading