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

cn.nukkit.nbt.tag.ListTag Maven / Gradle / Ivy

There is a newer version: 1.20.40-r1
Show newest version
package cn.nukkit.nbt.tag;

import cn.nukkit.nbt.stream.NBTInputStream;
import cn.nukkit.nbt.stream.NBTOutputStream;
import cn.nukkit.utils.StringUtils;

import java.io.IOException;
import java.io.PrintStream;
import java.util.*;
import java.util.stream.Collectors;

public class ListTag extends Tag {

    private List list = new ArrayList<>();

    public byte type;

    public ListTag() {
        super("");
    }

    public ListTag(String name) {
        super(name);
    }

    @Override
    void write(NBTOutputStream dos) throws IOException {
        if (list.size() > 0) type = list.get(0).getId();
        else type = 1;

        dos.writeByte(type);
        dos.writeInt(list.size());
        for (T aList : list) aList.write(dos);
    }

    @Override
    @SuppressWarnings("unchecked")
    void load(NBTInputStream dis) throws IOException {
        type = dis.readByte();
        int size = dis.readInt();

        list = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            Tag tag = Tag.newTag(type, null);
            tag.load(dis);
            tag.setName("");
            list.add((T) tag);
        }
    }

    @Override
    public byte getId() {
        return TAG_List;
    }

    @Override
    public String toString() {
        StringJoiner joiner = new StringJoiner(",\n\t");
        list.forEach(tag -> joiner.add(tag.toString().replace("\n", "\n\t")));
        return "ListTag '" + this.getName() + "' (" + list.size() + " entries of type " + Tag.getTagName(type) + ") {\n\t" + joiner + "\n}";
    }

    @Override
    public String toSnbt() {
        if (this.getName().equals("")) return "[" + list.stream()
                .map(tag -> StringUtils.afterFirst(tag.toSnbt(), ":"))
                .collect(Collectors.joining(",")) + "]";
        else return "\"" + this.getName() + "\":[" + list.stream()
                .map(tag -> StringUtils.afterFirst(tag.toSnbt(), ":"))
                .collect(Collectors.joining(",")) + "]";
    }

    @Override
    public String toSnbt(int space) {
        StringBuilder addSpace = new StringBuilder();
        addSpace.append(" ".repeat(Math.max(0, space)));
        if (list.isEmpty()) {
            return "\"" + this.getName() + "\": []";
        } else if (list.get(0) instanceof StringTag || list.get(0) instanceof CompoundTag || list.get(0) instanceof ListTag) {
            StringJoiner joiner1 = new StringJoiner(",\n" + addSpace);
            list.forEach(tag -> {
                var str = tag.toSnbt(space);
                joiner1.add(str.substring(str.indexOf(":") + 2).replace("\n", "\n" + addSpace));
            });
            return "\"" + this.getName() + "\": [\n" + addSpace + joiner1 + "\n]";
        } else {
            StringJoiner joiner2 = new StringJoiner(", ");
            list.forEach(tag -> {
                var str = tag.toSnbt(space);
                joiner2.add(str.substring(str.indexOf(":") + 2));
            });
            return "\"" + this.getName() + "\": [" + joiner2 + "]";
        }
    }

    @Override
    public void print(String prefix, PrintStream out) {
        super.print(prefix, out);

        out.println(prefix + "{");
        String orgPrefix = prefix;
        prefix += "   ";
        for (T aList : list) aList.print(prefix, out);
        out.println(orgPrefix + "}");
    }

    public ListTag add(T tag) {
        type = tag.getId();
        tag.setName("");
        list.add(tag);
        return this;
    }

    public ListTag add(int index, T tag) {
        type = tag.getId();
        tag.setName("");

        if (index >= list.size()) {
            list.add(index, tag);
        } else {
            list.set(index, tag);
        }
        return this;
    }

    @Override
    public List parseValue() {
        List value = new ArrayList<>(this.list.size());

        for (T t : this.list) {
            value.add(t.parseValue());
        }

        return value;
    }

    public T get(int index) {
        return list.get(index);
    }

    public List getAll() {
        return new ArrayList<>(list);
    }

    public void setAll(List tags) {
        this.list = new ArrayList<>(tags);
    }

    public void remove(T tag) {
        list.remove(tag);
    }

    public void remove(int index) {
        list.remove(index);
    }

    public void removeAll(Collection tags) {
        list.remove(tags);
    }

    public int size() {
        return list.size();
    }

    @Override
    public Tag copy() {
        ListTag res = new ListTag<>(getName());
        res.type = type;
        for (T t : list) {
            @SuppressWarnings("unchecked")
            T copy = (T) t.copy();
            res.list.add(copy);
        }
        return res;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean equals(Object obj) {
        if (super.equals(obj)) {
            ListTag o = (ListTag) obj;
            if (type == o.type) {
                return list.equals(o.list);
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), type, list);
    }
}