diff --git a/fabric-api-dev/build.gradle b/fabric-api-dev/build.gradle new file mode 100644 index 0000000000..85b5e378d4 --- /dev/null +++ b/fabric-api-dev/build.gradle @@ -0,0 +1 @@ +version = getSubprojectVersion(project) diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/api/dev/v1/FabricDevProperties.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/api/dev/v1/FabricDevProperties.java new file mode 100644 index 0000000000..70cba0c585 --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/api/dev/v1/FabricDevProperties.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.dev.v1; + +import java.util.function.Supplier; + +import com.mojang.brigadier.ParseResults; +import org.jetbrains.annotations.ApiStatus; + +import net.minecraft.Bootstrap; +import net.minecraft.server.command.CommandManager; +import net.minecraft.util.collection.Weight; +import net.minecraft.world.Heightmap; + +/** Mods should not directly use these fields; they only exist here as a reference of what Dev Properties exist */ +@ApiStatus.Internal +@SuppressWarnings("JavadocReference") +public class FabricDevProperties { + /** + * Logs an error when a weight is set to zero
+ * Property: fabric.dev.zeroWeightWarning
+ * {@link Weight#validate(int)} + */ + public static final boolean ZERO_WEIGHT_WARNING = getProperty("zeroWeightWarning"); + + /** + * Logs an error when a translation is missing
+ * Property: fabric.dev.logMissingTranslations
+ * {@link Bootstrap#logMissing()} + */ + public static final boolean LOG_MISSING_TRANSLATIONS = getProperty("logMissingTranslations"); + + /** + * Logs an error if Block classes don't end with "Block" and if Item classes don't end with "Item"
+ * Property: fabric.dev.logConventionIssues
+ * {@link net.minecraft.block.Block#Block} and {@link net.minecraft.item.Item#Item} + */ + public static final boolean LOG_BLOCK_AND_ITEM_CONVENTION_ISSUES = getProperty("logBlockAndItemConventionIssues"); + + /** + * Registers Minecraft's debug commands + * (TestCommand, RaidCommand, DebugPathCommand, DebugMobSpawningCommand, + * WardenSpawnTrackerCommand, SpawnArmorTrimsCommand, ServerPackCommand), + * and if on the server DebugConfigCommand
+ * Property: fabric.dev.registerDebugCommands
+ * {@link CommandManager#CommandManager} + */ + public static final boolean REGISTER_DEBUG_COMMANDS = getProperty("registerDebugCommands"); + + /** + * Logs an error if a command threw an exception
+ * Property: fabric.dev.enableCommandExceptionLogging
+ * {@link CommandManager#execute(ParseResults, String)} + */ + public static final boolean ENABLE_COMMAND_EXCEPTION_LOGGING = getProperty("enableCommandExceptionLogging"); + + /** + * Logs an error regarding argument ambiguity and throws an exception if an argument type is not registered
+ * Property: fabric.dev.enableCommandArgumentLogging
+ * {@link CommandManager#checkMissing()} + */ + public static final boolean ENABLE_COMMAND_ARGUMENT_LOGGING = getProperty("enableCommandArgumentLogging"); + + /** + * Throw's an exception if a bounding box is invalid
+ * Property: fabric.dev.throwOnInvalidBlockBoxes
+ * {@link net.minecraft.util.math.BlockBox#BlockBox(int, int, int, int, int, int)} + */ + public static final boolean THROW_ON_INVALID_BLOCK_BOXES = getProperty("throwOnInvalidBlockBoxes"); + + /** + * Logs an error if the heightmap is null
+ * Property: fabric.dev.enableUnprimedHeightmapLogging
+ * {@link net.minecraft.world.chunk.Chunk#sampleHeightmap(Heightmap.Type, int, int)} + */ + public static final boolean ENABLE_UNPRIMED_HEIGHTMAP_LOGGING = getProperty("enableUnprimedHeightmapLogging"); + + /** + * Set's the current thread's name to the activeThreadName if debugRunnable or debugSupplier is called
+ * Property: fabric.dev.enableSupplierAndRunnableDebugging
+ * {@link net.minecraft.util.Util#debugRunnable(String, Runnable)} and {@link net.minecraft.util.Util#debugSupplier(String, Supplier)} + */ + public static final boolean ENABLE_SUPPLIER_AND_RUNNABLE_DEBUGGING = getProperty("enableSupplierAndRunnableDebugging"); + + /** + * Invokes a method in which you should have a breakpoint to debug errors + * thrown with Util#error and exceptions thrown with Util#throwOrPause
+ * Property: fabric.dev.enableExceptionIdePausing
+ * {@link net.minecraft.util.Util#error(String)}, {@link net.minecraft.util.Util#error(String, Throwable)} + * and {@link net.minecraft.util.Util#throwOrPause(Throwable)} + */ + public static final boolean ENABLE_EXCEPTION_IDE_PAUSING = getProperty("enableExceptionIdePausing"); + + private static boolean getProperty(String name) { + return Boolean.getBoolean("fabric.dev." + name); + } +} diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BlockAndItemMixin.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BlockAndItemMixin.java new file mode 100644 index 0000000000..1134aac056 --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BlockAndItemMixin.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.dev; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; + +import net.fabricmc.fabric.api.dev.v1.FabricDevProperties; + +@Mixin({Block.class, Item.class}) +public class BlockAndItemMixin { + @ModifyExpressionValue(method = { + "(Lnet/minecraft/block/AbstractBlock$Settings;)V", + "(Lnet/minecraft/item/Item$Settings;)V" + }, at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private boolean isDevelopmentForDevModule(boolean original) { + return original || FabricDevProperties.LOG_BLOCK_AND_ITEM_CONVENTION_ISSUES; + } +} diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BlockBoxMixin.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BlockBoxMixin.java new file mode 100644 index 0000000000..2b7e1ce34f --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BlockBoxMixin.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.dev; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.util.math.BlockBox; + +import net.fabricmc.fabric.api.dev.v1.FabricDevProperties; + +@Mixin(BlockBox.class) +public class BlockBoxMixin { + @ModifyExpressionValue(method = "(IIIIII)V", at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private boolean isDevelopmentForDevModule(boolean original) { + return original || FabricDevProperties.THROW_ON_INVALID_BLOCK_BOXES; + } +} diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BootstrapMixin.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BootstrapMixin.java new file mode 100644 index 0000000000..a7fb07de7a --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/BootstrapMixin.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.dev; + +import java.util.Set; +import java.util.function.Consumer; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.Bootstrap; + +import net.fabricmc.fabric.api.dev.v1.FabricDevProperties; + +@Mixin(Bootstrap.class) +public class BootstrapMixin { + @ModifyExpressionValue(method = "logMissing", at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private static boolean isDevelopmentForDevModule(boolean original) { + return original || FabricDevProperties.LOG_MISSING_TRANSLATIONS || FabricDevProperties.ENABLE_COMMAND_ARGUMENT_LOGGING; + } + + @WrapWithCondition(method = "logMissing", at = @At(value = "INVOKE", target = "Ljava/util/Set;forEach(Ljava/util/function/Consumer;)V")) + private static boolean wrapWithConditionTranslationWarnings(Set instance, Consumer consumer) { + return FabricDevProperties.LOG_MISSING_TRANSLATIONS; + } + + @WrapWithCondition(method = "logMissing", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/command/CommandManager;checkMissing()V")) + private static boolean wrapWithConditionCommandArgumentWarnings() { + return FabricDevProperties.ENABLE_COMMAND_ARGUMENT_LOGGING; + } +} diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/ChunkMixin.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/ChunkMixin.java new file mode 100644 index 0000000000..aaecf247e9 --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/ChunkMixin.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.dev; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.world.chunk.Chunk; + +import net.fabricmc.fabric.api.dev.v1.FabricDevProperties; + +@Mixin(Chunk.class) +public class ChunkMixin { + @ModifyExpressionValue(method = "sampleHeightmap", at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private boolean isDevelopmentForDevModule(boolean original) { + return original || FabricDevProperties.ENABLE_UNPRIMED_HEIGHTMAP_LOGGING; + } +} diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/CommandManagerMixin.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/CommandManagerMixin.java new file mode 100644 index 0000000000..f803e9278c --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/CommandManagerMixin.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.dev; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.server.command.CommandManager; + +import net.fabricmc.fabric.api.dev.v1.FabricDevProperties; + +@Mixin(CommandManager.class) +public class CommandManagerMixin { + @ModifyExpressionValue(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private static boolean isDevelopmentForDevModule(boolean original) { + return original || FabricDevProperties.REGISTER_DEBUG_COMMANDS; + } + + @ModifyExpressionValue(method = "execute", at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private static boolean isDevelopmentForDevModule2(boolean original) { + return original || FabricDevProperties.ENABLE_COMMAND_EXCEPTION_LOGGING; + } +} diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/UtilMixin.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/UtilMixin.java new file mode 100644 index 0000000000..cc8699b0c2 --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/UtilMixin.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.dev; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.util.Util; + +import net.fabricmc.fabric.api.dev.v1.FabricDevProperties; + +@Mixin(Util.class) +public class UtilMixin { + @ModifyExpressionValue(method = { + "debugRunnable(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;", + "debugSupplier(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;" + }, at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private static boolean isDevelopmentForDevModule2(boolean original) { + return original || FabricDevProperties.ENABLE_SUPPLIER_AND_RUNNABLE_DEBUGGING; + } + + @ModifyExpressionValue(method = {"error(Ljava/lang/String;)V", "error(Ljava/lang/String;Ljava/lang/Throwable;)V", "throwOrPause"}, at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private static boolean isDevelopmentForDevModule3(boolean original) { + return original || FabricDevProperties.ENABLE_EXCEPTION_IDE_PAUSING; + } +} diff --git a/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/WeightMixin.java b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/WeightMixin.java new file mode 100644 index 0000000000..83e8266ce0 --- /dev/null +++ b/fabric-api-dev/src/main/java/net/fabricmc/fabric/mixin/dev/WeightMixin.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.dev; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.util.collection.Weight; + +import net.fabricmc.fabric.api.dev.v1.FabricDevProperties; + +@Mixin(Weight.class) +public class WeightMixin { + @ModifyExpressionValue(method = "validate", at = @At(value = "FIELD", target = "Lnet/minecraft/SharedConstants;isDevelopment:Z")) + private static boolean isDevelopmentForDevModule(boolean original) { + return original || FabricDevProperties.ZERO_WEIGHT_WARNING; + } +} diff --git a/fabric-api-dev/src/main/resources/assets/fabric-api-dev/icon.png b/fabric-api-dev/src/main/resources/assets/fabric-api-dev/icon.png new file mode 100644 index 0000000000..2931efbf61 Binary files /dev/null and b/fabric-api-dev/src/main/resources/assets/fabric-api-dev/icon.png differ diff --git a/fabric-api-dev/src/main/resources/fabric-api-dev.mixins.json b/fabric-api-dev/src/main/resources/fabric-api-dev.mixins.json new file mode 100644 index 0000000000..5414533e11 --- /dev/null +++ b/fabric-api-dev/src/main/resources/fabric-api-dev.mixins.json @@ -0,0 +1,17 @@ +{ + "required": true, + "package": "net.fabricmc.fabric.mixin.dev", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "BlockAndItemMixin", + "BlockBoxMixin", + "BootstrapMixin", + "ChunkMixin", + "CommandManagerMixin", + "UtilMixin", + "WeightMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/fabric-api-dev/src/main/resources/fabric.mod.json b/fabric-api-dev/src/main/resources/fabric.mod.json new file mode 100644 index 0000000000..7c287d5f91 --- /dev/null +++ b/fabric-api-dev/src/main/resources/fabric.mod.json @@ -0,0 +1,28 @@ +{ + "schemaVersion": 1, + "id": "fabric-api-dev", + "name": "Fabric API Dev Tools", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/fabric-api-dev/icon.png", + "contact": { + "homepage": "https://fabricmc.net", + "irc": "irc://irc.esper.net:6667/fabric", + "issues": "https://github.com/FabricMC/fabric/issues", + "sources": "https://github.com/FabricMC/fabric" + }, + "authors": [ + "FabricMC" + ], + "depends": { + "fabricloader": ">=0.15.11" + }, + "description": "Contains utilities for development environments.", + "mixins": [ + "fabric-api-dev.mixins.json" + ], + "custom": { + "fabric-api:module-lifecycle": "stable" + } +} diff --git a/gradle.properties b/gradle.properties index 53417403d3..0270ffeb78 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,6 +13,7 @@ curseforge_minecraft_version=1.21.1 # Do not manually update, use the bumpversions task: fabric-api-base-version=0.4.42 +fabric-api-dev-version=1.0.0 fabric-api-lookup-api-v1-version=1.6.70 fabric-biome-api-v1-version=13.0.30 fabric-block-api-v1-version=1.0.22 diff --git a/settings.gradle b/settings.gradle index 540cbccdbf..d6a95ecb6b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,6 +14,7 @@ include 'fabric-api-bom' include 'fabric-api-catalog' include 'fabric-api-base' +include 'fabric-api-dev' include 'fabric-api-lookup-api-v1' include 'fabric-biome-api-v1'