aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2024-03-22 03:19:38 -0400
committerAaron <51387595+AzureAaron@users.noreply.github.com>2024-04-26 16:23:20 -0400
commit44f1f0829a683217daba452faf01566abbd94a3e (patch)
treeb988fa9ca4ed06da536cd2e13c0cd38e7933597c /src
parent91665eac629f41eb6dc75bec44244c7f97e97565 (diff)
downloadSkyblocker-44f1f0829a683217daba452faf01566abbd94a3e.tar.gz
Skyblocker-44f1f0829a683217daba452faf01566abbd94a3e.tar.bz2
Skyblocker-44f1f0829a683217daba452faf01566abbd94a3e.zip
Add more item component data fixers
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java62
-rw-r--r--src/test/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixerTest.java42
2 files changed, 102 insertions, 2 deletions
diff --git a/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java b/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java
index f1306ad5..0fa909bf 100644
--- a/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java
+++ b/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java
@@ -1,26 +1,84 @@
package de.hysky.skyblocker.utils.datafixer;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.mojang.brigadier.StringReader;
import com.mojang.serialization.Dynamic;
+import net.minecraft.command.argument.ItemStringReader;
+import net.minecraft.command.argument.ItemStringReader.ItemResult;
+import net.minecraft.component.DataComponentType;
import net.minecraft.datafixer.Schemas;
import net.minecraft.datafixer.TypeReferences;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtOps;
+import net.minecraft.registry.DynamicRegistryManager;
+import net.minecraft.registry.Registries;
+import net.minecraft.registry.RegistryOps;
+import net.minecraft.util.Identifier;
/**
- * Contains a data fixer to convert legacy item NBT to the new components system.
+ * Contains a data fixer to convert legacy item NBT to the new components system, among other fixers related to the item components system.
*
* @see {@link net.minecraft.datafixer.fix.ItemStackComponentizationFix}
*/
public class ItemStackComponentizationFixer {
private static final int ITEM_NBT_DATA_VERSION = 3817;
- private static final int ITEM_COMPONENTS_DATA_VERSION = 3818;
+ private static final int ITEM_COMPONENTS_DATA_VERSION = 3820;
+ private static final DynamicRegistryManager REGISTRY_MANAGER = new DynamicRegistryManager.ImmutableImpl(List.of(Registries.ITEM, Registries.DATA_COMPONENT_TYPE));
public static ItemStack fixUpItem(NbtCompound nbt) {
Dynamic<NbtElement> dynamic = Schemas.getFixer().update(TypeReferences.ITEM_STACK, new Dynamic<NbtElement>(NbtOps.INSTANCE, nbt), ITEM_NBT_DATA_VERSION, ITEM_COMPONENTS_DATA_VERSION);
return ItemStack.CODEC.parse(dynamic).result().orElseThrow();
}
+
+ /**
+ * Modified version of {@link net.minecraft.command.argument.ItemStackArgument#asString(net.minecraft.registry.RegistryWrapper.WrapperLookup)} to only care about changed components.
+ *
+ * @return The {@link ItemStack}'s components as a string which is in the format that the {@code /give} command accepts.
+ */
+ public static String componentsAsString(ItemStack stack) {
+ RegistryOps<NbtElement> nbtRegistryOps = REGISTRY_MANAGER.getOps(NbtOps.INSTANCE);
+
+ String componentsString = stack.getComponentChanges().entrySet().stream().flatMap(entry -> {
+ @SuppressWarnings("unchecked")
+ DataComponentType<Object> dataComponentType = (DataComponentType<Object>) entry.getKey();
+ Identifier componentId = Registries.DATA_COMPONENT_TYPE.getId(dataComponentType);
+ Optional<NbtElement> encodedComponent = dataComponentType.getCodec().encodeStart(nbtRegistryOps, entry.getValue().orElseThrow()).result();
+
+ if (componentId == null || encodedComponent.isEmpty()) {
+ return Stream.empty();
+ }
+
+ return Stream.of(componentId.toString() + "=" + encodedComponent.orElseThrow());
+ }).collect(Collectors.joining(String.valueOf(',')));
+
+ return "[" + componentsString + "]";
+ }
+
+ /**
+ * Constructs an {@link ItemStack} from an {@code itemId}, with item components in string format as returned by {@link #componentsAsString(ItemStack)}, and with a specified stack count.
+ *
+ * @return an {@link ItemStack} or {@link ItemStack#EMPTY} if there was an exception thrown.
+ */
+ public static ItemStack fromComponentsString(String itemId, int count, String componentsString) {
+ ItemStringReader reader = new ItemStringReader(REGISTRY_MANAGER);
+
+ try {
+ ItemResult result = reader.consume(new StringReader(itemId + componentsString));
+ ItemStack stack = new ItemStack(result.item(), count);
+
+ stack.applyComponentsFrom(result.components());
+
+ return stack;
+ } catch (Exception ignored) {}
+
+ return ItemStack.EMPTY;
+ }
}
diff --git a/src/test/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixerTest.java b/src/test/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixerTest.java
index 82f33e6d..774f1735 100644
--- a/src/test/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixerTest.java
+++ b/src/test/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixerTest.java
@@ -10,13 +10,24 @@ import com.mojang.serialization.JsonOps;
import net.minecraft.Bootstrap;
import net.minecraft.SharedConstants;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.component.type.ItemEnchantmentsComponent;
+import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.StringNbtReader;
+import net.minecraft.util.Util;
public class ItemStackComponentizationFixerTest {
private final NbtCompound NBT = convertToNbt("{id:\"minecraft:diamond_sword\",Count:1,tag:{ExtraAttributes:{id:\"TEST\"}}}");
private final Gson GSON = new Gson();
+ private final ItemStack TEST_STACK = Util.make(new ItemStack(Items.DIAMOND_SWORD, 1), item -> {
+ ItemEnchantmentsComponent.Builder builder = new ItemEnchantmentsComponent.Builder(ItemEnchantmentsComponent.DEFAULT);
+
+ builder.add(Enchantments.SHARPNESS, 1);
+ item.set(DataComponentTypes.ENCHANTMENTS, builder.build());
+ });
@BeforeAll
public static void setup() {
@@ -36,6 +47,37 @@ public class ItemStackComponentizationFixerTest {
Assertions.assertEquals("{\"id\":\"minecraft:diamond_sword\",\"count\":1,\"components\":{\"minecraft:custom_data\":{\"ExtraAttributes\":{\"id\":\"TEST\"}}}}", GSON.toJson(stackJson));
}
+
+ @Test
+ void testComponentsAsString() {
+ String componentString = ItemStackComponentizationFixer.componentsAsString(TEST_STACK);
+
+ Assertions.assertEquals("[minecraft:enchantments={levels:{\"minecraft:sharpness\":1}}]", componentString);
+ }
+
+ @Test
+ void testFromComponentsString() {
+ String componentString = "[minecraft:enchantments={levels:{\"minecraft:sharpness\":1}}]";
+ ItemStack stack = ItemStackComponentizationFixer.fromComponentsString("minecraft:diamond_sword", 1, componentString);
+
+ Assertions.assertTrue(ItemStack.areItemsAndComponentsEqual(stack, TEST_STACK));
+ }
+
+ @Test
+ void testFromComponentsStringWithInvalidItem() {
+ String componentString = "[minecraft:enchantments={levels:{\"minecraft:sharpness\":1}}]";
+ ItemStack stack = ItemStackComponentizationFixer.fromComponentsString("minecraft:does_not_exist", 1, componentString);
+
+ Assertions.assertEquals(stack, ItemStack.EMPTY);
+ }
+
+ @Test
+ void testNbtToComponentsString() {
+ ItemStack fixedStack = ItemStackComponentizationFixer.fixUpItem(NBT);
+ String componentsString = ItemStackComponentizationFixer.componentsAsString(fixedStack);
+
+ Assertions.assertEquals("[minecraft:custom_data={ExtraAttributes:{id:\"TEST\"}}]", componentsString);
+ }
private static NbtCompound convertToNbt(String nbt) {
try {