From 8e6c76d8046752812bed534b1cfac103e9eebd13 Mon Sep 17 00:00:00 2001 From: Martin Prokoph Date: Sun, 7 Dec 2025 20:11:35 +0100 Subject: [PATCH] port: MC 1.21.11(-rc2) --- build.gradle.kts | 8 +++ gradle.properties | 2 +- settings.gradle.kts | 2 +- .../eu/midnightdust/core/MidnightLib.java | 2 +- .../core/mixin/MixinOptionsScreen.java | 6 +-- .../midnightdust/lib/config/AutoCommand.java | 6 ++- .../midnightdust/lib/config/ButtonEntry.java | 6 +-- .../lib/config/MidnightConfig.java | 26 ++++----- .../lib/config/MidnightConfigScreen.java | 12 ++--- .../midnightdust/test/MidnightLibExtras.java | 4 +- .../test/config/MidnightConfigExample.java | 6 +-- stonecutter.gradle.kts | 2 +- versions/1.21.11-rc2-fabric/gradle.properties | 12 +++++ .../src/main/resources/fabric.mod.json | 54 +++++++++++++++++++ 14 files changed, 114 insertions(+), 34 deletions(-) create mode 100644 versions/1.21.11-rc2-fabric/gradle.properties create mode 100644 versions/1.21.11-rc2-fabric/src/main/resources/fabric.mod.json diff --git a/build.gradle.kts b/build.gradle.kts index a840663..d22b4de 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -205,4 +205,12 @@ stonecutter { constants { arrayOf("fabric", "neoforge", "forge").forEach { it -> put(it, loader == it) } } + replacements.string { + direction = eval(current.version, ">=1.21.11-rc2") + replace("ResourceLocation", "Identifier") + } + replacements.string { + direction = eval(current.version, ">=1.21.11-rc2") + replace("net.minecraft.Util", "net.minecraft.util.Util") + } } diff --git a/gradle.properties b/gradle.properties index cb56064..c5924ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,7 +21,7 @@ mod.mc_title=[VERSIONED] mod.mc_targets=[VERSIONED] # Mod setup -deps.fabric_loader=0.17.3 +deps.fabric_loader=0.18.1 deps.fabric_version=[VERSIONED] deps.forge_loader=[VERSIONED] diff --git a/settings.gradle.kts b/settings.gradle.kts index 4f9d56a..b2e3739 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,7 +22,7 @@ stonecutter { for (version in versions) vers("$version-$loader", version) } //i would recommend to use neoforge for mc > 1.20.1, i haven't tested template for forge on versions higher than that - mc("fabric","1.20.1", "1.21.1", "1.21.5", "1.21.8", "1.21.10") + mc("fabric","1.20.1", "1.21.1", "1.21.5", "1.21.8", "1.21.10", "1.21.11-rc2") mc("forge","1.20.1") //WARNING: neoforge uses mods.toml instead of neoforge.mods.toml for versions 1.20.4 (?) and earlier mc("neoforge", "1.21.1", "1.21.5", "1.21.8", "1.21.10") diff --git a/src/main/java/eu/midnightdust/core/MidnightLib.java b/src/main/java/eu/midnightdust/core/MidnightLib.java index 3d18eed..fcd3ccf 100644 --- a/src/main/java/eu/midnightdust/core/MidnightLib.java +++ b/src/main/java/eu/midnightdust/core/MidnightLib.java @@ -7,7 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.UIManager; -import net.minecraft.Util; +import net.minecraft.util.Util; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java b/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java index 6693fa2..b80e0dc 100644 --- a/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java +++ b/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java @@ -12,7 +12,7 @@ import java.util.Objects; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; //? if >= 1.21 { import org.spongepowered.asm.mixin.Final; @@ -35,7 +35,7 @@ public abstract class MixinOptionsScreen extends Screen { @Shadow @Final private HeaderAndFooterLayout layout; @Unique SpriteIconButton midnightlib$button = SpriteIconButton.builder(Component.translatable("midnightlib.overview.title"), ( buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(new MidnightConfigOverviewScreen(this)), true) - .sprite(ResourceLocation.fromNamespaceAndPath(MOD_ID,"icon/"+MOD_ID), 16, 16).size(20, 20).build(); + .sprite(Identifier.fromNamespaceAndPath(MOD_ID,"icon/"+MOD_ID), 16, 16).size(20, 20).build(); @Inject(at = @At("HEAD"), method = "init") public void midnightlib$onInit(CallbackInfo ci) { @@ -55,7 +55,7 @@ public abstract class MixinOptionsScreen extends Screen { midnightlib$button.setPosition(layout.getWidth() / 2 + 158, layout.getY() + layout.getFooterHeight() - 4); } //?} else { - /*@Unique TextAndImageButton midnightlib$button = TextAndImageButton.builder(Component.translatable("midnightlib.overview.title"), new ResourceLocation("midnightlib", "icon/midnightlib.png"), + /*@Unique TextAndImageButton midnightlib$button = TextAndImageButton.builder(Component.translatable("midnightlib.overview.title"), new Identifier("midnightlib", "icon/midnightlib.png"), button -> Objects.requireNonNull(minecraft).setScreen(new MidnightConfigOverviewScreen(this))).textureSize(16, 16).usedTextureSize(16, 16).offset(0, 2).build(); @Inject(at = @At("HEAD"), method = "init") diff --git a/src/main/java/eu/midnightdust/lib/config/AutoCommand.java b/src/main/java/eu/midnightdust/lib/config/AutoCommand.java index 3fdd702..9e765cd 100644 --- a/src/main/java/eu/midnightdust/lib/config/AutoCommand.java +++ b/src/main/java/eu/midnightdust/lib/config/AutoCommand.java @@ -15,6 +15,9 @@ import net.minecraft.network.chat.Component; //? fabric import net.fabricmc.api.DedicatedServerModInitializer; +//? if >= 1.21.11 +import net.minecraft.server.permissions.*; + public class AutoCommand /*? fabric {*/ implements DedicatedServerModInitializer /*?}*/ { final static String VALUE = "value"; Field field; @@ -41,7 +44,8 @@ public class AutoCommand /*? fabric {*/ implements DedicatedServerModInitializer .then(Commands.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, action)))); } else command = command.then(Commands.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, ""))); - PlatformFunctions.registerCommand(Commands.literal("midnightconfig").requires(source -> source.hasPermission(2)).then(Commands.literal(modid).then(command))); + PlatformFunctions.registerCommand(Commands.literal("midnightconfig").requires(source -> + source/*? if >= 1.21.11 {*/.permissions().hasPermission(new Permission.HasCommandLevel(PermissionLevel.GAMEMASTERS))/*?} else {*/ /*.hasPermission(2) *//*?}*/).then(Commands.literal(modid).then(command))); } public ArgumentType getArgType() { diff --git a/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java b/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java index 28a1e49..6544929 100644 --- a/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java +++ b/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java @@ -15,7 +15,7 @@ import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.screens.ConfirmLinkScreen; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; //? if >= 1.21.9 { import net.minecraft.client.input.MouseButtonEvent; //?} @@ -64,8 +64,8 @@ public class ButtonEntry extends ContainerObjectSelectionList.Entry Optional.ofNullable(this.buttons.get(0)).ifPresent(widget -> { int idMode = this.info.entry.idMode(); if (idMode != -1) context.renderItem(idMode == 0 ? - BuiltInRegistries.ITEM./*? if >= 1.21.4 {*/ getValue /*?} else {*/ /*get *//*?}*/(ResourceLocation.tryParse(this.info.tempValue)).getDefaultInstance() - : BuiltInRegistries.BLOCK./*? if >= 1.21.4 {*/ getValue /*?} else {*/ /*get *//*?}*/(ResourceLocation.tryParse(this.info.tempValue)).asItem().getDefaultInstance(), + BuiltInRegistries.ITEM./*? if >= 1.21.4 {*/ getValue /*?} else {*/ /*get *//*?}*/(Identifier.tryParse(this.info.tempValue)).getDefaultInstance() + : BuiltInRegistries.BLOCK./*? if >= 1.21.4 {*/ getValue /*?} else {*/ /*get *//*?}*/(Identifier.tryParse(this.info.tempValue)).asItem().getDefaultInstance(), widget.getX() + widget.getWidth() - 18, y + 2); }); } diff --git a/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java b/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java index d522a70..a567ad3 100644 --- a/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java +++ b/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java @@ -10,7 +10,7 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Style; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.util.*; import org.jetbrains.annotations.Nullable; @@ -50,14 +50,14 @@ public abstract class MidnightConfig { public boolean shouldSkipClass(Class clazz) { return false; } public boolean shouldSkipField(FieldAttributes fieldAttributes) { return fieldAttributes.getAnnotation(Entry.class) == null; } }) - .registerTypeAdapter(ResourceLocation.class, + .registerTypeAdapter(Identifier.class, //? if >= 1.21.4 { - new TypeAdapter() { - public void write(JsonWriter out, ResourceLocation id) throws IOException { out.value(id.toString()); } - public ResourceLocation read(JsonReader in) throws IOException { return ResourceLocation.parse(in.nextString()); } + new TypeAdapter() { + public void write(JsonWriter out, Identifier id) throws IOException { out.value(id.toString()); } + public Identifier read(JsonReader in) throws IOException { return Identifier.parse(in.nextString()); } } //?} else { - /*new ResourceLocation.Serializer() + /*new Identifier.Serializer() *///?} ).setPrettyPrinting().create(); @@ -114,7 +114,7 @@ public abstract class MidnightConfig { if (info.dataType == int.class) textField(info, Integer::parseInt, INTEGER_ONLY, (int) e.min(), (int) e.max(), true); else if (info.dataType == float.class) textField(info, Float::parseFloat, DECIMAL_ONLY, (float) e.min(), (float) e.max(), false); else if (info.dataType == double.class) textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(), false); - else if (info.dataType == String.class || info.dataType == ResourceLocation.class) textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true); + else if (info.dataType == String.class || info.dataType == Identifier.class) textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true); else if (info.dataType == boolean.class) { Function func = value -> Component.translatable((Boolean) value ? "gui.yes" : "gui.no").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED); info.function = new AbstractMap.SimpleEntry>(button -> { @@ -158,7 +158,7 @@ public abstract class MidnightConfig { info.function = (BiFunction>) (t, b) -> s -> { s = s.trim(); if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches()) || - (info.dataType == ResourceLocation.class && ResourceLocation.read(s)./*? if >= 1.21 {*/isError() /*?} else {*/ /*error().isPresent() *//*?}*/)) return false; + (info.dataType == Identifier.class && Identifier.read(s)./*? if >= 1.21 {*/isError() /*?} else {*/ /*error().isPresent() *//*?}*/)) return false; Number value = 0; boolean inLimits = false; info.error = null; if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) { @@ -176,8 +176,8 @@ public abstract class MidnightConfig { b.active = entries.values().stream().allMatch(e -> e.inLimits); if (inLimits) { - if (info.dataType == ResourceLocation.class) - info.setValue(ResourceLocation.tryParse(s)); + if (info.dataType == Identifier.class) + info.setValue(Identifier.tryParse(s)); else info.setValue(isNumber ? value : s); } @@ -197,7 +197,9 @@ public abstract class MidnightConfig { * @param info the associated {@link EntryInfo} object * */ protected Component getEnumTranslatableText(Object value, EntryInfo info) { - if (value instanceof OptionEnum translatableOption) return translatableOption.getCaption(); + if (value instanceof StringRepresentable option) return Component.translatable(option.getSerializedName()); + //? if < 1.21.11 + /*if (value instanceof OptionEnum option) return option.getCaption();*/ assert info.dataType != null; String translationKey = "%s.midnightconfig.enum.%s.%s".formatted(modid, info.dataType.getSimpleName(), info.toTemporaryValue()); @@ -310,7 +312,7 @@ public abstract class MidnightConfig { /** * Entry Annotation
- * - width: The maximum character length of the {@link String}, {@link ResourceLocation} or String/Identifier {@link List<>} field
+ * - width: The maximum character length of the {@link String}, {@link Identifier} or String/Identifier {@link List<>} field
* - min: The minimum value of the int, float or double field
* - max: The maximum value of the int, float or double field
* - name: Will be used instead of the default translation key, if not empty
diff --git a/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java b/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java index 2c05999..cb7c609 100644 --- a/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java +++ b/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java @@ -2,7 +2,7 @@ package eu.midnightdust.lib.config; import com.google.common.collect.Lists; import net.minecraft.ChatFormatting; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.*; import net.minecraft.client.gui.components.Button; @@ -16,7 +16,7 @@ import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.contents.TranslatableContents; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; @@ -170,7 +170,7 @@ public class MidnightConfigScreen extends Screen { //? if >= 1.21 { SpriteIconButton resetButton = SpriteIconButton.builder(Component.translatable("controls.reset"), //?} else { - /*TextAndImageButton resetButton = TextAndImageButton.builder(Component.translatable("controls.reset"), new ResourceLocation("midnightlib", "icon/reset.png"), + /*TextAndImageButton resetButton = TextAndImageButton.builder(Component.translatable("controls.reset"), new Identifier("midnightlib", "icon/reset.png"), *///?} (button -> { info.value = info.defaultValue; @@ -179,7 +179,7 @@ public class MidnightConfigScreen extends Screen { updateList(); }) //? if >= 1.21 { - , true).sprite(ResourceLocation.fromNamespaceAndPath("midnightlib", "icon/reset"), 12, 12).size(20, 20).build(); + , true).sprite(Identifier.fromNamespaceAndPath("midnightlib", "icon/reset"), 12, 12).size(20, 20).build(); //?} else { /*).textureSize(12, 12).usedTextureSize(12, 12).offset(0, 4).build(); resetButton.setWidth(20); @@ -239,7 +239,7 @@ public class MidnightConfigScreen extends Screen { //? if >= 1.21 { SpriteIconButton.builder(Component.empty(), //?} else { - /*TextAndImageButton.builder(Component.empty(), new ResourceLocation("midnightlib", "icon/explorer.png"), + /*TextAndImageButton.builder(Component.empty(), new Identifier("midnightlib", "icon/explorer.png"), *///?} button -> new Thread(() -> { JFileChooser fileChooser = new JFileChooser(info.tempValue); @@ -255,7 +255,7 @@ public class MidnightConfigScreen extends Screen { } }).start() //? if >= 1.21 { - , true).sprite(ResourceLocation.fromNamespaceAndPath("midnightlib", "icon/explorer"), 12, 12).size(20, 20) + , true).sprite(Identifier.fromNamespaceAndPath("midnightlib", "icon/explorer"), 12, 12).size(20, 20) //?} else { /*).textureSize(12, 12).usedTextureSize(12, 12).offset(0, 4) *///?} diff --git a/src/test/java/eu/midnightdust/test/MidnightLibExtras.java b/src/test/java/eu/midnightdust/test/MidnightLibExtras.java index fcae6c9..31d26b8 100644 --- a/src/test/java/eu/midnightdust/test/MidnightLibExtras.java +++ b/src/test/java/eu/midnightdust/test/MidnightLibExtras.java @@ -16,7 +16,7 @@ import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.input.KeyEvent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; @@ -33,7 +33,7 @@ public class MidnightLibExtras { SpriteIconButton resetButton = SpriteIconButton.builder(Component.translatable("controls.reset"), (button -> { binding.setKey(binding.getDefaultKey()); screen.updateList(); - }), true).sprite(ResourceLocation.fromNamespaceAndPath("midnightlib","icon/reset"), 12, 12).size(20, 20).build(); + }), true).sprite(Identifier.fromNamespaceAndPath("midnightlib","icon/reset"), 12, 12).size(20, 20).build(); resetButton.setPosition(screen.width - 205 + 150 + 25, 0); editButton.resetButton = resetButton; editButton.updateMessage(false); diff --git a/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java b/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java index 10f94b5..126d52a 100644 --- a/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java +++ b/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java @@ -10,7 +10,7 @@ import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.util.OptionEnum; import org.jetbrains.annotations.NotNull; @@ -38,7 +38,7 @@ public class MidnightConfigExample extends MidnightConfig { @Entry(category = TEXT, name="I am a (non-primitive) Boolean") public static Boolean nonPrimitive = true; // Example for a non-primative boolean option @Entry(category = TEXT) public static String name = "Hello World!"; // Example for a string option, which is in a category! @Entry(category = TEXT, width = 7, min = 7, isColor = true, name = "I am a color!") public static String titleColor = "#ffffff"; // The isColor property adds a color chooser for a hexadecimal color - @Entry(category = TEXT, idMode = 0) public static ResourceLocation id = ResourceLocation.withDefaultNamespace("diamond"); // Example for an identifier with matching items displayed next to it! + @Entry(category = TEXT, idMode = 0) public static Identifier id = Identifier.withDefaultNamespace("diamond"); // Example for an identifier with matching items displayed next to it! @Entry(category = TEXT) public static ModPlatform modPlatform = ModPlatform.FABRIC; // Example for an enum option public enum ModPlatform { // Enums allow the user to cycle through predefined options QUILT, FABRIC, FORGE, NEOFORGE, VANILLA @@ -56,7 +56,7 @@ public class MidnightConfigExample extends MidnightConfig { // The name field can be used to specify a custom translation string or plain text @Entry(category = LISTS, name = "I am a string list!") public static List stringList = Lists.newArrayList("String1", "String2"); // Array String Lists are also supported @Entry(category = LISTS, isColor = true, name = "I am a color list!") public static List colorList = Lists.newArrayList("#ac5f99", "#11aa44"); // Lists also support colors - @Entry(category = LISTS, name = "I am an identifier list!", idMode = 1) public static List idList = Lists.newArrayList(ResourceLocation.withDefaultNamespace("dirt")); // A list of block identifiers + @Entry(category = LISTS, name = "I am an identifier list!", idMode = 1) public static List idList = Lists.newArrayList(Identifier.withDefaultNamespace("dirt")); // A list of block identifiers @Entry(category = LISTS, name = "I am an integer list!") public static List intList = Lists.newArrayList(69, 420); @Entry(category = LISTS, name = "I am a float list!") public static List floatList = Lists.newArrayList(4.1f, -1.3f, -1f); diff --git a/stonecutter.gradle.kts b/stonecutter.gradle.kts index c569200..acbc354 100644 --- a/stonecutter.gradle.kts +++ b/stonecutter.gradle.kts @@ -5,7 +5,7 @@ plugins { id("com.github.johnrengelman.shadow") version "8.1.1" apply false id("me.modmuss50.mod-publish-plugin") version "0.8.4" apply false } -stonecutter active "1.21.10-fabric" /* [SC] DO NOT EDIT */ +stonecutter active "1.21.11-rc2-fabric" /* [SC] DO NOT EDIT */ // See https://stonecutter.kikugie.dev/wiki/config/params stonecutter parameters { diff --git a/versions/1.21.11-rc2-fabric/gradle.properties b/versions/1.21.11-rc2-fabric/gradle.properties new file mode 100644 index 0000000..800b70b --- /dev/null +++ b/versions/1.21.11-rc2-fabric/gradle.properties @@ -0,0 +1,12 @@ +mod.mc_dep_fabric=>=1.21.11-rc.2 +mod.mc_dep_forgelike=[1.21.11,) +mod.mc_title=1.21.11-rc2 +mod.mc_targets=1.21.1-rc2 + +deps.forge_loader=0 +deps.neoforge_loader=21.10.47-beta + +deps.fabric_version=0.139.4+1.21.11 +deps.modmenu_version=17.0.0-alpha.1 + +loom.platform=fabric \ No newline at end of file diff --git a/versions/1.21.11-rc2-fabric/src/main/resources/fabric.mod.json b/versions/1.21.11-rc2-fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..b891091 --- /dev/null +++ b/versions/1.21.11-rc2-fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,54 @@ +{ + "schemaVersion": 1, + "id": "${id}", + "version": "${version}", + "name": "${name}", + "description": "Lightweight config library with config screens and commands.", + "authors": [ + "Motschen" + ], + "contributors": [ + "maloryware", + "Jaffe2718" + ], + "contact": { + "homepage": "https://www.midnightdust.eu/", + "sources": "https://github.com/TeamMidnightDust/MidnightLib", + "issues": "https://github.com/TeamMidnightDust/MidnightLib/issues" + }, + + "license": "MIT", + "icon": "assets/midnightlib/icon.png", + + "environment": "*", + "entrypoints": { + "server": [ + "eu.midnightdust.lib.config.AutoCommand" + ], + "client": [ + "eu.midnightdust.core.MidnightLib" + ], + "modmenu": [ + "eu.midnightdust.core.MidnightLib\$ModMenuInit" + ] + }, + "depends": { + "fabric-resource-loader-v0": "*", + "minecraft": "${minecraft}" + }, + + "mixins": [ + "midnightlib.mixins.json" + ], + + "custom": { + "modmenu": { + "links": { + "modmenu.discord": "http://discord.midnightdust.eu/", + "modmenu.website": "https://midnightdust.eu/midnightlib", + "midnightlib.wiki": "https://midnightdust.eu/wiki/midnightlib" + }, + "badges": [ "library" ] + } + } +}