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:
+ *
+ * - By passing it to {@link net.fabricmc.frozenblock.datafixer.api.FabricDataFixerBuilder}.
+ * - By passing it to {@link
+ * net.fabricmc.frozenblock.datafixer.api.FabricDataFixes#registerFixer(net.fabricmc.loader.api.ModContainer, int, com.mojang.datafixers.DataFixerUpper)}
+ * or other overloads taking the current version.
+ * - By setting it in the {@code fabric-data-fixer-api-v1:version} field of the {@code custom}
+ * object in the {@code fabric.mod.json} file, and using a method that uses the 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
}
}