3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-12-25 15:50:10 +01:00

Update OpenNBT (now ViaNBT)

Dieser Commit ist enthalten in:
Nassim Jahnke 2023-10-08 18:44:54 +10:00
Ursprung d8f98945e2
Commit 3e0eb90662
15 geänderte Dateien mit 40 neuen und 1164 gelöschten Zeilen

Datei anzeigen

@ -22,7 +22,7 @@ dependencies {
api(libs.fastutil)
api(libs.flare)
api(libs.flareFastutil)
api(libs.openNBT)
api(libs.nbt)
api(libs.gson)
compileOnlyApi(libs.snakeYaml)

Datei anzeigen

@ -1,216 +0,0 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2020 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 com.viaversion.viaversion.api.minecraft.nbt;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import java.io.BufferedInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.checkerframework.checker.nullness.qual.NonNull;
// Specific Via changes:
// - Use OpenNBT tags
// - Added readString/writeString methods from TagStringIO
// - Has not been updated for the sake of keeping the class simple
/**
* Serialization operations for binary tags.
*/
public final class BinaryTagIO {
private BinaryTagIO() {
}
/**
* Reads a compound tag from {@code path}.
*
* @param path the path
* @return the compound tag
* @throws IOException if an exception was encountered while reading a compound tag
*/
public static @NonNull CompoundTag readPath(final @NonNull Path path) throws IOException {
return readInputStream(Files.newInputStream(path));
}
/**
* Reads a compound tag from an input stream.
*
* @param input the input stream
* @return the compound tag
* @throws IOException if an exception was encountered while reading a compound tag
*/
public static @NonNull CompoundTag readInputStream(final @NonNull InputStream input) throws IOException {
try (final DataInputStream dis = new DataInputStream(input)) {
return readDataInput(dis);
}
}
/**
* Reads a compound tag from {@code path} using GZIP decompression.
*
* @param path the path
* @return the compound tag
* @throws IOException if an exception was encountered while reading a compound tag
*/
public static @NonNull CompoundTag readCompressedPath(final @NonNull Path path) throws IOException {
return readCompressedInputStream(Files.newInputStream(path));
}
/**
* Reads a compound tag from an input stream using GZIP decompression.
*
* @param input the input stream
* @return the compound tag
* @throws IOException if an exception was encountered while reading a compound tag
*/
public static @NonNull CompoundTag readCompressedInputStream(final @NonNull InputStream input) throws IOException {
try (final DataInputStream dis = new DataInputStream(new BufferedInputStream(new GZIPInputStream(input)))) {
return readDataInput(dis);
}
}
/**
* Reads a compound tag from {@code input}.
*
* @param input the input
* @return the compound tag
* @throws IOException if an exception was encountered while reading a compound tag
*/
public static @NonNull CompoundTag readDataInput(final @NonNull DataInput input) throws IOException {
byte type = input.readByte();
if (type != CompoundTag.ID) {
throw new IOException(String.format("Expected root tag to be a CompoundTag, was %s", type));
}
input.skipBytes(input.readUnsignedShort()); // read empty name
final CompoundTag compoundTag = new CompoundTag();
compoundTag.read(input);
return compoundTag;
}
/**
* Writes a compound tag to {@code path}.
*
* @param tag the compound tag
* @param path the path
* @throws IOException if an exception was encountered while writing the compound tag
*/
public static void writePath(final @NonNull CompoundTag tag, final @NonNull Path path) throws IOException {
writeOutputStream(tag, Files.newOutputStream(path));
}
/**
* Writes a compound tag to an output stream.
*
* @param tag the compound tag
* @param output the output stream
* @throws IOException if an exception was encountered while writing the compound tag
*/
public static void writeOutputStream(final @NonNull CompoundTag tag, final @NonNull OutputStream output) throws IOException {
try (final DataOutputStream dos = new DataOutputStream(output)) {
writeDataOutput(tag, dos);
}
}
/**
* Writes a compound tag to {@code path} using GZIP compression.
*
* @param tag the compound tag
* @param path the path
* @throws IOException if an exception was encountered while writing the compound tag
*/
public static void writeCompressedPath(final @NonNull CompoundTag tag, final @NonNull Path path) throws IOException {
writeCompressedOutputStream(tag, Files.newOutputStream(path));
}
/**
* Writes a compound tag to an output stream using GZIP compression.
*
* @param tag the compound tag
* @param output the output stream
* @throws IOException if an exception was encountered while writing the compound tag
*/
public static void writeCompressedOutputStream(final @NonNull CompoundTag tag, final @NonNull OutputStream output) throws IOException {
try (final DataOutputStream dos = new DataOutputStream(new GZIPOutputStream(output))) {
writeDataOutput(tag, dos);
}
}
/**
* Writes a compound tag to {@code output}.
*
* @param tag the compound tag
* @param output the output
* @throws IOException if an exception was encountered while writing the compound tag
*/
public static void writeDataOutput(final @NonNull CompoundTag tag, final @NonNull DataOutput output) throws IOException {
output.writeByte(CompoundTag.ID);
output.writeUTF(""); // write empty name
tag.write(output);
}
/**
* Reads a compound tag from a {@link String}.
*
* @param input the string
* @return the compound tag
* @throws IOException if an exception was encountered while reading a compound tag
*/
public static @NonNull CompoundTag readString(final @NonNull String input) throws IOException {
try {
final CharBuffer buffer = new CharBuffer(input);
final TagStringReader parser = new TagStringReader(buffer);
final CompoundTag tag = parser.compound();
if (buffer.skipWhitespace().hasMore()) {
throw new IOException("Document had trailing content after first CompoundTag");
}
return tag;
} catch (final StringTagParseException ex) {
throw new IOException(ex);
}
}
/**
* Writes a compound tag to a {@link String}.
*
* @param tag the compound tag
* @return the string
* @throws IOException if an exception was encountered while writing the compound tag
*/
public static @NonNull String writeString(final @NonNull CompoundTag tag) throws IOException {
final StringBuilder sb = new StringBuilder();
try (final TagStringWriter emit = new TagStringWriter(sb)) {
emit.writeTag(tag);
}
return sb.toString();
}
}

Datei anzeigen

@ -1,144 +0,0 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2021 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 com.viaversion.viaversion.api.minecraft.nbt;
/**
* A character buffer designed to be inspected by a parser.
*/
final class CharBuffer {
private final CharSequence sequence;
private int index;
CharBuffer(final CharSequence sequence) {
this.sequence = sequence;
}
/**
* Get the character at the current position.
*
* @return The current character
*/
public char peek() {
return this.sequence.charAt(this.index);
}
public char peek(final int offset) {
return this.sequence.charAt(this.index + offset);
}
/**
* Get the current character and advance.
*
* @return current character
*/
public char take() {
return this.sequence.charAt(this.index++);
}
public boolean advance() {
this.index++;
return this.hasMore();
}
public boolean hasMore() {
return this.index < this.sequence.length();
}
public boolean hasMore(final int offset) {
return this.index + offset < this.sequence.length();
}
/**
* Search for the provided token, and advance the reader index past the {@code until} character.
*
* @param until Case-insensitive token
* @return the string starting at the current position (inclusive) and going until the location of {@code until}, exclusive
*/
public CharSequence takeUntil(char until) throws StringTagParseException {
until = Character.toLowerCase(until);
int endIdx = -1;
for (int idx = this.index; idx < this.sequence.length(); ++idx) {
if (this.sequence.charAt(idx) == Tokens.ESCAPE_MARKER) {
idx++;
} else if (Character.toLowerCase(this.sequence.charAt(idx)) == until) {
endIdx = idx;
break;
}
}
if (endIdx == -1) {
throw this.makeError("No occurrence of " + until + " was found");
}
final CharSequence result = this.sequence.subSequence(this.index, endIdx);
this.index = endIdx + 1;
return result;
}
/**
* Assert that the next non-whitespace character is the provided parameter.
*
* <p>If the assertion is successful, the token will be consumed.</p>
*
* @param expectedChar expected character
* @return this
* @throws StringTagParseException if EOF or non-matching value is found
*/
public CharBuffer expect(final char expectedChar) throws StringTagParseException {
this.skipWhitespace();
if (!this.hasMore()) {
throw this.makeError("Expected character '" + expectedChar + "' but got EOF");
}
if (this.peek() != expectedChar) {
throw this.makeError("Expected character '" + expectedChar + "' but got '" + this.peek() + "'");
}
this.take();
return this;
}
/**
* If the next non-whitespace character is {@code token}, advance past it.
*
* <p>This method always consumes whitespace.</p>
*
* @param token next non-whitespace character to query
* @return if the next non-whitespace character is {@code token}
*/
public boolean takeIf(final char token) {
this.skipWhitespace();
if (this.hasMore() && this.peek() == token) {
this.advance();
return true;
}
return false;
}
public CharBuffer skipWhitespace() {
while (this.hasMore() && Character.isWhitespace(this.peek())) this.advance();
return this;
}
public StringTagParseException makeError(final String message) {
return new StringTagParseException(message, this.sequence, this.index);
}
}

Datei anzeigen

@ -1,46 +0,0 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2020 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 com.viaversion.viaversion.api.minecraft.nbt;
import java.io.IOException;
/**
* An exception thrown when parsing a string tag.
*/
class StringTagParseException extends IOException {
private static final long serialVersionUID = -3001637554903912905L;
private final CharSequence buffer;
private final int position;
public StringTagParseException(final String message, final CharSequence buffer, final int position) {
super(message);
this.buffer = buffer;
this.position = position;
}
@Override
public String getMessage() {
return super.getMessage() + "(at position " + this.position + ")";
}
}

Datei anzeigen

@ -1,358 +0,0 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2021 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 com.viaversion.viaversion.api.minecraft.nbt;
import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.DoubleTag;
import com.github.steveice10.opennbt.tag.builtin.FloatTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
import com.github.steveice10.opennbt.tag.builtin.LongTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
// Specific Via changes:
// - Use OpenNBT tags
// - Small byteArray() optimization
// - acceptLegacy = true by default
final class TagStringReader {
private static final int MAX_DEPTH = 512;
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
private static final int[] EMPTY_INT_ARRAY = new int[0];
private static final long[] EMPTY_LONG_ARRAY = new long[0];
private final CharBuffer buffer;
private boolean acceptLegacy = true; // Via - always true
private int depth;
TagStringReader(final CharBuffer buffer) {
this.buffer = buffer;
}
public CompoundTag compound() throws StringTagParseException {
this.buffer.expect(Tokens.COMPOUND_BEGIN);
final CompoundTag compoundTag = new CompoundTag();
if (this.buffer.takeIf(Tokens.COMPOUND_END)) {
return compoundTag;
}
while (this.buffer.hasMore()) {
compoundTag.put(this.key(), this.tag());
if (this.separatorOrCompleteWith(Tokens.COMPOUND_END)) {
return compoundTag;
}
}
throw this.buffer.makeError("Unterminated compound tag!");
}
public ListTag list() throws StringTagParseException {
final ListTag listTag = new ListTag();
this.buffer.expect(Tokens.ARRAY_BEGIN);
final boolean prefixedIndex = this.acceptLegacy && this.buffer.peek() == '0' && this.buffer.peek(1) == ':';
if (!prefixedIndex && this.buffer.takeIf(Tokens.ARRAY_END)) {
return listTag;
}
while (this.buffer.hasMore()) {
if (prefixedIndex) {
this.buffer.takeUntil(':');
}
final Tag next = this.tag();
listTag.add(next);
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
return listTag;
}
}
throw this.buffer.makeError("Reached end of file without end of list tag!");
}
/**
* Similar to a list tag in syntax, but returning a single array tag rather than a list of tags.
*
* @return array-typed tag
*/
public Tag array(char elementType) throws StringTagParseException {
this.buffer.expect(Tokens.ARRAY_BEGIN)
.expect(elementType)
.expect(Tokens.ARRAY_SIGNATURE_SEPARATOR);
elementType = Character.toLowerCase(elementType);
if (elementType == Tokens.TYPE_BYTE) {
return new ByteArrayTag(this.byteArray());
} else if (elementType == Tokens.TYPE_INT) {
return new IntArrayTag(this.intArray());
} else if (elementType == Tokens.TYPE_LONG) {
return new LongArrayTag(this.longArray());
} else {
throw this.buffer.makeError("Type " + elementType + " is not a valid element type in an array!");
}
}
private byte[] byteArray() throws StringTagParseException {
if (this.buffer.takeIf(Tokens.ARRAY_END)) {
return EMPTY_BYTE_ARRAY;
}
final IntList bytes = new IntArrayList(); // Via - no boxing
while (this.buffer.hasMore()) {
final CharSequence value = this.buffer.skipWhitespace().takeUntil(Tokens.TYPE_BYTE);
try {
bytes.add(Byte.parseByte(value.toString())); // Via
} catch (final NumberFormatException ex) {
throw this.buffer.makeError("All elements of a byte array must be bytes!");
}
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
final byte[] result = new byte[bytes.size()];
for (int i = 0; i < bytes.size(); ++i) {
result[i] = (byte) bytes.getInt(i); // Via
}
return result;
}
}
throw this.buffer.makeError("Reached end of document without array close");
}
private int[] intArray() throws StringTagParseException {
if (this.buffer.takeIf(Tokens.ARRAY_END)) {
return EMPTY_INT_ARRAY;
}
final IntStream.Builder builder = IntStream.builder();
while (this.buffer.hasMore()) {
final Tag value = this.tag();
if (!(value instanceof IntTag)) {
throw this.buffer.makeError("All elements of an int array must be ints!");
}
builder.add(((NumberTag) value).asInt());
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
return builder.build().toArray();
}
}
throw this.buffer.makeError("Reached end of document without array close");
}
private long[] longArray() throws StringTagParseException {
if (this.buffer.takeIf(Tokens.ARRAY_END)) {
return EMPTY_LONG_ARRAY;
}
final LongStream.Builder longs = LongStream.builder();
while (this.buffer.hasMore()) {
final CharSequence value = this.buffer.skipWhitespace().takeUntil(Tokens.TYPE_LONG);
try {
longs.add(Long.parseLong(value.toString()));
} catch (final NumberFormatException ex) {
throw this.buffer.makeError("All elements of a long array must be longs!");
}
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
return longs.build().toArray();
}
}
throw this.buffer.makeError("Reached end of document without array close");
}
public String key() throws StringTagParseException {
this.buffer.skipWhitespace();
final char starChar = this.buffer.peek();
try {
if (starChar == Tokens.SINGLE_QUOTE || starChar == Tokens.DOUBLE_QUOTE) {
return unescape(this.buffer.takeUntil(this.buffer.take()).toString());
}
final StringBuilder builder = new StringBuilder();
while (this.buffer.hasMore()) {
final char peek = this.buffer.peek();
if (!Tokens.id(peek)) {
if (this.acceptLegacy) {
// In legacy format, a key is any non-colon character, with escapes allowed
if (peek == Tokens.ESCAPE_MARKER) {
this.buffer.take(); // skip
continue;
} else if (peek != Tokens.COMPOUND_KEY_TERMINATOR) {
builder.append(this.buffer.take());
continue;
}
}
break;
}
builder.append(this.buffer.take());
}
return builder.toString();
} finally {
this.buffer.expect(Tokens.COMPOUND_KEY_TERMINATOR);
}
}
public Tag tag() throws StringTagParseException {
if (this.depth++ > MAX_DEPTH) {
throw this.buffer.makeError("Exceeded maximum allowed depth of " + MAX_DEPTH + " when reading tag");
}
try {
final char startToken = this.buffer.skipWhitespace().peek();
switch (startToken) {
case Tokens.COMPOUND_BEGIN:
return this.compound();
case Tokens.ARRAY_BEGIN:
// Maybe add in a legacy-only mode to read those?
if (this.buffer.hasMore(2) && this.buffer.peek(2) == ';') { // we know we're an array tag
return this.array(this.buffer.peek(1));
} else {
return this.list();
}
case Tokens.SINGLE_QUOTE:
case Tokens.DOUBLE_QUOTE:
// definitely a string tag
this.buffer.advance();
return new StringTag(unescape(this.buffer.takeUntil(startToken).toString()));
default: // scalar
return this.scalar();
}
} finally {
this.depth--;
}
}
/**
* A tag that is definitely some sort of scalar.
*
* <p>Does not detect quoted strings, so those should have been parsed already.</p>
*
* @return a parsed tag
*/
private Tag scalar() {
final StringBuilder builder = new StringBuilder();
int noLongerNumericAt = -1;
while (this.buffer.hasMore()) {
char current = this.buffer.peek();
if (current == '\\') { // escape -- we are significantly more lenient than original format at the moment
this.buffer.advance();
current = this.buffer.take();
} else if (Tokens.id(current)) {
this.buffer.advance();
} else { // end of value
break;
}
builder.append(current);
if (noLongerNumericAt == -1 && !Tokens.numeric(current)) {
noLongerNumericAt = builder.length();
}
}
final int length = builder.length();
final String built = builder.toString();
if (noLongerNumericAt == length) {
final char last = built.charAt(length - 1);
try {
switch (Character.toLowerCase(last)) { // try to read and return as a number
case Tokens.TYPE_BYTE:
return new ByteTag(Byte.parseByte(built.substring(0, length - 1)));
case Tokens.TYPE_SHORT:
return new ShortTag(Short.parseShort(built.substring(0, length - 1)));
case Tokens.TYPE_INT:
return new IntTag(Integer.parseInt(built.substring(0, length - 1)));
case Tokens.TYPE_LONG:
return new LongTag(Long.parseLong(built.substring(0, length - 1)));
case Tokens.TYPE_FLOAT:
final float floatValue = Float.parseFloat(built.substring(0, length - 1));
if (Float.isFinite(floatValue)) { // don't accept NaN and Infinity
return new FloatTag(floatValue);
}
break;
case Tokens.TYPE_DOUBLE:
final double doubleValue = Double.parseDouble(built.substring(0, length - 1));
if (Double.isFinite(doubleValue)) { // don't accept NaN and Infinity
return new DoubleTag(doubleValue);
}
break;
}
} catch (final NumberFormatException ignored) {
}
} else if (noLongerNumericAt == -1) { // if we run out of content without an explicit value separator, then we're either an integer or string tag -- all others have a character at the end
try {
return new IntTag(Integer.parseInt(built));
} catch (final NumberFormatException ex) {
if (built.indexOf('.') != -1) {
try {
return new DoubleTag(Double.parseDouble(built));
} catch (final NumberFormatException ex2) {
// ignore
}
}
}
}
if (built.equalsIgnoreCase(Tokens.LITERAL_TRUE)) {
return new ByteTag((byte) 1);
} else if (built.equalsIgnoreCase(Tokens.LITERAL_FALSE)) {
return new ByteTag((byte) 0);
}
return new StringTag(built);
}
private boolean separatorOrCompleteWith(final char endCharacter) throws StringTagParseException {
if (this.buffer.takeIf(endCharacter)) {
return true;
}
this.buffer.expect(Tokens.VALUE_SEPARATOR);
return this.buffer.takeIf(endCharacter);
}
/**
* Remove simple escape sequences from a string.
*
* @param withEscapes input string with escapes
* @return string with escapes processed
*/
private static String unescape(final String withEscapes) {
int escapeIdx = withEscapes.indexOf(Tokens.ESCAPE_MARKER);
if (escapeIdx == -1) { // nothing to unescape
return withEscapes;
}
int lastEscape = 0;
final StringBuilder output = new StringBuilder(withEscapes.length());
do {
output.append(withEscapes, lastEscape, escapeIdx);
lastEscape = escapeIdx + 1;
} while ((escapeIdx = withEscapes.indexOf(Tokens.ESCAPE_MARKER, lastEscape + 1)) != -1); // add one extra character to make sure we don't include escaped backslashes
output.append(withEscapes.substring(lastEscape));
return output.toString();
}
public void legacy(final boolean acceptLegacy) {
this.acceptLegacy = acceptLegacy;
}
}

Datei anzeigen

@ -1,261 +0,0 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2020 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 com.viaversion.viaversion.api.minecraft.nbt;
import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.DoubleTag;
import com.github.steveice10.opennbt.tag.builtin.FloatTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
import com.github.steveice10.opennbt.tag.builtin.LongTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
// Specific Via changes:
// - Use OpenNBT tags
// - Has not been updated to support pretty printing and legacy writing since that is not needed
/**
* An emitter for the SNBT format.
*
* <p>Details on the format are described in the package documentation.</p>
*/
final class TagStringWriter implements AutoCloseable {
private final Appendable out;
private int level;
/**
* Whether a {@link Tokens#VALUE_SEPARATOR} needs to be printed before the beginning of the next object.
*/
private boolean needsSeparator;
public TagStringWriter(final Appendable out) {
this.out = out;
}
// NBT-specific
public TagStringWriter writeTag(final Tag tag) throws IOException {
if (tag instanceof CompoundTag) {
return this.writeCompound((CompoundTag) tag);
} else if (tag instanceof ListTag) {
return this.writeList((ListTag) tag);
} else if (tag instanceof ByteArrayTag) {
return this.writeByteArray((ByteArrayTag) tag);
} else if (tag instanceof IntArrayTag) {
return this.writeIntArray((IntArrayTag) tag);
} else if (tag instanceof LongArrayTag) {
return this.writeLongArray((LongArrayTag) tag);
} else if (tag instanceof StringTag) {
return this.value(((StringTag) tag).getValue(), Tokens.EOF);
} else if (tag instanceof ByteTag) {
return this.value(Byte.toString(((NumberTag) tag).asByte()), Tokens.TYPE_BYTE);
} else if (tag instanceof ShortTag) {
return this.value(Short.toString(((NumberTag) tag).asShort()), Tokens.TYPE_SHORT);
} else if (tag instanceof IntTag) {
return this.value(Integer.toString(((NumberTag) tag).asInt()), Tokens.TYPE_INT);
} else if (tag instanceof LongTag) {
return this.value(Long.toString(((NumberTag) tag).asLong()), Character.toUpperCase(Tokens.TYPE_LONG)); // special case
} else if (tag instanceof FloatTag) {
return this.value(Float.toString(((NumberTag) tag).asFloat()), Tokens.TYPE_FLOAT);
} else if (tag instanceof DoubleTag) {
return this.value(Double.toString(((NumberTag) tag).asDouble()), Tokens.TYPE_DOUBLE);
} else {
throw new IOException("Unknown tag type: " + tag.getClass().getSimpleName());
// unknown!
}
}
private TagStringWriter writeCompound(final CompoundTag tag) throws IOException {
this.beginCompound();
for (final Map.Entry<String, Tag> entry : tag.entrySet()) {
this.key(entry.getKey());
this.writeTag(entry.getValue());
}
this.endCompound();
return this;
}
private TagStringWriter writeList(final ListTag tag) throws IOException {
this.beginList();
for (final Tag el : tag) {
this.printAndResetSeparator();
this.writeTag(el);
}
this.endList();
return this;
}
private TagStringWriter writeByteArray(final ByteArrayTag tag) throws IOException {
this.beginArray(Tokens.TYPE_BYTE);
final byte[] value = tag.getValue();
for (int i = 0, length = value.length; i < length; i++) {
this.printAndResetSeparator();
this.value(Byte.toString(value[i]), Tokens.TYPE_BYTE);
}
this.endArray();
return this;
}
private TagStringWriter writeIntArray(final IntArrayTag tag) throws IOException {
this.beginArray(Tokens.TYPE_INT);
final int[] value = tag.getValue();
for (int i = 0, length = value.length; i < length; i++) {
this.printAndResetSeparator();
this.value(Integer.toString(value[i]), Tokens.TYPE_INT);
}
this.endArray();
return this;
}
private TagStringWriter writeLongArray(final LongArrayTag tag) throws IOException {
this.beginArray(Tokens.TYPE_LONG);
final long[] value = tag.getValue();
for (int i = 0, length = value.length; i < length; i++) {
this.printAndResetSeparator();
this.value(Long.toString(value[i]), Tokens.TYPE_LONG);
}
this.endArray();
return this;
}
// Value types
public TagStringWriter beginCompound() throws IOException {
this.printAndResetSeparator();
this.level++;
this.out.append(Tokens.COMPOUND_BEGIN);
return this;
}
public TagStringWriter endCompound() throws IOException {
this.out.append(Tokens.COMPOUND_END);
this.level--;
this.needsSeparator = true;
return this;
}
public TagStringWriter key(final String key) throws IOException {
this.printAndResetSeparator();
this.writeMaybeQuoted(key, false);
this.out.append(Tokens.COMPOUND_KEY_TERMINATOR);
return this;
}
public TagStringWriter value(final String value, final char valueType) throws IOException {
if (valueType == Tokens.EOF) { // string doesn't have its type
this.writeMaybeQuoted(value, true);
} else {
this.out.append(value);
if (valueType != Tokens.TYPE_INT) {
this.out.append(valueType);
}
}
this.needsSeparator = true;
return this;
}
public TagStringWriter beginList() throws IOException {
this.printAndResetSeparator();
this.level++;
this.out.append(Tokens.ARRAY_BEGIN);
return this;
}
public TagStringWriter endList() throws IOException {
this.out.append(Tokens.ARRAY_END);
this.level--;
this.needsSeparator = true;
return this;
}
private TagStringWriter beginArray(final char type) throws IOException {
this.beginList()
.out.append(type)
.append(Tokens.ARRAY_SIGNATURE_SEPARATOR);
return this;
}
private TagStringWriter endArray() throws IOException {
return this.endList();
}
private void writeMaybeQuoted(final String content, boolean requireQuotes) throws IOException {
if (!requireQuotes) {
for (int i = 0; i < content.length(); ++i) {
if (!Tokens.id(content.charAt(i))) {
requireQuotes = true;
break;
}
}
}
if (requireQuotes) {
this.out.append(Tokens.DOUBLE_QUOTE);
this.out.append(escape(content, Tokens.DOUBLE_QUOTE));
this.out.append(Tokens.DOUBLE_QUOTE);
} else {
this.out.append(content);
}
}
private static String escape(final String content, final char quoteChar) {
final StringBuilder output = new StringBuilder(content.length());
for (int i = 0; i < content.length(); ++i) {
final char c = content.charAt(i);
if (c == quoteChar || c == '\\') {
output.append(Tokens.ESCAPE_MARKER);
}
output.append(c);
}
return output.toString();
}
private void printAndResetSeparator() throws IOException {
if (this.needsSeparator) {
this.out.append(Tokens.VALUE_SEPARATOR);
this.needsSeparator = false;
}
}
@Override
public void close() throws IOException {
if (this.level != 0) {
throw new IllegalStateException("Document finished with unbalanced start and end objects");
}
if (this.out instanceof Writer) {
((Writer) this.out).flush();
}
}
}

Datei anzeigen

@ -1,89 +0,0 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2021 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 com.viaversion.viaversion.api.minecraft.nbt;
final class Tokens {
// Compounds
static final char COMPOUND_BEGIN = '{';
static final char COMPOUND_END = '}';
static final char COMPOUND_KEY_TERMINATOR = ':';
// Arrays
static final char ARRAY_BEGIN = '[';
static final char ARRAY_END = ']';
static final char ARRAY_SIGNATURE_SEPARATOR = ';';
static final char VALUE_SEPARATOR = ',';
static final char SINGLE_QUOTE = '\'';
static final char DOUBLE_QUOTE = '"';
static final char ESCAPE_MARKER = '\\';
static final char TYPE_BYTE = 'b';
static final char TYPE_SHORT = 's';
static final char TYPE_INT = 'i'; // array only
static final char TYPE_LONG = 'l';
static final char TYPE_FLOAT = 'f';
static final char TYPE_DOUBLE = 'd';
static final String LITERAL_TRUE = "true";
static final String LITERAL_FALSE = "false";
static final String NEWLINE = System.getProperty("line.separator", "\n");
static final char EOF = '\0';
private Tokens() {
}
/**
* Return if a character is a valid component in an identifier.
*
* <p>An identifier character must match the expression {@code [a-zA-Z0-9_+.-]}</p>
*
* @param c the character
* @return identifier
*/
static boolean id(final char c) {
return (c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9')
|| c == '-' || c == '_'
|| c == '.' || c == '+';
}
/**
* Return whether a character could be at some position in a number.
*
* <p>A string passing this check does not necessarily mean it is syntactically valid.</p>
*
* @param c character to check
* @return if possibly part of a number
*/
static boolean numeric(final char c) {
return (c >= '0' && c <= '9') // digit
|| c == '+' || c == '-' // positive or negative
|| c == 'e' || c == 'E' // exponent
|| c == '.'; // decimal
}
}

Datei anzeigen

@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data;
import com.github.steveice10.opennbt.stringified.SNBT;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
@ -27,12 +28,10 @@ import com.google.gson.JsonPrimitive;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import java.io.IOException;
public class ComponentRewriter1_13<C extends ClientboundPacketType> extends ComponentRewriter<C> {
@ -54,7 +53,7 @@ public class ComponentRewriter1_13<C extends ClientboundPacketType> extends Comp
CompoundTag tag;
try {
tag = BinaryTagIO.readString(text);
tag = SNBT.deserializeCompoundTag(text);
} catch (Exception e) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("Error reading NBT in show_item:" + text);
@ -86,10 +85,10 @@ public class ComponentRewriter1_13<C extends ClientboundPacketType> extends Comp
array.add(object);
String serializedNBT;
try {
serializedNBT = BinaryTagIO.writeString(tag);
serializedNBT = SNBT.serialize(tag);
object.addProperty("text", serializedNBT);
hoverEvent.add("value", array);
} catch (IOException e) {
} catch (Exception e) {
Via.getPlatform().getLogger().warning("Error writing NBT in show_item:" + text);
e.printStackTrace();
}

Datei anzeigen

@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.data;
import com.github.steveice10.opennbt.NBTIO;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
@ -24,7 +25,6 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ -40,7 +40,7 @@ public class MappingData extends MappingDataBase {
@Override
public void loadExtras(final CompoundTag data) {
try {
dimensionRegistry = BinaryTagIO.readInputStream(MappingDataLoader.getResource("dimension-registry-1.16.2.nbt"));
dimensionRegistry = NBTIO.readTag(MappingDataLoader.getResource("dimension-registry-1.16.2.nbt"));
} catch (final IOException e) {
Via.getPlatform().getLogger().severe("Error loading dimension registry:");
e.printStackTrace();

Datei anzeigen

@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.protocols.protocol1_19_1to1_19;
import com.github.steveice10.opennbt.stringified.SNBT;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
@ -28,7 +29,6 @@ import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ProfileKey;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@ -46,7 +46,6 @@ import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.storage.NonceSto
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPackets1_19;
import com.viaversion.viaversion.util.CipherUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -83,11 +82,7 @@ public final class Protocol1_19_1To1_19 extends AbstractProtocol<ClientboundPack
private static final CompoundTag CHAT_REGISTRY;
static {
try {
CHAT_REGISTRY = BinaryTagIO.readString(CHAT_REGISTRY_SNBT).get("minecraft:chat_type");
} catch (final IOException e) {
throw new RuntimeException(e);
}
CHAT_REGISTRY = SNBT.deserializeCompoundTag(CHAT_REGISTRY_SNBT).get("minecraft:chat_type");
}
public Protocol1_19_1To1_19() {

Datei anzeigen

@ -17,10 +17,10 @@
*/
package com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.data;
import com.github.steveice10.opennbt.NBTIO;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import java.io.IOException;
public final class MappingData extends MappingDataBase {
@ -34,7 +34,7 @@ public final class MappingData extends MappingDataBase {
@Override
protected void loadExtras(final CompoundTag data) {
try {
damageTypesRegistry = BinaryTagIO.readInputStream(MappingDataLoader.getResource("damage-types-1.19.4.nbt"));
damageTypesRegistry = NBTIO.readTag(MappingDataLoader.getResource("damage-types-1.19.4.nbt"));
} catch (final IOException e) {
throw new RuntimeException(e);
}

Datei anzeigen

@ -17,13 +17,13 @@
*/
package com.viaversion.viaversion.protocols.protocol1_19to1_18_2.data;
import com.github.steveice10.opennbt.NBTIO;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.io.IOException;
@ -40,7 +40,7 @@ public final class MappingData extends MappingDataBase {
@Override
protected void loadExtras(final CompoundTag daata) {
try {
final ListTag chatTypes = BinaryTagIO.readInputStream(MappingDataLoader.getResource("chat-types-1.19.nbt")).get("values");
final ListTag chatTypes = NBTIO.readTag(MappingDataLoader.getResource("chat-types-1.19.nbt")).get("values");
for (final Tag chatType : chatTypes) {
final CompoundTag chatTypeCompound = (CompoundTag) chatType;
final NumberTag idTag = chatTypeCompound.get("id");

Datei anzeigen

@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets;
import com.github.steveice10.opennbt.stringified.SNBT;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
@ -31,7 +32,6 @@ import com.viaversion.viaversion.api.minecraft.entities.Entity1_19Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
@ -46,7 +46,6 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.Dimensio
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
@ -82,11 +81,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_18,
public static final CompoundTag CHAT_REGISTRY;
static {
try {
CHAT_REGISTRY = BinaryTagIO.readString(CHAT_REGISTRY_SNBT).get("minecraft:chat_type");
} catch (final IOException e) {
throw new RuntimeException(e);
}
CHAT_REGISTRY = SNBT.deserializeCompoundTag(CHAT_REGISTRY_SNBT).get("minecraft:chat_type");
}
public EntityPackets(final Protocol1_19To1_18_2 protocol) {

Datei anzeigen

@ -21,35 +21,36 @@ import java.io.IOException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO.readString;
import static com.github.steveice10.opennbt.stringified.SNBT.deserialize;
import static com.github.steveice10.opennbt.stringified.SNBT.deserializeCompoundTag;
public class NBTTagTest {
@Test
void test() throws IOException {
readString("{id:5}");
readString("{id:5b}");
readString("{id:test,test:1,}");
readString("{id:[3.2,64.5,129.5]}");
readString("{id:[I;1,2, 3, 4,5]}"); // >=1.11
readString("{id:1b,b:true}");
readString("{id:[L;1l,2L,3L]}"); // >=1.11
readString("{id:[I;1i,2I,3I]}");
readString("{id:'minecraft:stone'}"); // >=1.13
readString("{id:1,id:2}");
readString("{id:-20b,test:3.19f}");
readString("{id:[I;1,2,3,]}");
readString("{id:[1,2,3,]}");
deserialize("{id:5}");
deserialize("{id:5b}");
deserialize("{id:test,test:1,}");
deserialize("{id:[3.2,64.5,129.5]}");
deserialize("{id:[I;1,2, 3, 4,5]}"); // >=1.11
deserialize("{id:1b,b:true}");
deserialize("{id:[L;1l,2L,3L]}"); // >=1.11
deserialize("{id:[I;1i,2I,3I]}");
deserialize("{id:'minecraft:stone'}"); // >=1.13
deserialize("{id:1,id:2}");
deserialize("{id:-20b,test:3.19f}");
deserialize("{id:[I;1,2,3,]}");
deserialize("{id:[1,2,3,]}");
Assertions.assertEquals("0da", readString("{id:0da}").get("id").getValue());
Assertions.assertEquals("NaNd", readString("{id:NaNd}").get("id").getValue());
Assertions.assertEquals("Infinityd", readString("{id:Infinityd}").get("id").getValue());
Assertions.assertEquals("2147483649", readString("{id:9000b,thisisastring:2147483649}").get("thisisastring").getValue());
Assertions.assertEquals((byte) 1, readString("{thisisabyte:true}").get("thisisabyte").getValue());
Assertions.assertEquals((byte) 0, readString("{thisisabyte:false}").get("thisisabyte").getValue());
Assertions.assertEquals("0da", deserializeCompoundTag("{id:0da}").get("id").getValue());
Assertions.assertEquals("NaNd", deserializeCompoundTag("{id:NaNd}").get("id").getValue());
Assertions.assertEquals("Infinityd", deserializeCompoundTag("{id:Infinityd}").get("id").getValue());
Assertions.assertEquals("2147483649", deserializeCompoundTag("{id:9000b,thisisastring:2147483649}").get("thisisastring").getValue());
Assertions.assertEquals((byte) 1, deserializeCompoundTag("{thisisabyte:true}").get("thisisabyte").getValue());
Assertions.assertEquals((byte) 0, deserializeCompoundTag("{thisisabyte:false}").get("thisisabyte").getValue());
//TODO fix legacy < 1.12
// readString("{id:minecraft:stone}");
// readString("{id:[1,2, 3, 4,5]}");
// deserialize("{id:minecraft:stone}");
// deserialize("{id:[1,2, 3, 4,5]}");
}
}

Datei anzeigen

@ -6,7 +6,7 @@ adventure = "4.14.0"
gson = "2.10.1"
fastutil = "8.5.12"
flare = "2.0.1"
openNBT = "2.1.3"
nbt = "3.0.0"
# Common provided
netty = "4.0.20.Final"
@ -37,7 +37,7 @@ gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil" }
flare = { group = "space.vectrix.flare", name = "flare", version.ref = "flare" }
flareFastutil = { group = "space.vectrix.flare", name = "flare-fastutil", version.ref = "flare" }
openNBT = { group = "com.viaversion", name = "opennbt", version.ref = "openNBT" }
nbt = { group = "com.viaversion", name = "nbt", version.ref = "nbt" }
netty = { group = "io.netty", name = "netty-all", version.ref = "netty" }
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }