diff --git a/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java b/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java
new file mode 100644
index 000000000..747800701
--- /dev/null
+++ b/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java
@@ -0,0 +1,51 @@
+// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package dan200.computercraft.mixin;
+
+import com.llamalad7.mixinextras.sugar.Local;
+import com.mojang.datafixers.DataFixUtils;
+import com.mojang.datafixers.DataFixerBuilder;
+import com.mojang.datafixers.schemas.Schema;
+import dan200.computercraft.shared.datafix.TurtleUpgradeComponentizationFix;
+import net.minecraft.util.datafix.DataFixers;
+import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix;
+import net.minecraft.util.datafix.schemas.V3818_5;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+
+@Mixin(DataFixers.class)
+abstract class DataFixersMixin {
+ /**
+ * Register {@link TurtleUpgradeComponentizationFix} alongside {@link ItemStackComponentizationFix}.
+ *
+ * We use a {@link ModifyArg} to capture the schema passed to {@link ItemStackComponentizationFix}. This is a
+ * little gross, but is the easiest way to obtain the schema without hard-coding local ordinals.
+ *
+ * @param schema The {@link V3818_5} schema.
+ * @param builder The current datafixer builder
+ * @return The input schema.
+ */
+ @ModifyArg(
+ method = "addFixers",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/util/datafix/fixes/ItemStackComponentizationFix;(Lcom/mojang/datafixers/schemas/Schema;)V"),
+ index = 0,
+ allow = 1
+ )
+ @SuppressWarnings("UnusedMethod")
+ private static Schema addComponentizationFixes(Schema schema, @Local DataFixerBuilder builder) {
+ assertSchemaVersion(schema, DataFixUtils.makeKey(3818, 5));
+ builder.addFixer(new TurtleUpgradeComponentizationFix(schema));
+ return schema;
+ }
+
+ @Unique
+ private static void assertSchemaVersion(Schema schema, int version) {
+ if (schema.getVersionKey() != version) {
+ throw new IllegalStateException("Unexpected schema version. Expected " + version + ", got " + schema.getVersionKey());
+ }
+ }
+}
diff --git a/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java b/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java
index f3a92b1cd..64a4a295e 100644
--- a/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java
+++ b/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java
@@ -4,14 +4,11 @@
package dan200.computercraft.mixin;
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.mojang.datafixers.DataFix;
-import com.mojang.datafixers.TypeRewriteRule;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.serialization.Dynamic;
-import dan200.computercraft.shared.util.ComponentizationFixers;
+import dan200.computercraft.shared.datafix.ComponentizationFixers;
import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix;
-import net.minecraft.util.datafix.fixes.References;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -35,15 +32,4 @@ abstract class ItemStackComponentizationFixMixin extends DataFix {
private static void fixItemStack(ItemStackComponentizationFix.ItemStackData data, Dynamic> ops, CallbackInfo ci) {
ComponentizationFixers.fixItemComponents(data, ops);
}
-
- @ModifyReturnValue(method = "makeRule", at = @At("RETURN"), remap = false)
- @SuppressWarnings("UnusedMethod")
- private TypeRewriteRule wrapMakeRule(TypeRewriteRule existing) {
- return TypeRewriteRule.seq(existing, fixTypeEverywhereTyped(
- "Turtle upgrade componentization",
- getInputSchema().getType(References.BLOCK_ENTITY),
- getOutputSchema().getType(References.BLOCK_ENTITY),
- ComponentizationFixers.makeBlockEntityRewrites(getInputSchema(), getOutputSchema())
- ));
- }
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java b/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java
similarity index 99%
rename from projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java
rename to projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java
index 83baa9868..52336ff5b 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: MPL-2.0
-package dan200.computercraft.shared.util;
+package dan200.computercraft.shared.datafix;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.Typed;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java b/projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java
new file mode 100644
index 000000000..63e318ca0
--- /dev/null
+++ b/projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java
@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package dan200.computercraft.shared.datafix;
+
+import com.mojang.datafixers.DataFix;
+import com.mojang.datafixers.TypeRewriteRule;
+import com.mojang.datafixers.schemas.Schema;
+import net.minecraft.util.datafix.fixes.References;
+
+/**
+ * Rewrites turtle block entities to store upgrades as components.
+ *
+ * @see ComponentizationFixers#makeBlockEntityRewrites(Schema, Schema)
+ */
+public class TurtleUpgradeComponentizationFix extends DataFix {
+ public TurtleUpgradeComponentizationFix(Schema outputSchema) {
+ super(outputSchema, true);
+ }
+
+ @Override
+ protected TypeRewriteRule makeRule() {
+ return fixTypeEverywhereTyped(
+ "Turtle upgrade componentization",
+ getInputSchema().getType(References.BLOCK_ENTITY),
+ getOutputSchema().getType(References.BLOCK_ENTITY),
+ ComponentizationFixers.makeBlockEntityRewrites(getInputSchema(), getOutputSchema())
+ );
+ }
+}
diff --git a/projects/common/src/main/resources/computercraft.mixins.json b/projects/common/src/main/resources/computercraft.mixins.json
index 84cd67612..fcaf1e4d2 100644
--- a/projects/common/src/main/resources/computercraft.mixins.json
+++ b/projects/common/src/main/resources/computercraft.mixins.json
@@ -7,6 +7,7 @@
"defaultRequire": 1
},
"mixins": [
+ "DataFixersMixin",
"ItemStackComponentizationFixMixin",
"V1460Mixin"
]
diff --git a/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java b/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java
index 26b7806db..11c3cd544 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java
@@ -7,7 +7,7 @@ package dan200.computercraft.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.templates.TypeTemplate;
-import dan200.computercraft.shared.util.ComponentizationFixers;
+import dan200.computercraft.shared.datafix.ComponentizationFixers;
import net.minecraft.util.datafix.schemas.V3818_3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
diff --git a/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java b/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java
index 710f5c056..fbc9773d3 100644
--- a/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java
+++ b/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java
@@ -7,7 +7,7 @@ package dan200.computercraft.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.templates.TypeTemplate;
-import dan200.computercraft.shared.util.ComponentizationFixers;
+import dan200.computercraft.shared.datafix.ComponentizationFixers;
import net.minecraft.util.datafix.schemas.V3818_3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;