From 7af2c1432737d3bc7c55058788dec6e583c3eed0 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 23 Nov 2024 08:53:54 +0000 Subject: [PATCH] Move block entity component fixes to separate fixer Some mods run their own datafixer chain, rather than piggybacking on top of vanilla's. This is A BAD IDEA, but what can you do. If such a mod tries to use ItemStackComponentizationFix in their own schema, then CC:T's mixins will try to look up the turtle block entitie, and fail (as they're not registered under the modded schema). We now inject the block entity fix as a separate fixer, rather than abusing ItemStackComponentizationFix. See #2012 --- .../computercraft/mixin/DataFixersMixin.java | 51 +++++++++++++++++++ .../ItemStackComponentizationFixMixin.java | 16 +----- .../ComponentizationFixers.java | 2 +- .../TurtleUpgradeComponentizationFix.java | 31 +++++++++++ .../main/resources/computercraft.mixins.json | 1 + .../computercraft/mixin/V3818_3Mixin.java | 2 +- .../computercraft/mixin/V3818_3Mixin.java | 2 +- 7 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java rename projects/common/src/main/java/dan200/computercraft/shared/{util => datafix}/ComponentizationFixers.java (99%) create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java 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 @@ private ItemStackComponentizationFixMixin(Schema outputSchema, boolean changesTy 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 @@ 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 @@ 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;