Skip to content

Commit 6ded29f

Browse files
committed
fix: ensure cache is not used in CustomItemStringReader
1 parent afd5c67 commit 6ded29f

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

src/main/java/io/gitlab/jfronny/meteoradditions/util/CustomItemStringReader.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
import com.mojang.brigadier.StringReader;
44
import com.mojang.brigadier.exceptions.CommandSyntaxException;
5-
import com.mojang.serialization.DataResult;
6-
import io.gitlab.jfronny.commons.throwable.Coerce;
7-
import io.gitlab.jfronny.commons.throwable.ThrowingFunction;
5+
import com.mojang.serialization.*;
86
import net.minecraft.component.ComponentChanges;
97
import net.minecraft.component.DataComponentTypes;
108
import net.minecraft.component.type.NbtComponent;
@@ -14,40 +12,46 @@
1412
import net.minecraft.item.ItemStack;
1513
import net.minecraft.nbt.*;
1614
import net.minecraft.nbt.visitor.StringNbtWriter;
17-
import net.minecraft.registry.Registries;
15+
import net.minecraft.registry.*;
16+
import net.minecraft.server.command.CommandManager;
1817
import net.minecraft.text.Text;
1918
import net.minecraft.util.Identifier;
2019
import net.minecraft.util.InvalidIdentifierException;
2120

2221
import java.util.Optional;
2322

2423
public class CustomItemStringReader {
25-
private static final CustomWrapperLookup LOOKUP = new CustomWrapperLookup();
26-
private static final ThrowingFunction<NbtElement, ComponentChanges, ItemSyntaxException> parser = Coerce
27-
.<NbtElement, DataResult<ComponentChanges>, ItemSyntaxException>function(LOOKUP.getOps(NbtOps.INSTANCE).withParser(ComponentChanges.CODEC)::apply)
28-
.andThen(Coerce.function(result -> result.getOrThrow(e -> new ItemSyntaxException("Invalid item NBT: " + e))));
29-
private static final ThrowingFunction<ComponentChanges, NbtElement, ItemSyntaxException> encoder = Coerce
30-
.<ComponentChanges, DataResult<NbtElement>, ItemSyntaxException>function(LOOKUP.getOps(NbtOps.INSTANCE).withEncoder(ComponentChanges.CODEC)::apply)
31-
.andThen(Coerce.function(result -> result.getOrThrow(e -> new ItemSyntaxException("Invalid item NBT: " + e))));
32-
3324
public static String write(ItemStack stack) throws ItemSyntaxException {
25+
RegistryWrapper.WrapperLookup registries = CommandManager.createRegistryAccess(BuiltinRegistries.createWrapperLookup());
26+
DynamicOps<NbtElement> nbtOps = registries.getOps(NbtOps.INSTANCE);
27+
3428
StringBuilder sb = new StringBuilder(stack.getItem().toString());
35-
sb.append(new StringNbtWriter().apply(encoder.apply(stack.getComponentChanges())));
29+
DataResult<NbtElement> changes = ComponentChanges.CODEC.encode(stack.getComponentChanges(), nbtOps, nbtOps.empty());
30+
sb.append(new StringNbtWriter().apply(changes.getOrThrow(e -> new ItemSyntaxException("Invalid item NBT: " + e))));
3631
if (stack.getCount() != 1) sb.append('$').append(stack.getCount());
3732
return sb.toString();
3833
}
3934

4035
public static ItemStack read(String desc) throws ItemSyntaxException {
36+
RegistryWrapper.WrapperLookup registries = new CustomWrapperLookup();
37+
DynamicOps<NbtElement> nbtOps = registries.getOps(NbtOps.INSTANCE); // This ensures that caches are not used, which would cause a crash since reference equality is assumed in some vanilla code
38+
4139
StringReader reader = new StringReader(desc);
4240
Identifier identifier = readIdentifier(reader);
43-
Item item = Registries.ITEM.getOptionalValue(identifier).orElseThrow(() -> new ItemSyntaxException("Invalid item ID: " + identifier));
41+
Item item = registries.getOrThrow(RegistryKeys.ITEM)
42+
.getOptional(RegistryKey.of(RegistryKeys.ITEM, identifier))
43+
.orElseThrow(() -> new ItemSyntaxException("Invalid item ID: " + identifier))
44+
.value();
4445
ItemStack stack = new ItemStack(item, 1);
4546
while (reader.canRead()) {
4647
switch (reader.read()) {
4748
case '{' -> {
4849
try {
4950
reader.setCursor(reader.getCursor() - 1);
50-
stack.applyChanges(parser.apply(new StringNbtReader(reader).parseCompound()));
51+
DataResult<Dynamic<?>> datum = Codec.PASSTHROUGH.parse(nbtOps, new StringNbtReader(reader).parseCompound());
52+
datum = datum.map(dt -> RegistryOps.withRegistry(dt, registries));
53+
DataResult<ComponentChanges> changes = datum.flatMap(ComponentChanges.CODEC::parse);
54+
stack.applyChanges(changes.getOrThrow(e -> new ItemSyntaxException("Invalid item NBT: " + e)));
5155
} catch (CommandSyntaxException e) {
5256
throw new ItemSyntaxException("Could not parse NBT", e);
5357
}

src/main/java/io/gitlab/jfronny/meteoradditions/util/CustomWrapperLookup.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package io.gitlab.jfronny.meteoradditions.util;
22

33
import net.minecraft.client.MinecraftClient;
4-
import net.minecraft.entity.Entity;
54
import net.minecraft.registry.*;
5+
import net.minecraft.world.World;
66

77
import java.util.Optional;
88
import java.util.stream.Stream;
@@ -19,7 +19,7 @@ public <T> Optional<? extends RegistryWrapper.Impl<T>> getOptional(RegistryKey<?
1919
}
2020

2121
private Optional<DynamicRegistryManager> getRegistryManager() {
22-
return Optional.ofNullable(MinecraftClient.getInstance().player)
23-
.map(Entity::getRegistryManager);
22+
return Optional.ofNullable(MinecraftClient.getInstance().world)
23+
.map(World::getRegistryManager);
2424
}
2525
}

0 commit comments

Comments
 (0)