mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-14 03:11:25 +01:00
chore: basic nbt reader/writer for protocol while waiting for adventure
This commit is contained in:
parent
e61dc8188f
commit
18b6354d83
@ -12,13 +12,13 @@ import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.network.packet.server.play.data.WorldPos;
|
||||
import net.minestom.server.particle.Particle;
|
||||
import net.minestom.server.utils.Direction;
|
||||
import net.minestom.server.utils.nbt.BinaryTagReader;
|
||||
import net.minestom.server.utils.nbt.BinaryTagWriter;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.*;
|
||||
@ -79,8 +79,8 @@ public final class NetworkBuffer {
|
||||
int writeIndex;
|
||||
int readIndex;
|
||||
|
||||
DataOutput nbtWriter;
|
||||
DataInput nbtReader;
|
||||
BinaryTagWriter nbtWriter;
|
||||
BinaryTagReader nbtReader;
|
||||
|
||||
public NetworkBuffer(@NotNull ByteBuffer buffer, boolean resizable) {
|
||||
this.nioBuffer = buffer.order(ByteOrder.BIG_ENDIAN);
|
||||
|
@ -1,5 +1,8 @@
|
||||
package net.minestom.server.network;
|
||||
|
||||
import net.kyori.adventure.nbt.BinaryTag;
|
||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||
import net.kyori.adventure.nbt.EndBinaryTag;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.minestom.server.adventure.serializer.nbt.NbtComponentSerializer;
|
||||
@ -10,13 +13,12 @@ import net.minestom.server.item.Material;
|
||||
import net.minestom.server.network.packet.server.play.data.WorldPos;
|
||||
import net.minestom.server.particle.Particle;
|
||||
import net.minestom.server.particle.data.ParticleData;
|
||||
import net.minestom.server.utils.nbt.BinaryTagReader;
|
||||
import net.minestom.server.utils.nbt.BinaryTagWriter;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -283,37 +285,31 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
|
||||
}
|
||||
}
|
||||
|
||||
record NbtType() implements NetworkBufferTypeImpl<NBT> {
|
||||
record NbtType() implements NetworkBufferTypeImpl<BinaryTag> {
|
||||
@Override
|
||||
public void write(@NotNull NetworkBuffer buffer, org.jglrxavpok.hephaistos.nbt.NBT value) {
|
||||
NBTWriter nbtWriter = buffer.nbtWriter;
|
||||
public void write(@NotNull NetworkBuffer buffer, BinaryTag value) {
|
||||
BinaryTagWriter nbtWriter = buffer.nbtWriter;
|
||||
if (nbtWriter == null) {
|
||||
nbtWriter = new NBTWriter(new OutputStream() {
|
||||
nbtWriter = new BinaryTagWriter(new DataOutputStream(new OutputStream() {
|
||||
@Override
|
||||
public void write(int b) {
|
||||
buffer.write(BYTE, (byte) b);
|
||||
}
|
||||
}, CompressedProcesser.NONE);
|
||||
}));
|
||||
buffer.nbtWriter = nbtWriter;
|
||||
}
|
||||
try {
|
||||
if (value == NBTEnd.INSTANCE) {
|
||||
// Kotlin - https://discord.com/channels/706185253441634317/706186227493109860/1163703658341478462
|
||||
buffer.write(BYTE, (byte) NBTType.TAG_End.getOrdinal());
|
||||
} else {
|
||||
buffer.write(BYTE, (byte) value.getID().getOrdinal());
|
||||
nbtWriter.writeRaw(value);
|
||||
}
|
||||
nbtWriter.writeNameless(value);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.jglrxavpok.hephaistos.nbt.NBT read(@NotNull NetworkBuffer buffer) {
|
||||
NBTReader nbtReader = buffer.nbtReader;
|
||||
public BinaryTag read(@NotNull NetworkBuffer buffer) {
|
||||
BinaryTagReader nbtReader = buffer.nbtReader;
|
||||
if (nbtReader == null) {
|
||||
nbtReader = new NBTReader(new InputStream() {
|
||||
nbtReader = new BinaryTagReader(new DataInputStream(new InputStream() {
|
||||
@Override
|
||||
public int read() {
|
||||
return buffer.read(BYTE) & 0xFF;
|
||||
@ -323,15 +319,12 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
|
||||
public int available() {
|
||||
return buffer.readableBytes();
|
||||
}
|
||||
}, CompressedProcesser.NONE);
|
||||
}));
|
||||
buffer.nbtReader = nbtReader;
|
||||
}
|
||||
try {
|
||||
byte tagId = buffer.read(BYTE);
|
||||
if (tagId == NBTType.TAG_End.getOrdinal())
|
||||
return NBTEnd.INSTANCE;
|
||||
return nbtReader.readRaw(tagId);
|
||||
} catch (IOException | NBTException e) {
|
||||
return nbtReader.readNameless();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@ -362,13 +355,13 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
|
||||
record ComponentType() implements NetworkBufferTypeImpl<Component> {
|
||||
@Override
|
||||
public void write(@NotNull NetworkBuffer buffer, Component value) {
|
||||
final NBT nbt = NbtComponentSerializer.nbt().serialize(value);
|
||||
final BinaryTag nbt = NbtComponentSerializer.nbt().serialize(value);
|
||||
buffer.write(NBT, nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component read(@NotNull NetworkBuffer buffer) {
|
||||
final NBT nbt = buffer.read(NBT);
|
||||
final BinaryTag nbt = buffer.read(NBT);
|
||||
return NbtComponentSerializer.nbt().deserialize(nbt);
|
||||
}
|
||||
}
|
||||
@ -413,8 +406,8 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
|
||||
buffer.write(VAR_INT, value.material().id());
|
||||
buffer.write(BYTE, (byte) value.amount());
|
||||
// Vanilla does not write an empty object, just an end tag.
|
||||
NBTCompound nbt = value.meta().toNBT();
|
||||
buffer.write(NBT, nbt.isEmpty() ? NBTEnd.INSTANCE : nbt);
|
||||
CompoundBinaryTag nbt = value.meta().toNBT();
|
||||
buffer.write(NBT, nbt.size() == 0 ? EndBinaryTag.endBinaryTag() : nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -427,8 +420,8 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
|
||||
if (material == null) throw new RuntimeException("Unknown material id: " + id);
|
||||
|
||||
final int amount = buffer.read(BYTE);
|
||||
final NBT nbt = buffer.read(NBT);
|
||||
if (!(nbt instanceof NBTCompound compound)) {
|
||||
final BinaryTag nbt = buffer.read(NBT);
|
||||
if (!(nbt instanceof CompoundBinaryTag compound)) {
|
||||
return ItemStack.of(material, amount);
|
||||
}
|
||||
return ItemStack.fromNBT(material, compound, amount);
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.minestom.server.tag;
|
||||
|
||||
import net.kyori.adventure.nbt.*;
|
||||
import net.minestom.server.utils.NBTUtils;
|
||||
import net.minestom.server.utils.nbt.BinaryTagUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -51,7 +51,7 @@ final class TagNbtSeparator {
|
||||
var tagFunction = SUPPORTED_TYPES.get(nbt.type());
|
||||
if (tagFunction != null) {
|
||||
Tag tag = tagFunction.apply(key);
|
||||
consumer.accept(makeEntry(path, tag, NBTUtils.nbtValueFromTag(nbt)));
|
||||
consumer.accept(makeEntry(path, tag, BinaryTagUtil.nbtValueFromTag(nbt)));
|
||||
} else if (nbt instanceof CompoundBinaryTag nbtCompound) {
|
||||
for (var ent : nbtCompound) {
|
||||
var newPath = new ArrayList<>(path);
|
||||
@ -68,7 +68,7 @@ final class TagNbtSeparator {
|
||||
var tag = tagFunction.apply(key).list();
|
||||
Object[] values = new Object[nbtList.size()];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = NBTUtils.nbtValueFromTag(nbtList.get(i));
|
||||
values[i] = BinaryTagUtil.nbtValueFromTag(nbtList.get(i));
|
||||
}
|
||||
consumer.accept(makeEntry(path, Tag.class.cast(tag), List.of(values)));
|
||||
} catch (Exception e) {
|
||||
|
@ -0,0 +1,37 @@
|
||||
package net.minestom.server.utils.nbt;
|
||||
|
||||
import net.kyori.adventure.nbt.BinaryTag;
|
||||
import net.kyori.adventure.nbt.BinaryTagType;
|
||||
import net.kyori.adventure.nbt.BinaryTagTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
// Based on net.kyori.adventure.nbt.BinaryTagReaderImpl licensed under the MIT license.
|
||||
// https://github.com/KyoriPowered/adventure/blob/main/4/nbt/src/main/java/net/kyori/adventure/nbt/BinaryTagReaderImpl.java
|
||||
public class BinaryTagReader {
|
||||
|
||||
static {
|
||||
BinaryTagTypes.COMPOUND.id(); // Force initialization
|
||||
}
|
||||
|
||||
private final DataInput input;
|
||||
|
||||
public BinaryTagReader(@NotNull DataInput input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public @NotNull BinaryTag readNameless() throws IOException {
|
||||
BinaryTagType<? extends BinaryTag> type = BinaryTagUtil.nbtTypeFromId(input.readByte());
|
||||
return type.read(input);
|
||||
}
|
||||
|
||||
public @NotNull Map.Entry<String, BinaryTag> readNamed() throws IOException {
|
||||
BinaryTagType<? extends BinaryTag> type = BinaryTagUtil.nbtTypeFromId(input.readByte());
|
||||
String name = input.readUTF();
|
||||
return Map.entry(name, type.read(input));
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.minestom.server.utils;
|
||||
package net.minestom.server.utils.nbt;
|
||||
|
||||
import net.kyori.adventure.nbt.*;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
@ -6,7 +6,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class NBTUtils {
|
||||
public final class BinaryTagUtil {
|
||||
private static final BinaryTagType<?>[] TYPES = new BinaryTagType[]{
|
||||
BinaryTagTypes.END,
|
||||
BinaryTagTypes.BYTE,
|
||||
@ -54,6 +54,6 @@ public final class NBTUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private NBTUtils() {
|
||||
private BinaryTagUtil() {
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package net.minestom.server.utils.nbt;
|
||||
|
||||
import net.kyori.adventure.nbt.BinaryTag;
|
||||
import net.kyori.adventure.nbt.BinaryTagType;
|
||||
import net.kyori.adventure.nbt.BinaryTagTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
// Based on net.kyori.adventure.nbt.BinaryTagWriterImpl licensed under the MIT license.
|
||||
// https://github.com/KyoriPowered/adventure/blob/main/4/nbt/src/main/java/net/kyori/adventure/nbt/BinaryTagWriterImpl.java
|
||||
public class BinaryTagWriter {
|
||||
|
||||
static {
|
||||
BinaryTagTypes.COMPOUND.id(); // Force initialization
|
||||
}
|
||||
|
||||
private final DataOutput output;
|
||||
|
||||
public BinaryTagWriter(@NotNull DataOutput output) {
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public void writeNameless(@NotNull BinaryTag tag) throws IOException {
|
||||
//noinspection unchecked
|
||||
BinaryTagType<BinaryTag> type = (BinaryTagType<BinaryTag>) tag.type();
|
||||
output.writeByte(type.id());
|
||||
type.write(tag, output);
|
||||
}
|
||||
|
||||
public void readNamed(@NotNull String name, @NotNull BinaryTag tag) throws IOException {
|
||||
//noinspection unchecked
|
||||
BinaryTagType<BinaryTag> type = (BinaryTagType<BinaryTag>) tag.type();
|
||||
output.writeByte(type.id());
|
||||
output.writeUTF(name);
|
||||
type.write(tag, output);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user