All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.minestom.server.registry.ObjectSetImpl Maven / Gradle / Ivy

There is a newer version: 7320437640
Show newest version
package net.minestom.server.registry;

import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.BinaryTagTypes;
import net.kyori.adventure.nbt.ListBinaryTag;
import net.kyori.adventure.nbt.StringBinaryTag;
import net.minestom.server.MinecraftServer;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;

import java.util.HashSet;
import java.util.Set;

import static net.kyori.adventure.nbt.StringBinaryTag.stringBinaryTag;

sealed interface ObjectSetImpl extends ObjectSet permits ObjectSetImpl.Empty, ObjectSetImpl.Entries, ObjectSetImpl.Tag {

    record Empty() implements ObjectSetImpl {
        static final Empty INSTANCE = new Empty<>();

        @Override
        public boolean contains(@NotNull NamespaceID namespace) {
            return false;
        }
    }

    record Entries(@NotNull Set entries) implements ObjectSetImpl {

        public Entries {
            entries = Set.copyOf(entries);
        }

        @Override
        public boolean contains(@NotNull NamespaceID namespace) {
            return entries.contains(namespace);
        }
    }

    final class Tag implements ObjectSetImpl {
        private final net.minestom.server.gamedata.tags.Tag.BasicType tagType;
        private final String name;
        private volatile Set value = null;

        public Tag(@NotNull net.minestom.server.gamedata.tags.Tag.BasicType tagType, @NotNull String name) {
            this.tagType = tagType;
            this.name = name;
        }

        public Tag(@NotNull net.minestom.server.gamedata.tags.Tag tag) {
            this.tagType = null;
            this.name = tag.name();
            this.value = Set.copyOf(tag.getValues());
        }

        public @NotNull String name() {
            return name;
        }

        public Set value() {
            if (value == null) {
                synchronized (this) {
                    if (value == null) {
                        var group = MinecraftServer.getTagManager().getTag(tagType, name);
                        value = group == null ? Set.of() : Set.copyOf(group.getValues());
                    }
                }
            }
            return value;
        }

        @Override
        public boolean contains(@NotNull NamespaceID namespace) {
            return value().contains(namespace);
        }
    }

    record NbtType(
            @NotNull net.minestom.server.gamedata.tags.Tag.BasicType tagType
    ) implements BinaryTagSerializer> {

        @Override
        public @NotNull ObjectSet read(@NotNull BinaryTag tag) {
            return switch (tag) {
                case null -> ObjectSet.empty();
                case ListBinaryTag list -> {
                    if (list.size() == 0) yield ObjectSet.empty();

                    final Set entries = new HashSet<>(list.size());
                    for (BinaryTag entryTag : list) {
                        if (!(entryTag instanceof StringBinaryTag stringTag))
                            throw new IllegalArgumentException("Invalid entry type: " + entryTag.type());
                        entries.add(NamespaceID.from(stringTag.value()));
                    }
                    yield new Entries<>(entries);
                }
                case StringBinaryTag string -> {
                    // Could be a tag or a block name depending if it starts with a #
                    final String value = string.value();
                    if (value.startsWith("#")) {
                        yield new Tag<>(tagType(), value.substring(1));
                    } else {
                        yield new Entries<>(Set.of(NamespaceID.from(value)));
                    }
                }
                default -> throw new IllegalArgumentException("Invalid tag type: " + tag.type());
            };
        }

        @Override
        public @NotNull BinaryTag write(@NotNull ObjectSet value) {
            return switch (value) {
                case Empty empty -> ListBinaryTag.empty();
                case Entries entries -> {
                    if (entries.entries.size() == 1)
                        yield stringBinaryTag(entries.entries.stream().findFirst().get().asString());
                    ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.STRING);
                    for (NamespaceID entry : entries.entries)
                        builder.add(stringBinaryTag(entry.asString()));
                    yield builder.build();
                }
                case Tag tag -> stringBinaryTag("#" + tag.name());
            };
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy