Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-08 17:20:24 +01:00
Update adventure nbt i/o
Dieser Commit ist enthalten in:
Ursprung
12e2be40e8
Commit
88165088a9
@ -39,8 +39,12 @@ import java.nio.file.Path;
|
|||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
// Specific Via changes:
|
||||||
|
// - Use OpenNBT tags
|
||||||
|
// - Added readString/writeString methods from TagStringIO
|
||||||
|
// - Has not been updated for the sake of keeping the class simple
|
||||||
/**
|
/**
|
||||||
* See https://github.com/KyoriPowered/adventure.
|
* Serialization operations for binary tags.
|
||||||
*/
|
*/
|
||||||
public final class BinaryTagIO {
|
public final class BinaryTagIO {
|
||||||
private BinaryTagIO() {
|
private BinaryTagIO() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of adventure, licensed under the MIT License.
|
* This file is part of adventure, licensed under the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2020 KyoriPowered
|
* Copyright (c) 2017-2021 KyoriPowered
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -23,7 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.api.minecraft.nbt;
|
package com.viaversion.viaversion.api.minecraft.nbt;
|
||||||
|
|
||||||
/* package */ final class CharBuffer {
|
/**
|
||||||
|
* A character buffer designed to be inspected by a parser.
|
||||||
|
*/
|
||||||
|
final class CharBuffer {
|
||||||
private final CharSequence sequence;
|
private final CharSequence sequence;
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
@ -32,7 +35,7 @@ package com.viaversion.viaversion.api.minecraft.nbt;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the character at the current position
|
* Get the character at the current position.
|
||||||
*
|
*
|
||||||
* @return The current character
|
* @return The current character
|
||||||
*/
|
*/
|
||||||
@ -45,7 +48,7 @@ package com.viaversion.viaversion.api.minecraft.nbt;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current character and advance
|
* Get the current character and advance.
|
||||||
*
|
*
|
||||||
* @return current character
|
* @return current character
|
||||||
*/
|
*/
|
||||||
@ -62,6 +65,10 @@ package com.viaversion.viaversion.api.minecraft.nbt;
|
|||||||
return this.index < this.sequence.length();
|
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.
|
* Search for the provided token, and advance the reader index past the {@code until} character.
|
||||||
*
|
*
|
||||||
@ -109,6 +116,23 @@ package com.viaversion.viaversion.api.minecraft.nbt;
|
|||||||
return this;
|
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() {
|
public CharBuffer skipWhitespace() {
|
||||||
while (this.hasMore() && Character.isWhitespace(this.peek())) this.advance();
|
while (this.hasMore() && Character.isWhitespace(this.peek())) this.advance();
|
||||||
return this;
|
return this;
|
||||||
|
@ -26,9 +26,9 @@ package com.viaversion.viaversion.api.minecraft.nbt;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An exception thrown when parsing a string tag
|
* An exception thrown when parsing a string tag.
|
||||||
*/
|
*/
|
||||||
/* package */ class StringTagParseException extends IOException {
|
class StringTagParseException extends IOException {
|
||||||
private static final long serialVersionUID = -3001637554903912905L;
|
private static final long serialVersionUID = -3001637554903912905L;
|
||||||
private final CharSequence buffer;
|
private final CharSequence buffer;
|
||||||
private final int position;
|
private final int position;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of adventure, licensed under the MIT License.
|
* This file is part of adventure, licensed under the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2020 KyoriPowered
|
* Copyright (c) 2017-2021 KyoriPowered
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -37,33 +37,39 @@ import com.github.steveice10.opennbt.tag.builtin.NumberTag;
|
|||||||
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
|
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
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.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.IntStream;
|
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];
|
||||||
|
|
||||||
/**
|
|
||||||
* See https://github.com/KyoriPowered/adventure.
|
|
||||||
*/
|
|
||||||
/* package */ final class TagStringReader {
|
|
||||||
private final CharBuffer buffer;
|
private final CharBuffer buffer;
|
||||||
|
private boolean acceptLegacy = true;
|
||||||
|
private int depth;
|
||||||
|
|
||||||
public TagStringReader(final CharBuffer buffer) {
|
TagStringReader(final CharBuffer buffer) {
|
||||||
this.buffer = buffer;
|
this.buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag compound() throws StringTagParseException {
|
public CompoundTag compound() throws StringTagParseException {
|
||||||
this.buffer.expect(Tokens.COMPOUND_BEGIN);
|
this.buffer.expect(Tokens.COMPOUND_BEGIN);
|
||||||
final CompoundTag compoundTag = new CompoundTag();
|
final CompoundTag compoundTag = new CompoundTag();
|
||||||
if (this.buffer.peek() == Tokens.COMPOUND_END) {
|
if (this.buffer.takeIf(Tokens.COMPOUND_END)) {
|
||||||
this.buffer.take();
|
|
||||||
return compoundTag;
|
return compoundTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (this.buffer.hasMore()) {
|
while (this.buffer.hasMore()) {
|
||||||
final String key = this.key();
|
compoundTag.put(this.key(), this.tag());
|
||||||
final Tag tag = this.tag();
|
|
||||||
compoundTag.put(key, tag);
|
|
||||||
if (this.separatorOrCompleteWith(Tokens.COMPOUND_END)) {
|
if (this.separatorOrCompleteWith(Tokens.COMPOUND_END)) {
|
||||||
return compoundTag;
|
return compoundTag;
|
||||||
}
|
}
|
||||||
@ -74,13 +80,11 @@ import java.util.stream.IntStream;
|
|||||||
public ListTag list() throws StringTagParseException {
|
public ListTag list() throws StringTagParseException {
|
||||||
final ListTag listTag = new ListTag();
|
final ListTag listTag = new ListTag();
|
||||||
this.buffer.expect(Tokens.ARRAY_BEGIN);
|
this.buffer.expect(Tokens.ARRAY_BEGIN);
|
||||||
final boolean prefixedIndex = this.buffer.peek() == '0' && this.buffer.peek(1) == ':';
|
final boolean prefixedIndex = this.acceptLegacy && this.buffer.peek() == '0' && this.buffer.peek(1) == ':';
|
||||||
while (this.buffer.hasMore()) {
|
if (!prefixedIndex && this.buffer.takeIf(Tokens.ARRAY_END)) {
|
||||||
if (this.buffer.peek() == Tokens.ARRAY_END) {
|
|
||||||
this.buffer.advance();
|
|
||||||
return listTag;
|
return listTag;
|
||||||
}
|
}
|
||||||
|
while (this.buffer.hasMore()) {
|
||||||
if (prefixedIndex) {
|
if (prefixedIndex) {
|
||||||
this.buffer.takeUntil(':');
|
this.buffer.takeUntil(':');
|
||||||
}
|
}
|
||||||
@ -99,11 +103,12 @@ import java.util.stream.IntStream;
|
|||||||
*
|
*
|
||||||
* @return array-typed tag
|
* @return array-typed tag
|
||||||
*/
|
*/
|
||||||
public Tag array(final char elementType) throws StringTagParseException {
|
public Tag array(char elementType) throws StringTagParseException {
|
||||||
this.buffer.expect(Tokens.ARRAY_BEGIN)
|
this.buffer.expect(Tokens.ARRAY_BEGIN)
|
||||||
.expect(elementType)
|
.expect(elementType)
|
||||||
.expect(Tokens.ARRAY_SIGNATURE_SEPARATOR);
|
.expect(Tokens.ARRAY_SIGNATURE_SEPARATOR);
|
||||||
|
|
||||||
|
elementType = Character.toLowerCase(elementType);
|
||||||
if (elementType == Tokens.TYPE_BYTE) {
|
if (elementType == Tokens.TYPE_BYTE) {
|
||||||
return new ByteArrayTag(this.byteArray());
|
return new ByteArrayTag(this.byteArray());
|
||||||
} else if (elementType == Tokens.TYPE_INT) {
|
} else if (elementType == Tokens.TYPE_INT) {
|
||||||
@ -116,11 +121,15 @@ import java.util.stream.IntStream;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private byte[] byteArray() throws StringTagParseException {
|
private byte[] byteArray() throws StringTagParseException {
|
||||||
final List<Byte> bytes = new ArrayList<>();
|
if (this.buffer.takeIf(Tokens.ARRAY_END)) {
|
||||||
|
return EMPTY_BYTE_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
final IntList bytes = new IntArrayList();
|
||||||
while (this.buffer.hasMore()) {
|
while (this.buffer.hasMore()) {
|
||||||
final CharSequence value = this.buffer.skipWhitespace().takeUntil(Tokens.TYPE_BYTE);
|
final CharSequence value = this.buffer.skipWhitespace().takeUntil(Tokens.TYPE_BYTE);
|
||||||
try {
|
try {
|
||||||
bytes.add(Byte.valueOf(value.toString()));
|
bytes.add(Byte.parseByte(value.toString()));
|
||||||
} catch (final NumberFormatException ex) {
|
} catch (final NumberFormatException ex) {
|
||||||
throw this.buffer.makeError("All elements of a byte array must be bytes!");
|
throw this.buffer.makeError("All elements of a byte array must be bytes!");
|
||||||
}
|
}
|
||||||
@ -128,7 +137,7 @@ import java.util.stream.IntStream;
|
|||||||
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
|
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
|
||||||
final byte[] result = new byte[bytes.size()];
|
final byte[] result = new byte[bytes.size()];
|
||||||
for (int i = 0; i < bytes.size(); ++i) {
|
for (int i = 0; i < bytes.size(); ++i) {
|
||||||
result[i] = bytes.get(i);
|
result[i] = (byte) bytes.getInt(i);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -137,6 +146,10 @@ import java.util.stream.IntStream;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int[] intArray() throws StringTagParseException {
|
private int[] intArray() throws StringTagParseException {
|
||||||
|
if (this.buffer.takeIf(Tokens.ARRAY_END)) {
|
||||||
|
return EMPTY_INT_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
final IntStream.Builder builder = IntStream.builder();
|
final IntStream.Builder builder = IntStream.builder();
|
||||||
while (this.buffer.hasMore()) {
|
while (this.buffer.hasMore()) {
|
||||||
final Tag value = this.tag();
|
final Tag value = this.tag();
|
||||||
@ -152,21 +165,21 @@ import java.util.stream.IntStream;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long[] longArray() throws StringTagParseException {
|
private long[] longArray() throws StringTagParseException {
|
||||||
final List<Long> longs = new ArrayList<>();
|
if (this.buffer.takeIf(Tokens.ARRAY_END)) {
|
||||||
|
return EMPTY_LONG_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
final LongStream.Builder longs = LongStream.builder();
|
||||||
while (this.buffer.hasMore()) {
|
while (this.buffer.hasMore()) {
|
||||||
final CharSequence value = this.buffer.skipWhitespace().takeUntil(Tokens.TYPE_LONG);
|
final CharSequence value = this.buffer.skipWhitespace().takeUntil(Tokens.TYPE_LONG);
|
||||||
try {
|
try {
|
||||||
longs.add(Long.valueOf(value.toString()));
|
longs.add(Long.parseLong(value.toString()));
|
||||||
} catch (final NumberFormatException ex) {
|
} catch (final NumberFormatException ex) {
|
||||||
throw this.buffer.makeError("All elements of a long array must be longs!");
|
throw this.buffer.makeError("All elements of a long array must be longs!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
|
if (this.separatorOrCompleteWith(Tokens.ARRAY_END)) {
|
||||||
final long[] result = new long[longs.size()];
|
return longs.build().toArray();
|
||||||
for (int i = 0; i < longs.size(); ++i) {
|
|
||||||
result[i] = longs.get(i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw this.buffer.makeError("Reached end of document without array close");
|
throw this.buffer.makeError("Reached end of document without array close");
|
||||||
@ -181,7 +194,21 @@ import java.util.stream.IntStream;
|
|||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
while (this.buffer.peek() != ':') { // DO NOT CHECK FOR CHARACTER VALIDITY; LEGACY NBT ALLOWS ANY CHARACTER, EVEN WHEN UNQUOTED
|
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());
|
builder.append(this.buffer.take());
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
@ -191,12 +218,17 @@ import java.util.stream.IntStream;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Tag tag() throws StringTagParseException {
|
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();
|
final char startToken = this.buffer.skipWhitespace().peek();
|
||||||
switch (startToken) {
|
switch (startToken) {
|
||||||
case Tokens.COMPOUND_BEGIN:
|
case Tokens.COMPOUND_BEGIN:
|
||||||
return this.compound();
|
return this.compound();
|
||||||
case Tokens.ARRAY_BEGIN:
|
case Tokens.ARRAY_BEGIN:
|
||||||
if (this.buffer.peek(2) == ';') { // we know we're an array tag
|
// 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));
|
return this.array(this.buffer.peek(1));
|
||||||
} else {
|
} else {
|
||||||
return this.list();
|
return this.list();
|
||||||
@ -209,12 +241,15 @@ import java.util.stream.IntStream;
|
|||||||
default: // scalar
|
default: // scalar
|
||||||
return this.scalar();
|
return this.scalar();
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
this.depth--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A tag that is definitely some sort of scalar
|
* A tag that is definitely some sort of scalar.
|
||||||
*
|
*
|
||||||
* <p>Does not detect quoted strings, so </p>
|
* <p>Does not detect quoted strings, so those should have been parsed already.</p>
|
||||||
*
|
*
|
||||||
* @return a parsed tag
|
* @return a parsed tag
|
||||||
*/
|
*/
|
||||||
@ -227,7 +262,7 @@ import java.util.stream.IntStream;
|
|||||||
if (builder.length() != 0) {
|
if (builder.length() != 0) {
|
||||||
Tag result = null;
|
Tag result = null;
|
||||||
try {
|
try {
|
||||||
switch (Character.toUpperCase(current)) { // try to read and return as a number
|
switch (Character.toLowerCase(current)) { // try to read and return as a number
|
||||||
// case Tokens.TYPE_INTEGER: // handled below, ints are ~special~
|
// case Tokens.TYPE_INTEGER: // handled below, ints are ~special~
|
||||||
case Tokens.TYPE_BYTE:
|
case Tokens.TYPE_BYTE:
|
||||||
result = new ByteTag(Byte.parseByte(builder.toString()));
|
result = new ByteTag(Byte.parseByte(builder.toString()));
|
||||||
@ -269,29 +304,33 @@ import java.util.stream.IntStream;
|
|||||||
try {
|
try {
|
||||||
return new IntTag(Integer.parseInt(built));
|
return new IntTag(Integer.parseInt(built));
|
||||||
} catch (final NumberFormatException ex) {
|
} catch (final NumberFormatException ex) {
|
||||||
|
try {
|
||||||
|
return new DoubleTag(Double.parseDouble(built));
|
||||||
|
} catch (final NumberFormatException ex2) {
|
||||||
// ignore
|
// 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);
|
return new StringTag(built);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean separatorOrCompleteWith(final char endCharacter) throws StringTagParseException {
|
private boolean separatorOrCompleteWith(final char endCharacter) throws StringTagParseException {
|
||||||
if (this.buffer.skipWhitespace().peek() == endCharacter) {
|
if (this.buffer.takeIf(endCharacter)) {
|
||||||
this.buffer.take();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.buffer.expect(Tokens.VALUE_SEPARATOR);
|
this.buffer.expect(Tokens.VALUE_SEPARATOR);
|
||||||
if (this.buffer.skipWhitespace().peek() == endCharacter) {
|
|
||||||
this.buffer.take();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove simple escape sequences from a string
|
* Remove simple escape sequences from a string.
|
||||||
*
|
*
|
||||||
* @param withEscapes input string with escapes
|
* @param withEscapes input string with escapes
|
||||||
* @return string with escapes processed
|
* @return string with escapes processed
|
||||||
@ -310,4 +349,8 @@ import java.util.stream.IntStream;
|
|||||||
output.append(withEscapes.substring(lastEscape));
|
output.append(withEscapes.substring(lastEscape));
|
||||||
return output.toString();
|
return output.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void legacy(final boolean acceptLegacy) {
|
||||||
|
this.acceptLegacy = acceptLegacy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
|||||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
|
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.LongTag;
|
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.ShortTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
@ -41,12 +42,16 @@ import java.io.IOException;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Map;
|
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
|
||||||
/**
|
/**
|
||||||
* See https://github.com/KyoriPowered/adventure.
|
* An emitter for the SNBT format.
|
||||||
|
*
|
||||||
|
* <p>Details on the format are described in the package documentation.</p>
|
||||||
*/
|
*/
|
||||||
/* package */ final class TagStringWriter implements AutoCloseable {
|
final class TagStringWriter implements AutoCloseable {
|
||||||
private final Appendable out;
|
private final Appendable out;
|
||||||
private final String indent = " ";
|
|
||||||
private int level;
|
private int level;
|
||||||
/**
|
/**
|
||||||
* Whether a {@link Tokens#VALUE_SEPARATOR} needs to be printed before the beginning of the next object.
|
* Whether a {@link Tokens#VALUE_SEPARATOR} needs to be printed before the beginning of the next object.
|
||||||
@ -73,17 +78,17 @@ import java.util.Map;
|
|||||||
} else if (tag instanceof StringTag) {
|
} else if (tag instanceof StringTag) {
|
||||||
return this.value(((StringTag) tag).getValue(), Tokens.EOF);
|
return this.value(((StringTag) tag).getValue(), Tokens.EOF);
|
||||||
} else if (tag instanceof ByteTag) {
|
} else if (tag instanceof ByteTag) {
|
||||||
return this.value(Byte.toString(((ByteTag) tag).asByte()), Tokens.TYPE_BYTE);
|
return this.value(Byte.toString(((NumberTag) tag).asByte()), Tokens.TYPE_BYTE);
|
||||||
} else if (tag instanceof ShortTag) {
|
} else if (tag instanceof ShortTag) {
|
||||||
return this.value(Short.toString(((ShortTag) tag).asShort()), Tokens.TYPE_SHORT);
|
return this.value(Short.toString(((NumberTag) tag).asShort()), Tokens.TYPE_SHORT);
|
||||||
} else if (tag instanceof IntTag) {
|
} else if (tag instanceof IntTag) {
|
||||||
return this.value(Integer.toString(((IntTag) tag).asInt()), Tokens.TYPE_INT);
|
return this.value(Integer.toString(((NumberTag) tag).asInt()), Tokens.TYPE_INT);
|
||||||
} else if (tag instanceof LongTag) {
|
} else if (tag instanceof LongTag) {
|
||||||
return this.value(Long.toString(((LongTag) tag).asLong()), Tokens.TYPE_LONG);
|
return this.value(Long.toString(((NumberTag) tag).asLong()), Character.toUpperCase(Tokens.TYPE_LONG)); // special case
|
||||||
} else if (tag instanceof FloatTag) {
|
} else if (tag instanceof FloatTag) {
|
||||||
return this.value(Float.toString(((FloatTag) tag).asFloat()), Tokens.TYPE_FLOAT);
|
return this.value(Float.toString(((NumberTag) tag).asFloat()), Tokens.TYPE_FLOAT);
|
||||||
} else if (tag instanceof DoubleTag) {
|
} else if (tag instanceof DoubleTag) {
|
||||||
return this.value(Double.toString(((DoubleTag) tag).asDouble()), Tokens.TYPE_DOUBLE);
|
return this.value(Double.toString(((NumberTag) tag).asDouble()), Tokens.TYPE_DOUBLE);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Unknown tag type: " + tag.getClass().getSimpleName());
|
throw new IOException("Unknown tag type: " + tag.getClass().getSimpleName());
|
||||||
// unknown!
|
// unknown!
|
||||||
@ -92,7 +97,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
private TagStringWriter writeCompound(final CompoundTag tag) throws IOException {
|
private TagStringWriter writeCompound(final CompoundTag tag) throws IOException {
|
||||||
this.beginCompound();
|
this.beginCompound();
|
||||||
for (Map.Entry<String, Tag> entry : tag.entrySet()) {
|
for (final Map.Entry<String, Tag> entry : tag.entrySet()) {
|
||||||
this.key(entry.getKey());
|
this.key(entry.getKey());
|
||||||
this.writeTag(entry.getValue());
|
this.writeTag(entry.getValue());
|
||||||
}
|
}
|
||||||
@ -244,7 +249,6 @@ import java.util.Map;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (this.level != 0) {
|
if (this.level != 0) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of adventure, licensed under the MIT License.
|
* This file is part of adventure, licensed under the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2020 KyoriPowered
|
* Copyright (c) 2017-2021 KyoriPowered
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -23,10 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.viaversion.viaversion.api.minecraft.nbt;
|
package com.viaversion.viaversion.api.minecraft.nbt;
|
||||||
|
|
||||||
/**
|
final class Tokens {
|
||||||
* See https://github.com/KyoriPowered/adventure.
|
|
||||||
*/
|
|
||||||
/* package */ final class Tokens {
|
|
||||||
// Compounds
|
// Compounds
|
||||||
static final char COMPOUND_BEGIN = '{';
|
static final char COMPOUND_BEGIN = '{';
|
||||||
static final char COMPOUND_END = '}';
|
static final char COMPOUND_END = '}';
|
||||||
@ -43,20 +40,24 @@ package com.viaversion.viaversion.api.minecraft.nbt;
|
|||||||
static final char DOUBLE_QUOTE = '"';
|
static final char DOUBLE_QUOTE = '"';
|
||||||
static final char ESCAPE_MARKER = '\\';
|
static final char ESCAPE_MARKER = '\\';
|
||||||
|
|
||||||
static final char TYPE_BYTE = 'B';
|
static final char TYPE_BYTE = 'b';
|
||||||
static final char TYPE_SHORT = 'S';
|
static final char TYPE_SHORT = 's';
|
||||||
static final char TYPE_INT = 'I'; // array only
|
static final char TYPE_INT = 'i'; // array only
|
||||||
static final char TYPE_LONG = 'L';
|
static final char TYPE_LONG = 'l';
|
||||||
static final char TYPE_FLOAT = 'F';
|
static final char TYPE_FLOAT = 'f';
|
||||||
static final char TYPE_DOUBLE = 'D';
|
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';
|
static final char EOF = '\0';
|
||||||
|
|
||||||
private Tokens() {
|
private Tokens() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if a character is a valid component in an identifier
|
* 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>
|
* <p>An identifier character must match the expression {@code [a-zA-Z0-9_+.-]}</p>
|
||||||
*
|
*
|
||||||
@ -73,8 +74,8 @@ package com.viaversion.viaversion.api.minecraft.nbt;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether a character could be at some position in a number.
|
* 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>A string passing this check does not necessarily mean it is syntactically valid.</p>
|
||||||
*
|
*
|
||||||
* @param c character to check
|
* @param c character to check
|
||||||
* @return if possibly part of a number
|
* @return if possibly part of a number
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren