Initial Commit
This commit is contained in:
1 parent
377b32db6e
commit
2d9a5eecba
14134 files changed
+1160982
No files matched your search
+166
@@ -0,0 +1,166 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class ByteArrayTag extends CollectionTag<ByteTag> {
|
||||
private static final int SELF_SIZE_IN_BYTES = 24;
|
||||
public static final TagType<ByteArrayTag> TYPE = new TagType.VariableSize<ByteArrayTag>() {
|
||||
public ByteArrayTag load(DataInput p_128247_, int p_128248_, NbtAccounter p_128249_) throws IOException {
|
||||
p_128249_.accountBytes(24L);
|
||||
int i = p_128247_.readInt();
|
||||
p_128249_.accountBytes(1L * (long)i);
|
||||
byte[] abyte = new byte[i];
|
||||
p_128247_.readFully(abyte);
|
||||
return new ByteArrayTag(abyte);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197433_, StreamTagVisitor p_197434_) throws IOException {
|
||||
int i = p_197433_.readInt();
|
||||
byte[] abyte = new byte[i];
|
||||
p_197433_.readFully(abyte);
|
||||
return p_197434_.visit(abyte);
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197431_) throws IOException {
|
||||
p_197431_.skipBytes(p_197431_.readInt() * 1);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "BYTE[]";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Byte_Array";
|
||||
}
|
||||
};
|
||||
private byte[] data;
|
||||
|
||||
public ByteArrayTag(byte[] pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public ByteArrayTag(List<Byte> pDataList) {
|
||||
this(toArray(pDataList));
|
||||
}
|
||||
|
||||
private static byte[] toArray(List<Byte> pDataList) {
|
||||
byte[] abyte = new byte[pDataList.size()];
|
||||
|
||||
for(int i = 0; i < pDataList.size(); ++i) {
|
||||
Byte obyte = pDataList.get(i);
|
||||
abyte[i] = obyte == null ? 0 : obyte;
|
||||
}
|
||||
|
||||
return abyte;
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeInt(this.data.length);
|
||||
pOutput.write(this.data);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 24 + 1 * this.data.length;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 7;
|
||||
}
|
||||
|
||||
public TagType<ByteArrayTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public Tag copy() {
|
||||
byte[] abyte = new byte[this.data.length];
|
||||
System.arraycopy(this.data, 0, abyte, 0, this.data.length);
|
||||
return new ByteArrayTag(abyte);
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof ByteArrayTag && Arrays.equals(this.data, ((ByteArrayTag)pOther).data);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(this.data);
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitByteArray(this);
|
||||
}
|
||||
|
||||
public byte[] getAsByteArray() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.data.length;
|
||||
}
|
||||
|
||||
public ByteTag get(int p_128194_) {
|
||||
return ByteTag.valueOf(this.data[p_128194_]);
|
||||
}
|
||||
|
||||
public ByteTag set(int p_128196_, ByteTag p_128197_) {
|
||||
byte b0 = this.data[p_128196_];
|
||||
this.data[p_128196_] = p_128197_.getAsByte();
|
||||
return ByteTag.valueOf(b0);
|
||||
}
|
||||
|
||||
public void add(int p_128215_, ByteTag p_128216_) {
|
||||
this.data = ArrayUtils.add(this.data, p_128215_, p_128216_.getAsByte());
|
||||
}
|
||||
|
||||
public boolean setTag(int pIndex, Tag pNbt) {
|
||||
if (pNbt instanceof NumericTag) {
|
||||
this.data[pIndex] = ((NumericTag)pNbt).getAsByte();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTag(int pIndex, Tag pNbt) {
|
||||
if (pNbt instanceof NumericTag) {
|
||||
this.data = ArrayUtils.add(this.data, pIndex, ((NumericTag)pNbt).getAsByte());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ByteTag remove(int p_128213_) {
|
||||
byte b0 = this.data[p_128213_];
|
||||
this.data = ArrayUtils.remove(this.data, p_128213_);
|
||||
return ByteTag.valueOf(b0);
|
||||
}
|
||||
|
||||
public byte getElementType() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.data = new byte[0];
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ByteTag extends NumericTag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 9;
|
||||
public static final TagType<ByteTag> TYPE = new TagType.StaticSize<ByteTag>() {
|
||||
public ByteTag load(DataInput p_128292_, int p_128293_, NbtAccounter p_128294_) throws IOException {
|
||||
p_128294_.accountBytes(9L);
|
||||
return ByteTag.valueOf(p_128292_.readByte());
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197438_, StreamTagVisitor p_197439_) throws IOException {
|
||||
return p_197439_.visit(p_197438_.readByte());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "BYTE";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Byte";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
public static final ByteTag ZERO = valueOf((byte)0);
|
||||
public static final ByteTag ONE = valueOf((byte)1);
|
||||
private final byte data;
|
||||
|
||||
ByteTag(byte pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public static ByteTag valueOf(byte pData) {
|
||||
return ByteTag.Cache.cache[128 + pData];
|
||||
}
|
||||
|
||||
public static ByteTag valueOf(boolean pData) {
|
||||
return pData ? ONE : ZERO;
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeByte(this.data);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public TagType<ByteTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public ByteTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof ByteTag && this.data == ((ByteTag)pOther).data;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitByte(this);
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
return (long)this.data;
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
return (short)this.data;
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
return (double)this.data;
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
return (float)this.data;
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
|
||||
static class Cache {
|
||||
static final ByteTag[] cache = new ByteTag[256];
|
||||
|
||||
private Cache() {
|
||||
}
|
||||
|
||||
static {
|
||||
for(int i = 0; i < cache.length; ++i) {
|
||||
cache[i] = new ByteTag((byte)(i - 128));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.util.AbstractList;
|
||||
|
||||
public abstract class CollectionTag<T extends Tag> extends AbstractList<T> implements Tag {
|
||||
public abstract T set(int p_128318_, T p_128319_);
|
||||
|
||||
public abstract void add(int p_128315_, T p_128316_);
|
||||
|
||||
public abstract T remove(int p_128313_);
|
||||
|
||||
public abstract boolean setTag(int pIndex, Tag pTag);
|
||||
|
||||
public abstract boolean addTag(int pIndex, Tag pTag);
|
||||
|
||||
public abstract byte getElementType();
|
||||
}
|
||||
+561
@@ -0,0 +1,561 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.CrashReportCategory;
|
||||
import net.minecraft.ReportedException;
|
||||
|
||||
public class CompoundTag implements Tag {
|
||||
public static final Codec<CompoundTag> CODEC = Codec.PASSTHROUGH.comapFlatMap((p_274781_) -> {
|
||||
Tag tag = p_274781_.convert(NbtOps.INSTANCE).getValue();
|
||||
return tag instanceof CompoundTag ? DataResult.success((CompoundTag)tag) : DataResult.error(() -> {
|
||||
return "Not a compound tag: " + tag;
|
||||
});
|
||||
}, (p_128412_) -> {
|
||||
return new Dynamic<>(NbtOps.INSTANCE, p_128412_);
|
||||
});
|
||||
private static final int SELF_SIZE_IN_BYTES = 48;
|
||||
private static final int MAP_ENTRY_SIZE_IN_BYTES = 32;
|
||||
public static final TagType<CompoundTag> TYPE = new TagType.VariableSize<CompoundTag>() {
|
||||
public CompoundTag load(DataInput p_128485_, int p_128486_, NbtAccounter p_128487_) throws IOException {
|
||||
p_128487_.accountBytes(48L);
|
||||
if (p_128486_ > 512) {
|
||||
throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
|
||||
} else {
|
||||
Map<String, Tag> map = Maps.newHashMap();
|
||||
|
||||
byte b0;
|
||||
while((b0 = CompoundTag.readNamedTagType(p_128485_, p_128487_)) != 0) {
|
||||
String s = CompoundTag.readNamedTagName(p_128485_, p_128487_);
|
||||
p_128487_.accountBytes((long)(28 + 2 * s.length()));
|
||||
p_128487_.accountBytes(4); //Forge: 4 extra bytes for the object allocation.
|
||||
Tag tag = CompoundTag.readNamedTagData(TagTypes.getType(b0), s, p_128485_, p_128486_ + 1, p_128487_);
|
||||
if (map.put(s, tag) == null) {
|
||||
p_128487_.accountBytes(36L);
|
||||
}
|
||||
}
|
||||
|
||||
return new CompoundTag(map);
|
||||
}
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197446_, StreamTagVisitor p_197447_) throws IOException {
|
||||
while(true) {
|
||||
byte b0;
|
||||
if ((b0 = p_197446_.readByte()) != 0) {
|
||||
TagType<?> tagtype = TagTypes.getType(b0);
|
||||
switch (p_197447_.visitEntry(tagtype)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
StringTag.skipString(p_197446_);
|
||||
tagtype.skip(p_197446_);
|
||||
break;
|
||||
case SKIP:
|
||||
StringTag.skipString(p_197446_);
|
||||
tagtype.skip(p_197446_);
|
||||
continue;
|
||||
default:
|
||||
String s = p_197446_.readUTF();
|
||||
switch (p_197447_.visitEntry(tagtype, s)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
tagtype.skip(p_197446_);
|
||||
break;
|
||||
case SKIP:
|
||||
tagtype.skip(p_197446_);
|
||||
continue;
|
||||
default:
|
||||
switch (tagtype.parse(p_197446_, p_197447_)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b0 != 0) {
|
||||
while((b0 = p_197446_.readByte()) != 0) {
|
||||
StringTag.skipString(p_197446_);
|
||||
TagTypes.getType(b0).skip(p_197446_);
|
||||
}
|
||||
}
|
||||
|
||||
return p_197447_.visitContainerEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197444_) throws IOException {
|
||||
byte b0;
|
||||
while((b0 = p_197444_.readByte()) != 0) {
|
||||
StringTag.skipString(p_197444_);
|
||||
TagTypes.getType(b0).skip(p_197444_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "COMPOUND";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Compound";
|
||||
}
|
||||
};
|
||||
private final Map<String, Tag> tags;
|
||||
|
||||
protected CompoundTag(Map<String, Tag> pTags) {
|
||||
this.tags = pTags;
|
||||
}
|
||||
|
||||
public CompoundTag() {
|
||||
this(Maps.newHashMap());
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
for(String s : this.tags.keySet()) {
|
||||
Tag tag = this.tags.get(s);
|
||||
writeNamedTag(s, tag, pOutput);
|
||||
}
|
||||
|
||||
pOutput.writeByte(0);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
int i = 48;
|
||||
|
||||
for(Map.Entry<String, Tag> entry : this.tags.entrySet()) {
|
||||
i += 28 + 2 * entry.getKey().length();
|
||||
i += 36;
|
||||
i += entry.getValue().sizeInBytes();
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public Set<String> getAllKeys() {
|
||||
return this.tags.keySet();
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public TagType<CompoundTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.tags.size();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tag put(String pKey, Tag pValue) {
|
||||
if (pValue == null) throw new IllegalArgumentException("Invalid null NBT value with key " + pKey);
|
||||
return this.tags.put(pKey, pValue);
|
||||
}
|
||||
|
||||
public void putByte(String pKey, byte pValue) {
|
||||
this.tags.put(pKey, ByteTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
public void putShort(String pKey, short pValue) {
|
||||
this.tags.put(pKey, ShortTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
public void putInt(String pKey, int pValue) {
|
||||
this.tags.put(pKey, IntTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
public void putLong(String pKey, long pValue) {
|
||||
this.tags.put(pKey, LongTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
public void putUUID(String pKey, UUID pValue) {
|
||||
this.tags.put(pKey, NbtUtils.createUUID(pValue));
|
||||
}
|
||||
|
||||
public UUID getUUID(String pKey) {
|
||||
return NbtUtils.loadUUID(this.get(pKey));
|
||||
}
|
||||
|
||||
public boolean hasUUID(String pKey) {
|
||||
Tag tag = this.get(pKey);
|
||||
return tag != null && tag.getType() == IntArrayTag.TYPE && ((IntArrayTag)tag).getAsIntArray().length == 4;
|
||||
}
|
||||
|
||||
public void putFloat(String pKey, float pValue) {
|
||||
this.tags.put(pKey, FloatTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
public void putDouble(String pKey, double pValue) {
|
||||
this.tags.put(pKey, DoubleTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
public void putString(String pKey, String pValue) {
|
||||
this.tags.put(pKey, StringTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
public void putByteArray(String pKey, byte[] pValue) {
|
||||
this.tags.put(pKey, new ByteArrayTag(pValue));
|
||||
}
|
||||
|
||||
public void putByteArray(String pKey, List<Byte> pValue) {
|
||||
this.tags.put(pKey, new ByteArrayTag(pValue));
|
||||
}
|
||||
|
||||
public void putIntArray(String pKey, int[] pValue) {
|
||||
this.tags.put(pKey, new IntArrayTag(pValue));
|
||||
}
|
||||
|
||||
public void putIntArray(String pKey, List<Integer> pValue) {
|
||||
this.tags.put(pKey, new IntArrayTag(pValue));
|
||||
}
|
||||
|
||||
public void putLongArray(String pKey, long[] pValue) {
|
||||
this.tags.put(pKey, new LongArrayTag(pValue));
|
||||
}
|
||||
|
||||
public void putLongArray(String pKey, List<Long> pValue) {
|
||||
this.tags.put(pKey, new LongArrayTag(pValue));
|
||||
}
|
||||
|
||||
public void putBoolean(String pKey, boolean pValue) {
|
||||
this.tags.put(pKey, ByteTag.valueOf(pValue));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tag get(String pKey) {
|
||||
return this.tags.get(pKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the byte identifier of the tag of the specified {@code key}, or {@code 0} if no tag exists for the {@code
|
||||
* key}.
|
||||
*/
|
||||
public byte getTagType(String pKey) {
|
||||
Tag tag = this.tags.get(pKey);
|
||||
return tag == null ? 0 : tag.getId();
|
||||
}
|
||||
|
||||
public boolean contains(String pKey) {
|
||||
return this.tags.containsKey(pKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the tag of the specified {@code key} is a particular {@code tagType}. If the {@code tagType} is
|
||||
* {@code 99}, all numeric tags will be checked against the type of the stored tag.
|
||||
*/
|
||||
public boolean contains(String pKey, int pTagType) {
|
||||
int i = this.getTagType(pKey);
|
||||
if (i == pTagType) {
|
||||
return true;
|
||||
} else if (pTagType != 99) {
|
||||
return false;
|
||||
} else {
|
||||
return i == 1 || i == 2 || i == 3 || i == 4 || i == 5 || i == 6;
|
||||
}
|
||||
}
|
||||
|
||||
public byte getByte(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 99)) {
|
||||
return ((NumericTag)this.tags.get(pKey)).getAsByte();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public short getShort(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 99)) {
|
||||
return ((NumericTag)this.tags.get(pKey)).getAsShort();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getInt(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 99)) {
|
||||
return ((NumericTag)this.tags.get(pKey)).getAsInt();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getLong(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 99)) {
|
||||
return ((NumericTag)this.tags.get(pKey)).getAsLong();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public float getFloat(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 99)) {
|
||||
return ((NumericTag)this.tags.get(pKey)).getAsFloat();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
}
|
||||
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public double getDouble(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 99)) {
|
||||
return ((NumericTag)this.tags.get(pKey)).getAsDouble();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
}
|
||||
|
||||
return 0.0D;
|
||||
}
|
||||
|
||||
public String getString(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 8)) {
|
||||
return this.tags.get(pKey).getAsString();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public byte[] getByteArray(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 7)) {
|
||||
return ((ByteArrayTag)this.tags.get(pKey)).getAsByteArray();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.createReport(pKey, ByteArrayTag.TYPE, classcastexception));
|
||||
}
|
||||
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public int[] getIntArray(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 11)) {
|
||||
return ((IntArrayTag)this.tags.get(pKey)).getAsIntArray();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.createReport(pKey, IntArrayTag.TYPE, classcastexception));
|
||||
}
|
||||
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
public long[] getLongArray(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 12)) {
|
||||
return ((LongArrayTag)this.tags.get(pKey)).getAsLongArray();
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.createReport(pKey, LongArrayTag.TYPE, classcastexception));
|
||||
}
|
||||
|
||||
return new long[0];
|
||||
}
|
||||
|
||||
public CompoundTag getCompound(String pKey) {
|
||||
try {
|
||||
if (this.contains(pKey, 10)) {
|
||||
return (CompoundTag)this.tags.get(pKey);
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.createReport(pKey, TYPE, classcastexception));
|
||||
}
|
||||
|
||||
return new CompoundTag();
|
||||
}
|
||||
|
||||
public ListTag getList(String pKey, int pTagType) {
|
||||
try {
|
||||
if (this.getTagType(pKey) == 9) {
|
||||
ListTag listtag = (ListTag)this.tags.get(pKey);
|
||||
if (!listtag.isEmpty() && listtag.getElementType() != pTagType) {
|
||||
return new ListTag();
|
||||
}
|
||||
|
||||
return listtag;
|
||||
}
|
||||
} catch (ClassCastException classcastexception) {
|
||||
throw new ReportedException(this.createReport(pKey, ListTag.TYPE, classcastexception));
|
||||
}
|
||||
|
||||
return new ListTag();
|
||||
}
|
||||
|
||||
public boolean getBoolean(String pKey) {
|
||||
return this.getByte(pKey) != 0;
|
||||
}
|
||||
|
||||
public void remove(String pKey) {
|
||||
this.tags.remove(pKey);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getAsString();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.tags.isEmpty();
|
||||
}
|
||||
|
||||
private CrashReport createReport(String pTagName, TagType<?> pType, ClassCastException pException) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(pException, "Reading NBT data");
|
||||
CrashReportCategory crashreportcategory = crashreport.addCategory("Corrupt NBT tag", 1);
|
||||
crashreportcategory.setDetail("Tag type found", () -> {
|
||||
return this.tags.get(pTagName).getType().getName();
|
||||
});
|
||||
crashreportcategory.setDetail("Tag type expected", pType::getName);
|
||||
crashreportcategory.setDetail("Tag name", pTagName);
|
||||
return crashreport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public CompoundTag copy() {
|
||||
Map<String, Tag> map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy));
|
||||
return new CompoundTag(map);
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof CompoundTag && Objects.equals(this.tags, ((CompoundTag)pOther).tags);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.tags.hashCode();
|
||||
}
|
||||
|
||||
private static void writeNamedTag(String pName, Tag pTag, DataOutput pOutput) throws IOException {
|
||||
pOutput.writeByte(pTag.getId());
|
||||
if (pTag.getId() != 0) {
|
||||
pOutput.writeUTF(pName);
|
||||
pTag.write(pOutput);
|
||||
}
|
||||
}
|
||||
|
||||
static byte readNamedTagType(DataInput pInput, NbtAccounter pAccounter) throws IOException {
|
||||
pAccounter.accountBytes(2);
|
||||
return pInput.readByte();
|
||||
}
|
||||
|
||||
static String readNamedTagName(DataInput pInput, NbtAccounter pAccounter) throws IOException {
|
||||
return pAccounter.readUTF(pInput.readUTF());
|
||||
}
|
||||
|
||||
static Tag readNamedTagData(TagType<?> pType, String pName, DataInput pInput, int pDepth, NbtAccounter pAccounter) {
|
||||
try {
|
||||
return pType.load(pInput, pDepth, pAccounter);
|
||||
} catch (IOException ioexception) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(ioexception, "Loading NBT data");
|
||||
CrashReportCategory crashreportcategory = crashreport.addCategory("NBT Tag");
|
||||
crashreportcategory.setDetail("Tag name", pName);
|
||||
crashreportcategory.setDetail("Tag type", pType.getName());
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies all the tags of {@code other} into this tag, then returns itself.
|
||||
* @see #copy()
|
||||
*/
|
||||
public CompoundTag merge(CompoundTag pOther) {
|
||||
for(String s : pOther.tags.keySet()) {
|
||||
Tag tag = pOther.tags.get(s);
|
||||
if (tag.getId() == 10) {
|
||||
if (this.contains(s, 10)) {
|
||||
CompoundTag compoundtag = this.getCompound(s);
|
||||
compoundtag.merge((CompoundTag)tag);
|
||||
} else {
|
||||
this.put(s, tag.copy());
|
||||
}
|
||||
} else {
|
||||
this.put(s, tag.copy());
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitCompound(this);
|
||||
}
|
||||
|
||||
protected Map<String, Tag> entries() {
|
||||
return Collections.unmodifiableMap(this.tags);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
for(Map.Entry<String, Tag> entry : this.tags.entrySet()) {
|
||||
Tag tag = entry.getValue();
|
||||
TagType<?> tagtype = tag.getType();
|
||||
StreamTagVisitor.EntryResult streamtagvisitor$entryresult = pVisitor.visitEntry(tagtype);
|
||||
switch (streamtagvisitor$entryresult) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
return pVisitor.visitContainerEnd();
|
||||
case SKIP:
|
||||
break;
|
||||
default:
|
||||
streamtagvisitor$entryresult = pVisitor.visitEntry(tagtype, entry.getKey());
|
||||
switch (streamtagvisitor$entryresult) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
return pVisitor.visitContainerEnd();
|
||||
case SKIP:
|
||||
break;
|
||||
default:
|
||||
StreamTagVisitor.ValueResult streamtagvisitor$valueresult = tag.accept(pVisitor);
|
||||
switch (streamtagvisitor$valueresult) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
return pVisitor.visitContainerEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pVisitor.visitContainerEnd();
|
||||
}
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public class DoubleTag extends NumericTag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 16;
|
||||
public static final DoubleTag ZERO = new DoubleTag(0.0D);
|
||||
public static final TagType<DoubleTag> TYPE = new TagType.StaticSize<DoubleTag>() {
|
||||
public DoubleTag load(DataInput p_128524_, int p_128525_, NbtAccounter p_128526_) throws IOException {
|
||||
p_128526_.accountBytes(16L);
|
||||
return DoubleTag.valueOf(p_128524_.readDouble());
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197454_, StreamTagVisitor p_197455_) throws IOException {
|
||||
return p_197455_.visit(p_197454_.readDouble());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "DOUBLE";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Double";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private final double data;
|
||||
|
||||
private DoubleTag(double pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public static DoubleTag valueOf(double pData) {
|
||||
return pData == 0.0D ? ZERO : new DoubleTag(pData);
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeDouble(this.data);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
public TagType<DoubleTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public DoubleTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof DoubleTag && this.data == ((DoubleTag)pOther).data;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
long i = Double.doubleToLongBits(this.data);
|
||||
return (int)(i ^ i >>> 32);
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitDouble(this);
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
return (long)Math.floor(this.data);
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
return Mth.floor(this.data);
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
return (short)(Mth.floor(this.data) & '\uffff');
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
return (byte)(Mth.floor(this.data) & 255);
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
return (float)this.data;
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EndTag implements Tag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 8;
|
||||
public static final TagType<EndTag> TYPE = new TagType<EndTag>() {
|
||||
public EndTag load(DataInput p_128550_, int p_128551_, NbtAccounter p_128552_) {
|
||||
p_128552_.accountBytes(8L);
|
||||
return EndTag.INSTANCE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197465_, StreamTagVisitor p_197466_) {
|
||||
return p_197466_.visitEnd();
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197462_, int p_197463_) {
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197460_) {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "END";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_End";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
public static final EndTag INSTANCE = new EndTag();
|
||||
|
||||
private EndTag() {
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public TagType<EndTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public EndTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitEnd(this);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visitEnd();
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public class FloatTag extends NumericTag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 12;
|
||||
public static final FloatTag ZERO = new FloatTag(0.0F);
|
||||
public static final TagType<FloatTag> TYPE = new TagType.StaticSize<FloatTag>() {
|
||||
public FloatTag load(DataInput p_128590_, int p_128591_, NbtAccounter p_128592_) throws IOException {
|
||||
p_128592_.accountBytes(12L);
|
||||
return FloatTag.valueOf(p_128590_.readFloat());
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197470_, StreamTagVisitor p_197471_) throws IOException {
|
||||
return p_197471_.visit(p_197470_.readFloat());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "FLOAT";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Float";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private final float data;
|
||||
|
||||
private FloatTag(float pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public static FloatTag valueOf(float pData) {
|
||||
return pData == 0.0F ? ZERO : new FloatTag(pData);
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeFloat(this.data);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public TagType<FloatTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public FloatTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof FloatTag && this.data == ((FloatTag)pOther).data;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Float.floatToIntBits(this.data);
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitFloat(this);
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
return (long)this.data;
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
return Mth.floor(this.data);
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
return (short)(Mth.floor(this.data) & '\uffff');
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
return (byte)(Mth.floor(this.data) & 255);
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
return (double)this.data;
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class IntArrayTag extends CollectionTag<IntTag> {
|
||||
private static final int SELF_SIZE_IN_BYTES = 24;
|
||||
public static final TagType<IntArrayTag> TYPE = new TagType.VariableSize<IntArrayTag>() {
|
||||
public IntArrayTag load(DataInput p_128662_, int p_128663_, NbtAccounter p_128664_) throws IOException {
|
||||
p_128664_.accountBytes(24L);
|
||||
int i = p_128662_.readInt();
|
||||
p_128664_.accountBytes(4L * (long)i);
|
||||
int[] aint = new int[i];
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
aint[j] = p_128662_.readInt();
|
||||
}
|
||||
|
||||
return new IntArrayTag(aint);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197478_, StreamTagVisitor p_197479_) throws IOException {
|
||||
int i = p_197478_.readInt();
|
||||
int[] aint = new int[i];
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
aint[j] = p_197478_.readInt();
|
||||
}
|
||||
|
||||
return p_197479_.visit(aint);
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197476_) throws IOException {
|
||||
p_197476_.skipBytes(p_197476_.readInt() * 4);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "INT[]";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Int_Array";
|
||||
}
|
||||
};
|
||||
private int[] data;
|
||||
|
||||
public IntArrayTag(int[] pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public IntArrayTag(List<Integer> pDataList) {
|
||||
this(toArray(pDataList));
|
||||
}
|
||||
|
||||
private static int[] toArray(List<Integer> pDataList) {
|
||||
int[] aint = new int[pDataList.size()];
|
||||
|
||||
for(int i = 0; i < pDataList.size(); ++i) {
|
||||
Integer integer = pDataList.get(i);
|
||||
aint[i] = integer == null ? 0 : integer;
|
||||
}
|
||||
|
||||
return aint;
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeInt(this.data.length);
|
||||
|
||||
for(int i : this.data) {
|
||||
pOutput.writeInt(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 24 + 4 * this.data.length;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 11;
|
||||
}
|
||||
|
||||
public TagType<IntArrayTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public IntArrayTag copy() {
|
||||
int[] aint = new int[this.data.length];
|
||||
System.arraycopy(this.data, 0, aint, 0, this.data.length);
|
||||
return new IntArrayTag(aint);
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof IntArrayTag && Arrays.equals(this.data, ((IntArrayTag)pOther).data);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(this.data);
|
||||
}
|
||||
|
||||
public int[] getAsIntArray() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitIntArray(this);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.data.length;
|
||||
}
|
||||
|
||||
public IntTag get(int p_128608_) {
|
||||
return IntTag.valueOf(this.data[p_128608_]);
|
||||
}
|
||||
|
||||
public IntTag set(int p_128610_, IntTag p_128611_) {
|
||||
int i = this.data[p_128610_];
|
||||
this.data[p_128610_] = p_128611_.getAsInt();
|
||||
return IntTag.valueOf(i);
|
||||
}
|
||||
|
||||
public void add(int p_128629_, IntTag p_128630_) {
|
||||
this.data = ArrayUtils.add(this.data, p_128629_, p_128630_.getAsInt());
|
||||
}
|
||||
|
||||
public boolean setTag(int pIndex, Tag pNbt) {
|
||||
if (pNbt instanceof NumericTag) {
|
||||
this.data[pIndex] = ((NumericTag)pNbt).getAsInt();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTag(int pIndex, Tag pNbt) {
|
||||
if (pNbt instanceof NumericTag) {
|
||||
this.data = ArrayUtils.add(this.data, pIndex, ((NumericTag)pNbt).getAsInt());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IntTag remove(int p_128627_) {
|
||||
int i = this.data[p_128627_];
|
||||
this.data = ArrayUtils.remove(this.data, p_128627_);
|
||||
return IntTag.valueOf(i);
|
||||
}
|
||||
|
||||
public byte getElementType() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.data = new int[0];
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class IntTag extends NumericTag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 12;
|
||||
public static final TagType<IntTag> TYPE = new TagType.StaticSize<IntTag>() {
|
||||
public IntTag load(DataInput p_128703_, int p_128704_, NbtAccounter p_128705_) throws IOException {
|
||||
p_128705_.accountBytes(12L);
|
||||
return IntTag.valueOf(p_128703_.readInt());
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197483_, StreamTagVisitor p_197484_) throws IOException {
|
||||
return p_197484_.visit(p_197483_.readInt());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "INT";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Int";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private final int data;
|
||||
|
||||
IntTag(int pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public static IntTag valueOf(int pData) {
|
||||
return pData >= -128 && pData <= 1024 ? IntTag.Cache.cache[pData - -128] : new IntTag(pData);
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeInt(this.data);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public TagType<IntTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public IntTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof IntTag && this.data == ((IntTag)pOther).data;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitInt(this);
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
return (long)this.data;
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
return (short)(this.data & '\uffff');
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
return (byte)(this.data & 255);
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
return (double)this.data;
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
return (float)this.data;
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
|
||||
static class Cache {
|
||||
private static final int HIGH = 1024;
|
||||
private static final int LOW = -128;
|
||||
static final IntTag[] cache = new IntTag[1153];
|
||||
|
||||
private Cache() {
|
||||
}
|
||||
|
||||
static {
|
||||
for(int i = 0; i < cache.length; ++i) {
|
||||
cache[i] = new IntTag(-128 + i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+384
@@ -0,0 +1,384 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ListTag extends CollectionTag<Tag> {
|
||||
private static final int SELF_SIZE_IN_BYTES = 37;
|
||||
public static final TagType<ListTag> TYPE = new TagType.VariableSize<ListTag>() {
|
||||
public ListTag load(DataInput p_128792_, int p_128793_, NbtAccounter p_128794_) throws IOException {
|
||||
p_128794_.accountBytes(37L);
|
||||
if (p_128793_ > 512) {
|
||||
throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
|
||||
} else {
|
||||
byte b0 = p_128792_.readByte();
|
||||
int i = p_128792_.readInt();
|
||||
if (b0 == 0 && i > 0) {
|
||||
throw new RuntimeException("Missing type on ListTag");
|
||||
} else {
|
||||
p_128794_.accountBytes(4L * (long)i);
|
||||
TagType<?> tagtype = TagTypes.getType(b0);
|
||||
List<Tag> list = Lists.newArrayListWithCapacity(i);
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
list.add(tagtype.load(p_128792_, p_128793_ + 1, p_128794_));
|
||||
}
|
||||
|
||||
return new ListTag(list, b0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197491_, StreamTagVisitor p_197492_) throws IOException {
|
||||
TagType<?> tagtype = TagTypes.getType(p_197491_.readByte());
|
||||
int i = p_197491_.readInt();
|
||||
switch (p_197492_.visitList(tagtype, i)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
tagtype.skip(p_197491_, i);
|
||||
return p_197492_.visitContainerEnd();
|
||||
default:
|
||||
int j = 0;
|
||||
|
||||
while(true) {
|
||||
label45: {
|
||||
if (j < i) {
|
||||
switch (p_197492_.visitElement(tagtype, j)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
tagtype.skip(p_197491_);
|
||||
break;
|
||||
case SKIP:
|
||||
tagtype.skip(p_197491_);
|
||||
break label45;
|
||||
default:
|
||||
switch (tagtype.parse(p_197491_, p_197492_)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
break;
|
||||
default:
|
||||
break label45;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int k = i - 1 - j;
|
||||
if (k > 0) {
|
||||
tagtype.skip(p_197491_, k);
|
||||
}
|
||||
|
||||
return p_197492_.visitContainerEnd();
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197489_) throws IOException {
|
||||
TagType<?> tagtype = TagTypes.getType(p_197489_.readByte());
|
||||
int i = p_197489_.readInt();
|
||||
tagtype.skip(p_197489_, i);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "LIST";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_List";
|
||||
}
|
||||
};
|
||||
private final List<Tag> list;
|
||||
private byte type;
|
||||
|
||||
ListTag(List<Tag> pList, byte pType) {
|
||||
this.list = pList;
|
||||
this.type = pType;
|
||||
}
|
||||
|
||||
public ListTag() {
|
||||
this(Lists.newArrayList(), (byte)0);
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
if (this.list.isEmpty()) {
|
||||
this.type = 0;
|
||||
} else {
|
||||
this.type = this.list.get(0).getId();
|
||||
}
|
||||
|
||||
pOutput.writeByte(this.type);
|
||||
pOutput.writeInt(this.list.size());
|
||||
|
||||
for(Tag tag : this.list) {
|
||||
tag.write(pOutput);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
int i = 37;
|
||||
i += 4 * this.list.size();
|
||||
|
||||
for(Tag tag : this.list) {
|
||||
i += tag.sizeInBytes();
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
public TagType<ListTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getAsString();
|
||||
}
|
||||
|
||||
private void updateTypeAfterRemove() {
|
||||
if (this.list.isEmpty()) {
|
||||
this.type = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Tag remove(int p_128751_) {
|
||||
Tag tag = this.list.remove(p_128751_);
|
||||
this.updateTypeAfterRemove();
|
||||
return tag;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.list.isEmpty();
|
||||
}
|
||||
|
||||
public CompoundTag getCompound(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 10) {
|
||||
return (CompoundTag)tag;
|
||||
}
|
||||
}
|
||||
|
||||
return new CompoundTag();
|
||||
}
|
||||
|
||||
public ListTag getList(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 9) {
|
||||
return (ListTag)tag;
|
||||
}
|
||||
}
|
||||
|
||||
return new ListTag();
|
||||
}
|
||||
|
||||
public short getShort(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 2) {
|
||||
return ((ShortTag)tag).getAsShort();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getInt(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 3) {
|
||||
return ((IntTag)tag).getAsInt();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int[] getIntArray(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 11) {
|
||||
return ((IntArrayTag)tag).getAsIntArray();
|
||||
}
|
||||
}
|
||||
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
public long[] getLongArray(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 12) {
|
||||
return ((LongArrayTag)tag).getAsLongArray();
|
||||
}
|
||||
}
|
||||
|
||||
return new long[0];
|
||||
}
|
||||
|
||||
public double getDouble(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 6) {
|
||||
return ((DoubleTag)tag).getAsDouble();
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0D;
|
||||
}
|
||||
|
||||
public float getFloat(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
if (tag.getId() == 5) {
|
||||
return ((FloatTag)tag).getAsFloat();
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public String getString(int pIndex) {
|
||||
if (pIndex >= 0 && pIndex < this.list.size()) {
|
||||
Tag tag = this.list.get(pIndex);
|
||||
return tag.getId() == 8 ? tag.getAsString() : tag.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.list.size();
|
||||
}
|
||||
|
||||
public Tag get(int p_128781_) {
|
||||
return this.list.get(p_128781_);
|
||||
}
|
||||
|
||||
public Tag set(int p_128760_, Tag p_128761_) {
|
||||
Tag tag = this.get(p_128760_);
|
||||
if (!this.setTag(p_128760_, p_128761_)) {
|
||||
throw new UnsupportedOperationException(String.format(Locale.ROOT, "Trying to add tag of type %d to list of %d", p_128761_.getId(), this.type));
|
||||
} else {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
public void add(int p_128753_, Tag p_128754_) {
|
||||
if (!this.addTag(p_128753_, p_128754_)) {
|
||||
throw new UnsupportedOperationException(String.format(Locale.ROOT, "Trying to add tag of type %d to list of %d", p_128754_.getId(), this.type));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setTag(int pIndex, Tag pNbt) {
|
||||
if (this.updateType(pNbt)) {
|
||||
this.list.set(pIndex, pNbt);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTag(int pIndex, Tag pNbt) {
|
||||
if (this.updateType(pNbt)) {
|
||||
this.list.add(pIndex, pNbt);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateType(Tag pTag) {
|
||||
if (pTag.getId() == 0) {
|
||||
return false;
|
||||
} else if (this.type == 0) {
|
||||
this.type = pTag.getId();
|
||||
return true;
|
||||
} else {
|
||||
return this.type == pTag.getId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public ListTag copy() {
|
||||
Iterable<Tag> iterable = (Iterable<Tag>)(TagTypes.getType(this.type).isValue() ? this.list : Iterables.transform(this.list, Tag::copy));
|
||||
List<Tag> list = Lists.newArrayList(iterable);
|
||||
return new ListTag(list, this.type);
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof ListTag && Objects.equals(this.list, ((ListTag)pOther).list);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.list.hashCode();
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitList(this);
|
||||
}
|
||||
|
||||
public byte getElementType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.list.clear();
|
||||
this.type = 0;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
switch (pVisitor.visitList(TagTypes.getType(this.type), this.list.size())) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
return pVisitor.visitContainerEnd();
|
||||
default:
|
||||
int i = 0;
|
||||
|
||||
while(i < this.list.size()) {
|
||||
Tag tag = this.list.get(i);
|
||||
switch (pVisitor.visitElement(tag.getType(), i)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
return pVisitor.visitContainerEnd();
|
||||
default:
|
||||
switch (tag.accept(pVisitor)) {
|
||||
case HALT:
|
||||
return StreamTagVisitor.ValueResult.HALT;
|
||||
case BREAK:
|
||||
return pVisitor.visitContainerEnd();
|
||||
}
|
||||
case SKIP:
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return pVisitor.visitContainerEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class LongArrayTag extends CollectionTag<LongTag> {
|
||||
private static final int SELF_SIZE_IN_BYTES = 24;
|
||||
public static final TagType<LongArrayTag> TYPE = new TagType.VariableSize<LongArrayTag>() {
|
||||
public LongArrayTag load(DataInput p_128865_, int p_128866_, NbtAccounter p_128867_) throws IOException {
|
||||
p_128867_.accountBytes(24L);
|
||||
int i = p_128865_.readInt();
|
||||
p_128867_.accountBytes(8L * (long)i);
|
||||
long[] along = new long[i];
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
along[j] = p_128865_.readLong();
|
||||
}
|
||||
|
||||
return new LongArrayTag(along);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197501_, StreamTagVisitor p_197502_) throws IOException {
|
||||
int i = p_197501_.readInt();
|
||||
long[] along = new long[i];
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
along[j] = p_197501_.readLong();
|
||||
}
|
||||
|
||||
return p_197502_.visit(along);
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197499_) throws IOException {
|
||||
p_197499_.skipBytes(p_197499_.readInt() * 8);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "LONG[]";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Long_Array";
|
||||
}
|
||||
};
|
||||
private long[] data;
|
||||
|
||||
public LongArrayTag(long[] pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public LongArrayTag(LongSet pDataSet) {
|
||||
this.data = pDataSet.toLongArray();
|
||||
}
|
||||
|
||||
public LongArrayTag(List<Long> pDataList) {
|
||||
this(toArray(pDataList));
|
||||
}
|
||||
|
||||
private static long[] toArray(List<Long> pDataList) {
|
||||
long[] along = new long[pDataList.size()];
|
||||
|
||||
for(int i = 0; i < pDataList.size(); ++i) {
|
||||
Long olong = pDataList.get(i);
|
||||
along[i] = olong == null ? 0L : olong;
|
||||
}
|
||||
|
||||
return along;
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeInt(this.data.length);
|
||||
|
||||
for(long i : this.data) {
|
||||
pOutput.writeLong(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 24 + 8 * this.data.length;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
public TagType<LongArrayTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public LongArrayTag copy() {
|
||||
long[] along = new long[this.data.length];
|
||||
System.arraycopy(this.data, 0, along, 0, this.data.length);
|
||||
return new LongArrayTag(along);
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof LongArrayTag && Arrays.equals(this.data, ((LongArrayTag)pOther).data);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(this.data);
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitLongArray(this);
|
||||
}
|
||||
|
||||
public long[] getAsLongArray() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.data.length;
|
||||
}
|
||||
|
||||
public LongTag get(int p_128811_) {
|
||||
return LongTag.valueOf(this.data[p_128811_]);
|
||||
}
|
||||
|
||||
public LongTag set(int p_128813_, LongTag p_128814_) {
|
||||
long i = this.data[p_128813_];
|
||||
this.data[p_128813_] = p_128814_.getAsLong();
|
||||
return LongTag.valueOf(i);
|
||||
}
|
||||
|
||||
public void add(int p_128832_, LongTag p_128833_) {
|
||||
this.data = ArrayUtils.add(this.data, p_128832_, p_128833_.getAsLong());
|
||||
}
|
||||
|
||||
public boolean setTag(int pIndex, Tag pNbt) {
|
||||
if (pNbt instanceof NumericTag) {
|
||||
this.data[pIndex] = ((NumericTag)pNbt).getAsLong();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTag(int pIndex, Tag pNbt) {
|
||||
if (pNbt instanceof NumericTag) {
|
||||
this.data = ArrayUtils.add(this.data, pIndex, ((NumericTag)pNbt).getAsLong());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public LongTag remove(int p_128830_) {
|
||||
long i = this.data[p_128830_];
|
||||
this.data = ArrayUtils.remove(this.data, p_128830_);
|
||||
return LongTag.valueOf(i);
|
||||
}
|
||||
|
||||
public byte getElementType() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.data = new long[0];
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LongTag extends NumericTag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 16;
|
||||
public static final TagType<LongTag> TYPE = new TagType.StaticSize<LongTag>() {
|
||||
public LongTag load(DataInput p_128906_, int p_128907_, NbtAccounter p_128908_) throws IOException {
|
||||
p_128908_.accountBytes(16L);
|
||||
return LongTag.valueOf(p_128906_.readLong());
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197506_, StreamTagVisitor p_197507_) throws IOException {
|
||||
return p_197507_.visit(p_197506_.readLong());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "LONG";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Long";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private final long data;
|
||||
|
||||
LongTag(long pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public static LongTag valueOf(long pData) {
|
||||
return pData >= -128L && pData <= 1024L ? LongTag.Cache.cache[(int)pData - -128] : new LongTag(pData);
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeLong(this.data);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public TagType<LongTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public LongTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof LongTag && this.data == ((LongTag)pOther).data;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (int)(this.data ^ this.data >>> 32);
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitLong(this);
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
return (int)(this.data & -1L);
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
return (short)((int)(this.data & 65535L));
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
return (byte)((int)(this.data & 255L));
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
return (double)this.data;
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
return (float)this.data;
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
|
||||
static class Cache {
|
||||
private static final int HIGH = 1024;
|
||||
private static final int LOW = -128;
|
||||
static final LongTag[] cache = new LongTag[1153];
|
||||
|
||||
private Cache() {
|
||||
}
|
||||
|
||||
static {
|
||||
for(int i = 0; i < cache.length; ++i) {
|
||||
cache[i] = new LongTag((long)(-128 + i));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
public class NbtAccounter {
|
||||
public static final NbtAccounter UNLIMITED = new NbtAccounter(0L) {
|
||||
/**
|
||||
* Adds the bytes to the current number of read bytes. If the number of bytes is greater than the stored quota, an
|
||||
* exception will occur.
|
||||
* @throws RuntimeException if the number of {@code usage} bytes exceed the number of {@code quota} bytes
|
||||
*/
|
||||
public void accountBytes(long p_128927_) {
|
||||
}
|
||||
};
|
||||
private final long quota;
|
||||
private long usage;
|
||||
|
||||
public NbtAccounter(long pQuota) {
|
||||
this.quota = pQuota;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the bytes to the current number of read bytes. If the number of bytes is greater than the stored quota, an
|
||||
* exception will occur.
|
||||
* @throws RuntimeException if the number of {@code usage} bytes exceed the number of {@code quota} bytes
|
||||
*/
|
||||
public void accountBytes(long pBytes) {
|
||||
this.usage += pBytes;
|
||||
if (this.usage > this.quota) {
|
||||
throw new RuntimeException("Tried to read NBT tag that was too big; tried to allocate: " + this.usage + "bytes where max allowed: " + this.quota);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* UTF8 is not a simple encoding system, each character can be either
|
||||
* 1, 2, or 3 bytes. Depending on where it's numerical value falls.
|
||||
* We have to count up each character individually to see the true
|
||||
* length of the data.
|
||||
*
|
||||
* Basic concept is that it uses the MSB of each byte as a 'read more' signal.
|
||||
* So it has to shift each 7-bit segment.
|
||||
*
|
||||
* This will accurately count the correct byte length to encode this string, plus the 2 bytes for it's length prefix.
|
||||
*/
|
||||
public String readUTF(String data) {
|
||||
accountBytes(2); //Header length
|
||||
if (data == null)
|
||||
return data;
|
||||
|
||||
int len = data.length();
|
||||
int utflen = 0;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
int c = data.charAt(i);
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) utflen += 1;
|
||||
else if (c > 0x07FF) utflen += 3;
|
||||
else utflen += 2;
|
||||
}
|
||||
accountBytes(utflen);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public long getUsage() {
|
||||
return this.usage;
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.CrashReportCategory;
|
||||
import net.minecraft.ReportedException;
|
||||
import net.minecraft.util.FastBufferedInputStream;
|
||||
|
||||
public class NbtIo {
|
||||
public static CompoundTag readCompressed(File pFile) throws IOException {
|
||||
try (InputStream inputstream = new FileInputStream(pFile)) {
|
||||
return readCompressed(inputstream);
|
||||
}
|
||||
}
|
||||
|
||||
private static DataInputStream createDecompressorStream(InputStream pZippedStream) throws IOException {
|
||||
return new DataInputStream(new FastBufferedInputStream(new GZIPInputStream(pZippedStream)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a compressed compound tag from a GNU zipped file.
|
||||
* @see #readCompressed(File)
|
||||
*/
|
||||
public static CompoundTag readCompressed(InputStream pZippedStream) throws IOException {
|
||||
try (DataInputStream datainputstream = createDecompressorStream(pZippedStream)) {
|
||||
return read(datainputstream, NbtAccounter.UNLIMITED);
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseCompressed(File pFile, StreamTagVisitor pVisitor) throws IOException {
|
||||
try (InputStream inputstream = new FileInputStream(pFile)) {
|
||||
parseCompressed(inputstream, pVisitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void parseCompressed(InputStream pZippedStream, StreamTagVisitor pVisitor) throws IOException {
|
||||
try (DataInputStream datainputstream = createDecompressorStream(pZippedStream)) {
|
||||
parse(datainputstream, pVisitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void writeCompressed(CompoundTag pCompoundTag, File pFile) throws IOException {
|
||||
try (OutputStream outputstream = new FileOutputStream(pFile)) {
|
||||
writeCompressed(pCompoundTag, outputstream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes and compresses a compound tag to a GNU zipped file.
|
||||
* @see #writeCompressed(CompoundTag, File)
|
||||
*/
|
||||
public static void writeCompressed(CompoundTag pCompoundTag, OutputStream pOutputStream) throws IOException {
|
||||
try (DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(pOutputStream)))) {
|
||||
write(pCompoundTag, dataoutputstream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void write(CompoundTag pCompoundTag, File pFile) throws IOException {
|
||||
try (
|
||||
FileOutputStream fileoutputstream = new FileOutputStream(pFile);
|
||||
DataOutputStream dataoutputstream = new DataOutputStream(fileoutputstream);
|
||||
) {
|
||||
write(pCompoundTag, dataoutputstream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CompoundTag read(File pFile) throws IOException {
|
||||
if (!pFile.exists()) {
|
||||
return null;
|
||||
} else {
|
||||
CompoundTag compoundtag;
|
||||
try (
|
||||
FileInputStream fileinputstream = new FileInputStream(pFile);
|
||||
DataInputStream datainputstream = new DataInputStream(fileinputstream);
|
||||
) {
|
||||
compoundtag = read(datainputstream, NbtAccounter.UNLIMITED);
|
||||
}
|
||||
|
||||
return compoundtag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a compound tag from a file. The size of the file can be infinite.
|
||||
*/
|
||||
public static CompoundTag read(DataInput pInput) throws IOException {
|
||||
return read(pInput, NbtAccounter.UNLIMITED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a compound tag from a file. The size of the file is limited by the {@code accounter}.
|
||||
* @throws RuntimeException if the size of the file is larger than the maximum amount of bytes specified by the
|
||||
* {@code accounter}
|
||||
*/
|
||||
public static CompoundTag read(DataInput pInput, NbtAccounter pAccounter) throws IOException {
|
||||
Tag tag = readUnnamedTag(pInput, 0, pAccounter);
|
||||
if (tag instanceof CompoundTag) {
|
||||
return (CompoundTag)tag;
|
||||
} else {
|
||||
throw new IOException("Root tag must be a named compound tag");
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(CompoundTag pCompoundTag, DataOutput pOutput) throws IOException {
|
||||
writeUnnamedTag(pCompoundTag, pOutput);
|
||||
}
|
||||
|
||||
public static void parse(DataInput pInput, StreamTagVisitor pVisitor) throws IOException {
|
||||
TagType<?> tagtype = TagTypes.getType(pInput.readByte());
|
||||
if (tagtype == EndTag.TYPE) {
|
||||
if (pVisitor.visitRootEntry(EndTag.TYPE) == StreamTagVisitor.ValueResult.CONTINUE) {
|
||||
pVisitor.visitEnd();
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (pVisitor.visitRootEntry(tagtype)) {
|
||||
case HALT:
|
||||
default:
|
||||
break;
|
||||
case BREAK:
|
||||
StringTag.skipString(pInput);
|
||||
tagtype.skip(pInput);
|
||||
break;
|
||||
case CONTINUE:
|
||||
StringTag.skipString(pInput);
|
||||
tagtype.parse(pInput, pVisitor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeUnnamedTag(Tag pTag, DataOutput pOutput) throws IOException {
|
||||
pOutput.writeByte(pTag.getId());
|
||||
if (pTag.getId() != 0) {
|
||||
pOutput.writeUTF("");
|
||||
pTag.write(pOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private static Tag readUnnamedTag(DataInput pInput, int pDepth, NbtAccounter pAccounter) throws IOException {
|
||||
byte b0 = pInput.readByte();
|
||||
pAccounter.accountBytes(1); // Forge: Count everything!
|
||||
if (b0 == 0) {
|
||||
return EndTag.INSTANCE;
|
||||
} else {
|
||||
pAccounter.readUTF(pInput.readUTF()); //Forge: Count this string.
|
||||
pAccounter.accountBytes(4); //Forge: 4 extra bytes for the object allocation.
|
||||
|
||||
try {
|
||||
return TagTypes.getType(b0).load(pInput, pDepth, pAccounter);
|
||||
} catch (IOException ioexception) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(ioexception, "Loading NBT data");
|
||||
CrashReportCategory crashreportcategory = crashreport.addCategory("NBT Tag");
|
||||
crashreportcategory.setDetail("Tag type", b0);
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+654
@@ -0,0 +1,654 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.datafixers.DataFixUtils;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.MapLike;
|
||||
import com.mojang.serialization.RecordBuilder;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class NbtOps implements DynamicOps<Tag> {
|
||||
public static final NbtOps INSTANCE = new NbtOps();
|
||||
private static final String WRAPPER_MARKER = "";
|
||||
|
||||
protected NbtOps() {
|
||||
}
|
||||
|
||||
public Tag empty() {
|
||||
return EndTag.INSTANCE;
|
||||
}
|
||||
|
||||
public <U> U convertTo(DynamicOps<U> pOps, Tag pTag) {
|
||||
switch (pTag.getId()) {
|
||||
case 0:
|
||||
return pOps.empty();
|
||||
case 1:
|
||||
return pOps.createByte(((NumericTag)pTag).getAsByte());
|
||||
case 2:
|
||||
return pOps.createShort(((NumericTag)pTag).getAsShort());
|
||||
case 3:
|
||||
return pOps.createInt(((NumericTag)pTag).getAsInt());
|
||||
case 4:
|
||||
return pOps.createLong(((NumericTag)pTag).getAsLong());
|
||||
case 5:
|
||||
return pOps.createFloat(((NumericTag)pTag).getAsFloat());
|
||||
case 6:
|
||||
return pOps.createDouble(((NumericTag)pTag).getAsDouble());
|
||||
case 7:
|
||||
return pOps.createByteList(ByteBuffer.wrap(((ByteArrayTag)pTag).getAsByteArray()));
|
||||
case 8:
|
||||
return pOps.createString(pTag.getAsString());
|
||||
case 9:
|
||||
return this.convertList(pOps, pTag);
|
||||
case 10:
|
||||
return this.convertMap(pOps, pTag);
|
||||
case 11:
|
||||
return pOps.createIntList(Arrays.stream(((IntArrayTag)pTag).getAsIntArray()));
|
||||
case 12:
|
||||
return pOps.createLongList(Arrays.stream(((LongArrayTag)pTag).getAsLongArray()));
|
||||
default:
|
||||
throw new IllegalStateException("Unknown tag type: " + pTag);
|
||||
}
|
||||
}
|
||||
|
||||
public DataResult<Number> getNumberValue(Tag pTag) {
|
||||
if (pTag instanceof NumericTag numerictag) {
|
||||
return DataResult.success(numerictag.getAsNumber());
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a number";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Tag createNumeric(Number pData) {
|
||||
return DoubleTag.valueOf(pData.doubleValue());
|
||||
}
|
||||
|
||||
public Tag createByte(byte pData) {
|
||||
return ByteTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public Tag createShort(short pData) {
|
||||
return ShortTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public Tag createInt(int pData) {
|
||||
return IntTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public Tag createLong(long pData) {
|
||||
return LongTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public Tag createFloat(float pData) {
|
||||
return FloatTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public Tag createDouble(double pData) {
|
||||
return DoubleTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public Tag createBoolean(boolean pData) {
|
||||
return ByteTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public DataResult<String> getStringValue(Tag pTag) {
|
||||
if (pTag instanceof StringTag stringtag) {
|
||||
return DataResult.success(stringtag.getAsString());
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a string";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Tag createString(String pData) {
|
||||
return StringTag.valueOf(pData);
|
||||
}
|
||||
|
||||
public DataResult<Tag> mergeToList(Tag pList, Tag pTag) {
|
||||
return createCollector(pList).map((p_248053_) -> {
|
||||
return DataResult.success(p_248053_.accept(pTag).result());
|
||||
}).orElseGet(() -> {
|
||||
return DataResult.error(() -> {
|
||||
return "mergeToList called with not a list: " + pList;
|
||||
}, pList);
|
||||
});
|
||||
}
|
||||
|
||||
public DataResult<Tag> mergeToList(Tag pList, List<Tag> pTags) {
|
||||
return createCollector(pList).map((p_248048_) -> {
|
||||
return DataResult.success(p_248048_.acceptAll(pTags).result());
|
||||
}).orElseGet(() -> {
|
||||
return DataResult.error(() -> {
|
||||
return "mergeToList called with not a list: " + pList;
|
||||
}, pList);
|
||||
});
|
||||
}
|
||||
|
||||
public DataResult<Tag> mergeToMap(Tag pMap, Tag pKey, Tag pValue) {
|
||||
if (!(pMap instanceof CompoundTag) && !(pMap instanceof EndTag)) {
|
||||
return DataResult.error(() -> {
|
||||
return "mergeToMap called with not a map: " + pMap;
|
||||
}, pMap);
|
||||
} else if (!(pKey instanceof StringTag)) {
|
||||
return DataResult.error(() -> {
|
||||
return "key is not a string: " + pKey;
|
||||
}, pMap);
|
||||
} else {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
if (pMap instanceof CompoundTag) {
|
||||
CompoundTag compoundtag1 = (CompoundTag)pMap;
|
||||
compoundtag1.getAllKeys().forEach((p_129068_) -> {
|
||||
compoundtag.put(p_129068_, compoundtag1.get(p_129068_));
|
||||
});
|
||||
}
|
||||
|
||||
compoundtag.put(pKey.getAsString(), pValue);
|
||||
return DataResult.success(compoundtag);
|
||||
}
|
||||
}
|
||||
|
||||
public DataResult<Tag> mergeToMap(Tag pMap, MapLike<Tag> pOtherMap) {
|
||||
if (!(pMap instanceof CompoundTag) && !(pMap instanceof EndTag)) {
|
||||
return DataResult.error(() -> {
|
||||
return "mergeToMap called with not a map: " + pMap;
|
||||
}, pMap);
|
||||
} else {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
if (pMap instanceof CompoundTag) {
|
||||
CompoundTag compoundtag1 = (CompoundTag)pMap;
|
||||
compoundtag1.getAllKeys().forEach((p_129059_) -> {
|
||||
compoundtag.put(p_129059_, compoundtag1.get(p_129059_));
|
||||
});
|
||||
}
|
||||
|
||||
List<Tag> list = Lists.newArrayList();
|
||||
pOtherMap.entries().forEach((p_128994_) -> {
|
||||
Tag tag = p_128994_.getFirst();
|
||||
if (!(tag instanceof StringTag)) {
|
||||
list.add(tag);
|
||||
} else {
|
||||
compoundtag.put(tag.getAsString(), p_128994_.getSecond());
|
||||
}
|
||||
});
|
||||
return !list.isEmpty() ? DataResult.error(() -> {
|
||||
return "some keys are not strings: " + list;
|
||||
}, compoundtag) : DataResult.success(compoundtag);
|
||||
}
|
||||
}
|
||||
|
||||
public DataResult<Stream<Pair<Tag, Tag>>> getMapValues(Tag pMap) {
|
||||
if (pMap instanceof CompoundTag compoundtag) {
|
||||
return DataResult.success(compoundtag.getAllKeys().stream().map((p_129021_) -> {
|
||||
return Pair.of(this.createString(p_129021_), compoundtag.get(p_129021_));
|
||||
}));
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a map: " + pMap;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public DataResult<Consumer<BiConsumer<Tag, Tag>>> getMapEntries(Tag pMap) {
|
||||
if (pMap instanceof CompoundTag compoundtag) {
|
||||
return DataResult.success((p_129024_) -> {
|
||||
compoundtag.getAllKeys().forEach((p_178006_) -> {
|
||||
p_129024_.accept(this.createString(p_178006_), compoundtag.get(p_178006_));
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a map: " + pMap;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public DataResult<MapLike<Tag>> getMap(Tag pMap) {
|
||||
if (pMap instanceof final CompoundTag compoundtag) {
|
||||
return DataResult.success(new MapLike<Tag>() {
|
||||
@Nullable
|
||||
public Tag get(Tag p_129174_) {
|
||||
return compoundtag.get(p_129174_.getAsString());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tag get(String p_129169_) {
|
||||
return compoundtag.get(p_129169_);
|
||||
}
|
||||
|
||||
public Stream<Pair<Tag, Tag>> entries() {
|
||||
return compoundtag.getAllKeys().stream().map((p_129172_) -> {
|
||||
return Pair.of(NbtOps.this.createString(p_129172_), compoundtag.get(p_129172_));
|
||||
});
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "MapLike[" + compoundtag + "]";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a map: " + pMap;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Tag createMap(Stream<Pair<Tag, Tag>> pData) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
pData.forEach((p_129018_) -> {
|
||||
compoundtag.put(p_129018_.getFirst().getAsString(), p_129018_.getSecond());
|
||||
});
|
||||
return compoundtag;
|
||||
}
|
||||
|
||||
private static Tag tryUnwrap(CompoundTag pTag) {
|
||||
if (pTag.size() == 1) {
|
||||
Tag tag = pTag.get("");
|
||||
if (tag != null) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
return pTag;
|
||||
}
|
||||
|
||||
public DataResult<Stream<Tag>> getStream(Tag pTag) {
|
||||
if (pTag instanceof ListTag listtag) {
|
||||
return listtag.getElementType() == 10 ? DataResult.success(listtag.stream().map((p_248049_) -> {
|
||||
return tryUnwrap((CompoundTag)p_248049_);
|
||||
})) : DataResult.success(listtag.stream());
|
||||
} else if (pTag instanceof CollectionTag<?> collectiontag) {
|
||||
return DataResult.success(collectiontag.stream().map((p_129158_) -> {
|
||||
return p_129158_;
|
||||
}));
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a list";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public DataResult<Consumer<Consumer<Tag>>> getList(Tag pTag) {
|
||||
if (pTag instanceof ListTag listtag) {
|
||||
return listtag.getElementType() == 10 ? DataResult.success((p_248055_) -> {
|
||||
listtag.forEach((p_248051_) -> {
|
||||
p_248055_.accept(tryUnwrap((CompoundTag)p_248051_));
|
||||
});
|
||||
}) : DataResult.success(listtag::forEach);
|
||||
} else if (pTag instanceof CollectionTag<?> collectiontag) {
|
||||
return DataResult.success(collectiontag::forEach);
|
||||
} else {
|
||||
return DataResult.error(() -> {
|
||||
return "Not a list: " + pTag;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public DataResult<ByteBuffer> getByteBuffer(Tag pTag) {
|
||||
if (pTag instanceof ByteArrayTag bytearraytag) {
|
||||
return DataResult.success(ByteBuffer.wrap(bytearraytag.getAsByteArray()));
|
||||
} else {
|
||||
return DynamicOps.super.getByteBuffer(pTag);
|
||||
}
|
||||
}
|
||||
|
||||
public Tag createByteList(ByteBuffer pData) {
|
||||
return new ByteArrayTag(DataFixUtils.toArray(pData));
|
||||
}
|
||||
|
||||
public DataResult<IntStream> getIntStream(Tag pTag) {
|
||||
if (pTag instanceof IntArrayTag intarraytag) {
|
||||
return DataResult.success(Arrays.stream(intarraytag.getAsIntArray()));
|
||||
} else {
|
||||
return DynamicOps.super.getIntStream(pTag);
|
||||
}
|
||||
}
|
||||
|
||||
public Tag createIntList(IntStream pData) {
|
||||
return new IntArrayTag(pData.toArray());
|
||||
}
|
||||
|
||||
public DataResult<LongStream> getLongStream(Tag pTag) {
|
||||
if (pTag instanceof LongArrayTag longarraytag) {
|
||||
return DataResult.success(Arrays.stream(longarraytag.getAsLongArray()));
|
||||
} else {
|
||||
return DynamicOps.super.getLongStream(pTag);
|
||||
}
|
||||
}
|
||||
|
||||
public Tag createLongList(LongStream pData) {
|
||||
return new LongArrayTag(pData.toArray());
|
||||
}
|
||||
|
||||
public Tag createList(Stream<Tag> pData) {
|
||||
return NbtOps.InitialListCollector.INSTANCE.acceptAll(pData).result();
|
||||
}
|
||||
|
||||
public Tag remove(Tag pMap, String pRemoveKey) {
|
||||
if (pMap instanceof CompoundTag compoundtag) {
|
||||
CompoundTag compoundtag1 = new CompoundTag();
|
||||
compoundtag.getAllKeys().stream().filter((p_128988_) -> {
|
||||
return !Objects.equals(p_128988_, pRemoveKey);
|
||||
}).forEach((p_129028_) -> {
|
||||
compoundtag1.put(p_129028_, compoundtag.get(p_129028_));
|
||||
});
|
||||
return compoundtag1;
|
||||
} else {
|
||||
return pMap;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "NBT";
|
||||
}
|
||||
|
||||
public RecordBuilder<Tag> mapBuilder() {
|
||||
return new NbtOps.NbtRecordBuilder();
|
||||
}
|
||||
|
||||
private static Optional<NbtOps.ListCollector> createCollector(Tag pTag) {
|
||||
if (pTag instanceof EndTag) {
|
||||
return Optional.of(NbtOps.InitialListCollector.INSTANCE);
|
||||
} else {
|
||||
if (pTag instanceof CollectionTag) {
|
||||
CollectionTag<?> collectiontag = (CollectionTag)pTag;
|
||||
if (collectiontag.isEmpty()) {
|
||||
return Optional.of(NbtOps.InitialListCollector.INSTANCE);
|
||||
}
|
||||
|
||||
if (collectiontag instanceof ListTag) {
|
||||
ListTag listtag = (ListTag)collectiontag;
|
||||
Optional optional;
|
||||
switch (listtag.getElementType()) {
|
||||
case 0:
|
||||
optional = Optional.of(NbtOps.InitialListCollector.INSTANCE);
|
||||
break;
|
||||
case 10:
|
||||
optional = Optional.of(new NbtOps.HeterogenousListCollector(listtag));
|
||||
break;
|
||||
default:
|
||||
optional = Optional.of(new NbtOps.HomogenousListCollector(listtag));
|
||||
}
|
||||
|
||||
return optional;
|
||||
}
|
||||
|
||||
if (collectiontag instanceof ByteArrayTag) {
|
||||
ByteArrayTag bytearraytag = (ByteArrayTag)collectiontag;
|
||||
return Optional.of(new NbtOps.ByteListCollector(bytearraytag.getAsByteArray()));
|
||||
}
|
||||
|
||||
if (collectiontag instanceof IntArrayTag) {
|
||||
IntArrayTag intarraytag = (IntArrayTag)collectiontag;
|
||||
return Optional.of(new NbtOps.IntListCollector(intarraytag.getAsIntArray()));
|
||||
}
|
||||
|
||||
if (collectiontag instanceof LongArrayTag) {
|
||||
LongArrayTag longarraytag = (LongArrayTag)collectiontag;
|
||||
return Optional.of(new NbtOps.LongListCollector(longarraytag.getAsLongArray()));
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
static class ByteListCollector implements NbtOps.ListCollector {
|
||||
private final ByteArrayList values = new ByteArrayList();
|
||||
|
||||
public ByteListCollector(byte pValue) {
|
||||
this.values.add(pValue);
|
||||
}
|
||||
|
||||
public ByteListCollector(byte[] pValues) {
|
||||
this.values.addElements(0, pValues);
|
||||
}
|
||||
|
||||
public NbtOps.ListCollector accept(Tag pTag) {
|
||||
if (pTag instanceof ByteTag bytetag) {
|
||||
this.values.add(bytetag.getAsByte());
|
||||
return this;
|
||||
} else {
|
||||
return (new NbtOps.HeterogenousListCollector(this.values)).accept(pTag);
|
||||
}
|
||||
}
|
||||
|
||||
public Tag result() {
|
||||
return new ByteArrayTag(this.values.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
static class HeterogenousListCollector implements NbtOps.ListCollector {
|
||||
private final ListTag result = new ListTag();
|
||||
|
||||
public HeterogenousListCollector() {
|
||||
}
|
||||
|
||||
public HeterogenousListCollector(Collection<Tag> p_249606_) {
|
||||
this.result.addAll(p_249606_);
|
||||
}
|
||||
|
||||
public HeterogenousListCollector(IntArrayList p_250270_) {
|
||||
p_250270_.forEach((p_249166_) -> {
|
||||
this.result.add(wrapElement(IntTag.valueOf(p_249166_)));
|
||||
});
|
||||
}
|
||||
|
||||
public HeterogenousListCollector(ByteArrayList p_248575_) {
|
||||
p_248575_.forEach((p_249160_) -> {
|
||||
this.result.add(wrapElement(ByteTag.valueOf(p_249160_)));
|
||||
});
|
||||
}
|
||||
|
||||
public HeterogenousListCollector(LongArrayList p_249410_) {
|
||||
p_249410_.forEach((p_249754_) -> {
|
||||
this.result.add(wrapElement(LongTag.valueOf(p_249754_)));
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isWrapper(CompoundTag p_252073_) {
|
||||
return p_252073_.size() == 1 && p_252073_.contains("");
|
||||
}
|
||||
|
||||
private static Tag wrapIfNeeded(Tag p_252042_) {
|
||||
if (p_252042_ instanceof CompoundTag compoundtag) {
|
||||
if (!isWrapper(compoundtag)) {
|
||||
return compoundtag;
|
||||
}
|
||||
}
|
||||
|
||||
return wrapElement(p_252042_);
|
||||
}
|
||||
|
||||
private static CompoundTag wrapElement(Tag p_251263_) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
compoundtag.put("", p_251263_);
|
||||
return compoundtag;
|
||||
}
|
||||
|
||||
public NbtOps.ListCollector accept(Tag p_249045_) {
|
||||
this.result.add(wrapIfNeeded(p_249045_));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tag result() {
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
|
||||
static class HomogenousListCollector implements NbtOps.ListCollector {
|
||||
private final ListTag result = new ListTag();
|
||||
|
||||
HomogenousListCollector(Tag pValue) {
|
||||
this.result.add(pValue);
|
||||
}
|
||||
|
||||
HomogenousListCollector(ListTag pValues) {
|
||||
this.result.addAll(pValues);
|
||||
}
|
||||
|
||||
public NbtOps.ListCollector accept(Tag pTag) {
|
||||
if (pTag.getId() != this.result.getElementType()) {
|
||||
return (new NbtOps.HeterogenousListCollector()).acceptAll(this.result).accept(pTag);
|
||||
} else {
|
||||
this.result.add(pTag);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Tag result() {
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
|
||||
static class InitialListCollector implements NbtOps.ListCollector {
|
||||
public static final NbtOps.InitialListCollector INSTANCE = new NbtOps.InitialListCollector();
|
||||
|
||||
private InitialListCollector() {
|
||||
}
|
||||
|
||||
public NbtOps.ListCollector accept(Tag p_251635_) {
|
||||
if (p_251635_ instanceof CompoundTag compoundtag) {
|
||||
return (new NbtOps.HeterogenousListCollector()).accept(compoundtag);
|
||||
} else if (p_251635_ instanceof ByteTag bytetag) {
|
||||
return new NbtOps.ByteListCollector(bytetag.getAsByte());
|
||||
} else if (p_251635_ instanceof IntTag inttag) {
|
||||
return new NbtOps.IntListCollector(inttag.getAsInt());
|
||||
} else if (p_251635_ instanceof LongTag longtag) {
|
||||
return new NbtOps.LongListCollector(longtag.getAsLong());
|
||||
} else {
|
||||
return new NbtOps.HomogenousListCollector(p_251635_);
|
||||
}
|
||||
}
|
||||
|
||||
public Tag result() {
|
||||
return new ListTag();
|
||||
}
|
||||
}
|
||||
|
||||
static class IntListCollector implements NbtOps.ListCollector {
|
||||
private final IntArrayList values = new IntArrayList();
|
||||
|
||||
public IntListCollector(int pValue) {
|
||||
this.values.add(pValue);
|
||||
}
|
||||
|
||||
public IntListCollector(int[] pValues) {
|
||||
this.values.addElements(0, pValues);
|
||||
}
|
||||
|
||||
public NbtOps.ListCollector accept(Tag pTag) {
|
||||
if (pTag instanceof IntTag inttag) {
|
||||
this.values.add(inttag.getAsInt());
|
||||
return this;
|
||||
} else {
|
||||
return (new NbtOps.HeterogenousListCollector(this.values)).accept(pTag);
|
||||
}
|
||||
}
|
||||
|
||||
public Tag result() {
|
||||
return new IntArrayTag(this.values.toIntArray());
|
||||
}
|
||||
}
|
||||
|
||||
interface ListCollector {
|
||||
NbtOps.ListCollector accept(Tag pTag);
|
||||
|
||||
default NbtOps.ListCollector acceptAll(Iterable<Tag> p_249781_) {
|
||||
NbtOps.ListCollector nbtops$listcollector = this;
|
||||
|
||||
for(Tag tag : p_249781_) {
|
||||
nbtops$listcollector = nbtops$listcollector.accept(tag);
|
||||
}
|
||||
|
||||
return nbtops$listcollector;
|
||||
}
|
||||
|
||||
default NbtOps.ListCollector acceptAll(Stream<Tag> p_249876_) {
|
||||
return this.acceptAll(p_249876_::iterator);
|
||||
}
|
||||
|
||||
Tag result();
|
||||
}
|
||||
|
||||
static class LongListCollector implements NbtOps.ListCollector {
|
||||
private final LongArrayList values = new LongArrayList();
|
||||
|
||||
public LongListCollector(long pValue) {
|
||||
this.values.add(pValue);
|
||||
}
|
||||
|
||||
public LongListCollector(long[] pValues) {
|
||||
this.values.addElements(0, pValues);
|
||||
}
|
||||
|
||||
public NbtOps.ListCollector accept(Tag pTag) {
|
||||
if (pTag instanceof LongTag longtag) {
|
||||
this.values.add(longtag.getAsLong());
|
||||
return this;
|
||||
} else {
|
||||
return (new NbtOps.HeterogenousListCollector(this.values)).accept(pTag);
|
||||
}
|
||||
}
|
||||
|
||||
public Tag result() {
|
||||
return new LongArrayTag(this.values.toLongArray());
|
||||
}
|
||||
}
|
||||
|
||||
class NbtRecordBuilder extends RecordBuilder.AbstractStringBuilder<Tag, CompoundTag> {
|
||||
protected NbtRecordBuilder() {
|
||||
super(NbtOps.this);
|
||||
}
|
||||
|
||||
protected CompoundTag initBuilder() {
|
||||
return new CompoundTag();
|
||||
}
|
||||
|
||||
protected CompoundTag append(String pKey, Tag pValue, CompoundTag pTag) {
|
||||
pTag.put(pKey, pValue);
|
||||
return pTag;
|
||||
}
|
||||
|
||||
protected DataResult<Tag> build(CompoundTag p_129190_, Tag p_129191_) {
|
||||
if (p_129191_ != null && p_129191_ != EndTag.INSTANCE) {
|
||||
if (!(p_129191_ instanceof CompoundTag)) {
|
||||
return DataResult.error(() -> {
|
||||
return "mergeToMap called with not a map: " + p_129191_;
|
||||
}, p_129191_);
|
||||
} else {
|
||||
CompoundTag compoundtag = (CompoundTag)p_129191_;
|
||||
CompoundTag compoundtag1 = new CompoundTag(Maps.newHashMap(compoundtag.entries()));
|
||||
|
||||
for(Map.Entry<String, Tag> entry : p_129190_.entries().entrySet()) {
|
||||
compoundtag1.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return DataResult.success(compoundtag1);
|
||||
}
|
||||
} else {
|
||||
return DataResult.success(p_129190_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+657
@@ -0,0 +1,657 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.StringUtil;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.StateHolder;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public final class NbtUtils {
|
||||
private static final Comparator<ListTag> YXZ_LISTTAG_INT_COMPARATOR = Comparator.<ListTag>comparingInt((p_178074_) -> {
|
||||
return p_178074_.getInt(1);
|
||||
}).thenComparingInt((p_178070_) -> {
|
||||
return p_178070_.getInt(0);
|
||||
}).thenComparingInt((p_178066_) -> {
|
||||
return p_178066_.getInt(2);
|
||||
});
|
||||
private static final Comparator<ListTag> YXZ_LISTTAG_DOUBLE_COMPARATOR = Comparator.<ListTag>comparingDouble((p_178060_) -> {
|
||||
return p_178060_.getDouble(1);
|
||||
}).thenComparingDouble((p_178056_) -> {
|
||||
return p_178056_.getDouble(0);
|
||||
}).thenComparingDouble((p_178042_) -> {
|
||||
return p_178042_.getDouble(2);
|
||||
});
|
||||
public static final String SNBT_DATA_TAG = "data";
|
||||
private static final char PROPERTIES_START = '{';
|
||||
private static final char PROPERTIES_END = '}';
|
||||
private static final String ELEMENT_SEPARATOR = ",";
|
||||
private static final char KEY_VALUE_SEPARATOR = ':';
|
||||
private static final Splitter COMMA_SPLITTER = Splitter.on(",");
|
||||
private static final Splitter COLON_SPLITTER = Splitter.on(':').limit(2);
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int INDENT = 2;
|
||||
private static final int NOT_FOUND = -1;
|
||||
|
||||
private NbtUtils() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GameProfile readGameProfile(CompoundTag pTag) {
|
||||
String s = null;
|
||||
UUID uuid = null;
|
||||
if (pTag.contains("Name", 8)) {
|
||||
s = pTag.getString("Name");
|
||||
}
|
||||
|
||||
if (pTag.hasUUID("Id")) {
|
||||
uuid = pTag.getUUID("Id");
|
||||
}
|
||||
|
||||
try {
|
||||
GameProfile gameprofile = new GameProfile(uuid, s);
|
||||
if (pTag.contains("Properties", 10)) {
|
||||
CompoundTag compoundtag = pTag.getCompound("Properties");
|
||||
|
||||
for(String s1 : compoundtag.getAllKeys()) {
|
||||
ListTag listtag = compoundtag.getList(s1, 10);
|
||||
|
||||
for(int i = 0; i < listtag.size(); ++i) {
|
||||
CompoundTag compoundtag1 = listtag.getCompound(i);
|
||||
String s2 = compoundtag1.getString("Value");
|
||||
if (compoundtag1.contains("Signature", 8)) {
|
||||
gameprofile.getProperties().put(s1, new com.mojang.authlib.properties.Property(s1, s2, compoundtag1.getString("Signature")));
|
||||
} else {
|
||||
gameprofile.getProperties().put(s1, new com.mojang.authlib.properties.Property(s1, s2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gameprofile;
|
||||
} catch (Throwable throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a {@code profile} to the given {@code tag}.
|
||||
*/
|
||||
public static CompoundTag writeGameProfile(CompoundTag pTag, GameProfile pProfile) {
|
||||
if (!StringUtil.isNullOrEmpty(pProfile.getName())) {
|
||||
pTag.putString("Name", pProfile.getName());
|
||||
}
|
||||
|
||||
if (pProfile.getId() != null) {
|
||||
pTag.putUUID("Id", pProfile.getId());
|
||||
}
|
||||
|
||||
if (!pProfile.getProperties().isEmpty()) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
|
||||
for(String s : pProfile.getProperties().keySet()) {
|
||||
ListTag listtag = new ListTag();
|
||||
|
||||
for(com.mojang.authlib.properties.Property property : pProfile.getProperties().get(s)) {
|
||||
CompoundTag compoundtag1 = new CompoundTag();
|
||||
compoundtag1.putString("Value", property.getValue());
|
||||
if (property.hasSignature()) {
|
||||
compoundtag1.putString("Signature", property.getSignature());
|
||||
}
|
||||
|
||||
listtag.add(compoundtag1);
|
||||
}
|
||||
|
||||
compoundtag.put(s, listtag);
|
||||
}
|
||||
|
||||
pTag.put("Properties", compoundtag);
|
||||
}
|
||||
|
||||
return pTag;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static boolean compareNbt(@Nullable Tag pTag, @Nullable Tag pOther, boolean pCompareListTag) {
|
||||
if (pTag == pOther) {
|
||||
return true;
|
||||
} else if (pTag == null) {
|
||||
return true;
|
||||
} else if (pOther == null) {
|
||||
return false;
|
||||
} else if (!pTag.getClass().equals(pOther.getClass())) {
|
||||
return false;
|
||||
} else if (pTag instanceof CompoundTag) {
|
||||
CompoundTag compoundtag = (CompoundTag)pTag;
|
||||
CompoundTag compoundtag1 = (CompoundTag)pOther;
|
||||
|
||||
for(String s : compoundtag.getAllKeys()) {
|
||||
Tag tag1 = compoundtag.get(s);
|
||||
if (!compareNbt(tag1, compoundtag1.get(s), pCompareListTag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (pTag instanceof ListTag && pCompareListTag) {
|
||||
ListTag listtag = (ListTag)pTag;
|
||||
ListTag listtag1 = (ListTag)pOther;
|
||||
if (listtag.isEmpty()) {
|
||||
return listtag1.isEmpty();
|
||||
} else {
|
||||
for(int i = 0; i < listtag.size(); ++i) {
|
||||
Tag tag = listtag.get(i);
|
||||
boolean flag = false;
|
||||
|
||||
for(int j = 0; j < listtag1.size(); ++j) {
|
||||
if (compareNbt(tag, listtag1.get(j), pCompareListTag)) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return pTag.equals(pOther);
|
||||
}
|
||||
}
|
||||
|
||||
public static IntArrayTag createUUID(UUID pUuid) {
|
||||
return new IntArrayTag(UUIDUtil.uuidToIntArray(pUuid));
|
||||
}
|
||||
|
||||
public static UUID loadUUID(Tag pTag) {
|
||||
if (pTag.getType() != IntArrayTag.TYPE) {
|
||||
throw new IllegalArgumentException("Expected UUID-Tag to be of type " + IntArrayTag.TYPE.getName() + ", but found " + pTag.getType().getName() + ".");
|
||||
} else {
|
||||
int[] aint = ((IntArrayTag)pTag).getAsIntArray();
|
||||
if (aint.length != 4) {
|
||||
throw new IllegalArgumentException("Expected UUID-Array to be of length 4, but found " + aint.length + ".");
|
||||
} else {
|
||||
return UUIDUtil.uuidFromIntArray(aint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BlockPos readBlockPos(CompoundTag pTag) {
|
||||
return new BlockPos(pTag.getInt("X"), pTag.getInt("Y"), pTag.getInt("Z"));
|
||||
}
|
||||
|
||||
public static CompoundTag writeBlockPos(BlockPos pPos) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
compoundtag.putInt("X", pPos.getX());
|
||||
compoundtag.putInt("Y", pPos.getY());
|
||||
compoundtag.putInt("Z", pPos.getZ());
|
||||
return compoundtag;
|
||||
}
|
||||
|
||||
public static BlockState readBlockState(HolderGetter<Block> pBlockGetter, CompoundTag pTag) {
|
||||
if (!pTag.contains("Name", 8)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
} else {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(pTag.getString("Name"));
|
||||
Optional<? extends Holder<Block>> optional = pBlockGetter.get(ResourceKey.create(Registries.BLOCK, resourcelocation));
|
||||
if (optional.isEmpty()) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
} else {
|
||||
Block block = optional.get().value();
|
||||
BlockState blockstate = block.defaultBlockState();
|
||||
if (pTag.contains("Properties", 10)) {
|
||||
CompoundTag compoundtag = pTag.getCompound("Properties");
|
||||
StateDefinition<Block, BlockState> statedefinition = block.getStateDefinition();
|
||||
|
||||
for(String s : compoundtag.getAllKeys()) {
|
||||
Property<?> property = statedefinition.getProperty(s);
|
||||
if (property != null) {
|
||||
blockstate = setValueHelper(blockstate, property, s, compoundtag, pTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blockstate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <S extends StateHolder<?, S>, T extends Comparable<T>> S setValueHelper(S pStateHolder, Property<T> pProperty, String pPropertyName, CompoundTag pPropertiesTag, CompoundTag pBlockStateTag) {
|
||||
Optional<T> optional = pProperty.getValue(pPropertiesTag.getString(pPropertyName));
|
||||
if (optional.isPresent()) {
|
||||
return pStateHolder.setValue(pProperty, optional.get());
|
||||
} else {
|
||||
LOGGER.warn("Unable to read property: {} with value: {} for blockstate: {}", pPropertyName, pPropertiesTag.getString(pPropertyName), pBlockStateTag.toString());
|
||||
return pStateHolder;
|
||||
}
|
||||
}
|
||||
|
||||
public static CompoundTag writeBlockState(BlockState pState) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
compoundtag.putString("Name", BuiltInRegistries.BLOCK.getKey(pState.getBlock()).toString());
|
||||
ImmutableMap<Property<?>, Comparable<?>> immutablemap = pState.getValues();
|
||||
if (!immutablemap.isEmpty()) {
|
||||
CompoundTag compoundtag1 = new CompoundTag();
|
||||
|
||||
for(Map.Entry<Property<?>, Comparable<?>> entry : immutablemap.entrySet()) {
|
||||
Property<?> property = entry.getKey();
|
||||
compoundtag1.putString(property.getName(), getName(property, entry.getValue()));
|
||||
}
|
||||
|
||||
compoundtag.put("Properties", compoundtag1);
|
||||
}
|
||||
|
||||
return compoundtag;
|
||||
}
|
||||
|
||||
public static CompoundTag writeFluidState(FluidState pState) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
compoundtag.putString("Name", BuiltInRegistries.FLUID.getKey(pState.getType()).toString());
|
||||
ImmutableMap<Property<?>, Comparable<?>> immutablemap = pState.getValues();
|
||||
if (!immutablemap.isEmpty()) {
|
||||
CompoundTag compoundtag1 = new CompoundTag();
|
||||
|
||||
for(Map.Entry<Property<?>, Comparable<?>> entry : immutablemap.entrySet()) {
|
||||
Property<?> property = entry.getKey();
|
||||
compoundtag1.putString(property.getName(), getName(property, entry.getValue()));
|
||||
}
|
||||
|
||||
compoundtag.put("Properties", compoundtag1);
|
||||
}
|
||||
|
||||
return compoundtag;
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> String getName(Property<T> pProperty, Comparable<?> pValue) {
|
||||
return pProperty.getName((T)pValue);
|
||||
}
|
||||
|
||||
public static String prettyPrint(Tag pTag) {
|
||||
return prettyPrint(pTag, false);
|
||||
}
|
||||
|
||||
public static String prettyPrint(Tag pTag, boolean pPrettyPrintArray) {
|
||||
return prettyPrint(new StringBuilder(), pTag, 0, pPrettyPrintArray).toString();
|
||||
}
|
||||
|
||||
public static StringBuilder prettyPrint(StringBuilder pStringBuilder, Tag pTag, int pIndentLevel, boolean pPrettyPrintArray) {
|
||||
switch (pTag.getId()) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 8:
|
||||
pStringBuilder.append((Object)pTag);
|
||||
break;
|
||||
case 7:
|
||||
ByteArrayTag bytearraytag = (ByteArrayTag)pTag;
|
||||
byte[] abyte = bytearraytag.getAsByteArray();
|
||||
int k1 = abyte.length;
|
||||
indent(pIndentLevel, pStringBuilder).append("byte[").append(k1).append("] {\n");
|
||||
if (!pPrettyPrintArray) {
|
||||
indent(pIndentLevel + 1, pStringBuilder).append(" // Skipped, supply withBinaryBlobs true");
|
||||
} else {
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
|
||||
for(int i2 = 0; i2 < abyte.length; ++i2) {
|
||||
if (i2 != 0) {
|
||||
pStringBuilder.append(',');
|
||||
}
|
||||
|
||||
if (i2 % 16 == 0 && i2 / 16 > 0) {
|
||||
pStringBuilder.append('\n');
|
||||
if (i2 < abyte.length) {
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
}
|
||||
} else if (i2 != 0) {
|
||||
pStringBuilder.append(' ');
|
||||
}
|
||||
|
||||
pStringBuilder.append(String.format(Locale.ROOT, "0x%02X", abyte[i2] & 255));
|
||||
}
|
||||
}
|
||||
|
||||
pStringBuilder.append('\n');
|
||||
indent(pIndentLevel, pStringBuilder).append('}');
|
||||
break;
|
||||
case 9:
|
||||
ListTag listtag = (ListTag)pTag;
|
||||
int k = listtag.size();
|
||||
int j1 = listtag.getElementType();
|
||||
String s1 = j1 == 0 ? "undefined" : TagTypes.getType(j1).getPrettyName();
|
||||
indent(pIndentLevel, pStringBuilder).append("list<").append(s1).append(">[").append(k).append("] [");
|
||||
if (k != 0) {
|
||||
pStringBuilder.append('\n');
|
||||
}
|
||||
|
||||
for(int i3 = 0; i3 < k; ++i3) {
|
||||
if (i3 != 0) {
|
||||
pStringBuilder.append(",\n");
|
||||
}
|
||||
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
prettyPrint(pStringBuilder, listtag.get(i3), pIndentLevel + 1, pPrettyPrintArray);
|
||||
}
|
||||
|
||||
if (k != 0) {
|
||||
pStringBuilder.append('\n');
|
||||
}
|
||||
|
||||
indent(pIndentLevel, pStringBuilder).append(']');
|
||||
break;
|
||||
case 10:
|
||||
CompoundTag compoundtag = (CompoundTag)pTag;
|
||||
List<String> list = Lists.newArrayList(compoundtag.getAllKeys());
|
||||
Collections.sort(list);
|
||||
indent(pIndentLevel, pStringBuilder).append('{');
|
||||
if (pStringBuilder.length() - pStringBuilder.lastIndexOf("\n") > 2 * (pIndentLevel + 1)) {
|
||||
pStringBuilder.append('\n');
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
}
|
||||
|
||||
int i1 = list.stream().mapToInt(String::length).max().orElse(0);
|
||||
String s = Strings.repeat(" ", i1);
|
||||
|
||||
for(int l2 = 0; l2 < list.size(); ++l2) {
|
||||
if (l2 != 0) {
|
||||
pStringBuilder.append(",\n");
|
||||
}
|
||||
|
||||
String s2 = list.get(l2);
|
||||
indent(pIndentLevel + 1, pStringBuilder).append('"').append(s2).append('"').append((CharSequence)s, 0, s.length() - s2.length()).append(": ");
|
||||
prettyPrint(pStringBuilder, compoundtag.get(s2), pIndentLevel + 1, pPrettyPrintArray);
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
pStringBuilder.append('\n');
|
||||
}
|
||||
|
||||
indent(pIndentLevel, pStringBuilder).append('}');
|
||||
break;
|
||||
case 11:
|
||||
IntArrayTag intarraytag = (IntArrayTag)pTag;
|
||||
int[] aint = intarraytag.getAsIntArray();
|
||||
int l = 0;
|
||||
|
||||
for(int k3 : aint) {
|
||||
l = Math.max(l, String.format(Locale.ROOT, "%X", k3).length());
|
||||
}
|
||||
|
||||
int l1 = aint.length;
|
||||
indent(pIndentLevel, pStringBuilder).append("int[").append(l1).append("] {\n");
|
||||
if (!pPrettyPrintArray) {
|
||||
indent(pIndentLevel + 1, pStringBuilder).append(" // Skipped, supply withBinaryBlobs true");
|
||||
} else {
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
|
||||
for(int k2 = 0; k2 < aint.length; ++k2) {
|
||||
if (k2 != 0) {
|
||||
pStringBuilder.append(',');
|
||||
}
|
||||
|
||||
if (k2 % 16 == 0 && k2 / 16 > 0) {
|
||||
pStringBuilder.append('\n');
|
||||
if (k2 < aint.length) {
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
}
|
||||
} else if (k2 != 0) {
|
||||
pStringBuilder.append(' ');
|
||||
}
|
||||
|
||||
pStringBuilder.append(String.format(Locale.ROOT, "0x%0" + l + "X", aint[k2]));
|
||||
}
|
||||
}
|
||||
|
||||
pStringBuilder.append('\n');
|
||||
indent(pIndentLevel, pStringBuilder).append('}');
|
||||
break;
|
||||
case 12:
|
||||
LongArrayTag longarraytag = (LongArrayTag)pTag;
|
||||
long[] along = longarraytag.getAsLongArray();
|
||||
long i = 0L;
|
||||
|
||||
for(long j : along) {
|
||||
i = Math.max(i, (long)String.format(Locale.ROOT, "%X", j).length());
|
||||
}
|
||||
|
||||
long j2 = (long)along.length;
|
||||
indent(pIndentLevel, pStringBuilder).append("long[").append(j2).append("] {\n");
|
||||
if (!pPrettyPrintArray) {
|
||||
indent(pIndentLevel + 1, pStringBuilder).append(" // Skipped, supply withBinaryBlobs true");
|
||||
} else {
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
|
||||
for(int j3 = 0; j3 < along.length; ++j3) {
|
||||
if (j3 != 0) {
|
||||
pStringBuilder.append(',');
|
||||
}
|
||||
|
||||
if (j3 % 16 == 0 && j3 / 16 > 0) {
|
||||
pStringBuilder.append('\n');
|
||||
if (j3 < along.length) {
|
||||
indent(pIndentLevel + 1, pStringBuilder);
|
||||
}
|
||||
} else if (j3 != 0) {
|
||||
pStringBuilder.append(' ');
|
||||
}
|
||||
|
||||
pStringBuilder.append(String.format(Locale.ROOT, "0x%0" + i + "X", along[j3]));
|
||||
}
|
||||
}
|
||||
|
||||
pStringBuilder.append('\n');
|
||||
indent(pIndentLevel, pStringBuilder).append('}');
|
||||
break;
|
||||
default:
|
||||
pStringBuilder.append("<UNKNOWN :(>");
|
||||
}
|
||||
|
||||
return pStringBuilder;
|
||||
}
|
||||
|
||||
private static StringBuilder indent(int pIndentLevel, StringBuilder pStringBuilder) {
|
||||
int i = pStringBuilder.lastIndexOf("\n") + 1;
|
||||
int j = pStringBuilder.length() - i;
|
||||
|
||||
for(int k = 0; k < 2 * pIndentLevel - j; ++k) {
|
||||
pStringBuilder.append(' ');
|
||||
}
|
||||
|
||||
return pStringBuilder;
|
||||
}
|
||||
|
||||
public static Component toPrettyComponent(Tag pTag) {
|
||||
return (new TextComponentTagVisitor("", 0)).visit(pTag);
|
||||
}
|
||||
|
||||
public static String structureToSnbt(CompoundTag pTag) {
|
||||
return (new SnbtPrinterTagVisitor()).visit(packStructureTemplate(pTag));
|
||||
}
|
||||
|
||||
public static CompoundTag snbtToStructure(String pText) throws CommandSyntaxException {
|
||||
return unpackStructureTemplate(TagParser.parseTag(pText));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static CompoundTag packStructureTemplate(CompoundTag pTag) {
|
||||
boolean flag = pTag.contains("palettes", 9);
|
||||
ListTag listtag;
|
||||
if (flag) {
|
||||
listtag = pTag.getList("palettes", 9).getList(0);
|
||||
} else {
|
||||
listtag = pTag.getList("palette", 10);
|
||||
}
|
||||
|
||||
ListTag listtag1 = listtag.stream().map(CompoundTag.class::cast).map(NbtUtils::packBlockState).map(StringTag::valueOf).collect(Collectors.toCollection(ListTag::new));
|
||||
pTag.put("palette", listtag1);
|
||||
if (flag) {
|
||||
ListTag listtag2 = new ListTag();
|
||||
ListTag listtag3 = pTag.getList("palettes", 9);
|
||||
listtag3.stream().map(ListTag.class::cast).forEach((p_178049_) -> {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
|
||||
for(int i = 0; i < p_178049_.size(); ++i) {
|
||||
compoundtag.putString(listtag1.getString(i), packBlockState(p_178049_.getCompound(i)));
|
||||
}
|
||||
|
||||
listtag2.add(compoundtag);
|
||||
});
|
||||
pTag.put("palettes", listtag2);
|
||||
}
|
||||
|
||||
if (pTag.contains("entities", 9)) {
|
||||
ListTag listtag4 = pTag.getList("entities", 10);
|
||||
ListTag listtag6 = listtag4.stream().map(CompoundTag.class::cast).sorted(Comparator.comparing((p_178080_) -> {
|
||||
return p_178080_.getList("pos", 6);
|
||||
}, YXZ_LISTTAG_DOUBLE_COMPARATOR)).collect(Collectors.toCollection(ListTag::new));
|
||||
pTag.put("entities", listtag6);
|
||||
}
|
||||
|
||||
ListTag listtag5 = pTag.getList("blocks", 10).stream().map(CompoundTag.class::cast).sorted(Comparator.comparing((p_178078_) -> {
|
||||
return p_178078_.getList("pos", 3);
|
||||
}, YXZ_LISTTAG_INT_COMPARATOR)).peek((p_178045_) -> {
|
||||
p_178045_.putString("state", listtag1.getString(p_178045_.getInt("state")));
|
||||
}).collect(Collectors.toCollection(ListTag::new));
|
||||
pTag.put("data", listtag5);
|
||||
pTag.remove("blocks");
|
||||
return pTag;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static CompoundTag unpackStructureTemplate(CompoundTag pTag) {
|
||||
ListTag listtag = pTag.getList("palette", 8);
|
||||
Map<String, Tag> map = listtag.stream().map(StringTag.class::cast).map(StringTag::getAsString).collect(ImmutableMap.toImmutableMap(Function.identity(), NbtUtils::unpackBlockState));
|
||||
if (pTag.contains("palettes", 9)) {
|
||||
pTag.put("palettes", pTag.getList("palettes", 10).stream().map(CompoundTag.class::cast).map((p_178033_) -> {
|
||||
return map.keySet().stream().map(p_178033_::getString).map(NbtUtils::unpackBlockState).collect(Collectors.toCollection(ListTag::new));
|
||||
}).collect(Collectors.toCollection(ListTag::new)));
|
||||
pTag.remove("palette");
|
||||
} else {
|
||||
pTag.put("palette", map.values().stream().collect(Collectors.toCollection(ListTag::new)));
|
||||
}
|
||||
|
||||
if (pTag.contains("data", 9)) {
|
||||
Object2IntMap<String> object2intmap = new Object2IntOpenHashMap<>();
|
||||
object2intmap.defaultReturnValue(-1);
|
||||
|
||||
for(int i = 0; i < listtag.size(); ++i) {
|
||||
object2intmap.put(listtag.getString(i), i);
|
||||
}
|
||||
|
||||
ListTag listtag1 = pTag.getList("data", 10);
|
||||
|
||||
for(int j = 0; j < listtag1.size(); ++j) {
|
||||
CompoundTag compoundtag = listtag1.getCompound(j);
|
||||
String s = compoundtag.getString("state");
|
||||
int k = object2intmap.getInt(s);
|
||||
if (k == -1) {
|
||||
throw new IllegalStateException("Entry " + s + " missing from palette");
|
||||
}
|
||||
|
||||
compoundtag.putInt("state", k);
|
||||
}
|
||||
|
||||
pTag.put("blocks", listtag1);
|
||||
pTag.remove("data");
|
||||
}
|
||||
|
||||
return pTag;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static String packBlockState(CompoundTag p_178076_) {
|
||||
StringBuilder stringbuilder = new StringBuilder(p_178076_.getString("Name"));
|
||||
if (p_178076_.contains("Properties", 10)) {
|
||||
CompoundTag compoundtag = p_178076_.getCompound("Properties");
|
||||
String s = compoundtag.getAllKeys().stream().sorted().map((p_178036_) -> {
|
||||
return p_178036_ + ":" + compoundtag.get(p_178036_).getAsString();
|
||||
}).collect(Collectors.joining(","));
|
||||
stringbuilder.append('{').append(s).append('}');
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static CompoundTag unpackBlockState(String p_178054_) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
int i = p_178054_.indexOf(123);
|
||||
String s;
|
||||
if (i >= 0) {
|
||||
s = p_178054_.substring(0, i);
|
||||
CompoundTag compoundtag1 = new CompoundTag();
|
||||
if (i + 2 <= p_178054_.length()) {
|
||||
String s1 = p_178054_.substring(i + 1, p_178054_.indexOf(125, i));
|
||||
COMMA_SPLITTER.split(s1).forEach((p_178040_) -> {
|
||||
List<String> list = COLON_SPLITTER.splitToList(p_178040_);
|
||||
if (list.size() == 2) {
|
||||
compoundtag1.putString(list.get(0), list.get(1));
|
||||
} else {
|
||||
LOGGER.error("Something went wrong parsing: '{}' -- incorrect gamedata!", (Object)p_178054_);
|
||||
}
|
||||
|
||||
});
|
||||
compoundtag.put("Properties", compoundtag1);
|
||||
}
|
||||
} else {
|
||||
s = p_178054_;
|
||||
}
|
||||
|
||||
compoundtag.putString("Name", s);
|
||||
return compoundtag;
|
||||
}
|
||||
|
||||
public static CompoundTag addCurrentDataVersion(CompoundTag pTag) {
|
||||
int i = SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
||||
return addDataVersion(pTag, i);
|
||||
}
|
||||
|
||||
public static CompoundTag addDataVersion(CompoundTag pTag, int pDataVersion) {
|
||||
pTag.putInt("DataVersion", pDataVersion);
|
||||
return pTag;
|
||||
}
|
||||
|
||||
public static int getDataVersion(CompoundTag pTag, int pDefaultValue) {
|
||||
return pTag.contains("DataVersion", 99) ? pTag.getInt("DataVersion") : pDefaultValue;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
public abstract class NumericTag implements Tag {
|
||||
protected NumericTag() {
|
||||
}
|
||||
|
||||
public abstract long getAsLong();
|
||||
|
||||
public abstract int getAsInt();
|
||||
|
||||
public abstract short getAsShort();
|
||||
|
||||
public abstract byte getAsByte();
|
||||
|
||||
public abstract double getAsDouble();
|
||||
|
||||
public abstract float getAsFloat();
|
||||
|
||||
public abstract Number getAsNumber();
|
||||
|
||||
public String toString() {
|
||||
return this.getAsString();
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ShortTag extends NumericTag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 10;
|
||||
public static final TagType<ShortTag> TYPE = new TagType.StaticSize<ShortTag>() {
|
||||
public ShortTag load(DataInput p_129277_, int p_129278_, NbtAccounter p_129279_) throws IOException {
|
||||
p_129279_.accountBytes(10L);
|
||||
return ShortTag.valueOf(p_129277_.readShort());
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197517_, StreamTagVisitor p_197518_) throws IOException {
|
||||
return p_197518_.visit(p_197517_.readShort());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "SHORT";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_Short";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private final short data;
|
||||
|
||||
ShortTag(short pData) {
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public static ShortTag valueOf(short pData) {
|
||||
return pData >= -128 && pData <= 1024 ? ShortTag.Cache.cache[pData - -128] : new ShortTag(pData);
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
pOutput.writeShort(this.data);
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public TagType<ShortTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public ShortTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof ShortTag && this.data == ((ShortTag)pOther).data;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitShort(this);
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
return (long)this.data;
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
return (byte)(this.data & 255);
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
return (double)this.data;
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
return (float)this.data;
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
|
||||
static class Cache {
|
||||
private static final int HIGH = 1024;
|
||||
private static final int LOW = -128;
|
||||
static final ShortTag[] cache = new ShortTag[1153];
|
||||
|
||||
private Cache() {
|
||||
}
|
||||
|
||||
static {
|
||||
for(int i = 0; i < cache.length; ++i) {
|
||||
cache[i] = new ShortTag((short)(-128 + i));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import net.minecraft.Util;
|
||||
|
||||
public class SnbtPrinterTagVisitor implements TagVisitor {
|
||||
private static final Map<String, List<String>> KEY_ORDER = Util.make(Maps.newHashMap(), (p_178114_) -> {
|
||||
p_178114_.put("{}", Lists.newArrayList("DataVersion", "author", "size", "data", "entities", "palette", "palettes"));
|
||||
p_178114_.put("{}.data.[].{}", Lists.newArrayList("pos", "state", "nbt"));
|
||||
p_178114_.put("{}.entities.[].{}", Lists.newArrayList("blockPos", "pos"));
|
||||
});
|
||||
private static final Set<String> NO_INDENTATION = Sets.newHashSet("{}.size.[]", "{}.data.[].{}", "{}.palette.[].{}", "{}.entities.[].{}");
|
||||
private static final Pattern SIMPLE_VALUE = Pattern.compile("[A-Za-z0-9._+-]+");
|
||||
private static final String NAME_VALUE_SEPARATOR = String.valueOf(':');
|
||||
private static final String ELEMENT_SEPARATOR = String.valueOf(',');
|
||||
private static final String LIST_OPEN = "[";
|
||||
private static final String LIST_CLOSE = "]";
|
||||
private static final String LIST_TYPE_SEPARATOR = ";";
|
||||
private static final String ELEMENT_SPACING = " ";
|
||||
private static final String STRUCT_OPEN = "{";
|
||||
private static final String STRUCT_CLOSE = "}";
|
||||
private static final String NEWLINE = "\n";
|
||||
private final String indentation;
|
||||
private final int depth;
|
||||
private final List<String> path;
|
||||
private String result = "";
|
||||
|
||||
public SnbtPrinterTagVisitor() {
|
||||
this(" ", 0, Lists.newArrayList());
|
||||
}
|
||||
|
||||
public SnbtPrinterTagVisitor(String pIndentation, int pDepth, List<String> pPath) {
|
||||
this.indentation = pIndentation;
|
||||
this.depth = pDepth;
|
||||
this.path = pPath;
|
||||
}
|
||||
|
||||
public String visit(Tag pTag) {
|
||||
pTag.accept(this);
|
||||
return this.result;
|
||||
}
|
||||
|
||||
public void visitString(StringTag pTag) {
|
||||
this.result = StringTag.quoteAndEscape(pTag.getAsString());
|
||||
}
|
||||
|
||||
public void visitByte(ByteTag pTag) {
|
||||
this.result = pTag.getAsNumber() + "b";
|
||||
}
|
||||
|
||||
public void visitShort(ShortTag pTag) {
|
||||
this.result = pTag.getAsNumber() + "s";
|
||||
}
|
||||
|
||||
public void visitInt(IntTag pTag) {
|
||||
this.result = String.valueOf((Object)pTag.getAsNumber());
|
||||
}
|
||||
|
||||
public void visitLong(LongTag pTag) {
|
||||
this.result = pTag.getAsNumber() + "L";
|
||||
}
|
||||
|
||||
public void visitFloat(FloatTag pTag) {
|
||||
this.result = pTag.getAsFloat() + "f";
|
||||
}
|
||||
|
||||
public void visitDouble(DoubleTag pTag) {
|
||||
this.result = pTag.getAsDouble() + "d";
|
||||
}
|
||||
|
||||
public void visitByteArray(ByteArrayTag pTag) {
|
||||
StringBuilder stringbuilder = (new StringBuilder("[")).append("B").append(";");
|
||||
byte[] abyte = pTag.getAsByteArray();
|
||||
|
||||
for(int i = 0; i < abyte.length; ++i) {
|
||||
stringbuilder.append(" ").append((int)abyte[i]).append("B");
|
||||
if (i != abyte.length - 1) {
|
||||
stringbuilder.append(ELEMENT_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
stringbuilder.append("]");
|
||||
this.result = stringbuilder.toString();
|
||||
}
|
||||
|
||||
public void visitIntArray(IntArrayTag pTag) {
|
||||
StringBuilder stringbuilder = (new StringBuilder("[")).append("I").append(";");
|
||||
int[] aint = pTag.getAsIntArray();
|
||||
|
||||
for(int i = 0; i < aint.length; ++i) {
|
||||
stringbuilder.append(" ").append(aint[i]);
|
||||
if (i != aint.length - 1) {
|
||||
stringbuilder.append(ELEMENT_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
stringbuilder.append("]");
|
||||
this.result = stringbuilder.toString();
|
||||
}
|
||||
|
||||
public void visitLongArray(LongArrayTag pTag) {
|
||||
String s = "L";
|
||||
StringBuilder stringbuilder = (new StringBuilder("[")).append("L").append(";");
|
||||
long[] along = pTag.getAsLongArray();
|
||||
|
||||
for(int i = 0; i < along.length; ++i) {
|
||||
stringbuilder.append(" ").append(along[i]).append("L");
|
||||
if (i != along.length - 1) {
|
||||
stringbuilder.append(ELEMENT_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
stringbuilder.append("]");
|
||||
this.result = stringbuilder.toString();
|
||||
}
|
||||
|
||||
public void visitList(ListTag pTag) {
|
||||
if (pTag.isEmpty()) {
|
||||
this.result = "[]";
|
||||
} else {
|
||||
StringBuilder stringbuilder = new StringBuilder("[");
|
||||
this.pushPath("[]");
|
||||
String s = NO_INDENTATION.contains(this.pathString()) ? "" : this.indentation;
|
||||
if (!s.isEmpty()) {
|
||||
stringbuilder.append("\n");
|
||||
}
|
||||
|
||||
for(int i = 0; i < pTag.size(); ++i) {
|
||||
stringbuilder.append(Strings.repeat(s, this.depth + 1));
|
||||
stringbuilder.append((new SnbtPrinterTagVisitor(s, this.depth + 1, this.path)).visit(pTag.get(i)));
|
||||
if (i != pTag.size() - 1) {
|
||||
stringbuilder.append(ELEMENT_SEPARATOR).append(s.isEmpty() ? " " : "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.isEmpty()) {
|
||||
stringbuilder.append("\n").append(Strings.repeat(s, this.depth));
|
||||
}
|
||||
|
||||
stringbuilder.append("]");
|
||||
this.result = stringbuilder.toString();
|
||||
this.popPath();
|
||||
}
|
||||
}
|
||||
|
||||
public void visitCompound(CompoundTag pTag) {
|
||||
if (pTag.isEmpty()) {
|
||||
this.result = "{}";
|
||||
} else {
|
||||
StringBuilder stringbuilder = new StringBuilder("{");
|
||||
this.pushPath("{}");
|
||||
String s = NO_INDENTATION.contains(this.pathString()) ? "" : this.indentation;
|
||||
if (!s.isEmpty()) {
|
||||
stringbuilder.append("\n");
|
||||
}
|
||||
|
||||
Collection<String> collection = this.getKeys(pTag);
|
||||
Iterator<String> iterator = collection.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
String s1 = iterator.next();
|
||||
Tag tag = pTag.get(s1);
|
||||
this.pushPath(s1);
|
||||
stringbuilder.append(Strings.repeat(s, this.depth + 1)).append(handleEscapePretty(s1)).append(NAME_VALUE_SEPARATOR).append(" ").append((new SnbtPrinterTagVisitor(s, this.depth + 1, this.path)).visit(tag));
|
||||
this.popPath();
|
||||
if (iterator.hasNext()) {
|
||||
stringbuilder.append(ELEMENT_SEPARATOR).append(s.isEmpty() ? " " : "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.isEmpty()) {
|
||||
stringbuilder.append("\n").append(Strings.repeat(s, this.depth));
|
||||
}
|
||||
|
||||
stringbuilder.append("}");
|
||||
this.result = stringbuilder.toString();
|
||||
this.popPath();
|
||||
}
|
||||
}
|
||||
|
||||
private void popPath() {
|
||||
this.path.remove(this.path.size() - 1);
|
||||
}
|
||||
|
||||
private void pushPath(String pKey) {
|
||||
this.path.add(pKey);
|
||||
}
|
||||
|
||||
protected List<String> getKeys(CompoundTag pTag) {
|
||||
Set<String> set = Sets.newHashSet(pTag.getAllKeys());
|
||||
List<String> list = Lists.newArrayList();
|
||||
List<String> list1 = KEY_ORDER.get(this.pathString());
|
||||
if (list1 != null) {
|
||||
for(String s : list1) {
|
||||
if (set.remove(s)) {
|
||||
list.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (!set.isEmpty()) {
|
||||
set.stream().sorted().forEach(list::add);
|
||||
}
|
||||
} else {
|
||||
list.addAll(set);
|
||||
Collections.sort(list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public String pathString() {
|
||||
return String.join(".", this.path);
|
||||
}
|
||||
|
||||
protected static String handleEscapePretty(String pText) {
|
||||
return SIMPLE_VALUE.matcher(pText).matches() ? pText : StringTag.quoteAndEscape(pText);
|
||||
}
|
||||
|
||||
public void visitEnd(EndTag pTag) {
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
public interface StreamTagVisitor {
|
||||
StreamTagVisitor.ValueResult visitEnd();
|
||||
|
||||
StreamTagVisitor.ValueResult visit(String pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(byte pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(short pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(int pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(long pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(float pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(double pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(byte[] pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(int[] pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visit(long[] pEntry);
|
||||
|
||||
StreamTagVisitor.ValueResult visitList(TagType<?> pType, int p_197528_);
|
||||
|
||||
StreamTagVisitor.EntryResult visitEntry(TagType<?> pType);
|
||||
|
||||
StreamTagVisitor.EntryResult visitEntry(TagType<?> pType, String pId);
|
||||
|
||||
StreamTagVisitor.EntryResult visitElement(TagType<?> pType, int p_197537_);
|
||||
|
||||
StreamTagVisitor.ValueResult visitContainerEnd();
|
||||
|
||||
StreamTagVisitor.ValueResult visitRootEntry(TagType<?> pType);
|
||||
|
||||
public static enum EntryResult {
|
||||
ENTER,
|
||||
SKIP,
|
||||
BREAK,
|
||||
HALT;
|
||||
}
|
||||
|
||||
public static enum ValueResult {
|
||||
CONTINUE,
|
||||
BREAK,
|
||||
HALT;
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.UTFDataFormatException;
|
||||
import java.util.Objects;
|
||||
import net.minecraft.Util;
|
||||
|
||||
public class StringTag implements Tag {
|
||||
private static final int SELF_SIZE_IN_BYTES = 36;
|
||||
public static final TagType<StringTag> TYPE = new TagType.VariableSize<StringTag>() {
|
||||
public StringTag load(DataInput p_129315_, int p_129316_, NbtAccounter p_129317_) throws IOException {
|
||||
p_129317_.accountBytes(36L);
|
||||
String s = p_129315_.readUTF();
|
||||
p_129317_.readUTF(s);
|
||||
return StringTag.valueOf(s);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197570_, StreamTagVisitor p_197571_) throws IOException {
|
||||
return p_197571_.visit(p_197570_.readUTF());
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197568_) throws IOException {
|
||||
StringTag.skipString(p_197568_);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "STRING";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "TAG_String";
|
||||
}
|
||||
|
||||
public boolean isValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private static final StringTag EMPTY = new StringTag("");
|
||||
private static final char DOUBLE_QUOTE = '"';
|
||||
private static final char SINGLE_QUOTE = '\'';
|
||||
private static final char ESCAPE = '\\';
|
||||
private static final char NOT_SET = '\u0000';
|
||||
private final String data;
|
||||
|
||||
public static void skipString(DataInput pInput) throws IOException {
|
||||
pInput.skipBytes(pInput.readUnsignedShort());
|
||||
}
|
||||
|
||||
private StringTag(String pData) {
|
||||
Objects.requireNonNull(pData, "Null string not allowed");
|
||||
this.data = pData;
|
||||
}
|
||||
|
||||
public static StringTag valueOf(String pData) {
|
||||
return pData.isEmpty() ? EMPTY : new StringTag(pData);
|
||||
}
|
||||
|
||||
public void write(DataOutput pOutput) throws IOException {
|
||||
try {
|
||||
pOutput.writeUTF(this.data);
|
||||
} catch (UTFDataFormatException utfdataformatexception) {
|
||||
Util.logAndPauseIfInIde("Failed to write NBT String", utfdataformatexception);
|
||||
pOutput.writeUTF("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int sizeInBytes() {
|
||||
return 36 + 2 * this.data.length();
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public TagType<StringTag> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Tag.super.getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
public StringTag copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else {
|
||||
return pOther instanceof StringTag && Objects.equals(this.data, ((StringTag)pOther).data);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.data.hashCode();
|
||||
}
|
||||
|
||||
public String getAsString() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public void accept(TagVisitor pVisitor) {
|
||||
pVisitor.visitString(this);
|
||||
}
|
||||
|
||||
public static String quoteAndEscape(String pText) {
|
||||
StringBuilder stringbuilder = new StringBuilder(" ");
|
||||
char c0 = 0;
|
||||
|
||||
for(int i = 0; i < pText.length(); ++i) {
|
||||
char c1 = pText.charAt(i);
|
||||
if (c1 == '\\') {
|
||||
stringbuilder.append('\\');
|
||||
} else if (c1 == '"' || c1 == '\'') {
|
||||
if (c0 == 0) {
|
||||
c0 = (char)(c1 == '"' ? 39 : 34);
|
||||
}
|
||||
|
||||
if (c0 == c1) {
|
||||
stringbuilder.append('\\');
|
||||
}
|
||||
}
|
||||
|
||||
stringbuilder.append(c1);
|
||||
}
|
||||
|
||||
if (c0 == 0) {
|
||||
c0 = '"';
|
||||
}
|
||||
|
||||
stringbuilder.setCharAt(0, c0);
|
||||
stringbuilder.append(c0);
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor) {
|
||||
return pVisitor.visit(this.data);
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class StringTagVisitor implements TagVisitor {
|
||||
private static final Pattern SIMPLE_VALUE = Pattern.compile("[A-Za-z0-9._+-]+");
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
public String visit(Tag pTag) {
|
||||
pTag.accept(this);
|
||||
return this.builder.toString();
|
||||
}
|
||||
|
||||
public void visitString(StringTag pTag) {
|
||||
this.builder.append(StringTag.quoteAndEscape(pTag.getAsString()));
|
||||
}
|
||||
|
||||
public void visitByte(ByteTag pTag) {
|
||||
this.builder.append((Object)pTag.getAsNumber()).append('b');
|
||||
}
|
||||
|
||||
public void visitShort(ShortTag pTag) {
|
||||
this.builder.append((Object)pTag.getAsNumber()).append('s');
|
||||
}
|
||||
|
||||
public void visitInt(IntTag pTag) {
|
||||
this.builder.append((Object)pTag.getAsNumber());
|
||||
}
|
||||
|
||||
public void visitLong(LongTag pTag) {
|
||||
this.builder.append((Object)pTag.getAsNumber()).append('L');
|
||||
}
|
||||
|
||||
public void visitFloat(FloatTag pTag) {
|
||||
this.builder.append(pTag.getAsFloat()).append('f');
|
||||
}
|
||||
|
||||
public void visitDouble(DoubleTag pTag) {
|
||||
this.builder.append(pTag.getAsDouble()).append('d');
|
||||
}
|
||||
|
||||
public void visitByteArray(ByteArrayTag pTag) {
|
||||
this.builder.append("[B;");
|
||||
byte[] abyte = pTag.getAsByteArray();
|
||||
|
||||
for(int i = 0; i < abyte.length; ++i) {
|
||||
if (i != 0) {
|
||||
this.builder.append(',');
|
||||
}
|
||||
|
||||
this.builder.append((int)abyte[i]).append('B');
|
||||
}
|
||||
|
||||
this.builder.append(']');
|
||||
}
|
||||
|
||||
public void visitIntArray(IntArrayTag pTag) {
|
||||
this.builder.append("[I;");
|
||||
int[] aint = pTag.getAsIntArray();
|
||||
|
||||
for(int i = 0; i < aint.length; ++i) {
|
||||
if (i != 0) {
|
||||
this.builder.append(',');
|
||||
}
|
||||
|
||||
this.builder.append(aint[i]);
|
||||
}
|
||||
|
||||
this.builder.append(']');
|
||||
}
|
||||
|
||||
public void visitLongArray(LongArrayTag pTag) {
|
||||
this.builder.append("[L;");
|
||||
long[] along = pTag.getAsLongArray();
|
||||
|
||||
for(int i = 0; i < along.length; ++i) {
|
||||
if (i != 0) {
|
||||
this.builder.append(',');
|
||||
}
|
||||
|
||||
this.builder.append(along[i]).append('L');
|
||||
}
|
||||
|
||||
this.builder.append(']');
|
||||
}
|
||||
|
||||
public void visitList(ListTag pTag) {
|
||||
this.builder.append('[');
|
||||
|
||||
for(int i = 0; i < pTag.size(); ++i) {
|
||||
if (i != 0) {
|
||||
this.builder.append(',');
|
||||
}
|
||||
|
||||
this.builder.append((new StringTagVisitor()).visit(pTag.get(i)));
|
||||
}
|
||||
|
||||
this.builder.append(']');
|
||||
}
|
||||
|
||||
public void visitCompound(CompoundTag pTag) {
|
||||
this.builder.append('{');
|
||||
List<String> list = Lists.newArrayList(pTag.getAllKeys());
|
||||
Collections.sort(list);
|
||||
|
||||
for(String s : list) {
|
||||
if (this.builder.length() != 1) {
|
||||
this.builder.append(',');
|
||||
}
|
||||
|
||||
this.builder.append(handleEscape(s)).append(':').append((new StringTagVisitor()).visit(pTag.get(s)));
|
||||
}
|
||||
|
||||
this.builder.append('}');
|
||||
}
|
||||
|
||||
protected static String handleEscape(String pText) {
|
||||
return SIMPLE_VALUE.matcher(pText).matches() ? pText : StringTag.quoteAndEscape(pText);
|
||||
}
|
||||
|
||||
public void visitEnd(EndTag pTag) {
|
||||
this.builder.append("END");
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Tag {
|
||||
int OBJECT_HEADER = 8;
|
||||
int ARRAY_HEADER = 12;
|
||||
int OBJECT_REFERENCE = 4;
|
||||
int STRING_SIZE = 28;
|
||||
byte TAG_END = 0;
|
||||
byte TAG_BYTE = 1;
|
||||
byte TAG_SHORT = 2;
|
||||
byte TAG_INT = 3;
|
||||
byte TAG_LONG = 4;
|
||||
byte TAG_FLOAT = 5;
|
||||
byte TAG_DOUBLE = 6;
|
||||
byte TAG_BYTE_ARRAY = 7;
|
||||
byte TAG_STRING = 8;
|
||||
byte TAG_LIST = 9;
|
||||
byte TAG_COMPOUND = 10;
|
||||
byte TAG_INT_ARRAY = 11;
|
||||
byte TAG_LONG_ARRAY = 12;
|
||||
byte TAG_ANY_NUMERIC = 99;
|
||||
int MAX_DEPTH = 512;
|
||||
|
||||
void write(DataOutput pOutput) throws IOException;
|
||||
|
||||
String toString();
|
||||
|
||||
byte getId();
|
||||
|
||||
TagType<?> getType();
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the value held by this tag. Primitive and string tage will return the same tag instance
|
||||
* while all other objects will return a new tag instance with the copied data.
|
||||
*/
|
||||
Tag copy();
|
||||
|
||||
int sizeInBytes();
|
||||
|
||||
default String getAsString() {
|
||||
return (new StringTagVisitor()).visit(this);
|
||||
}
|
||||
|
||||
void accept(TagVisitor pVisitor);
|
||||
|
||||
StreamTagVisitor.ValueResult accept(StreamTagVisitor pVisitor);
|
||||
|
||||
default void acceptAsRoot(StreamTagVisitor pVisitor) {
|
||||
StreamTagVisitor.ValueResult streamtagvisitor$valueresult = pVisitor.visitRootEntry(this.getType());
|
||||
if (streamtagvisitor$valueresult == StreamTagVisitor.ValueResult.CONTINUE) {
|
||||
this.accept(pVisitor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public class TagParser {
|
||||
public static final SimpleCommandExceptionType ERROR_TRAILING_DATA = new SimpleCommandExceptionType(Component.translatable("argument.nbt.trailing"));
|
||||
public static final SimpleCommandExceptionType ERROR_EXPECTED_KEY = new SimpleCommandExceptionType(Component.translatable("argument.nbt.expected.key"));
|
||||
public static final SimpleCommandExceptionType ERROR_EXPECTED_VALUE = new SimpleCommandExceptionType(Component.translatable("argument.nbt.expected.value"));
|
||||
public static final Dynamic2CommandExceptionType ERROR_INSERT_MIXED_LIST = new Dynamic2CommandExceptionType((p_129366_, p_129367_) -> {
|
||||
return Component.translatable("argument.nbt.list.mixed", p_129366_, p_129367_);
|
||||
});
|
||||
public static final Dynamic2CommandExceptionType ERROR_INSERT_MIXED_ARRAY = new Dynamic2CommandExceptionType((p_129357_, p_129358_) -> {
|
||||
return Component.translatable("argument.nbt.array.mixed", p_129357_, p_129358_);
|
||||
});
|
||||
public static final DynamicCommandExceptionType ERROR_INVALID_ARRAY = new DynamicCommandExceptionType((p_129355_) -> {
|
||||
return Component.translatable("argument.nbt.array.invalid", p_129355_);
|
||||
});
|
||||
public static final char ELEMENT_SEPARATOR = ',';
|
||||
public static final char NAME_VALUE_SEPARATOR = ':';
|
||||
private static final char LIST_OPEN = '[';
|
||||
private static final char LIST_CLOSE = ']';
|
||||
private static final char STRUCT_CLOSE = '}';
|
||||
private static final char STRUCT_OPEN = '{';
|
||||
private static final Pattern DOUBLE_PATTERN_NOSUFFIX = Pattern.compile("[-+]?(?:[0-9]+[.]|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?", 2);
|
||||
private static final Pattern DOUBLE_PATTERN = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
|
||||
private static final Pattern FLOAT_PATTERN = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?f", 2);
|
||||
private static final Pattern BYTE_PATTERN = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)b", 2);
|
||||
private static final Pattern LONG_PATTERN = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)l", 2);
|
||||
private static final Pattern SHORT_PATTERN = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)s", 2);
|
||||
private static final Pattern INT_PATTERN = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)");
|
||||
private final StringReader reader;
|
||||
|
||||
public static CompoundTag parseTag(String pText) throws CommandSyntaxException {
|
||||
return (new TagParser(new StringReader(pText))).readSingleStruct();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
CompoundTag readSingleStruct() throws CommandSyntaxException {
|
||||
CompoundTag compoundtag = this.readStruct();
|
||||
this.reader.skipWhitespace();
|
||||
if (this.reader.canRead()) {
|
||||
throw ERROR_TRAILING_DATA.createWithContext(this.reader);
|
||||
} else {
|
||||
return compoundtag;
|
||||
}
|
||||
}
|
||||
|
||||
public TagParser(StringReader pReader) {
|
||||
this.reader = pReader;
|
||||
}
|
||||
|
||||
protected String readKey() throws CommandSyntaxException {
|
||||
this.reader.skipWhitespace();
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_KEY.createWithContext(this.reader);
|
||||
} else {
|
||||
return this.reader.readString();
|
||||
}
|
||||
}
|
||||
|
||||
protected Tag readTypedValue() throws CommandSyntaxException {
|
||||
this.reader.skipWhitespace();
|
||||
int i = this.reader.getCursor();
|
||||
if (StringReader.isQuotedStringStart(this.reader.peek())) {
|
||||
return StringTag.valueOf(this.reader.readQuotedString());
|
||||
} else {
|
||||
String s = this.reader.readUnquotedString();
|
||||
if (s.isEmpty()) {
|
||||
this.reader.setCursor(i);
|
||||
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
||||
} else {
|
||||
return this.type(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Tag type(String pValue) {
|
||||
try {
|
||||
if (FLOAT_PATTERN.matcher(pValue).matches()) {
|
||||
return FloatTag.valueOf(Float.parseFloat(pValue.substring(0, pValue.length() - 1)));
|
||||
}
|
||||
|
||||
if (BYTE_PATTERN.matcher(pValue).matches()) {
|
||||
return ByteTag.valueOf(Byte.parseByte(pValue.substring(0, pValue.length() - 1)));
|
||||
}
|
||||
|
||||
if (LONG_PATTERN.matcher(pValue).matches()) {
|
||||
return LongTag.valueOf(Long.parseLong(pValue.substring(0, pValue.length() - 1)));
|
||||
}
|
||||
|
||||
if (SHORT_PATTERN.matcher(pValue).matches()) {
|
||||
return ShortTag.valueOf(Short.parseShort(pValue.substring(0, pValue.length() - 1)));
|
||||
}
|
||||
|
||||
if (INT_PATTERN.matcher(pValue).matches()) {
|
||||
return IntTag.valueOf(Integer.parseInt(pValue));
|
||||
}
|
||||
|
||||
if (DOUBLE_PATTERN.matcher(pValue).matches()) {
|
||||
return DoubleTag.valueOf(Double.parseDouble(pValue.substring(0, pValue.length() - 1)));
|
||||
}
|
||||
|
||||
if (DOUBLE_PATTERN_NOSUFFIX.matcher(pValue).matches()) {
|
||||
return DoubleTag.valueOf(Double.parseDouble(pValue));
|
||||
}
|
||||
|
||||
if ("true".equalsIgnoreCase(pValue)) {
|
||||
return ByteTag.ONE;
|
||||
}
|
||||
|
||||
if ("false".equalsIgnoreCase(pValue)) {
|
||||
return ByteTag.ZERO;
|
||||
}
|
||||
} catch (NumberFormatException numberformatexception) {
|
||||
}
|
||||
|
||||
return StringTag.valueOf(pValue);
|
||||
}
|
||||
|
||||
public Tag readValue() throws CommandSyntaxException {
|
||||
this.reader.skipWhitespace();
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
||||
} else {
|
||||
char c0 = this.reader.peek();
|
||||
if (c0 == '{') {
|
||||
return this.readStruct();
|
||||
} else {
|
||||
return c0 == '[' ? this.readList() : this.readTypedValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Tag readList() throws CommandSyntaxException {
|
||||
return this.reader.canRead(3) && !StringReader.isQuotedStringStart(this.reader.peek(1)) && this.reader.peek(2) == ';' ? this.readArrayTag() : this.readListTag();
|
||||
}
|
||||
|
||||
public CompoundTag readStruct() throws CommandSyntaxException {
|
||||
this.expect('{');
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
this.reader.skipWhitespace();
|
||||
|
||||
while(this.reader.canRead() && this.reader.peek() != '}') {
|
||||
int i = this.reader.getCursor();
|
||||
String s = this.readKey();
|
||||
if (s.isEmpty()) {
|
||||
this.reader.setCursor(i);
|
||||
throw ERROR_EXPECTED_KEY.createWithContext(this.reader);
|
||||
}
|
||||
|
||||
this.expect(':');
|
||||
compoundtag.put(s, this.readValue());
|
||||
if (!this.hasElementSeparator()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_KEY.createWithContext(this.reader);
|
||||
}
|
||||
}
|
||||
|
||||
this.expect('}');
|
||||
return compoundtag;
|
||||
}
|
||||
|
||||
private Tag readListTag() throws CommandSyntaxException {
|
||||
this.expect('[');
|
||||
this.reader.skipWhitespace();
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
||||
} else {
|
||||
ListTag listtag = new ListTag();
|
||||
TagType<?> tagtype = null;
|
||||
|
||||
while(this.reader.peek() != ']') {
|
||||
int i = this.reader.getCursor();
|
||||
Tag tag = this.readValue();
|
||||
TagType<?> tagtype1 = tag.getType();
|
||||
if (tagtype == null) {
|
||||
tagtype = tagtype1;
|
||||
} else if (tagtype1 != tagtype) {
|
||||
this.reader.setCursor(i);
|
||||
throw ERROR_INSERT_MIXED_LIST.createWithContext(this.reader, tagtype1.getPrettyName(), tagtype.getPrettyName());
|
||||
}
|
||||
|
||||
listtag.add(tag);
|
||||
if (!this.hasElementSeparator()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
||||
}
|
||||
}
|
||||
|
||||
this.expect(']');
|
||||
return listtag;
|
||||
}
|
||||
}
|
||||
|
||||
private Tag readArrayTag() throws CommandSyntaxException {
|
||||
this.expect('[');
|
||||
int i = this.reader.getCursor();
|
||||
char c0 = this.reader.read();
|
||||
this.reader.read();
|
||||
this.reader.skipWhitespace();
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
||||
} else if (c0 == 'B') {
|
||||
return new ByteArrayTag(this.readArray(ByteArrayTag.TYPE, ByteTag.TYPE));
|
||||
} else if (c0 == 'L') {
|
||||
return new LongArrayTag(this.readArray(LongArrayTag.TYPE, LongTag.TYPE));
|
||||
} else if (c0 == 'I') {
|
||||
return new IntArrayTag(this.readArray(IntArrayTag.TYPE, IntTag.TYPE));
|
||||
} else {
|
||||
this.reader.setCursor(i);
|
||||
throw ERROR_INVALID_ARRAY.createWithContext(this.reader, String.valueOf(c0));
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends Number> List<T> readArray(TagType<?> pArrayType, TagType<?> pElementType) throws CommandSyntaxException {
|
||||
List<T> list = Lists.newArrayList();
|
||||
|
||||
while(true) {
|
||||
if (this.reader.peek() != ']') {
|
||||
int i = this.reader.getCursor();
|
||||
Tag tag = this.readValue();
|
||||
TagType<?> tagtype = tag.getType();
|
||||
if (tagtype != pElementType) {
|
||||
this.reader.setCursor(i);
|
||||
throw ERROR_INSERT_MIXED_ARRAY.createWithContext(this.reader, tagtype.getPrettyName(), pArrayType.getPrettyName());
|
||||
}
|
||||
|
||||
if (pElementType == ByteTag.TYPE) {
|
||||
list.add((T)(Byte)((NumericTag)tag).getAsByte());
|
||||
} else if (pElementType == LongTag.TYPE) {
|
||||
list.add((T)(Long)((NumericTag)tag).getAsLong());
|
||||
} else {
|
||||
list.add((T)(Integer)((NumericTag)tag).getAsInt());
|
||||
}
|
||||
|
||||
if (this.hasElementSeparator()) {
|
||||
if (!this.reader.canRead()) {
|
||||
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this.expect(']');
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasElementSeparator() {
|
||||
this.reader.skipWhitespace();
|
||||
if (this.reader.canRead() && this.reader.peek() == ',') {
|
||||
this.reader.skip();
|
||||
this.reader.skipWhitespace();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void expect(char pExpected) throws CommandSyntaxException {
|
||||
this.reader.skipWhitespace();
|
||||
this.reader.expect(pExpected);
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface TagType<T extends Tag> {
|
||||
T load(DataInput pInput, int pDepth, NbtAccounter pAccounter) throws IOException;
|
||||
|
||||
StreamTagVisitor.ValueResult parse(DataInput pInput, StreamTagVisitor pVisitor) throws IOException;
|
||||
|
||||
default void parseRoot(DataInput pInput, StreamTagVisitor pVisitor) throws IOException {
|
||||
switch (pVisitor.visitRootEntry(this)) {
|
||||
case CONTINUE:
|
||||
this.parse(pInput, pVisitor);
|
||||
case HALT:
|
||||
default:
|
||||
break;
|
||||
case BREAK:
|
||||
this.skip(pInput);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void skip(DataInput pInput, int p_197577_) throws IOException;
|
||||
|
||||
void skip(DataInput pInput) throws IOException;
|
||||
|
||||
default boolean isValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
String getName();
|
||||
|
||||
String getPrettyName();
|
||||
|
||||
static TagType<EndTag> createInvalid(final int pId) {
|
||||
return new TagType<EndTag>() {
|
||||
private IOException createException() {
|
||||
return new IOException("Invalid tag id: " + pId);
|
||||
}
|
||||
|
||||
public EndTag load(DataInput p_129387_, int p_129388_, NbtAccounter p_129389_) throws IOException {
|
||||
throw this.createException();
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult parse(DataInput p_197589_, StreamTagVisitor p_197590_) throws IOException {
|
||||
throw this.createException();
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197586_, int p_197587_) throws IOException {
|
||||
throw this.createException();
|
||||
}
|
||||
|
||||
public void skip(DataInput p_197584_) throws IOException {
|
||||
throw this.createException();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "INVALID[" + pId + "]";
|
||||
}
|
||||
|
||||
public String getPrettyName() {
|
||||
return "UNKNOWN_" + pId;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public interface StaticSize<T extends Tag> extends TagType<T> {
|
||||
default void skip(DataInput p_197595_) throws IOException {
|
||||
p_197595_.skipBytes(this.size());
|
||||
}
|
||||
|
||||
default void skip(DataInput p_197597_, int p_197598_) throws IOException {
|
||||
p_197597_.skipBytes(this.size() * p_197598_);
|
||||
}
|
||||
|
||||
int size();
|
||||
}
|
||||
|
||||
public interface VariableSize<T extends Tag> extends TagType<T> {
|
||||
default void skip(DataInput p_197600_, int p_197601_) throws IOException {
|
||||
for(int i = 0; i < p_197601_; ++i) {
|
||||
this.skip(p_197600_);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
public class TagTypes {
|
||||
private static final TagType<?>[] TYPES = new TagType[]{EndTag.TYPE, ByteTag.TYPE, ShortTag.TYPE, IntTag.TYPE, LongTag.TYPE, FloatTag.TYPE, DoubleTag.TYPE, ByteArrayTag.TYPE, StringTag.TYPE, ListTag.TYPE, CompoundTag.TYPE, IntArrayTag.TYPE, LongArrayTag.TYPE};
|
||||
|
||||
public static TagType<?> getType(int pId) {
|
||||
return pId >= 0 && pId < TYPES.length ? TYPES[pId] : TagType.createInvalid(pId);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
public interface TagVisitor {
|
||||
void visitString(StringTag pTag);
|
||||
|
||||
void visitByte(ByteTag pTag);
|
||||
|
||||
void visitShort(ShortTag pTag);
|
||||
|
||||
void visitInt(IntTag pTag);
|
||||
|
||||
void visitLong(LongTag pTag);
|
||||
|
||||
void visitFloat(FloatTag pTag);
|
||||
|
||||
void visitDouble(DoubleTag pTag);
|
||||
|
||||
void visitByteArray(ByteArrayTag pTag);
|
||||
|
||||
void visitIntArray(IntArrayTag pTag);
|
||||
|
||||
void visitLongArray(LongArrayTag pTag);
|
||||
|
||||
void visitList(ListTag pTag);
|
||||
|
||||
void visitCompound(CompoundTag pTag);
|
||||
|
||||
void visitEnd(EndTag pTag);
|
||||
}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteCollection;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteOpenHashSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class TextComponentTagVisitor implements TagVisitor {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int INLINE_LIST_THRESHOLD = 8;
|
||||
private static final ByteCollection INLINE_ELEMENT_TYPES = new ByteOpenHashSet(Arrays.asList((byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6));
|
||||
private static final ChatFormatting SYNTAX_HIGHLIGHTING_KEY = ChatFormatting.AQUA;
|
||||
private static final ChatFormatting SYNTAX_HIGHLIGHTING_STRING = ChatFormatting.GREEN;
|
||||
private static final ChatFormatting SYNTAX_HIGHLIGHTING_NUMBER = ChatFormatting.GOLD;
|
||||
private static final ChatFormatting SYNTAX_HIGHLIGHTING_NUMBER_TYPE = ChatFormatting.RED;
|
||||
private static final Pattern SIMPLE_VALUE = Pattern.compile("[A-Za-z0-9._+-]+");
|
||||
private static final String NAME_VALUE_SEPARATOR = String.valueOf(':');
|
||||
private static final String ELEMENT_SEPARATOR = String.valueOf(',');
|
||||
private static final String LIST_OPEN = "[";
|
||||
private static final String LIST_CLOSE = "]";
|
||||
private static final String LIST_TYPE_SEPARATOR = ";";
|
||||
private static final String ELEMENT_SPACING = " ";
|
||||
private static final String STRUCT_OPEN = "{";
|
||||
private static final String STRUCT_CLOSE = "}";
|
||||
private static final String NEWLINE = "\n";
|
||||
private final String indentation;
|
||||
private final int depth;
|
||||
private Component result = CommonComponents.EMPTY;
|
||||
|
||||
public TextComponentTagVisitor(String pIndentation, int pDepth) {
|
||||
this.indentation = pIndentation;
|
||||
this.depth = pDepth;
|
||||
}
|
||||
|
||||
public Component visit(Tag pTag) {
|
||||
pTag.accept(this);
|
||||
return this.result;
|
||||
}
|
||||
|
||||
public void visitString(StringTag pTag) {
|
||||
String s = StringTag.quoteAndEscape(pTag.getAsString());
|
||||
String s1 = s.substring(0, 1);
|
||||
Component component = Component.literal(s.substring(1, s.length() - 1)).withStyle(SYNTAX_HIGHLIGHTING_STRING);
|
||||
this.result = Component.literal(s1).append(component).append(s1);
|
||||
}
|
||||
|
||||
public void visitByte(ByteTag pTag) {
|
||||
Component component = Component.literal("b").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
this.result = Component.literal(String.valueOf((Object)pTag.getAsNumber())).append(component).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
}
|
||||
|
||||
public void visitShort(ShortTag pTag) {
|
||||
Component component = Component.literal("s").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
this.result = Component.literal(String.valueOf((Object)pTag.getAsNumber())).append(component).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
}
|
||||
|
||||
public void visitInt(IntTag pTag) {
|
||||
this.result = Component.literal(String.valueOf((Object)pTag.getAsNumber())).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
}
|
||||
|
||||
public void visitLong(LongTag pTag) {
|
||||
Component component = Component.literal("L").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
this.result = Component.literal(String.valueOf((Object)pTag.getAsNumber())).append(component).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
}
|
||||
|
||||
public void visitFloat(FloatTag pTag) {
|
||||
Component component = Component.literal("f").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
this.result = Component.literal(String.valueOf(pTag.getAsFloat())).append(component).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
}
|
||||
|
||||
public void visitDouble(DoubleTag pTag) {
|
||||
Component component = Component.literal("d").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
this.result = Component.literal(String.valueOf(pTag.getAsDouble())).append(component).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
}
|
||||
|
||||
public void visitByteArray(ByteArrayTag pTag) {
|
||||
Component component = Component.literal("B").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
MutableComponent mutablecomponent = Component.literal("[").append(component).append(";");
|
||||
byte[] abyte = pTag.getAsByteArray();
|
||||
|
||||
for(int i = 0; i < abyte.length; ++i) {
|
||||
MutableComponent mutablecomponent1 = Component.literal(String.valueOf((int)abyte[i])).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
mutablecomponent.append(" ").append(mutablecomponent1).append(component);
|
||||
if (i != abyte.length - 1) {
|
||||
mutablecomponent.append(ELEMENT_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
mutablecomponent.append("]");
|
||||
this.result = mutablecomponent;
|
||||
}
|
||||
|
||||
public void visitIntArray(IntArrayTag pTag) {
|
||||
Component component = Component.literal("I").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
MutableComponent mutablecomponent = Component.literal("[").append(component).append(";");
|
||||
int[] aint = pTag.getAsIntArray();
|
||||
|
||||
for(int i = 0; i < aint.length; ++i) {
|
||||
mutablecomponent.append(" ").append(Component.literal(String.valueOf(aint[i])).withStyle(SYNTAX_HIGHLIGHTING_NUMBER));
|
||||
if (i != aint.length - 1) {
|
||||
mutablecomponent.append(ELEMENT_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
mutablecomponent.append("]");
|
||||
this.result = mutablecomponent;
|
||||
}
|
||||
|
||||
public void visitLongArray(LongArrayTag pTag) {
|
||||
Component component = Component.literal("L").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
|
||||
MutableComponent mutablecomponent = Component.literal("[").append(component).append(";");
|
||||
long[] along = pTag.getAsLongArray();
|
||||
|
||||
for(int i = 0; i < along.length; ++i) {
|
||||
Component component1 = Component.literal(String.valueOf(along[i])).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
|
||||
mutablecomponent.append(" ").append(component1).append(component);
|
||||
if (i != along.length - 1) {
|
||||
mutablecomponent.append(ELEMENT_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
mutablecomponent.append("]");
|
||||
this.result = mutablecomponent;
|
||||
}
|
||||
|
||||
public void visitList(ListTag pTag) {
|
||||
if (pTag.isEmpty()) {
|
||||
this.result = Component.literal("[]");
|
||||
} else if (INLINE_ELEMENT_TYPES.contains(pTag.getElementType()) && pTag.size() <= 8) {
|
||||
String s = ELEMENT_SEPARATOR + " ";
|
||||
MutableComponent mutablecomponent2 = Component.literal("[");
|
||||
|
||||
for(int j = 0; j < pTag.size(); ++j) {
|
||||
if (j != 0) {
|
||||
mutablecomponent2.append(s);
|
||||
}
|
||||
|
||||
mutablecomponent2.append((new TextComponentTagVisitor(this.indentation, this.depth)).visit(pTag.get(j)));
|
||||
}
|
||||
|
||||
mutablecomponent2.append("]");
|
||||
this.result = mutablecomponent2;
|
||||
} else {
|
||||
MutableComponent mutablecomponent = Component.literal("[");
|
||||
if (!this.indentation.isEmpty()) {
|
||||
mutablecomponent.append("\n");
|
||||
}
|
||||
|
||||
for(int i = 0; i < pTag.size(); ++i) {
|
||||
MutableComponent mutablecomponent1 = Component.literal(Strings.repeat(this.indentation, this.depth + 1));
|
||||
mutablecomponent1.append((new TextComponentTagVisitor(this.indentation, this.depth + 1)).visit(pTag.get(i)));
|
||||
if (i != pTag.size() - 1) {
|
||||
mutablecomponent1.append(ELEMENT_SEPARATOR).append(this.indentation.isEmpty() ? " " : "\n");
|
||||
}
|
||||
|
||||
mutablecomponent.append(mutablecomponent1);
|
||||
}
|
||||
|
||||
if (!this.indentation.isEmpty()) {
|
||||
mutablecomponent.append("\n").append(Strings.repeat(this.indentation, this.depth));
|
||||
}
|
||||
|
||||
mutablecomponent.append("]");
|
||||
this.result = mutablecomponent;
|
||||
}
|
||||
}
|
||||
|
||||
public void visitCompound(CompoundTag pTag) {
|
||||
if (pTag.isEmpty()) {
|
||||
this.result = Component.literal("{}");
|
||||
} else {
|
||||
MutableComponent mutablecomponent = Component.literal("{");
|
||||
Collection<String> collection = pTag.getAllKeys();
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
List<String> list = Lists.newArrayList(pTag.getAllKeys());
|
||||
Collections.sort(list);
|
||||
collection = list;
|
||||
}
|
||||
|
||||
if (!this.indentation.isEmpty()) {
|
||||
mutablecomponent.append("\n");
|
||||
}
|
||||
|
||||
MutableComponent mutablecomponent1;
|
||||
for(Iterator<String> iterator = collection.iterator(); iterator.hasNext(); mutablecomponent.append(mutablecomponent1)) {
|
||||
String s = iterator.next();
|
||||
mutablecomponent1 = Component.literal(Strings.repeat(this.indentation, this.depth + 1)).append(handleEscapePretty(s)).append(NAME_VALUE_SEPARATOR).append(" ").append((new TextComponentTagVisitor(this.indentation, this.depth + 1)).visit(pTag.get(s)));
|
||||
if (iterator.hasNext()) {
|
||||
mutablecomponent1.append(ELEMENT_SEPARATOR).append(this.indentation.isEmpty() ? " " : "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.indentation.isEmpty()) {
|
||||
mutablecomponent.append("\n").append(Strings.repeat(this.indentation, this.depth));
|
||||
}
|
||||
|
||||
mutablecomponent.append("}");
|
||||
this.result = mutablecomponent;
|
||||
}
|
||||
}
|
||||
|
||||
protected static Component handleEscapePretty(String pText) {
|
||||
if (SIMPLE_VALUE.matcher(pText).matches()) {
|
||||
return Component.literal(pText).withStyle(SYNTAX_HIGHLIGHTING_KEY);
|
||||
} else {
|
||||
String s = StringTag.quoteAndEscape(pText);
|
||||
String s1 = s.substring(0, 1);
|
||||
Component component = Component.literal(s.substring(1, s.length() - 1)).withStyle(SYNTAX_HIGHLIGHTING_KEY);
|
||||
return Component.literal(s1).append(component).append(s1);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitEnd(EndTag pTag) {
|
||||
this.result = CommonComponents.EMPTY;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
package net.minecraft.nbt;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package net.minecraft.nbt.visitors;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Set;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.StreamTagVisitor;
|
||||
import net.minecraft.nbt.TagType;
|
||||
|
||||
public class CollectFields extends CollectToTag {
|
||||
private int fieldsToGetCount;
|
||||
private final Set<TagType<?>> wantedTypes;
|
||||
private final Deque<FieldTree> stack = new ArrayDeque<>();
|
||||
|
||||
public CollectFields(FieldSelector... pSelectors) {
|
||||
this.fieldsToGetCount = pSelectors.length;
|
||||
ImmutableSet.Builder<TagType<?>> builder = ImmutableSet.builder();
|
||||
FieldTree fieldtree = FieldTree.createRoot();
|
||||
|
||||
for(FieldSelector fieldselector : pSelectors) {
|
||||
fieldtree.addEntry(fieldselector);
|
||||
builder.add(fieldselector.type());
|
||||
}
|
||||
|
||||
this.stack.push(fieldtree);
|
||||
builder.add(CompoundTag.TYPE);
|
||||
this.wantedTypes = builder.build();
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visitRootEntry(TagType<?> pType) {
|
||||
return pType != CompoundTag.TYPE ? StreamTagVisitor.ValueResult.HALT : super.visitRootEntry(pType);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.EntryResult visitEntry(TagType<?> pType) {
|
||||
FieldTree fieldtree = this.stack.element();
|
||||
if (this.depth() > fieldtree.depth()) {
|
||||
return super.visitEntry(pType);
|
||||
} else if (this.fieldsToGetCount <= 0) {
|
||||
return StreamTagVisitor.EntryResult.HALT;
|
||||
} else {
|
||||
return !this.wantedTypes.contains(pType) ? StreamTagVisitor.EntryResult.SKIP : super.visitEntry(pType);
|
||||
}
|
||||
}
|
||||
|
||||
public StreamTagVisitor.EntryResult visitEntry(TagType<?> pType, String pId) {
|
||||
FieldTree fieldtree = this.stack.element();
|
||||
if (this.depth() > fieldtree.depth()) {
|
||||
return super.visitEntry(pType, pId);
|
||||
} else if (fieldtree.selectedFields().remove(pId, pType)) {
|
||||
--this.fieldsToGetCount;
|
||||
return super.visitEntry(pType, pId);
|
||||
} else {
|
||||
if (pType == CompoundTag.TYPE) {
|
||||
FieldTree fieldtree1 = fieldtree.fieldsToRecurse().get(pId);
|
||||
if (fieldtree1 != null) {
|
||||
this.stack.push(fieldtree1);
|
||||
return super.visitEntry(pType, pId);
|
||||
}
|
||||
}
|
||||
|
||||
return StreamTagVisitor.EntryResult.SKIP;
|
||||
}
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visitContainerEnd() {
|
||||
if (this.depth() == this.stack.element().depth()) {
|
||||
this.stack.pop();
|
||||
}
|
||||
|
||||
return super.visitContainerEnd();
|
||||
}
|
||||
|
||||
public int getMissingFieldCount() {
|
||||
return this.fieldsToGetCount;
|
||||
}
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
package net.minecraft.nbt.visitors;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.nbt.ByteArrayTag;
|
||||
import net.minecraft.nbt.ByteTag;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.DoubleTag;
|
||||
import net.minecraft.nbt.EndTag;
|
||||
import net.minecraft.nbt.FloatTag;
|
||||
import net.minecraft.nbt.IntArrayTag;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.LongArrayTag;
|
||||
import net.minecraft.nbt.LongTag;
|
||||
import net.minecraft.nbt.ShortTag;
|
||||
import net.minecraft.nbt.StreamTagVisitor;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.nbt.TagType;
|
||||
|
||||
public class CollectToTag implements StreamTagVisitor {
|
||||
private String lastId = "";
|
||||
@Nullable
|
||||
private Tag rootTag;
|
||||
private final Deque<Consumer<Tag>> consumerStack = new ArrayDeque<>();
|
||||
|
||||
@Nullable
|
||||
public Tag getResult() {
|
||||
return this.rootTag;
|
||||
}
|
||||
|
||||
protected int depth() {
|
||||
return this.consumerStack.size();
|
||||
}
|
||||
|
||||
private void appendEntry(Tag pTag) {
|
||||
this.consumerStack.getLast().accept(pTag);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visitEnd() {
|
||||
this.appendEntry(EndTag.INSTANCE);
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(String pEntry) {
|
||||
this.appendEntry(StringTag.valueOf(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(byte pEntry) {
|
||||
this.appendEntry(ByteTag.valueOf(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(short pEntry) {
|
||||
this.appendEntry(ShortTag.valueOf(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(int pEntry) {
|
||||
this.appendEntry(IntTag.valueOf(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(long pEntry) {
|
||||
this.appendEntry(LongTag.valueOf(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(float pEntry) {
|
||||
this.appendEntry(FloatTag.valueOf(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(double pEntry) {
|
||||
this.appendEntry(DoubleTag.valueOf(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(byte[] pEntry) {
|
||||
this.appendEntry(new ByteArrayTag(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(int[] pEntry) {
|
||||
this.appendEntry(new IntArrayTag(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visit(long[] pEntry) {
|
||||
this.appendEntry(new LongArrayTag(pEntry));
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visitList(TagType<?> pType, int p_197688_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.EntryResult visitElement(TagType<?> pType, int p_197710_) {
|
||||
this.enterContainerIfNeeded(pType);
|
||||
return StreamTagVisitor.EntryResult.ENTER;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.EntryResult visitEntry(TagType<?> pType) {
|
||||
return StreamTagVisitor.EntryResult.ENTER;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.EntryResult visitEntry(TagType<?> pType, String pId) {
|
||||
this.lastId = pId;
|
||||
this.enterContainerIfNeeded(pType);
|
||||
return StreamTagVisitor.EntryResult.ENTER;
|
||||
}
|
||||
|
||||
private void enterContainerIfNeeded(TagType<?> pType) {
|
||||
if (pType == ListTag.TYPE) {
|
||||
ListTag listtag = new ListTag();
|
||||
this.appendEntry(listtag);
|
||||
this.consumerStack.addLast(listtag::add);
|
||||
} else if (pType == CompoundTag.TYPE) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
this.appendEntry(compoundtag);
|
||||
this.consumerStack.addLast((p_197703_) -> {
|
||||
compoundtag.put(this.lastId, p_197703_);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visitContainerEnd() {
|
||||
this.consumerStack.removeLast();
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visitRootEntry(TagType<?> pType) {
|
||||
if (pType == ListTag.TYPE) {
|
||||
ListTag listtag = new ListTag();
|
||||
this.rootTag = listtag;
|
||||
this.consumerStack.addLast(listtag::add);
|
||||
} else if (pType == CompoundTag.TYPE) {
|
||||
CompoundTag compoundtag = new CompoundTag();
|
||||
this.rootTag = compoundtag;
|
||||
this.consumerStack.addLast((p_197681_) -> {
|
||||
compoundtag.put(this.lastId, p_197681_);
|
||||
});
|
||||
} else {
|
||||
this.consumerStack.addLast((p_197705_) -> {
|
||||
this.rootTag = p_197705_;
|
||||
});
|
||||
}
|
||||
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package net.minecraft.nbt.visitors;
|
||||
|
||||
import java.util.List;
|
||||
import net.minecraft.nbt.TagType;
|
||||
|
||||
public record FieldSelector(List<String> path, TagType<?> type, String name) {
|
||||
public FieldSelector(TagType<?> pType, String pName) {
|
||||
this(List.of(), pType, pName);
|
||||
}
|
||||
|
||||
public FieldSelector(String pElement, TagType<?> pType, String pName) {
|
||||
this(List.of(pElement), pType, pName);
|
||||
}
|
||||
|
||||
public FieldSelector(String pFirstElement, String pSecondElement, TagType<?> pType, String pName) {
|
||||
this(List.of(pFirstElement, pSecondElement), pType, pName);
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package net.minecraft.nbt.visitors;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.minecraft.nbt.TagType;
|
||||
|
||||
public record FieldTree(int depth, Map<String, TagType<?>> selectedFields, Map<String, FieldTree> fieldsToRecurse) {
|
||||
private FieldTree(int pDepth) {
|
||||
this(pDepth, new HashMap<>(), new HashMap<>());
|
||||
}
|
||||
|
||||
public static FieldTree createRoot() {
|
||||
return new FieldTree(1);
|
||||
}
|
||||
|
||||
public void addEntry(FieldSelector pSelector) {
|
||||
if (this.depth <= pSelector.path().size()) {
|
||||
this.fieldsToRecurse.computeIfAbsent(pSelector.path().get(this.depth - 1), (p_202534_) -> {
|
||||
return new FieldTree(this.depth + 1);
|
||||
}).addEntry(pSelector);
|
||||
} else {
|
||||
this.selectedFields.put(pSelector.name(), pSelector.type());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isSelected(TagType<?> pType, String pName) {
|
||||
return pType.equals(this.selectedFields().get(pName));
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package net.minecraft.nbt.visitors;
|
||||
|
||||
import net.minecraft.nbt.StreamTagVisitor;
|
||||
import net.minecraft.nbt.TagType;
|
||||
|
||||
public interface SkipAll extends StreamTagVisitor {
|
||||
SkipAll INSTANCE = new SkipAll() {
|
||||
};
|
||||
|
||||
default StreamTagVisitor.ValueResult visitEnd() {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(String p_197729_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(byte p_197719_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(short p_197739_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(int p_197725_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(long p_197727_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(float p_197723_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(double p_197721_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(byte[] p_197741_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(int[] p_197743_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visit(long[] p_197745_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visitList(TagType<?> p_197733_, int p_197734_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.EntryResult visitElement(TagType<?> p_197750_, int p_197751_) {
|
||||
return StreamTagVisitor.EntryResult.SKIP;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.EntryResult visitEntry(TagType<?> p_197731_) {
|
||||
return StreamTagVisitor.EntryResult.SKIP;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.EntryResult visitEntry(TagType<?> p_197736_, String p_197737_) {
|
||||
return StreamTagVisitor.EntryResult.SKIP;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visitContainerEnd() {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
|
||||
default StreamTagVisitor.ValueResult visitRootEntry(TagType<?> p_197748_) {
|
||||
return StreamTagVisitor.ValueResult.CONTINUE;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package net.minecraft.nbt.visitors;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.StreamTagVisitor;
|
||||
import net.minecraft.nbt.TagType;
|
||||
|
||||
public class SkipFields extends CollectToTag {
|
||||
private final Deque<FieldTree> stack = new ArrayDeque<>();
|
||||
|
||||
public SkipFields(FieldSelector... pSelectors) {
|
||||
FieldTree fieldtree = FieldTree.createRoot();
|
||||
|
||||
for(FieldSelector fieldselector : pSelectors) {
|
||||
fieldtree.addEntry(fieldselector);
|
||||
}
|
||||
|
||||
this.stack.push(fieldtree);
|
||||
}
|
||||
|
||||
public StreamTagVisitor.EntryResult visitEntry(TagType<?> pType, String pId) {
|
||||
FieldTree fieldtree = this.stack.element();
|
||||
if (fieldtree.isSelected(pType, pId)) {
|
||||
return StreamTagVisitor.EntryResult.SKIP;
|
||||
} else {
|
||||
if (pType == CompoundTag.TYPE) {
|
||||
FieldTree fieldtree1 = fieldtree.fieldsToRecurse().get(pId);
|
||||
if (fieldtree1 != null) {
|
||||
this.stack.push(fieldtree1);
|
||||
}
|
||||
}
|
||||
|
||||
return super.visitEntry(pType, pId);
|
||||
}
|
||||
}
|
||||
|
||||
public StreamTagVisitor.ValueResult visitContainerEnd() {
|
||||
if (this.depth() == this.stack.element().depth()) {
|
||||
this.stack.pop();
|
||||
}
|
||||
|
||||
return super.visitContainerEnd();
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
package net.minecraft.nbt.visitors;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
Reference in new issue
Block a user