diff --git a/build.gradle.kts b/build.gradle.kts index fc341d4ac..0fdf84b6e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -296,6 +296,7 @@ tasks { license { if (licenseChecks) { + rule(file("codeformat/FABRIC_QUILT_MODIFIED_HEADER")) rule(file("codeformat/QUILT_MODIFIED_HEADER")) rule(file("codeformat/HEADER")) diff --git a/codeformat/FABRIC_QUILT_MODIFIED_HEADER b/codeformat/FABRIC_QUILT_MODIFIED_HEADER new file mode 100644 index 000000000..c66a6f04a --- /dev/null +++ b/codeformat/FABRIC_QUILT_MODIFIED_HEADER @@ -0,0 +1,28 @@ +Copyright (c) ${YEAR} FabricMC +Copyright (c) ${YEAR} FrozenBlock +Modified to use Mojang's Official Mappings + +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. + +This file is a modified version of Quilt Standard Libraries, +authored by QuiltMC. + +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2016-2022 FabricMC +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2016, 2017, 2018, 2019 FabricMC +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2022 FabricMC +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2021-2022 FabricMC +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2023 FabricMC +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2021-2023 FabricMC +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2022-2023 FabricMC +;;match_from: \/\*\r?\n \* Copyright (\(c\) )?2024 FabricMC +;;year_display: lenient_range diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/api/DataFixerEntrypoint.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/DataFixerEntrypoint.java new file mode 100644 index 000000000..e27ad5b8a --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/DataFixerEntrypoint.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.api; + +import com.mojang.datafixers.schemas.Schema; + +public interface DataFixerEntrypoint { + void onRegisterBlockEntities(SchemaRegistry registry, Schema schema); + + void onRegisterEntities(SchemaRegistry registry, Schema schema); +} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/EmptySchema.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/EmptySchema.java similarity index 58% rename from src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/EmptySchema.java rename to src/main/java/net/fabricmc/frozenblock/datafixer/api/EmptySchema.java index dcba53b51..f3123744d 100644 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/EmptySchema.java +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/EmptySchema.java @@ -1,7 +1,7 @@ /* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,12 @@ * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. */ -package org.quiltmc.qsl.frozenblock.misc.datafixerupper.api; +package net.fabricmc.frozenblock.datafixer.api; import com.mojang.datafixers.DSL; import com.mojang.datafixers.schemas.Schema; @@ -29,27 +32,27 @@ /** * Represents an empty {@link Schema}, having no parent and containing no type definitions. - *

- * Modified to work on Fabric */ public final class EmptySchema extends FirstSchema { - /** - * Constructs an empty schema. - * - * @param versionKey the data version key - */ - public EmptySchema(@Range(from = 0, to = Integer.MAX_VALUE) int versionKey) { - super(versionKey); - } + // From QSL. + + /** + * Constructs an empty schema. + * + * @param versionKey the data version key + */ + public EmptySchema(@Range(from = 0, to = Integer.MAX_VALUE) int versionKey) { + super(versionKey); + } - // Ensure the schema stays empty. - @Override - public void registerType(boolean recursive, DSL.TypeReference type, Supplier template) { - throw new UnsupportedOperationException(); - } + // Ensure the schema stays empty. + @Override + public void registerType(boolean recursive, DSL.TypeReference type, Supplier template) { + throw new UnsupportedOperationException(); + } - @Override - protected Map> buildTypes() { - return Object2ObjectMaps.emptyMap(); - } + @Override + protected Map> buildTypes() { + return Object2ObjectMaps.emptyMap(); + } } diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/api/FabricDataFixerBuilder.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/FabricDataFixerBuilder.java new file mode 100644 index 000000000..bcf2d9f32 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/FabricDataFixerBuilder.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.api; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFixerBuilder; +import com.mojang.datafixers.DataFixerUpper; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.function.Supplier; +import net.fabricmc.frozenblock.datafixer.impl.FabricDataFixesInternals; +import net.fabricmc.loader.api.ModContainer; +import net.minecraft.Util; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Range; + +/** + * An extended variant of the {@link DataFixerBuilder} class, which provides an extra method. + */ +public class FabricDataFixerBuilder extends DataFixerBuilder { + // From QSL. + protected final int dataVersion; + + /** + * Creates a new {@code FabricDataFixerBuilder}. + * + * @param dataVersion the current data version + */ + public FabricDataFixerBuilder(@Range(from = 0, to = Integer.MAX_VALUE) int dataVersion) { + super(dataVersion); + this.dataVersion = dataVersion; + } + + /** + * Creates a new {@code FabricDataFixerBuilder}. This method gets the current version from + * the {@code fabric-data-fixer-api-v1:version} field in the {@code custom} object of + * the {@code fabric.mod.json} file of {@code mod}. To specify the version + * manually, use the other overload. + * + * @param mod the mod container + * @return the data fixer builder + * @throws RuntimeException if the version field does not exist or is not a number + */ + public static FabricDataFixerBuilder create(ModContainer mod) { + Objects.requireNonNull(mod, "mod cannot be null"); + int dataVersion = FabricDataFixesInternals.getDataVersionFromMetadata(mod); + return new FabricDataFixerBuilder(dataVersion); + } + + /** + * @return the current data version + */ + @Range(from = 0, to = Integer.MAX_VALUE) + public int getDataVersion() { + return this.dataVersion; + } + + /** + * Builds the final {@code DataFixer}. + * + *

This will build either an {@linkplain #build() unoptimized fixer} or an + * optimized fixer, depending on the vanilla game's settings. + * + * @param types the set of required {@link DSL.TypeReference}s, only used if the game is using optimized data fixers + * @param executorGetter the executor supplier, only invoked if the game is using optimized data fixers + * @return the newly built data fixer + */ + @Contract(value = "_, _ -> new") + public DataFixerUpper build(Set types, Supplier executorGetter) { + Objects.requireNonNull(executorGetter, "executorGetter cannot be null"); + return (DataFixerUpper) (types.isEmpty() ? this.build().fixer() : Util.make(() -> { + Result result = this.build(); + result.optimize(types, executorGetter.get()).join(); + return result.fixer(); + })); + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/api/FabricDataFixes.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/FabricDataFixes.java new file mode 100644 index 000000000..00b3aff15 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/FabricDataFixes.java @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.api; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.DataFixerBuilder; +import com.mojang.datafixers.DataFixerUpper; +import com.mojang.datafixers.schemas.Schema; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import net.fabricmc.frozenblock.datafixer.impl.FabricDataFixesInternals; +import net.fabricmc.loader.api.ModContainer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.datafix.DataFixTypes; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; +import static java.util.Objects.requireNonNull; + +/** + * Provides methods to register custom {@link DataFixer}s. + */ +public final class FabricDataFixes { + // From QSL. + private FabricDataFixes() { + throw new RuntimeException("FabricDataFixes only contains static declarations."); + } + + /** + * A "base" version {@code 0} schema, for use by all mods. + * + *

This schema must be the first one added! + * + * @see DataFixerBuilder#addSchema(int, BiFunction) + */ + public static BiFunction getBaseSchema() { + return (version, parent) -> { + Preconditions.checkArgument(version == 0, "version must be 0"); + Preconditions.checkArgument(parent == null, "parent must be null"); + return FabricDataFixesInternals.get().getBaseSchema(); + }; + } + + /** + * Registers a new data fixer. + * + * @param modId the mod ID + * @param currentVersion the current version of the mod's data + * @param dataFixer the data fixer + */ + public static void registerFixer(String modId, + @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, + DataFixerUpper dataFixer) { + registerFixer(modId, currentVersion, null, dataFixer); + } + + /** + * Registers a new data fixer. + * + * @param modId the mod ID + * @param currentVersion the current version of the mod's data + * @param key the optional key of the saved current version + * @param dataFixer the data fixer + */ + public static void registerFixer(String modId, + @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, + @Nullable String key, DataFixerUpper dataFixer) { + Objects.requireNonNull(modId, "modId cannot be null"); + //noinspection ConstantConditions + Preconditions.checkArgument(currentVersion >= 0, "currentVersion must be positive"); + Objects.requireNonNull(dataFixer, "dataFixer cannot be null"); + + if (isFrozen()) { + throw new IllegalStateException("Can't register data fixer after registry is frozen"); + } + + FabricDataFixesInternals.get().registerFixer(modId, currentVersion, key, dataFixer); + } + + /** + * Registers a new data fixer. + * + * @param mod the mod container + * @param currentVersion the current version of the mod's data + * @param dataFixer the data fixer + */ + public static void registerFixer(ModContainer mod, + @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, + DataFixerUpper dataFixer) { + registerFixer(mod, currentVersion, null, dataFixer); + } + + /** + * Registers a new data fixer. + * + * @param mod the mod container + * @param currentVersion the current version of the mod's data + * @param key the optional key of the saved current version + * @param dataFixer the data fixer + */ + public static void registerFixer(ModContainer mod, + @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, + @Nullable String key, + DataFixerUpper dataFixer) { + Objects.requireNonNull(mod, "mod cannot be null"); + + registerFixer(mod.getMetadata().getId(), currentVersion, key, dataFixer); + } + + /** + * Registers a new data fixer. This method gets the current version from + * the {@code fabric-data-fixer-api-v1:version} field in the {@code custom} object of + * the {@code fabric.mod.json} file of {@code mod}. To specify the version + * manually, use the other overloads. + * + * @param mod the mod container + * @param dataFixer the data fixer + * @throws RuntimeException if the version field does not exist or is not a number + */ + public static void registerFixer(ModContainer mod, DataFixerUpper dataFixer) { + Objects.requireNonNull(mod, "mod cannot be null"); + registerFixer(mod.getMetadata().getId(), FabricDataFixesInternals.getDataVersionFromMetadata(mod), FabricDataFixesInternals.getKeyFromMetadata(mod), dataFixer); + } + + /** + * Builds and registers a new data fixer. + * + * @param mod the mod container + * @param builder the data fixer builder + */ + public static void buildAndRegisterFixer(ModContainer mod, + FabricDataFixerBuilder builder) { + buildAndRegisterFixer(mod, null, builder); + } + + /** + * Builds and registers a new data fixer. + * + * @param mod the mod container + * @param builder the data fixer builder + */ + public static void buildAndRegisterFixer(ModContainer mod, + @Nullable String key, FabricDataFixerBuilder builder) { + Objects.requireNonNull(mod, "mod cannot be null"); + Objects.requireNonNull(builder, "data fixer builder cannot be null"); + + Supplier executor = () -> Executors.newSingleThreadExecutor( + new ThreadFactoryBuilder().setNameFormat("Fabric DataFixer Bootstrap").setDaemon(true).setPriority(1).build() + ); + + registerFixer(mod.getMetadata().getId(), builder.getDataVersion(), + key, builder.build(DataFixTypes.TYPES_FOR_LEVEL_LIST, executor)); + } + + /** + * Builds a new data fixer. + * + * @param dataFixerBuilder the data fixer builder + * @return The built data fixer. + */ + public static DataFixer buildFixer(@NotNull FabricDataFixerBuilder dataFixerBuilder) { + requireNonNull(dataFixerBuilder, "data fixer builder cannot be null"); + + Supplier executor = () -> Executors.newSingleThreadExecutor( + new ThreadFactoryBuilder().setNameFormat("FrozenLib Quilt Datafixer Bootstrap").setDaemon(true).setPriority(1).build() + ); + + return dataFixerBuilder.build(DataFixTypes.TYPES_FOR_LEVEL_LIST, executor); + } + + /** + * Gets a mod's data fixers. + * + * @param modId the mod ID + * @return the mod's data fixers, or empty optional if the mod hasn't registered any + */ + public static Optional>> getFixers(String modId) { + Objects.requireNonNull(modId, "modId cannot be null"); + + List> fixers = new ArrayList<>(); + + List entries = FabricDataFixesInternals.get().getFixerEntries(modId); + + if (entries == null) { + return Optional.empty(); + } + + for (FabricDataFixesInternals.DataFixerEntry entry : entries) { + if (entry == null) { + fixers.add(Optional.empty()); + } else { + fixers.add(Optional.of(entry.dataFixer())); + } + } + + return Optional.of(fixers); + } + + /** + * Gets a mod's data version from a {@link CompoundTag}. + * + * @param nbt the NBT compound + * @param modId the mod ID + * @return the mod's data version, or {@code 0} if the NBT has no data for that mod + */ + @Contract(pure = true) + @Range(from = 0, to = Integer.MAX_VALUE) + public static int getModDataVersion(CompoundTag nbt, String modId) { + return getModDataVersion(nbt, modId, null); + } + + /** + * Gets a mod's data version from a {@link CompoundTag}. + * + * @param nbt the NBT compound + * @param modId the mod ID + * @return the mod's data version, or {@code 0} if the NBT has no data for that mod + */ + @Contract(pure = true) + @Range(from = 0, to = Integer.MAX_VALUE) + public static int getModDataVersion(CompoundTag nbt, String modId, @Nullable String key) { + Objects.requireNonNull(nbt, "compound cannot be null"); + Objects.requireNonNull(modId, "modId cannot be null"); + + return FabricDataFixesInternals.getModDataVersion(nbt, modId, key); + } + + /** + * Checks if the data fixer registry is frozen. Data fixers cannot be registered + * after the registry gets frozen. + * + * @return {@code true} if frozen, or {@code false} otherwise. + */ + @Contract(pure = true) + public static boolean isFrozen() { + return FabricDataFixesInternals.get().isFrozen(); + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/api/FirstSchema.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/FirstSchema.java new file mode 100644 index 000000000..490316a11 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/FirstSchema.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.api; + +import com.mojang.datafixers.schemas.Schema; +import com.mojang.datafixers.types.templates.TypeTemplate; +import java.util.Map; +import java.util.function.Supplier; +import org.jetbrains.annotations.Range; + +/** + * Represents a {@link Schema} that has no parent. + */ +public class FirstSchema extends Schema { + // From QSL. + + /** + * Creates a schema. + * + * @param versionKey the data version key + */ + public FirstSchema(@Range(from = 0, to = Integer.MAX_VALUE) int versionKey) { + super(versionKey, null); + } + + // all of these methods refer to this.parent without checking if its null + @Override + public void registerTypes(Schema schema, Map> entityTypes, + Map> blockEntityTypes) { + } + + @Override + public Map> registerEntities(Schema schema) { + return Map.of(); + } + + @Override + public Map> registerBlockEntities(Schema schema) { + return Map.of(); + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/api/SchemaRegistry.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/SchemaRegistry.java new file mode 100644 index 000000000..de62c2929 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/SchemaRegistry.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.api; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.datafixers.types.templates.TypeTemplate; +import com.mojang.datafixers.util.Either; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; +import net.minecraft.resources.ResourceLocation; + +public interface SchemaRegistry { + void register(ResourceLocation id, Supplier template); + + void register(ResourceLocation id, Function template); + + void addSchema(BiFunction factory); + + Supplier remove(ResourceLocation id); + + ImmutableMap, Function>> get(); + + ImmutableList getKeys(); + + ImmutableList, Function>> getValues(); + + ImmutableList> getFutureSchemas(); +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/api/SimpleFixes.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/SimpleFixes.java new file mode 100644 index 000000000..e34115df5 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/SimpleFixes.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.api; + +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFix; +import com.mojang.datafixers.DataFixerBuilder; +import com.mojang.datafixers.TypeRewriteRule; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.serialization.Dynamic; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.datafix.DataFixers; +import net.minecraft.util.datafix.fixes.BlockRenameFix; +import net.minecraft.util.datafix.fixes.ItemRenameFix; +import net.minecraft.util.datafix.fixes.NamespacedTypeRenameFix; +import net.minecraft.util.datafix.fixes.References; +import net.minecraft.util.datafix.fixes.SimplestEntityRenameFix; +import net.minecraft.util.datafix.schemas.NamespacedSchema; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import static java.util.Objects.requireNonNull; + +/** + * Provides methods to add common {@link DataFix}es to {@link DataFixerBuilder}s. + */ +public final class SimpleFixes { + // From QSL. + private SimpleFixes() { + throw new RuntimeException("SimpleFixes contains only static declarations."); + } + + /** + * Adds a block rename fix to the builder, in case a block's identifier is changed. + * + * @param builder the builder + * @param name the fix's name + * @param oldId the block's old identifier + * @param newId the block's new identifier + * @param schema the schema this fixer should be a part of + * @see BlockRenameFix + */ + public static void addBlockRenameFix(DataFixerBuilder builder, String name, + ResourceLocation oldId, ResourceLocation newId, + Schema schema) { + Objects.requireNonNull(builder, "DataFixerBuilder cannot be null"); + Objects.requireNonNull(name, "Fix name cannot be null"); + Objects.requireNonNull(oldId, "Old identifier cannot be null"); + Objects.requireNonNull(newId, "New identifier cannot be null"); + Objects.requireNonNull(schema, "Schema cannot be null"); + + final String oldIdStr = oldId.toString(), newIdStr = newId.toString(); + builder.addFixer(BlockRenameFix.create(schema, name, (inputName) -> + Objects.equals(NamespacedSchema.ensureNamespaced(inputName), oldIdStr) ? newIdStr : inputName)); + } + + /** + * Adds an entity rename fix to the builder, in case an entity's identifier is changed. + * + * @param builder the builder + * @param name the fix's name + * @param oldId the entity's old identifier + * @param newId the entity's new identifier + * @param schema the schema this fix should be a part of + * @see SimplestEntityRenameFix + */ + public static void addEntityRenameFix(DataFixerBuilder builder, String name, + ResourceLocation oldId, ResourceLocation newId, + Schema schema) { + requireNonNull(builder, "DataFixerBuilder cannot be null"); + requireNonNull(name, "Fix name cannot be null"); + requireNonNull(oldId, "Old identifier cannot be null"); + requireNonNull(newId, "New identifier cannot be null"); + requireNonNull(schema, "Schema cannot be null"); + + final String oldIdStr = oldId.toString(), newIdStr = newId.toString(); + builder.addFixer(new SimplestEntityRenameFix(name, schema, false) { + @Override + protected String rename(String inputName) { + return Objects.equals(NamespacedSchema.ensureNamespaced(inputName), oldIdStr) ? newIdStr : inputName; + } + }); + } + + /** + * Adds an item rename fix to the builder, in case an item's identifier is changed. + * + * @param builder the builder + * @param name the fix's name + * @param oldId the item's old identifier + * @param newId the item's new identifier + * @param schema the schema this fix should be a part of + * @see ItemRenameFix + */ + public static void addItemRenameFix(DataFixerBuilder builder, String name, + ResourceLocation oldId, ResourceLocation newId, + Schema schema) { + Objects.requireNonNull(builder, "DataFixerBuilder cannot be null"); + Objects.requireNonNull(name, "Fix name cannot be null"); + Objects.requireNonNull(oldId, "Old identifier cannot be null"); + Objects.requireNonNull(newId, "New identifier cannot be null"); + Objects.requireNonNull(schema, "Schema cannot be null"); + + final String oldIdStr = oldId.toString(), newIdStr = newId.toString(); + builder.addFixer(ItemRenameFix.create(schema, name, (inputName) -> + Objects.equals(NamespacedSchema.ensureNamespaced(inputName), oldIdStr) ? newIdStr : inputName)); + } + + /** + * Adds a blockstate rename fix to the builder, in case a blockstate's name is changed. + * + * @param builder the builder + * @param name the fix's name + * @param blockId the block's identifier + * @param oldState the blockstate's old name + * @param defaultValue the blockstate's default value + * @param newState the blockstates's new name + * @param schema the schema this fixer should be a part of + * @see BlockStateRenameFix + */ + public static void addBlockStateRenameFix(DataFixerBuilder builder, String name, ResourceLocation blockId, String oldState, + String defaultValue, String newState, + Schema schema) { + requireNonNull(builder, "DataFixerBuilder cannot be null"); + requireNonNull(name, "Fix name cannot be null"); + requireNonNull(blockId, "Block Id cannot be null"); + requireNonNull(oldState, "Old BlockState cannot be null"); + requireNonNull(defaultValue, "Default value cannot be null"); + requireNonNull(newState, "New BlockState cannot be null"); + requireNonNull(schema, "Schema cannot be null"); + + final String blockIdStr = blockId.toString(); + builder.addFixer(new BlockStateRenameFix(schema, name, blockIdStr, oldState, defaultValue, newState)); + } + + /** + * Adds a biome rename fix to the builder, in case biome identifiers are changed. + * + * @param builder the builder + * @param name the fix's name + * @param changes a map of old biome identifiers to new biome identifiers + * @param schema the schema this fixer should be a part of + * @see NamespacedTypeRenameFix + */ + public static void addBiomeRenameFix(DataFixerBuilder builder, String name, + Map changes, + Schema schema) { + Objects.requireNonNull(builder, "DataFixerBuilder cannot be null"); + Objects.requireNonNull(name, "Fix name cannot be null"); + Objects.requireNonNull(changes, "Changes cannot be null"); + Objects.requireNonNull(schema, "Schema cannot be null"); + + ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); + + for (Map.Entry entry : changes.entrySet()) { + mapBuilder.put(entry.getKey().toString(), entry.getValue().toString()); + } + + builder.addFixer(new NamespacedTypeRenameFix(schema, name, References.BIOME, DataFixers.createRenamer(mapBuilder.build()))); + } + + public static class BlockStateRenameFix extends DataFix { + private final String name; + private final String blockId; + private final String oldState; + private final String defaultState; + private final String newState; + + public BlockStateRenameFix(Schema outputSchema, String name, String blockId, String oldState, String defaultState, String newState) { + super(outputSchema, false); + this.name = name; + this.blockId = blockId; + this.oldState = oldState; + this.defaultState = defaultState; + this.newState = newState; + } + + private Dynamic fix(Dynamic dynamic) { + Optional optional = dynamic.get("Name").asString().result(); + return optional.equals(Optional.of(this.blockId)) ? dynamic.update("Properties", dynamic1 -> { + String string = dynamic1.get(this.oldState).asString(this.defaultState); + return dynamic1.remove(this.oldState).set(this.newState, dynamic1.createString(string)); + }) : dynamic; + } + + @Override + protected TypeRewriteRule makeRule() { + return this.fixTypeEverywhereTyped(this.name, this.getInputSchema().getType(References.BLOCK_STATE), + typed -> typed.update(DSL.remainderFinder(), this::fix) + ); + } + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/api/package-info.java b/src/main/java/net/fabricmc/frozenblock/datafixer/api/package-info.java new file mode 100644 index 000000000..78d4a6c65 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/api/package-info.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +/** + *

Custom DataFixerUpper API

+ * + *

This API lets you register a {@code DataFixer} for your own mod, allowing mods to make + * changes affecting world save without breaking compatibility! + * + *

Here is an example simple use of this API: + *

{@code
+ * // the latest version of the mod's data
+ * // this should match the version of the last schema added!
+ * // note that the default data version is 0, meaning that you can upgrade
+ * //  from a version that did not have a fixer
+ * //  (by registering a schema for upgrading from version 0 to version 1)
+ * public static final int CURRENT_DATA_VERSION = 1;
+ *
+ * public static void initialize(ModContainer mod) {
+ *     // create a builder
+ *     FabricDataFixerBuilder builder = new FabricDataFixerBuilder(CURRENT_DATA_VERSION);
+ *     // add the "base" version 0 schema
+ *     builder.addSchema(0, FabricDataFixes.BASE_SCHEMA);
+ *     // add a schema for upgrading from version 0 to version 1
+ *     Schema schemaV1 = builder.addSchema(1, IdentifierNormalizingSchema::new)
+ *     // add fixes to the schema - for example, an item rename (identifier change)
+ *     // multiple fixes can share the same schema
+ *     SimpleFixes.addItemRenameFix(builder, "Rename cool_item to awesome_item",
+ *         new Identifier("mymod", "cool_item"),
+ *         new Identifier("mymod", "awesome_item"),
+ *         schemaV1);
+ *
+ *     // register the fixer!
+ *     // this will create either an unoptimized fixer or an optimized fixer,
+ *     //  depending on the game configuration
+ *     FabricDataFixes.buildAndRegisterFixer(mod, builder);
+ * }
+ * }
+ * + *

Data version

+ * + *

A data fixer needs an integer "data version" to function. This is different from the + * mod version given in {@code version} key of the {@code fabric.mod.json} file. + * + *

The default data version, used for versions without datafixers, is {@code 0}. + * To add a data fixer, you must assign a positive integer as the current data version. + * This is increased every time a new data fixer is added, unless the version is + * already increased in the same release. Multiple mod versions can share the same + * data version if no data fixes are needed between those. + * + *

Data versions do not have to be consecutive (incremented one by one). However, + * it should never decrease. When making a significant change (such as forking or + * updating to a new Minecraft release), it is usually recommended to have a "gap" + * between the two data versions, to be used for data fixers before the significant + * change. + * + *

There are three ways to specify the current data version: + *

+ * + *

The data version for a specific data fix is assigned when creating a schema using + * the {@code addSchema} method. Multiple data fixes can share the same schema, if they + * all provide fixes for the same data version. + * + * @see net.fabricmc.frozenblock.datafixer.api.FabricDataFixes + * @see net.fabricmc.frozenblock.datafixer.api.SimpleFixes + * @see net.fabricmc.frozenblock.datafixer.api.FabricDataFixerBuilder + */ + +// From QSL. +package net.fabricmc.frozenblock.datafixer.api; diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/DataFixTypesAccessor.java b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/DataFixerUpperExtension.java similarity index 56% rename from src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/DataFixTypesAccessor.java rename to src/main/java/net/fabricmc/frozenblock/datafixer/impl/DataFixerUpperExtension.java index 89b9d9031..e5c6b1142 100644 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/DataFixTypesAccessor.java +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/DataFixerUpperExtension.java @@ -1,7 +1,7 @@ /* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,16 @@ * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. */ -package org.quiltmc.qsl.frozenblock.misc.datafixerupper.mixin; - -import com.mojang.datafixers.DSL; -import net.minecraft.util.datafix.DataFixTypes; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; +package net.fabricmc.frozenblock.datafixer.impl; -@Mixin(DataFixTypes.class) -public interface DataFixTypesAccessor { +import com.mojang.datafixers.schemas.Schema; +import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap; - @Accessor - DSL.TypeReference getType(); +public interface DataFixerUpperExtension { + Int2ObjectSortedMap frozenLib_getSchemas(); } diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricDataFixesInternals.java b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricDataFixesInternals.java new file mode 100644 index 000000000..66003b8ab --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricDataFixesInternals.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.impl; + +import com.mojang.datafixers.DataFixUtils; +import com.mojang.datafixers.DataFixerUpper; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.Dynamic; +import java.util.List; +import net.fabricmc.frozenblock.datafixer.api.DataFixerEntrypoint; +import net.fabricmc.frozenblock.datafixer.api.SchemaRegistry; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.fabricmc.loader.api.entrypoint.EntrypointContainer; +import net.fabricmc.loader.api.metadata.CustomValue; +import net.minecraft.SharedConstants; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.util.datafix.DataFixTypes; +import net.minecraft.util.datafix.DataFixers; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; +import org.slf4j.Logger; + +public abstract class FabricDataFixesInternals { + // From QSL. + private static final Logger LOGGER = LogUtils.getLogger(); + protected static final String DATA_VERSIONS_KEY = "_FabricDataVersions"; + public static final String METADATA_VERSION_KEY = "fabric-data-fixer-api-v1:version"; + public static final String METADATA_KEY_KEY = "fabric-data-fixer-api-v1:key"; + private static final String ENTRYPOINT_KEY = "fabric-data-fixer"; + + public record DataFixerEntry(DataFixerUpper dataFixer, int currentVersion, @Nullable String key) { + } + + @Range(from = 0, to = Integer.MAX_VALUE) + public static int getDataVersionFromMetadata(ModContainer mod) { + CustomValue version = mod.getMetadata().getCustomValue(METADATA_VERSION_KEY); + + if (version == null || version.getType() != CustomValue.CvType.NUMBER) { + throw new RuntimeException("Data version is not set in the fabric.mod.json file; set it or pass explicitly"); + } + + return version.getAsNumber().intValue(); + } + + @Nullable + public static String getKeyFromMetadata(ModContainer mod) { + CustomValue key = mod.getMetadata().getCustomValue(METADATA_KEY_KEY); + + if (key == null) { + return null; + } + + if (key.getType() != CustomValue.CvType.STRING) { + throw new RuntimeException("Key is not a string in the fabric.mod.json file"); + } + + return key.getAsString(); + } + + @Contract(pure = true) + @Range(from = 0, to = Integer.MAX_VALUE) + public static int getModDataVersion(CompoundTag nbt, String modId, @Nullable String key) { + // LEGACY + String legacyKey = modId + "_DataVersion"; + if (key != null) { + legacyKey += ('_' + key); + } + if (nbt.contains(legacyKey)) { + return nbt.getInt(legacyKey); + } + + // FABRIC + String nbtKey = modId; + + if (key != null) { + nbtKey += ('_' + key); + } + + CompoundTag dataVersions = nbt.getCompound(DATA_VERSIONS_KEY); + return dataVersions.getInt(nbtKey); + } + + private static List getEntrypoints() { + List> dataFixerEntrypoints = FabricLoader.getInstance() + .getEntrypointContainers(ENTRYPOINT_KEY, DataFixerEntrypoint.class); + return dataFixerEntrypoints.stream().map(EntrypointContainer::getEntrypoint).toList(); + } + + public static void registerBlockEntities(SchemaRegistry registry, Schema schema) { + List entrypoints = getEntrypoints(); + + for (DataFixerEntrypoint entrypoint : entrypoints) { + entrypoint.onRegisterBlockEntities(registry, schema); + } + } + + public static void registerEntities(SchemaRegistry registry, Schema schema) { + List entrypoints = getEntrypoints(); + + for (DataFixerEntrypoint entrypoint : entrypoints) { + entrypoint.onRegisterEntities(registry, schema); + } + } + + private static FabricDataFixesInternals instance; + + public static FabricDataFixesInternals get() { + if (instance == null) { + Schema latestVanillaSchema; + + try { + latestVanillaSchema = DataFixers.getDataFixer() + .getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getDataVersion().getVersion())); + } catch (Throwable e) { + latestVanillaSchema = null; + } + + if (latestVanillaSchema == null) { + LOGGER.warn("[Fabric DFU API] Failed to initialize! Either someone stopped DFU from initializing,"); + LOGGER.warn("[Fabric DFU API] or this Minecraft build is hosed."); + LOGGER.warn("[Fabric DFU API] Using no-op implementation."); + instance = new NoOpFabricDataFixesInternals(); + } else { + instance = new FabricDataFixesInternalsImpl(latestVanillaSchema); + } + } + + return instance; + } + + public abstract void registerFixer(String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @Nullable String key, DataFixerUpper dataFixer); + + public abstract boolean isEmpty(); + + public abstract @Nullable List getFixerEntries(String modId); + + @Contract(value = "-> new", pure = true) + public abstract Schema getBaseSchema(); + + public abstract Dynamic updateWithAllFixers(DataFixTypes dataFixTypes, Dynamic element); + + public abstract CompoundTag addModDataVersions(CompoundTag nbt); + + public abstract void freeze(); + + @Contract(pure = true) + public abstract boolean isFrozen(); +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricDataFixesInternalsImpl.java b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricDataFixesInternalsImpl.java new file mode 100644 index 000000000..de112b2ff --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricDataFixesInternalsImpl.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.impl; + +import com.mojang.datafixers.DataFixerUpper; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.serialization.Dynamic; +import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.util.datafix.DataFixTypes; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public final class FabricDataFixesInternalsImpl extends FabricDataFixesInternals { + // From QSL. + private Schema latestSchema; + + private Map> modDataFixers; + private boolean frozen; + + public FabricDataFixesInternalsImpl(Schema latestVanillaSchema) { + this.latestSchema = latestVanillaSchema; + this.modDataFixers = new Object2ReferenceOpenHashMap<>(); + this.frozen = false; + } + + @Override + public void registerFixer(String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, + @Nullable String key, DataFixerUpper dataFixer) { + Int2ObjectSortedMap schemas = ((DataFixerUpperExtension) dataFixer).frozenLib_getSchemas(); + Schema lastSchema = schemas.getOrDefault(schemas.lastIntKey(), null); + + if (lastSchema != null) { + this.latestSchema = lastSchema; + } + + this.modDataFixers.computeIfAbsent(modId, modIdx -> new ObjectArrayList<>()) + .add(new DataFixerEntry(dataFixer, currentVersion, key)); + } + + @Override + public boolean isEmpty() { + return this.modDataFixers.isEmpty(); + } + + @Override + public @Nullable List getFixerEntries(String modId) { + return modDataFixers.get(modId); + } + + @Override + public Schema getBaseSchema() { + return new Schema(0, this.latestSchema); + } + + @Override + public Dynamic updateWithAllFixers(DataFixTypes dataFixTypes, Dynamic current) { + CompoundTag compound = (CompoundTag) current.getValue(); + + for (Map.Entry> entry : this.modDataFixers.entrySet()) { + List dataFixerEntries = entry.getValue(); + + for (DataFixerEntry dataFixerEntry : dataFixerEntries) { + int modDataVersion = FabricDataFixesInternals.getModDataVersion(compound, entry.getKey(), dataFixerEntry.key()); + + current = dataFixerEntry.dataFixer() + .update(dataFixTypes.type, + current, + modDataVersion, dataFixerEntry.currentVersion()); + } + } + + return current; + } + + @Override + public CompoundTag addModDataVersions(CompoundTag nbt) { + CompoundTag dataVersions = nbt.getCompound(DATA_VERSIONS_KEY); + + for (Map.Entry> entries : this.modDataFixers.entrySet()) { + for (DataFixerEntry entry : entries.getValue()) { + String finalEntryKey = entries.getKey(); + String entryKey = entry.key(); + + if (entryKey != null) { + finalEntryKey += ('_' + entryKey); + } + + dataVersions.putInt(finalEntryKey, entry.currentVersion()); + } + } + + nbt.put(DATA_VERSIONS_KEY, dataVersions); + return nbt; + } + + @Override + public void freeze() { + if (!this.frozen) { + modDataFixers = Collections.unmodifiableMap(this.modDataFixers); + } + + this.frozen = true; + } + + @Override + public boolean isFrozen() { + return this.frozen; + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricSubSchema.java b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricSubSchema.java new file mode 100644 index 000000000..c16659313 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/FabricSubSchema.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.impl; + +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.datafixers.types.templates.TypeTemplate; +import com.mojang.datafixers.util.Either; +import net.fabricmc.frozenblock.datafixer.api.SchemaRegistry; +import net.minecraft.util.datafix.schemas.NamespacedSchema; + +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +public class FabricSubSchema extends NamespacedSchema { + public SchemaRegistry registeredBlockEntities; + public SchemaRegistry registeredEntities; + + public FabricSubSchema(int versionKey, Schema parent) { + super(versionKey, parent); + } + + @Override + public Map> registerBlockEntities(Schema schema) { + Map> map = super.registerBlockEntities(schema); + + this.registeredBlockEntities = new SchemaRegistryImpl(); + FabricDataFixesInternals.registerBlockEntities(this.registeredBlockEntities, schema); + + ImmutableMap, Function>> modRegistry = this.registeredBlockEntities.get(); + + for (Map.Entry, Function>> entry : modRegistry.entrySet()) { + Either, Function> value = entry.getValue(); + + value.ifLeft(supplier -> schema.register(map, entry.getKey(), supplier)); + + value.ifRight(function -> schema.register(map, entry.getKey(), function)); + } + + return map; + } + + @Override + public Map> registerEntities(Schema schema) { + Map> map = super.registerEntities(schema); + + this.registeredEntities = new SchemaRegistryImpl(); + FabricDataFixesInternals.registerEntities(this.registeredEntities, schema); + + ImmutableMap, Function>> modRegistry = this.registeredEntities.get(); + + for (Map.Entry, Function>> entry : modRegistry.entrySet()) { + Either, Function> value = entry.getValue(); + + value.ifLeft(supplier -> schema.register(map, entry.getKey(), supplier)); + + value.ifRight(function -> schema.register(map, entry.getKey(), function)); + } + + return map; + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/impl/NoOpFabricDataFixesInternals.java b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/NoOpFabricDataFixesInternals.java new file mode 100644 index 000000000..601c4761e --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/NoOpFabricDataFixesInternals.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.impl; + +import com.mojang.datafixers.DataFixerUpper; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.serialization.Dynamic; +import java.util.List; +import net.fabricmc.frozenblock.datafixer.api.EmptySchema; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.util.datafix.DataFixTypes; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; + +public final class NoOpFabricDataFixesInternals extends FabricDataFixesInternals { + // From QSL. + private final Schema schema = new EmptySchema(0); + + private boolean frozen = false; + + public NoOpFabricDataFixesInternals() { + } + + @Override + public void registerFixer(String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @Nullable String key, DataFixerUpper dataFixer) { + } + + @Override + public boolean isEmpty() { + return true; + } + + @Override + public @Nullable List getFixerEntries(String modId) { + return null; + } + + @Override + public Schema getBaseSchema() { + return this.schema; + } + + @Override + public Dynamic updateWithAllFixers(DataFixTypes dataFixTypes, Dynamic dynamic) { + return new Dynamic<>(dynamic.getOps(), dynamic.getValue().copy()); + } + + @Override + public CompoundTag addModDataVersions(CompoundTag nbt) { + return nbt; + } + + @Override + public void freeze() { + this.frozen = true; + } + + @Override + public boolean isFrozen() { + return this.frozen; + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/impl/SchemaRegistryImpl.java b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/SchemaRegistryImpl.java new file mode 100644 index 000000000..c52272212 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/SchemaRegistryImpl.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.impl; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.datafixers.types.templates.TypeTemplate; +import com.mojang.datafixers.util.Either; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.fabricmc.frozenblock.datafixer.api.SchemaRegistry; +import net.minecraft.resources.ResourceLocation; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +public class SchemaRegistryImpl implements SchemaRegistry { + private final Map, Function>> registry = new Object2ReferenceOpenHashMap<>(); + private final List> subVersionSchemas = new ObjectArrayList<>(); + + @Override + public void register(ResourceLocation id, Supplier template) { + this.registry.put(id.toString(), Either.left(template)); + } + + @Override + public void register(ResourceLocation id, Function template) { + this.registry.put(id.toString(), Either.right(template)); + } + + @Override + public void addSchema(BiFunction factory) { + this.subVersionSchemas.add(factory); + } + + @Override + public Supplier remove(ResourceLocation id) { + Either, Function> found = this.registry.get(id.toString()); + AtomicReference> supplier = new AtomicReference<>(); + + found.ifLeft(supplier::set); + found.ifRight(function -> supplier.set(() -> function.apply(id.toString()))); + + this.registry.remove(id.toString()); + return supplier.get(); + } + + @Override + public ImmutableMap, Function>> get() { + return ImmutableMap.copyOf(this.registry); + } + + @Override + public ImmutableList getKeys() { + return ImmutableList.copyOf(this.registry.keySet()); + } + + @Override + public ImmutableList, Function>> getValues() { + return ImmutableList.copyOf(this.registry.values()); + } + + @Override + public ImmutableList> getFutureSchemas() { + return ImmutableList.copyOf(this.subVersionSchemas); + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/impl/server/ServerFreezer.java b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/server/ServerFreezer.java new file mode 100644 index 000000000..34b3ae0cd --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/impl/server/ServerFreezer.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.impl.server; + +import net.fabricmc.api.DedicatedServerModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.frozenblock.datafixer.impl.FabricDataFixesInternals; + +public final class ServerFreezer implements DedicatedServerModInitializer { + // From QSL. + @Override + public void onInitializeServer() { + ServerLifecycleEvents.SERVER_STARTING.register((server) -> FabricDataFixesInternals.get().freeze()); + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/DataFixTypesMixin.java b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/DataFixTypesMixin.java new file mode 100644 index 000000000..f212196d6 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/DataFixTypesMixin.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.mixin; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.mojang.datafixers.DataFixer; +import com.mojang.serialization.Dynamic; +import net.fabricmc.frozenblock.datafixer.impl.FabricDataFixesInternals; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.util.datafix.DataFixTypes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(DataFixTypes.class) +public class DataFixTypesMixin { + // From QSL. + @SuppressWarnings({"rawtypes", "unchecked"}) + @ModifyReturnValue( + method = "update(Lcom/mojang/datafixers/DataFixer;Lcom/mojang/serialization/Dynamic;II)Lcom/mojang/serialization/Dynamic;", + at = @At("RETURN") + ) + private Dynamic updateDataWithFixers(Dynamic original, DataFixer fixer, Dynamic dynamic, int oldVersion, int targetVersion) { + DataFixTypes type = DataFixTypes.class.cast(this); + Object value = original.getValue(); + + if (type != DataFixTypes.WORLD_GEN_SETTINGS && value instanceof Tag) { + return FabricDataFixesInternals.get().updateWithAllFixers(type, (Dynamic) original); + } + + return original; + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/DataFixerUpperMixin.java b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/DataFixerUpperMixin.java new file mode 100644 index 000000000..bc26825c4 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/DataFixerUpperMixin.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.mixin; + +import com.mojang.datafixers.DataFixerUpper; +import com.mojang.datafixers.schemas.Schema; +import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap; +import net.fabricmc.frozenblock.datafixer.impl.DataFixerUpperExtension; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(DataFixerUpper.class) +public class DataFixerUpperMixin implements DataFixerUpperExtension { + @Shadow + @Final + private Int2ObjectSortedMap schemas; + + @Override + public Int2ObjectSortedMap frozenLib_getSchemas() { + return this.schemas; + } +} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/NbtUtilsMixin.java b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/NbtHelperMixin.java similarity index 64% rename from src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/NbtUtilsMixin.java rename to src/main/java/net/fabricmc/frozenblock/datafixer/mixin/NbtHelperMixin.java index 65ac781f4..9209944fd 100644 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/NbtUtilsMixin.java +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/NbtHelperMixin.java @@ -1,7 +1,7 @@ /* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,22 +14,24 @@ * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. */ -package org.quiltmc.qsl.frozenblock.misc.datafixerupper.mixin; +package net.fabricmc.frozenblock.datafixer.mixin; import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import net.fabricmc.frozenblock.datafixer.impl.FabricDataFixesInternals; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.QuiltDataFixesInternals; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @Mixin(NbtUtils.class) -public class NbtUtilsMixin { - +public class NbtHelperMixin { @ModifyReturnValue(method = "addDataVersion", at = @At("RETURN")) - private static CompoundTag addDataVersion(CompoundTag original) { - return QuiltDataFixesInternals.get().addModDataVersions(original); + private static CompoundTag addModDataVersions(CompoundTag original) { + return FabricDataFixesInternals.get().addModDataVersions(original); } } diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/SchemasMixin.java b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/SchemasMixin.java new file mode 100644 index 000000000..c2d24df73 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/SchemasMixin.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.mixin; + +import com.mojang.datafixers.DataFixerBuilder; +import net.fabricmc.frozenblock.datafixer.impl.FabricSubSchema; +import net.minecraft.util.datafix.DataFixers; +import net.minecraft.util.datafix.fixes.AddNewChoices; +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; +import org.spongepowered.asm.mixin.injection.Slice; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(DataFixers.class) +public class SchemasMixin { + @Inject( + method = "addFixers", + at = @At( + value = "INVOKE", + target = "Lcom/mojang/datafixers/DataFixerBuilder;addSchema(ILjava/util/function/BiFunction;)Lcom/mojang/datafixers/schemas/Schema;", + ordinal = 0 + ), + slice = @Slice( + from = @At( + value = "CONSTANT", + args = "intValue=1803" + ) + ) + ) + private static void addFabricFixers(DataFixerBuilder builder, CallbackInfo ci) { + FabricSubSchema schema = (FabricSubSchema) builder.addSchema(1903, FabricSubSchema::new); + + if (!schema.registeredBlockEntities.getKeys().isEmpty()) { + builder.addFixer(new AddNewChoices(schema, "Add Fabric block entities.", References.BLOCK_ENTITY)); + } + + if (!schema.registeredEntities.getKeys().isEmpty()) { + builder.addFixer(new AddNewChoices(schema, "Add Fabric entities.", References.ENTITY)); + } + + schema.registeredBlockEntities = null; + schema.registeredEntities = null; + } +} diff --git a/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/VersionedChunkStorageMixin.java b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/VersionedChunkStorageMixin.java new file mode 100644 index 000000000..5c27a7703 --- /dev/null +++ b/src/main/java/net/fabricmc/frozenblock/datafixer/mixin/VersionedChunkStorageMixin.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 FabricMC + * Copyright (c) 2024 FrozenBlock + * Modified to use Mojang's Official Mappings + * + * 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. + * + * This file is a modified version of Quilt Standard Libraries, + * authored by QuiltMC. + */ + +package net.fabricmc.frozenblock.datafixer.mixin; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.fabricmc.frozenblock.datafixer.impl.FabricDataFixesInternals; +import net.minecraft.world.level.chunk.storage.ChunkStorage; +import net.minecraft.world.level.storage.DataVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(ChunkStorage.class) +public class VersionedChunkStorageMixin { + @WrapOperation(method = "upgradeChunkTag", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/DataVersion;getVersion()I")) + private int bypassCheck(DataVersion instance, Operation original) { + if (!FabricDataFixesInternals.get().isEmpty()) { + return -1; + } + + return original.call(instance); + } +} diff --git a/src/main/java/net/frozenblock/lib/FrozenClient.java b/src/main/java/net/frozenblock/lib/FrozenClient.java index 47d8077c2..ebca4a8f6 100644 --- a/src/main/java/net/frozenblock/lib/FrozenClient.java +++ b/src/main/java/net/frozenblock/lib/FrozenClient.java @@ -43,7 +43,6 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; import org.quiltmc.qsl.frozenblock.core.registry.impl.sync.client.ClientRegistrySync; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.client.ClientFreezer; public final class FrozenClient implements ClientModInitializer { @@ -53,7 +52,6 @@ public void onInitializeClient() { ModIntegrations.initializePreFreeze(); // Mod integrations must run after normal mod initialization // QUILT INIT - ClientFreezer.onInitializeClient(); ClientRegistrySync.registerHandlers(); // CONTINUE FROZENLIB INIT diff --git a/src/main/java/net/frozenblock/lib/FrozenMain.java b/src/main/java/net/frozenblock/lib/FrozenMain.java index 33eaf5dcd..7fa3f8c66 100644 --- a/src/main/java/net/frozenblock/lib/FrozenMain.java +++ b/src/main/java/net/frozenblock/lib/FrozenMain.java @@ -62,7 +62,6 @@ import net.minecraft.world.level.storage.DimensionDataStorage; import org.quiltmc.qsl.frozenblock.core.registry.api.sync.ModProtocol; import org.quiltmc.qsl.frozenblock.core.registry.impl.sync.server.ServerRegistrySync; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.ServerFreezer; public final class FrozenMain extends FrozenModInitializer { @@ -76,7 +75,6 @@ public void onInitialize(String modId, ModContainer container) { // QUILT INIT - ServerFreezer.onInitialize(); ModProtocol.loadVersions(); ServerRegistrySync.registerHandlers(); diff --git a/src/main/java/net/frozenblock/lib/config/frozenlib_config/FrozenLibConfig.java b/src/main/java/net/frozenblock/lib/config/frozenlib_config/FrozenLibConfig.java index f8ceda1e8..1d80ce931 100644 --- a/src/main/java/net/frozenblock/lib/config/frozenlib_config/FrozenLibConfig.java +++ b/src/main/java/net/frozenblock/lib/config/frozenlib_config/FrozenLibConfig.java @@ -21,6 +21,8 @@ import java.util.List; import me.shedaniel.autoconfig.annotation.ConfigEntry; import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.frozenblock.datafixer.api.FabricDataFixerBuilder; +import net.fabricmc.frozenblock.datafixer.api.FabricDataFixes; import net.frozenblock.lib.FrozenSharedConstants; import net.frozenblock.lib.config.api.instance.Config; import net.frozenblock.lib.config.api.instance.json.JsonConfig; @@ -28,8 +30,6 @@ import net.frozenblock.lib.config.api.registry.ConfigRegistry; import net.frozenblock.lib.config.api.sync.SyncBehavior; import net.frozenblock.lib.config.api.sync.annotation.EntrySyncData; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.api.QuiltDataFixerBuilder; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.api.QuiltDataFixes; public class FrozenLibConfig { @@ -39,7 +39,7 @@ public class FrozenLibConfig { FrozenLibConfig.class, JsonType.JSON5_UNQUOTED_KEYS, true, - QuiltDataFixes.buildFixer(new QuiltDataFixerBuilder(0)), + FabricDataFixes.buildFixer(new FabricDataFixerBuilder(0)), 0 ) { @Override diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/FirstSchema.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/FirstSchema.java deleted file mode 100644 index 639fdd72c..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/FirstSchema.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.api; - -import com.mojang.datafixers.schemas.Schema; -import com.mojang.datafixers.types.templates.TypeTemplate; -import java.util.Map; -import java.util.function.Supplier; -import org.jetbrains.annotations.Range; - -/** - * Represents a {@link Schema} that has no parent. - *

- * Modified to work on Fabric - */ -public class FirstSchema extends Schema { - /** - * Creates a schema. - * @param versionKey the data version key - */ - public FirstSchema(@Range(from = 0, to = Integer.MAX_VALUE) int versionKey) { - super(versionKey, null); - } - - // all of these methods refer to this.parent without checking if its null - @Override - public void registerTypes(Schema schema, Map> entityTypes, - Map> blockEntityTypes) {} - - @Override - public Map> registerEntities(Schema schema) { - return Map.of(); - } - - @Override - public Map> registerBlockEntities(Schema schema) { - return Map.of(); - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/QuiltDataFixerBuilder.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/QuiltDataFixerBuilder.java deleted file mode 100644 index e17e8406e..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/QuiltDataFixerBuilder.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.api; - -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.function.Supplier; -import net.minecraft.Util; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Range; - -/** - * An extended variant of the {@link DataFixerBuilder} class, which provides an extra method. - *

- * Modified to work on Fabric - */ -public class QuiltDataFixerBuilder extends DataFixerBuilder { - protected final int dataVersion; - - /** - * Creates a new {@code QuiltDataFixerBuilder}. - * - * @param dataVersion the current data version - */ - public QuiltDataFixerBuilder(@Range(from = 0, to = Integer.MAX_VALUE) int dataVersion) { - super(dataVersion); - this.dataVersion = dataVersion; - } - - /** - * {@return the current data version} - */ - @Range(from = 0, to = Integer.MAX_VALUE) - public int getDataVersion() { - return this.dataVersion; - } - - /** - * Builds the final {@code DataFixer}. - *

- * This will build either an {@linkplain #build() unoptimized fixer} or an - * {@linkplain #build(Set, Supplier) optimized fixer}, depending on the vanilla game's settings. - * - * @param executorGetter the executor supplier, only invoked if the game is using optimized data fixers - * @return the newly built data fixer - */ - @Contract(value = "_, _ -> new") - public @NotNull DataFixer build(Set types, @NotNull Supplier executorGetter) { - return types.isEmpty() ? this.build().fixer() : Util.make(() -> { - var result = this.build(); - result.optimize(types, executorGetter.get()).join(); - return result.fixer(); - }); - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/QuiltDataFixes.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/QuiltDataFixes.java deleted file mode 100644 index 8dab9b303..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/QuiltDataFixes.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.api; - -import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import static java.util.Objects.requireNonNull; -import java.util.Optional; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import lombok.experimental.UtilityClass; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.datafix.DataFixTypes; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Range; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.QuiltDataFixesInternals; - -/** - * Provides methods to register custom {@link DataFixer}s. - *

- * Modified to work on Fabric - */ -@UtilityClass -public class QuiltDataFixes { - - /** - * A "base" version {@code 0} schema, for use by all mods. - *

- * This schema must be the first one added! - * - * @see DataFixerBuilder#addSchema(int, BiFunction) - */ - public static final BiFunction BASE_SCHEMA = (version, parent) -> { - checkArgument(version == 0, "version must be 0"); - checkArgument(parent == null, "parent must be null"); - return QuiltDataFixesInternals.get().createBaseSchema(); - }; - - /** - * Registers a new data fixer. - * - * @param modId the mod identifier - * @param currentVersion the current version of the mod's data - * @param dataFixer the data fixer - */ - public static void registerFixer( - @NotNull String modId, - @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, - @NotNull DataFixer dataFixer - ) { - requireNonNull(modId, "modId cannot be null"); - //noinspection ConstantConditions - checkArgument(currentVersion >= 0, "currentVersion must be positive"); - requireNonNull(dataFixer, "dataFixer cannot be null"); - - if (isFrozen()) { - throw new IllegalStateException("Can't register data fixer after registry is frozen"); - } - - QuiltDataFixesInternals.get().registerFixer(modId, currentVersion, dataFixer); - } - - /** - * Registers a new data fixer. - * - * @param mod the mod container - * @param currentVersion the current version of the mod's data - * @param dataFixer the data fixer - */ - public static void registerFixer( - @NotNull ModContainer mod, - @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, - @NotNull DataFixer dataFixer - ) { - requireNonNull(mod, "mod cannot be null"); - - registerFixer(mod.getMetadata().getId(), currentVersion, dataFixer); - } - - /** - * Builds and registers a new data fixer. - * - * @param mod the mod container - * @param dataFixerBuilder the data fixer builder - */ - public static void buildAndRegisterFixer( - @NotNull ModContainer mod, - @NotNull QuiltDataFixerBuilder dataFixerBuilder - ) { - requireNonNull(mod, "mod cannot be null"); - requireNonNull(dataFixerBuilder, "data fixer builder cannot be null"); - - registerFixer(mod.getMetadata().getId(), dataFixerBuilder.getDataVersion(), buildFixer(dataFixerBuilder)); - } - - /** - * Registers a new data fixer for use with Minecraft version-specific datafixing. - * - * @param modId the mod identifier - * @param currentVersion the current version of the mod's data - * @param dataFixer the data fixer - */ - public static void registerMinecraftFixer( - @NotNull String modId, - @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, - @NotNull DataFixer dataFixer - ) { - requireNonNull(modId, "modId cannot be null"); - //noinspection ConstantConditions - checkArgument(currentVersion >= 0, "currentVersion must be positive"); - requireNonNull(dataFixer, "dataFixer cannot be null"); - - if (isFrozen()) { - throw new IllegalStateException("Can't register data fixer after registry is frozen"); - } - - QuiltDataFixesInternals.get().registerMinecraftFixer(modId, currentVersion, dataFixer); - } - - /** - * Registers a new data fixer for use with Minecraft version-specific datafixing. - * - * @param mod the mod container - * @param currentVersion the current version of the mod's data - * @param dataFixer the data fixer - */ - public static void registerMinecraftFixer( - @NotNull ModContainer mod, - @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, - @NotNull DataFixer dataFixer - ) { - requireNonNull(mod, "mod cannot be null"); - - registerMinecraftFixer(mod.getMetadata().getId(), currentVersion, dataFixer); - } - - /** - * Builds and registers a new data fixer for use with Minecraft version-specific datafixing. - * - * @param mod the mod container - * @param dataFixerBuilder the data fixer builder - */ - public static void buildAndRegisterMinecraftFixer( - @NotNull ModContainer mod, - @NotNull QuiltDataFixerBuilder dataFixerBuilder - ) { - requireNonNull(mod, "mod cannot be null"); - requireNonNull(dataFixerBuilder, "data fixer builder cannot be null"); - - registerMinecraftFixer(mod.getMetadata().getId(), dataFixerBuilder.getDataVersion(), buildFixer(dataFixerBuilder)); - } - - /** - * Builds a new data fixer. - * - * @param dataFixerBuilder the data fixer builder - * @return The built data fixer. - */ - public static DataFixer buildFixer(@NotNull QuiltDataFixerBuilder dataFixerBuilder) { - requireNonNull(dataFixerBuilder, "data fixer builder cannot be null"); - - Supplier executor = () -> Executors.newSingleThreadExecutor( - new ThreadFactoryBuilder().setNameFormat("FrozenLib Quilt Datafixer Bootstrap").setDaemon(true).setPriority(1).build() - ); - - return dataFixerBuilder.build(DataFixTypes.TYPES_FOR_LEVEL_LIST, executor); - } - - /** - * Gets a mod's Minecraft version-specificdata fixer. - * - * @param modId the mod identifier - * @return the mod's data fixer, or empty if the mod hasn't registered one - */ - public static @NotNull Optional getFixer(@NotNull String modId) { - requireNonNull(modId, "modId cannot be null"); - - QuiltDataFixesInternals.DataFixerEntry entry = QuiltDataFixesInternals.get().getFixerEntry(modId); - if (entry == null) { - return Optional.empty(); - } - return Optional.of(entry.dataFixer()); - } - - /** - * Gets a mod's Minecraft version-specific data fixer. - * - * @param modId the mod identifier - * @return the mod's data fixer, or empty if the mod hasn't registered one - */ - public static @NotNull Optional getMinecraftFixer(@NotNull String modId) { - requireNonNull(modId, "modId cannot be null"); - - QuiltDataFixesInternals.DataFixerEntry entry = QuiltDataFixesInternals.get().getMinecraftFixerEntry(modId); - if (entry == null) { - return Optional.empty(); - } - return Optional.of(entry.dataFixer()); - } - - /** - * Gets a mod's Minecraft version-specific data version from a {@link CompoundTag}. - * - * @param compound the compound - * @param modId the mod identifier - * @return the mod's data version, or {@code 0} if the compound has no data for that mod - */ - @Contract(pure = true) - @Range(from = 0, to = Integer.MAX_VALUE) - public static int getModDataVersion(@NotNull CompoundTag compound, @NotNull String modId) { - requireNonNull(compound, "compound cannot be null"); - requireNonNull(modId, "modId cannot be null"); - - return QuiltDataFixesInternals.getModDataVersion(compound, modId).orElse(0); - } - - /** - * Gets a mod's Minecraft version-specific data version from a {@link CompoundTag}. - * - * @param compound the compound - * @param modId the mod identifier - * @return the mod's data version, or {@code 0} if the compound has no data for that mod - */ - @Contract(pure = true) - @Range(from = 0, to = Integer.MAX_VALUE) - public static int getModMinecraftDataVersion(@NotNull CompoundTag compound, @NotNull String modId) { - requireNonNull(compound, "compound cannot be null"); - requireNonNull(modId, "modId cannot be null"); - - return QuiltDataFixesInternals.getModMinecraftDataVersion(compound, modId).orElse(0); - } - - /** - * Checks if the data fixer registry is frozen. - * - * @return {@code true} if frozen, or {@code false} otherwise. - */ - @Contract(pure = true) - public static boolean isFrozen() { - return QuiltDataFixesInternals.get().isFrozen(); - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/SimpleFixes.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/SimpleFixes.java deleted file mode 100644 index c2caa557c..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/SimpleFixes.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.api; - -import com.google.common.collect.ImmutableMap; -import com.mojang.datafixers.DataFix; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import java.util.Map; -import java.util.Objects; -import static java.util.Objects.requireNonNull; -import net.frozenblock.lib.datafix.api.BlockStateRenameFix; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.datafix.DataFixers; -import net.minecraft.util.datafix.fixes.BlockRenameFix; -import net.minecraft.util.datafix.fixes.ItemRenameFix; -import net.minecraft.util.datafix.fixes.NamespacedTypeRenameFix; -import net.minecraft.util.datafix.fixes.References; -import net.minecraft.util.datafix.fixes.SimplestEntityRenameFix; -import net.minecraft.util.datafix.schemas.NamespacedSchema; -import org.jetbrains.annotations.NotNull; - -/** - * Provides methods to add common {@link DataFix}es to {@link DataFixerBuilder}s. - *

- * Modified to work on Fabric - */ -public final class SimpleFixes { - private SimpleFixes() { - throw new RuntimeException("SimpleFixes contains only static declarations."); - } - - /** - * Adds a block rename fix to the builder, in case a block's identifier is changed. - * - * @param builder the builder - * @param name the fix's name - * @param oldId the block's old identifier - * @param newId the block's new identifier - * @param schema the schema this fixer should be a part of - * @see BlockRenameFix - */ - public static void addBlockRenameFix(@NotNull DataFixerBuilder builder, @NotNull String name, - @NotNull ResourceLocation oldId, @NotNull ResourceLocation newId, - @NotNull Schema schema) { - requireNonNull(builder, "DataFixerBuilder cannot be null"); - requireNonNull(name, "Fix name cannot be null"); - requireNonNull(oldId, "Old identifier cannot be null"); - requireNonNull(newId, "New identifier cannot be null"); - requireNonNull(schema, "Schema cannot be null"); - - final String oldIdStr = oldId.toString(), newIdStr = newId.toString(); - builder.addFixer(BlockRenameFix.create(schema, name, (inputName) -> - Objects.equals(NamespacedSchema.ensureNamespaced(inputName), oldIdStr) ? newIdStr : inputName)); - } - - /** - * Adds an entity rename fix to the builder, in case an entity's identifier is changed. - * - * @param builder the builder - * @param name the fix's name - * @param oldId the entity's old identifier - * @param newId the entity's new identifier - * @param schema the schema this fix should be a part of - * @see SimplestEntityRenameFix - */ - public static void addEntityRenameFix(@NotNull DataFixerBuilder builder, @NotNull String name, - @NotNull ResourceLocation oldId, @NotNull ResourceLocation newId, - @NotNull Schema schema) { - requireNonNull(builder, "DataFixerBuilder cannot be null"); - requireNonNull(name, "Fix name cannot be null"); - requireNonNull(oldId, "Old identifier cannot be null"); - requireNonNull(newId, "New identifier cannot be null"); - requireNonNull(schema, "Schema cannot be null"); - - final String oldIdStr = oldId.toString(), newIdStr = newId.toString(); - builder.addFixer(new SimplestEntityRenameFix(name, schema, false) { - @Override - protected String rename(String inputName) { - return Objects.equals(NamespacedSchema.ensureNamespaced(inputName), oldIdStr) ? newIdStr : inputName; - } - }); - } - - /** - * Adds an item rename fix to the builder, in case an item's identifier is changed. - * - * @param builder the builder - * @param name the fix's name - * @param oldId the item's old identifier - * @param newId the item's new identifier - * @param schema the schema this fix should be a part of - * @see ItemRenameFix - */ - public static void addItemRenameFix(@NotNull DataFixerBuilder builder, @NotNull String name, - @NotNull ResourceLocation oldId, @NotNull ResourceLocation newId, - @NotNull Schema schema) { - requireNonNull(builder, "DataFixerBuilder cannot be null"); - requireNonNull(name, "Fix name cannot be null"); - requireNonNull(oldId, "Old identifier cannot be null"); - requireNonNull(newId, "New identifier cannot be null"); - requireNonNull(schema, "Schema cannot be null"); - - final String oldIdStr = oldId.toString(), newIdStr = newId.toString(); - builder.addFixer(ItemRenameFix.create(schema, name, (inputName) -> - Objects.equals(NamespacedSchema.ensureNamespaced(inputName), oldIdStr) ? newIdStr : inputName)); - } - - /** - * Adds a blockstate rename fix to the builder, in case a blockstate's name is changed. - * - * @param builder the builder - * @param name the fix's name - * @param blockId the block's identifier - * @param oldState the blockstate's old name - * @param defaultValue the blockstate's default value - * @param newState the blockstates's new name - * @param schema the schema this fixer should be a part of - * @see BlockStateRenameFix - */ - public static void addBlockStateRenameFix(@NotNull DataFixerBuilder builder, @NotNull String name, - @NotNull ResourceLocation blockId, @NotNull String oldState, - @NotNull String defaultValue, @NotNull String newState, - @NotNull Schema schema) { - requireNonNull(builder, "DataFixerBuilder cannot be null"); - requireNonNull(name, "Fix name cannot be null"); - requireNonNull(blockId, "Block Id cannot be null"); - requireNonNull(oldState, "Old BlockState cannot be null"); - requireNonNull(defaultValue, "Default value cannot be null"); - requireNonNull(newState, "New BlockState cannot be null"); - requireNonNull(schema, "Schema cannot be null"); - - final String blockIdStr = blockId.toString(); - builder.addFixer(new BlockStateRenameFix(schema, name, blockIdStr, oldState, defaultValue, newState)); - } - - /** - * Adds a biome rename fix to the builder, in case biome identifiers are changed. - * - * @param builder the builder - * @param name the fix's name - * @param changes a map of old biome identifiers to new biome identifiers - * @param schema the schema this fixer should be a part of - * @see NamespacedTypeRenameFix - */ - public static void addBiomeRenameFix(@NotNull DataFixerBuilder builder, @NotNull String name, - @NotNull Map changes, - @NotNull Schema schema) { - requireNonNull(builder, "DataFixerBuilder cannot be null"); - requireNonNull(name, "Fix name cannot be null"); - requireNonNull(changes, "Changes cannot be null"); - requireNonNull(schema, "Schema cannot be null"); - - var mapBuilder = ImmutableMap.builder(); - for (var entry : changes.entrySet()) { - mapBuilder.put(entry.getKey().toString(), entry.getValue().toString()); - } - builder.addFixer(new NamespacedTypeRenameFix(schema, name, References.BIOME, DataFixers.createRenamer(mapBuilder.build()))); - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/package-info.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/package-info.java deleted file mode 100644 index 76a7690ba..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/api/package-info.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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. - */ - -/** - *

Custom DataFixerUpper API

- *

- * This API lets you register a {@code DataFixer} for your own mod, letting you use Minecraft's built-in - * "old save compatibility" system without bodges! - *

- * Here is an example simple use of this API: - *


- * // the latest version of the mod's data
- * // this should match the version of the last schema added!
- * // note that the default data version is 0, meaning that you can upgrade
- * //  from a version that did not have a fixer
- * //  (by registering a schema for upgrading from version 0 to version 1)
- * public static final int CURRENT_DATA_VERSION = 1;
- *
- * public static void initialize(ModContainer mod) {
- *     // create a builder
- *     var builder = new QuiltDataFixerBuilder(CURRENT_DATA_VERSION);
- *     // add the "base" version 0 schema
- *     builder.addSchema(0, QuiltDataFixes.BASE_SCHEMA);
- *     // add a schema for upgrading from version 0 to version 1
- *     Schema schemaV1 = builder.addSchema(1, IdentifierNormalizingSchema::new)
- *     // add fixes to the schema - for example, an item rename (identifier change)
- *     SimpleFixes.addItemRenameFix(builder, "Rename cool_item to awesome_item",
- *         new Identifier("mymod", "cool_item"),
- *         new Identifier("mymod", "awesome_item"),
- *         schemaV1);
- *
- *     // register the fixer!
- *     // this will create either an unoptimized fixer or an optimized fixer,
- *     //  depending on the game configuration
- *     QuiltDataFixes.buildAndRegisterFixer(mod, builder);
- * }
- * 
- * - * @see org.quiltmc.qsl.frozenblock.misc.datafixerupper.api.QuiltDataFixes - * @see org.quiltmc.qsl.frozenblock.misc.datafixerupper.api.SimpleFixes - * @see org.quiltmc.qsl.frozenblock.misc.datafixerupper.api.QuiltDataFixerBuilder - */ - -package org.quiltmc.qsl.frozenblock.misc.datafixerupper.api; diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/NoOpQuiltDataFixesInternals.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/NoOpQuiltDataFixesInternals.java deleted file mode 100644 index 7903c751e..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/NoOpQuiltDataFixesInternals.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl; - -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import net.minecraft.util.datafix.DataFixTypes; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Range; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.api.EmptySchema; - -/** - * Modified to work on Fabric - */ -@ApiStatus.Internal -public final class NoOpQuiltDataFixesInternals extends QuiltDataFixesInternals { - private final Schema schema; - - private boolean frozen; - - public NoOpQuiltDataFixesInternals() { - this.schema = new EmptySchema(0); - - this.frozen = false; - } - - @Override - public void registerFixer(@NotNull String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @NotNull DataFixer dataFixer) {} - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public @Nullable DataFixerEntry getFixerEntry(@NotNull String modId) { - return null; - } - - @Override - public void registerMinecraftFixer(@NotNull String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @NotNull DataFixer dataFixer) {} - - @Override - public @Nullable DataFixerEntry getMinecraftFixerEntry(@NotNull String modId) { - return null; - } - - @Override - public @NotNull Schema createBaseSchema() { - return this.schema; - } - - @Override - public @NotNull Dynamic updateWithAllFixers(@NotNull DataFixTypes dataFixTypes, @NotNull Dynamic dynamic) { - return new Dynamic<>(dynamic.getOps(), dynamic.getValue().copy()); - } - - @Override - public @NotNull CompoundTag addModDataVersions(@NotNull CompoundTag compound) { - return compound; - } - - @Override - public void freeze() { - this.frozen = true; - } - - @Override - public boolean isFrozen() { - return this.frozen; - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/QuiltDataFixesInternals.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/QuiltDataFixesInternals.java deleted file mode 100644 index d0cc59fcd..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/QuiltDataFixesInternals.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl; - -import com.mojang.datafixers.DataFixUtils; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.logging.LogUtils; -import com.mojang.serialization.Dynamic; -import net.minecraft.SharedConstants; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import net.minecraft.util.datafix.DataFixTypes; -import net.minecraft.util.datafix.DataFixers; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Range; -import org.slf4j.Logger; -import java.util.OptionalInt; - -/** - * Modified to work on Fabric - */ -@ApiStatus.Internal -public abstract class QuiltDataFixesInternals { - private static final Logger LOGGER = LogUtils.getLogger(); - - public record DataFixerEntry(DataFixer dataFixer, int currentVersion) {} - - @Contract(pure = true) - @Range(from = 0, to = Integer.MAX_VALUE) // Changed to OptionalInt by FrozenBlock - public static OptionalInt getModDataVersion(@NotNull CompoundTag compound, @NotNull String modId) { - String key = modId + "_DataVersion"; - return compound.contains(key) ? OptionalInt.of(compound.getInt(modId + "_DataVersion")) : OptionalInt.empty(); - } - - @Contract(pure = true) - @Range(from = 0, to = Integer.MAX_VALUE) // Changed to OptionalInt by FrozenBlock - public static OptionalInt getModMinecraftDataVersion(@NotNull CompoundTag compound, @NotNull String modId) { - String key = modId + "_DataVersion_Minecraft"; - return compound.contains(key) ? OptionalInt.of(compound.getInt(modId + "_DataVersion_Minecraft")) : OptionalInt.empty(); - } - - private static QuiltDataFixesInternals instance; - - public static @NotNull QuiltDataFixesInternals get() { - if (instance == null) { - Schema latestVanillaSchema; - try { - latestVanillaSchema = DataFixers.getDataFixer() - .getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getDataVersion().getVersion())); - } catch (Exception e) { - latestVanillaSchema = null; - } - - if (latestVanillaSchema == null) { - LOGGER.warn("[Quilt DFU API] Failed to initialize! Either someone stopped DFU from initializing,"); - LOGGER.warn("[Quilt DFU API] or this Minecraft build is hosed."); - LOGGER.warn("[Quilt DFU API] Using no-op implementation."); - instance = new NoOpQuiltDataFixesInternals(); - } else { - instance = new QuiltDataFixesInternalsImpl(latestVanillaSchema); - } - } - - return instance; - } - - public abstract void registerFixer(@NotNull String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @NotNull DataFixer dataFixer); - - public abstract boolean isEmpty(); - - public abstract @Nullable DataFixerEntry getFixerEntry(@NotNull String modId); - - public abstract void registerMinecraftFixer(@NotNull String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @NotNull DataFixer dataFixer); - - public abstract @Nullable DataFixerEntry getMinecraftFixerEntry(@NotNull String modId); - - @Contract(value = "-> new", pure = true) - public abstract @NotNull Schema createBaseSchema(); - - public abstract @NotNull Dynamic updateWithAllFixers(@NotNull DataFixTypes dataFixTypes, @NotNull Dynamic dynamic); - - public abstract @NotNull CompoundTag addModDataVersions(@NotNull CompoundTag compound); - - public abstract void freeze(); - - @Contract(pure = true) - public abstract boolean isFrozen(); -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/QuiltDataFixesInternalsImpl.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/QuiltDataFixesInternalsImpl.java deleted file mode 100644 index 586b915f4..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/QuiltDataFixesInternalsImpl.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl; - -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; -import java.util.Collections; -import java.util.Map; -import java.util.OptionalInt; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import net.minecraft.util.datafix.DataFixTypes; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Range; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.mixin.DataFixTypesAccessor; - -/** - * Modified to work on Fabric - */ -@ApiStatus.Internal -public final class QuiltDataFixesInternalsImpl extends QuiltDataFixesInternals { - private final @NotNull Schema latestVanillaSchema; - - private Map modDataFixers; - private Map modMinecraftDataFixers; - private boolean frozen; - - public QuiltDataFixesInternalsImpl(@NotNull Schema latestVanillaSchema) { - this.latestVanillaSchema = latestVanillaSchema; - - this.modDataFixers = new Object2ReferenceOpenHashMap<>(); - this.modMinecraftDataFixers = new Object2ReferenceOpenHashMap<>(); - this.frozen = false; - } - - @Override - public void registerFixer(@NotNull String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @NotNull DataFixer dataFixer) { - if (this.modDataFixers.containsKey(modId)) { - throw new IllegalArgumentException("Mod '" + modId + "' already has a registered data fixer"); - } - - this.modDataFixers.put(modId, new DataFixerEntry(dataFixer, currentVersion)); - } - - @Override - public boolean isEmpty() { - return this.modDataFixers.isEmpty() && this.modMinecraftDataFixers.isEmpty(); - } - - @Override - public @Nullable DataFixerEntry getFixerEntry(@NotNull String modId) { - return modDataFixers.get(modId); - } - - @Override - public void registerMinecraftFixer(@NotNull String modId, @Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @NotNull DataFixer dataFixer) { - if (this.modMinecraftDataFixers.containsKey(modId)) { - throw new IllegalArgumentException("Mod '" + modId + "' already has a registered Minecraft-version-based data fixer"); - } - - this.modMinecraftDataFixers.put(modId, new DataFixerEntry(dataFixer, currentVersion)); - } - - @Override - public @Nullable DataFixerEntry getMinecraftFixerEntry(@NotNull String modId) { - return modMinecraftDataFixers.get(modId); - } - - @Override - public @NotNull Schema createBaseSchema() { - return new Schema(0, this.latestVanillaSchema); - } - - @Override - public @NotNull Dynamic updateWithAllFixers(@NotNull DataFixTypes dataFixTypes, @NotNull Dynamic current) { - var compound = (CompoundTag) current.getValue(); - - // Minecraft fixer added by FrozenBlock - for (Map.Entry entry : this.modMinecraftDataFixers.entrySet()) { - // Changed to OptionalInt by FrozenBlock - OptionalInt modDataVersion = getModMinecraftDataVersion(compound, entry.getKey()); - DataFixerEntry dataFixerEntry = entry.getValue(); - - // Check implemented by FrozenBlock for performance. - // We recommend you register a DataFixer even if you don't need to fix anything currently to have a 100% success. - if (modDataVersion.isPresent()) { - current = dataFixerEntry.dataFixer().update( - DataFixTypesAccessor.class.cast(dataFixTypes).getType(), - current, - modDataVersion.getAsInt(), - dataFixerEntry.currentVersion() - ); - } - } - - for (Map.Entry entry : this.modDataFixers.entrySet()) { - // Changed to OptionalInt by FrozenBlock - OptionalInt modDataVersion = getModDataVersion(compound, entry.getKey()); - DataFixerEntry dataFixerEntry = entry.getValue(); - - // Check implemented by FrozenBlock for performance. - // We recommend you register a DataFixer even if you don't need to fix anything currently to have a 100% success. - if (modDataVersion.isPresent()) { - current = dataFixerEntry.dataFixer().update( - DataFixTypesAccessor.class.cast(dataFixTypes).getType(), - current, - modDataVersion.getAsInt(), - dataFixerEntry.currentVersion() - ); - } - } - - return current; - } - - @Override - public @NotNull CompoundTag addModDataVersions(@NotNull CompoundTag compound) { - for (Map.Entry entry : this.modDataFixers.entrySet()) { - compound.putInt(entry.getKey() + "_DataVersion", entry.getValue().currentVersion()); - } - for (Map.Entry entry : this.modMinecraftDataFixers.entrySet()) { - compound.putInt(entry.getKey() + "_DataVersion_Minecraft", entry.getValue().currentVersion()); - } - - return compound; - } - - @Override - public void freeze() { - if (!this.frozen) { - this.modDataFixers = Collections.unmodifiableMap(this.modDataFixers); - this.modMinecraftDataFixers = Collections.unmodifiableMap(this.modMinecraftDataFixers); - } - - this.frozen = true; - } - - @Override - public boolean isFrozen() { - return this.frozen; - } - -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/ServerFreezer.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/ServerFreezer.java deleted file mode 100644 index 8c707f7de..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/ServerFreezer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl; - -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; -import net.frozenblock.lib.FrozenLogUtils; -import org.jetbrains.annotations.ApiStatus; - -/** - * Modified to work on Fabric - */ -@ApiStatus.Internal -public final class ServerFreezer { - - public static void onInitialize() { - ServerLifecycleEvents.SERVER_STARTING.register(server -> { - FrozenLogUtils.log("[Quilt DFU API] Serverside DataFixer Registry is about to freeze", true); - QuiltDataFixesInternals.get().freeze(); - FrozenLogUtils.log("[Quilt DFU API] Serverside DataFixer Registry was frozen", true); - }); - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/client/ClientFreezer.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/client/ClientFreezer.java deleted file mode 100644 index 2bce1e3cc..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/impl/client/ClientFreezer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.client; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.frozenblock.lib.FrozenLogUtils; -import org.jetbrains.annotations.ApiStatus; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.QuiltDataFixesInternals; - -/** - * Modified to work on Fabric - */ -@Environment(EnvType.CLIENT) -@ApiStatus.Internal -public final class ClientFreezer { - - public static void onInitializeClient() { - ClientLifecycleEvents.CLIENT_STARTED.register(client -> { - FrozenLogUtils.log("[Quilt DFU API] Clientside DataFixer Registry is about to freeze", true); - QuiltDataFixesInternals.get().freeze(); - FrozenLogUtils.log("[Quilt DFU API] Clientside DataFixer Registry was frozen", true); - }); - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/ChunkStorageMixin.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/ChunkStorageMixin.java deleted file mode 100644 index f4dcc5867..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/ChunkStorageMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2024 FrozenBlock - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.quiltmc.qsl.frozenblock.misc.datafixerupper.mixin; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.world.level.chunk.storage.ChunkStorage; -import net.minecraft.world.level.storage.DataVersion; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.QuiltDataFixesInternals; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(ChunkStorage.class) -public class ChunkStorageMixin { - - @WrapOperation(method = "upgradeChunkTag", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/DataVersion;getVersion()I")) - private int bypassCheck(DataVersion instance, Operation original) { - if (!QuiltDataFixesInternals.get().isEmpty()) { - return -1; - } - - return original.call(instance); - } -} diff --git a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/DataFixTypesMixin.java b/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/DataFixTypesMixin.java deleted file mode 100644 index 598a1aa3a..000000000 --- a/src/main/java/org/quiltmc/qsl/frozenblock/misc/datafixerupper/mixin/DataFixTypesMixin.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2024 The Quilt Project - * Copyright 2024 FrozenBlock - * Modified to work on Fabric - * - * 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 org.quiltmc.qsl.frozenblock.misc.datafixerupper.mixin; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DataFixer; -import com.mojang.serialization.Dynamic; -import net.frozenblock.lib.config.frozenlib_config.FrozenLibConfig; -import net.minecraft.nbt.Tag; -import net.minecraft.util.datafix.DataFixTypes; -import org.quiltmc.qsl.frozenblock.misc.datafixerupper.impl.QuiltDataFixesInternals; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Modified to work on Fabric - * Original name was NbtHelperMixin - */ -@Mixin(value = DataFixTypes.class, priority = 1001) -public class DataFixTypesMixin { - - @Shadow - @Final - private DSL.TypeReference type; - - @ModifyReturnValue( - method = "update(Lcom/mojang/datafixers/DataFixer;Lcom/mojang/serialization/Dynamic;II)Lcom/mojang/serialization/Dynamic;", - at = @At("RETURN") - ) - private Dynamic updateDataWithFixers(Dynamic original, DataFixer fixer, Dynamic dynamic, int oldVersion, int targetVersion) { - var type = DataFixTypes.class.cast(this); - var value = original.getValue(); - - if (value instanceof Tag && !FrozenLibConfig.get().dataFixer.disabledDataFixTypes.contains(this.type.typeName())) { - //noinspection unchecked - return (Dynamic) QuiltDataFixesInternals.get().updateWithAllFixers(type, (Dynamic) original); - } - return original; - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index c2988d1f9..a4e40997e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -33,7 +33,8 @@ "net.frozenblock.lib.FrozenClient" ], "server": [ - "net.frozenblock.lib.FrozenServer" + "net.frozenblock.lib.FrozenServer", + "net.fabricmc.frozenblock.datafixer.impl.server.ServerFreezer" ], "modmenu": [ "net.frozenblock.lib.config.frozenlib_config.gui.ModMenuIntegration" @@ -72,7 +73,8 @@ "mixin/frozenlib.worldgen.surface.mixins.json", "mixin/frozenlib.worldgen.vein.mixins.json", - "mixin/frozenlib_quiltmc_datafixerupper.mixins.json", + "mixin/frozenlib_fabric_data_fixer.mixins.json", + "mixin/frozenlib_quiltmc_registry.mixins.json", "mixin/frozenlib_quiltmc_resource_loader.mixins.json" ], diff --git a/src/main/resources/frozenlib.accesswidener b/src/main/resources/frozenlib.accesswidener index d3ceb9d64..beeb6935d 100644 --- a/src/main/resources/frozenlib.accesswidener +++ b/src/main/resources/frozenlib.accesswidener @@ -227,6 +227,7 @@ transitive-mutable field net/minecraft/world/flag/FeatureFlags REGISTRY Lnet/min transitive-mutable field net/minecraft/world/flag/FeatureFlags CODEC Lcom/mojang/serialization/Codec; # DataFixerUpper +transitive-accessible field net/minecraft/util/datafix/DataFixTypes type Lcom/mojang/datafixers/DSL$TypeReference; transitive-accessible method net/minecraft/util/datafix/DataFixers createRenamer (Ljava/util/Map;)Ljava/util/function/UnaryOperator; # World Loading diff --git a/src/main/resources/mixin/frozenlib_fabric_data_fixer.mixins.json b/src/main/resources/mixin/frozenlib_fabric_data_fixer.mixins.json new file mode 100644 index 000000000..2031b0d64 --- /dev/null +++ b/src/main/resources/mixin/frozenlib_fabric_data_fixer.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8.5", + "package": "net.fabricmc.frozenblock.datafixer.mixin", + "compatibilityLevel": "JAVA_21", + "injectors": { + "defaultRequire": 1 + }, + "mixins": [ + "DataFixerUpperMixin", + "DataFixTypesMixin", + "NbtHelperMixin", + "SchemasMixin", + "VersionedChunkStorageMixin" + ] +} diff --git a/src/main/resources/mixin/frozenlib_quiltmc_datafixerupper.mixins.json b/src/main/resources/mixin/frozenlib_quiltmc_datafixerupper.mixins.json deleted file mode 100644 index 53b855696..000000000 --- a/src/main/resources/mixin/frozenlib_quiltmc_datafixerupper.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8.5", - "package": "org.quiltmc.qsl.frozenblock.misc.datafixerupper.mixin", - "compatibilityLevel": "JAVA_21", - "mixins": [ - "ChunkStorageMixin", - "DataFixTypesAccessor", - "DataFixTypesMixin", - "NbtUtilsMixin" - ], - "client": [ - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/src/main/resources/mixin/frozenlib_quiltmc_registry.mixins.json b/src/main/resources/mixin/frozenlib_quiltmc_registry.mixins.json index bb284d422..dab599b66 100644 --- a/src/main/resources/mixin/frozenlib_quiltmc_registry.mixins.json +++ b/src/main/resources/mixin/frozenlib_quiltmc_registry.mixins.json @@ -3,6 +3,9 @@ "minVersion": "0.8.5", "package": "org.quiltmc.qsl.frozenblock.core.registry.mixin", "compatibilityLevel": "JAVA_21", + "injectors": { + "defaultRequire": 1 + }, "mixins": [ "BuiltInRegistriesMixin", "ConnectionMixin", @@ -10,9 +13,6 @@ "RegistryDataLoaderMixin", "ServerStatusVersionMixin" ], - "injectors": { - "defaultRequire": 1 - }, "client": [ "client.MinecraftMixin", "client.ServerDataMixin" diff --git a/src/main/resources/mixin/frozenlib_quiltmc_resource_loader.mixins.json b/src/main/resources/mixin/frozenlib_quiltmc_resource_loader.mixins.json index 31a33968e..604f6409b 100644 --- a/src/main/resources/mixin/frozenlib_quiltmc_resource_loader.mixins.json +++ b/src/main/resources/mixin/frozenlib_quiltmc_resource_loader.mixins.json @@ -12,6 +12,6 @@ "client.IntegratedServerLoaderMixin" ], "injectors": { - "defaultRequire": 1 + "defaultRequire": 1 } }