Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: MiniDigger | Martin <admin@minidigger.dev>
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Shane Freeder <theboyetronic@gmail.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com>
Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>
This commit is contained in:
Nassim Jahnke
2025-04-12 17:26:44 +02:00
parent 0767902699
commit f00727c57e
2092 changed files with 50551 additions and 48729 deletions

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/nbt/CompoundTag.java
+++ b/net/minecraft/nbt/CompoundTag.java
@@ -49,7 +_,7 @@
@@ -54,7 +_,7 @@
private static CompoundTag loadCompound(DataInput input, NbtAccounter nbtAccounter) throws IOException {
nbtAccounter.accountBytes(48L);
@@ -9,55 +9,21 @@
byte b;
while ((b = input.readByte()) != 0) {
@@ -166,7 +_,7 @@
@@ -171,7 +_,7 @@
}
public CompoundTag() {
- this(Maps.newHashMap());
- this(new HashMap<>());
+ this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - Reduce memory footprint of CompoundTag
}
@Override
@@ -232,14 +_,34 @@
}
public void putUUID(String key, UUID value) {
+ // Paper start - Support old UUID format
+ if (this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
+ this.tags.remove(key + "Most");
+ this.tags.remove(key + "Least");
+ }
+ // Paper end - Support old UUID format
this.tags.put(key, NbtUtils.createUUID(value));
}
+
+ /**
+ * You must use {@link #hasUUID(String)} before or else it <b>will</b> throw an NPE.
+ */
public UUID getUUID(String key) {
+ // Paper start - Support old UUID format
+ if (!contains(key, 11) && this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
+ return new UUID(this.getLong(key + "Most"), this.getLong(key + "Least"));
+ }
+ // Paper end - Support old UUID format
return NbtUtils.loadUUID(this.get(key));
}
public boolean hasUUID(String key) {
+ // Paper start - Support old UUID format
+ if (this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
+ return true;
+ }
+ // Paper end - Support old UUID format
Tag tag = this.get(key);
return tag != null && tag.getType() == IntArrayTag.TYPE && ((IntArrayTag)tag).getAsIntArray().length == 4;
}
@@ -477,8 +_,16 @@
@@ -402,9 +_,16 @@
@Override
public CompoundTag copy() {
- Map<String, Tag> map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy));
- HashMap<String, Tag> map = new HashMap<>();
- this.tags.forEach((string, tag) -> map.put(string, tag.copy()));
- return new CompoundTag(map);
+ // Paper start - Reduce memory footprint of CompoundTag
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
@@ -72,3 +38,55 @@
}
@Override
@@ -525,22 +_,47 @@
this.merge((CompoundTag)mapCodec.encoder().encodeStart(ops, data).getOrThrow());
}
- public <T> Optional<T> read(String key, Codec<T> codec) {
+ public <T> Optional<T> read(String key, Codec<T> codec) { // Paper - option to read via codec without logging errors - diff on change
return this.read(key, codec, NbtOps.INSTANCE);
}
- public <T> Optional<T> read(String key, Codec<T> codec, DynamicOps<Tag> ops) {
+ public <T> Optional<T> read(String key, Codec<T> codec, DynamicOps<Tag> ops) { // Paper - option to read via codec without logging errors - diff on change
Tag tag = this.get(key);
return tag == null
? Optional.empty()
: codec.parse(ops, tag).resultOrPartial(string -> LOGGER.error("Failed to read field ({}={}): {}", key, tag, string));
}
- public <T> Optional<T> read(MapCodec<T> mapCodec) {
+ public <T> Optional<T> read(MapCodec<T> mapCodec) { // Paper - option to read via codec without logging errors - diff on change
return this.read(mapCodec, NbtOps.INSTANCE);
}
- public <T> Optional<T> read(MapCodec<T> mapCodec, DynamicOps<Tag> ops) {
+ public <T> Optional<T> read(MapCodec<T> mapCodec, DynamicOps<Tag> ops) { // Paper - option to read via codec without logging errors - diff on change
return mapCodec.decode(ops, ops.getMap(this).getOrThrow()).resultOrPartial(string -> LOGGER.error("Failed to read value ({}): {}", this, string));
}
+
+ // Paper start - option to read via codec without logging errors
+ // The below methods are 1 to 1 copies of the above-defined read methods without the logging part.
+ // Copying was chosen over overloading the read methods as a boolean parameter to mark a method as quiet
+ // is not intuitive and would require even more overloads.
+ // Not a lot of diff in these methods is expected
+ public <T> Optional<T> readQuiet(String key, Codec<T> codec) {
+ return this.readQuiet(key, codec, NbtOps.INSTANCE);
+ }
+
+ public <T> Optional<T> readQuiet(String key, Codec<T> codec, DynamicOps<Tag> ops) {
+ Tag tag = this.get(key);
+ return tag == null
+ ? Optional.empty()
+ : codec.parse(ops, tag).resultOrPartial();
+ }
+
+ public <T> Optional<T> readQuiet(MapCodec<T> mapCodec) {
+ return this.readQuiet(mapCodec, NbtOps.INSTANCE);
+ }
+
+ public <T> Optional<T> readQuiet(MapCodec<T> mapCodec, DynamicOps<Tag> ops) {
+ return mapCodec.decode(ops, ops.getMap(this).getOrThrow()).resultOrPartial();
+ }
+ // Paper end - option to read via codec without logging errors
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/nbt/NbtIo.java
+++ b/net/minecraft/nbt/NbtIo.java
@@ -118,6 +_,11 @@
@@ -119,6 +_,11 @@
}
public static CompoundTag read(DataInput input, NbtAccounter accounter) throws IOException {

View File

@@ -1,15 +0,0 @@
--- a/net/minecraft/nbt/NbtUtils.java
+++ b/net/minecraft/nbt/NbtUtils.java
@@ -143,8 +_,10 @@
if (!tag.contains("Name", 8)) {
return Blocks.AIR.defaultBlockState();
} else {
- ResourceLocation resourceLocation = ResourceLocation.parse(tag.getString("Name"));
- Optional<? extends Holder<Block>> optional = blockGetter.get(ResourceKey.create(Registries.BLOCK, resourceLocation));
+ // Paper start - Validate resource location
+ ResourceLocation resourceLocation = ResourceLocation.tryParse(tag.getString("Name"));
+ Optional<? extends Holder<Block>> optional = resourceLocation != null ? blockGetter.get(ResourceKey.create(Registries.BLOCK, resourceLocation)) : Optional.empty();
+ // Paper end - Validate resource location
if (optional.isEmpty()) {
return Blocks.AIR.defaultBlockState();
} else {

View File

@@ -0,0 +1,21 @@
--- a/net/minecraft/nbt/SnbtGrammar.java
+++ b/net/minecraft/nbt/SnbtGrammar.java
@@ -591,7 +_,7 @@
Atom<List<Entry<String, T>>> atom30 = Atom.of("map_entries");
dictionary.put(atom30, Term.repeatedWithTrailingSeparator(namedRule3, atom30, StringReaderTerms.character(',')), scope -> scope.getOrThrow(atom30));
Atom<T> atom31 = Atom.of("map_literal");
- dictionary.put(atom31, Term.sequence(StringReaderTerms.character('{'), dictionary.named(atom30), StringReaderTerms.character('}')), scope -> {
+ dictionary.put(atom31, Term.sequence(StringReaderTerms.character('{'), Scope.increaseDepth(), dictionary.named(atom30), Scope.decreaseDepth(), StringReaderTerms.character('}')), scope -> { // Paper - track depth
List<Entry<String, T>> list = scope.getOrThrow(atom30);
if (list.isEmpty()) {
return object2;
@@ -626,7 +_,9 @@
atom35,
Term.sequence(
StringReaderTerms.character('['),
+ Scope.increaseDepth(), // Paper - track depth
Term.alternative(Term.sequence(dictionary.named(atom33), StringReaderTerms.character(';'), dictionary.named(atom34)), dictionary.named(atom32)),
+ Scope.decreaseDepth(), // Paper - track depth
StringReaderTerms.character(']')
),
parseState -> {

View File

@@ -1,54 +0,0 @@
--- a/net/minecraft/nbt/TagParser.java
+++ b/net/minecraft/nbt/TagParser.java
@@ -49,6 +_,7 @@
}, CompoundTag::toString);
public static final Codec<CompoundTag> LENIENT_CODEC = Codec.withAlternative(AS_CODEC, CompoundTag.CODEC);
private final StringReader reader;
+ private int depth; // Paper
public static CompoundTag parseTag(String text) throws CommandSyntaxException {
return new TagParser(new StringReader(text)).readSingleStruct();
@@ -159,6 +_,7 @@
public CompoundTag readStruct() throws CommandSyntaxException {
this.expect('{');
+ this.increaseDepth(); // Paper
CompoundTag compoundTag = new CompoundTag();
this.reader.skipWhitespace();
@@ -182,6 +_,7 @@
}
this.expect('}');
+ this.depth--; // Paper
return compoundTag;
}
@@ -191,6 +_,7 @@
if (!this.reader.canRead()) {
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
} else {
+ this.increaseDepth(); // Paper
ListTag listTag = new ListTag();
TagType<?> tagType = null;
@@ -216,6 +_,7 @@
}
this.expect(']');
+ this.depth--; // Paper
return listTag;
}
}
@@ -287,5 +_,11 @@
private void expect(char expected) throws CommandSyntaxException {
this.reader.skipWhitespace();
this.reader.expect(expected);
+ }
+ private void increaseDepth() throws CommandSyntaxException {
+ this.depth++;
+ if (this.depth > 512) {
+ throw new io.papermc.paper.brigadier.TagParseCommandSyntaxException("NBT tag is too complex, depth > 512");
+ }
}
}