From 6240c883f255af1a6aed3eaee3f162107a73eaf3 Mon Sep 17 00:00:00 2001 From: qouteall Date: Sat, 22 Jul 2023 15:33:13 +0800 Subject: [PATCH 1/4] Make DFU error-tolerant to mod custom generator types. --- .../impl/dimension/TaggedChoiceExtension.java | 5 ++ .../dimension/TaggedChoiceTypeExtension.java | 5 ++ .../mixin/dimension/MixinSchema2832.java | 41 ++++++++++++++ .../mixin/dimension/MixinTaggedChoice.java | 41 ++++++++++++++ .../dimension/MixinTaggedChoiceType.java | 53 +++++++++++++++++++ .../fabric-dimensions-v1.mixins.json | 3 ++ .../dimension/void_earlier_in_hash_map.json | 22 ++++++++ 7 files changed, 170 insertions(+) create mode 100644 fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java create mode 100644 fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java create mode 100644 fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinSchema2832.java create mode 100644 fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoice.java create mode 100644 fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoiceType.java create mode 100644 fabric-dimensions-v1/src/testmod/resources/data/fabric_dimension/dimension/void_earlier_in_hash_map.json diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java new file mode 100644 index 0000000000..6609462e83 --- /dev/null +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java @@ -0,0 +1,5 @@ +package net.fabricmc.fabric.impl.dimension; + +public interface TaggedChoiceExtension { + void fabric$setFailSoft(boolean cond); +} diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java new file mode 100644 index 0000000000..623ce3ebfe --- /dev/null +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java @@ -0,0 +1,5 @@ +package net.fabricmc.fabric.impl.dimension; + +public interface TaggedChoiceTypeExtension { + void fabric$setFailSoft(boolean cond); +} diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinSchema2832.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinSchema2832.java new file mode 100644 index 0000000000..543b676376 --- /dev/null +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinSchema2832.java @@ -0,0 +1,41 @@ +package net.fabricmc.fabric.mixin.dimension; + +import java.util.Map; +import java.util.function.Supplier; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.types.Type; +import com.mojang.datafixers.types.templates.TaggedChoice; +import com.mojang.datafixers.types.templates.TypeTemplate; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import net.minecraft.datafixer.schema.Schema2832; + +import net.fabricmc.fabric.impl.dimension.TaggedChoiceExtension; + +@Mixin(value = Schema2832.class, remap = false) +public class MixinSchema2832 { + /** + * Make the DSL.taggedChoiceLazy to ignore mod custom generator types and not cause deserialization failure. + */ + @Redirect( + method = { + "method_38837", "method_38838" + }, + at = @At( + value = "INVOKE", + target = "Lcom/mojang/datafixers/DSL;taggedChoiceLazy(Ljava/lang/String;Lcom/mojang/datafixers/types/Type;Ljava/util/Map;)Lcom/mojang/datafixers/types/templates/TaggedChoice;", + remap = false + ), + remap = false + ) + private static TaggedChoice redirectTaggedChoiceLazy( + String name, Type keyType, Map> templates + ) { + TaggedChoice result = DSL.taggedChoiceLazy(name, keyType, templates); + ((TaggedChoiceExtension) (Object) result).fabric$setFailSoft(true); + return result; + } +} diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoice.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoice.java new file mode 100644 index 0000000000..4d33463edc --- /dev/null +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoice.java @@ -0,0 +1,41 @@ +package net.fabricmc.fabric.mixin.dimension; + +import com.mojang.datafixers.types.Type; +import com.mojang.datafixers.types.templates.TaggedChoice; +import com.mojang.datafixers.util.Pair; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.fabricmc.fabric.impl.dimension.TaggedChoiceExtension; +import net.fabricmc.fabric.impl.dimension.TaggedChoiceTypeExtension; + +@Mixin(value = TaggedChoice.class, remap = false) +public class MixinTaggedChoice implements TaggedChoiceExtension { + @Unique + boolean failSoft = false; + + @Override + public void fabric$setFailSoft(boolean cond) { + failSoft = cond; + } + + /** + * Pass the failSoft information into TaggedChoice.TaggedChoiceType. + */ + @SuppressWarnings("rawtypes") + @Inject( + method = "lambda$apply$0", at = @At("RETURN"), remap = false + ) + private void onApply(Pair key, CallbackInfoReturnable cir) { + if (failSoft) { + Type returnValue = cir.getReturnValue(); + + if (returnValue instanceof TaggedChoice.TaggedChoiceType taggedChoiceType) { + ((TaggedChoiceTypeExtension) (Object) taggedChoiceType).fabric$setFailSoft(true); + } + } + } +} diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoiceType.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoiceType.java new file mode 100644 index 0000000000..d777166e08 --- /dev/null +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoiceType.java @@ -0,0 +1,53 @@ +package net.fabricmc.fabric.mixin.dimension; + +import com.mojang.datafixers.types.Type; +import com.mojang.datafixers.types.templates.TaggedChoice; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.fabricmc.fabric.impl.dimension.TaggedChoiceTypeExtension; + +@Mixin(value = TaggedChoice.TaggedChoiceType.class, remap = false) +public class MixinTaggedChoiceType implements TaggedChoiceTypeExtension { + @Unique + private static final Logger LOGGER = LoggerFactory.getLogger("TaggedChoiceType_DimDataFix"); + + @Shadow(remap = false) + @Final + protected Object2ObjectMap> types; + + @Unique + private boolean failSoft; + + /** + * Make the DSL.taggedChoiceLazy to ignore mod custom generator types and not cause deserialization failure. + * The Codec.PASSTHROUGH will not make Dynamic to be deserialized and serialized to Dynamic. + * This will avoid deserialization failure from DFU when upgrading level.dat that contains mod custom generator types. + */ + @Inject( + method = "getCodec", at = @At("HEAD"), cancellable = true, remap = false + ) + private void onGetCodec(K k, CallbackInfoReturnable>> cir) { + if (failSoft) { + if (!types.containsKey(k)) { + LOGGER.warn("Not recognizing key {}. Using pass-through codec. {}", k, this); + cir.setReturnValue(DataResult.success(Codec.PASSTHROUGH)); + } + } + } + + @Override + public void fabric$setFailSoft(boolean cond) { + failSoft = cond; + } +} diff --git a/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json b/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json index bc4fcdd35b..169b24c4ba 100644 --- a/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json +++ b/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json @@ -4,6 +4,9 @@ "compatibilityLevel": "JAVA_16", "mixins": [ "EntityMixin", + "MixinSchema2832", + "MixinTaggedChoice", + "MixinTaggedChoiceType", "RegistryCodecsMixin" ], "injectors": { diff --git a/fabric-dimensions-v1/src/testmod/resources/data/fabric_dimension/dimension/void_earlier_in_hash_map.json b/fabric-dimensions-v1/src/testmod/resources/data/fabric_dimension/dimension/void_earlier_in_hash_map.json new file mode 100644 index 0000000000..c071854bb0 --- /dev/null +++ b/fabric-dimensions-v1/src/testmod/resources/data/fabric_dimension/dimension/void_earlier_in_hash_map.json @@ -0,0 +1,22 @@ +{ + "$comments": [ + "CompoundListCodec is sensitive to the order of elements in hash map in NbtCompound.", + "In CompoundListCodec, when one entry fails deserialization,", + "entries before it will remain but entries after it will be lost.", + "Coincidentally, fabric_dimension:void's position in hash map is after all vanilla dimensions.", + "When fabric_dimension:void fails deserialization in DFU, the vanilla dimensions will still be deserialized.", + "But a mod dimension's id could be before the vanilla dimensions in the hash map,", + "which will make it deserialize before vanilla dimensions and cause vanilla dimension lost.", + "This dimension fabric_dimension:void_earilier_in_hash_map has a different hashcode ", + "and is before minecraft:the_nether in the hash map, so it can reproduce that issue." + ], + "generator": { + "type": "fabric_dimension:void", + "custom_bool": true, + "biome_source": { + "type": "minecraft:fixed", + "biome": "minecraft:plains" + } + }, + "type": "fabric_dimension:void_type" +} From 0597beaa02e9099fff935d1eca94ec40041ca426 Mon Sep 17 00:00:00 2001 From: qouteall Date: Sat, 22 Jul 2023 16:08:25 +0800 Subject: [PATCH 2/4] Fix license. Rename mixin. --- ...xinSchema2832.java => Schema2832Mixin.java} | 18 +++++++++++++++++- ...aggedChoice.java => TaggedChoiceMixin.java} | 18 +++++++++++++++++- ...iceType.java => TaggedChoiceTypeMixin.java} | 18 +++++++++++++++++- .../resources/fabric-dimensions-v1.mixins.json | 8 ++++---- 4 files changed, 55 insertions(+), 7 deletions(-) rename fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/{MixinSchema2832.java => Schema2832Mixin.java} (67%) rename fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/{MixinTaggedChoice.java => TaggedChoiceMixin.java} (64%) rename fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/{MixinTaggedChoiceType.java => TaggedChoiceTypeMixin.java} (73%) diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinSchema2832.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java similarity index 67% rename from fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinSchema2832.java rename to fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java index 543b676376..e53d5b7818 100644 --- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinSchema2832.java +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.dimension; import java.util.Map; @@ -16,7 +32,7 @@ import net.fabricmc.fabric.impl.dimension.TaggedChoiceExtension; @Mixin(value = Schema2832.class, remap = false) -public class MixinSchema2832 { +public class Schema2832Mixin { /** * Make the DSL.taggedChoiceLazy to ignore mod custom generator types and not cause deserialization failure. */ diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoice.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceMixin.java similarity index 64% rename from fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoice.java rename to fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceMixin.java index 4d33463edc..e1da627b68 100644 --- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoice.java +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceMixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.dimension; import com.mojang.datafixers.types.Type; @@ -13,7 +29,7 @@ import net.fabricmc.fabric.impl.dimension.TaggedChoiceTypeExtension; @Mixin(value = TaggedChoice.class, remap = false) -public class MixinTaggedChoice implements TaggedChoiceExtension { +public class TaggedChoiceMixin implements TaggedChoiceExtension { @Unique boolean failSoft = false; diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoiceType.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceTypeMixin.java similarity index 73% rename from fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoiceType.java rename to fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceTypeMixin.java index d777166e08..f0339e408e 100644 --- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/MixinTaggedChoiceType.java +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceTypeMixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.dimension; import com.mojang.datafixers.types.Type; @@ -18,7 +34,7 @@ import net.fabricmc.fabric.impl.dimension.TaggedChoiceTypeExtension; @Mixin(value = TaggedChoice.TaggedChoiceType.class, remap = false) -public class MixinTaggedChoiceType implements TaggedChoiceTypeExtension { +public class TaggedChoiceTypeMixin implements TaggedChoiceTypeExtension { @Unique private static final Logger LOGGER = LoggerFactory.getLogger("TaggedChoiceType_DimDataFix"); diff --git a/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json b/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json index 169b24c4ba..74f20a425f 100644 --- a/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json +++ b/fabric-dimensions-v1/src/main/resources/fabric-dimensions-v1.mixins.json @@ -4,10 +4,10 @@ "compatibilityLevel": "JAVA_16", "mixins": [ "EntityMixin", - "MixinSchema2832", - "MixinTaggedChoice", - "MixinTaggedChoiceType", - "RegistryCodecsMixin" + "RegistryCodecsMixin", + "Schema2832Mixin", + "TaggedChoiceMixin", + "TaggedChoiceTypeMixin" ], "injectors": { "defaultRequire": 1 From c1fd7fc6c94d98d66b02e1ce80ab41063ba076fd Mon Sep 17 00:00:00 2001 From: qouteall Date: Sat, 22 Jul 2023 16:20:51 +0800 Subject: [PATCH 3/4] Fix license. --- .../impl/dimension/TaggedChoiceExtension.java | 16 ++++++++++++++++ .../dimension/TaggedChoiceTypeExtension.java | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java index 6609462e83..2bb7340afb 100644 --- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceExtension.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.impl.dimension; public interface TaggedChoiceExtension { diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java index 623ce3ebfe..8e041d1b0f 100644 --- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/TaggedChoiceTypeExtension.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.impl.dimension; public interface TaggedChoiceTypeExtension { From a78b69cd69dc078fa3eccef3b545389aa99806a4 Mon Sep 17 00:00:00 2001 From: qouteall Date: Wed, 9 Aug 2023 21:16:51 +0800 Subject: [PATCH 4/4] Disable remap in Schema2832Mixin --- .../net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java index e53d5b7818..c441aee85d 100644 --- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java +++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/Schema2832Mixin.java @@ -31,7 +31,7 @@ import net.fabricmc.fabric.impl.dimension.TaggedChoiceExtension; -@Mixin(value = Schema2832.class, remap = false) +@Mixin(Schema2832.class) public class Schema2832Mixin { /** * Make the DSL.taggedChoiceLazy to ignore mod custom generator types and not cause deserialization failure. @@ -44,8 +44,7 @@ public class Schema2832Mixin { value = "INVOKE", target = "Lcom/mojang/datafixers/DSL;taggedChoiceLazy(Ljava/lang/String;Lcom/mojang/datafixers/types/Type;Ljava/util/Map;)Lcom/mojang/datafixers/types/templates/TaggedChoice;", remap = false - ), - remap = false + ) ) private static TaggedChoice redirectTaggedChoiceLazy( String name, Type keyType, Map> templates