|
2 | 2 |
|
3 | 3 | import com.mojang.brigadier.StringReader; |
4 | 4 | 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.*; |
8 | 6 | import net.minecraft.component.ComponentChanges; |
9 | 7 | import net.minecraft.component.DataComponentTypes; |
10 | 8 | import net.minecraft.component.type.NbtComponent; |
|
14 | 12 | import net.minecraft.item.ItemStack; |
15 | 13 | import net.minecraft.nbt.*; |
16 | 14 | import net.minecraft.nbt.visitor.StringNbtWriter; |
17 | | -import net.minecraft.registry.Registries; |
| 15 | +import net.minecraft.registry.*; |
| 16 | +import net.minecraft.server.command.CommandManager; |
18 | 17 | import net.minecraft.text.Text; |
19 | 18 | import net.minecraft.util.Identifier; |
20 | 19 | import net.minecraft.util.InvalidIdentifierException; |
21 | 20 |
|
22 | 21 | import java.util.Optional; |
23 | 22 |
|
24 | 23 | 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 | | - |
33 | 24 | 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 | + |
34 | 28 | 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)))); |
36 | 31 | if (stack.getCount() != 1) sb.append('$').append(stack.getCount()); |
37 | 32 | return sb.toString(); |
38 | 33 | } |
39 | 34 |
|
40 | 35 | 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 | + |
41 | 39 | StringReader reader = new StringReader(desc); |
42 | 40 | 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(); |
44 | 45 | ItemStack stack = new ItemStack(item, 1); |
45 | 46 | while (reader.canRead()) { |
46 | 47 | switch (reader.read()) { |
47 | 48 | case '{' -> { |
48 | 49 | try { |
49 | 50 | 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))); |
51 | 55 | } catch (CommandSyntaxException e) { |
52 | 56 | throw new ItemSyntaxException("Could not parse NBT", e); |
53 | 57 | } |
|
0 commit comments