diff --git a/gradle.properties b/gradle.properties index 772748f..5000d4b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ org.gradle.jvmargs=-Xmx1G yarn_mappings=1.19.2+build.18 loader_version=0.14.9 # Mod Properties - mod_version = 1.1.4 + mod_version = 1.1.5 maven_group = net.saltymc.eaa archives_base_name = EAA_MOD diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a2..e750102 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/net/saltymc/eaa/custom/ping/CustomPlayerListHud.java b/src/main/java/net/saltymc/eaa/custom/ping/CustomPlayerListHud.java index b599b2b..8b47223 100644 --- a/src/main/java/net/saltymc/eaa/custom/ping/CustomPlayerListHud.java +++ b/src/main/java/net/saltymc/eaa/custom/ping/CustomPlayerListHud.java @@ -1,32 +1,14 @@ package net.saltymc.eaa.custom.ping; -import com.google.common.collect.ComparisonChain; -import com.google.common.collect.Ordering; -import com.mojang.authlib.GameProfile; import com.mojang.blaze3d.systems.RenderSystem; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.hud.PlayerListHud; -import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.render.entity.PlayerModelPart; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.scoreboard.Scoreboard; -import net.minecraft.scoreboard.ScoreboardCriterion; -import net.minecraft.scoreboard.ScoreboardObjective; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.OrderedText; -import net.minecraft.text.Text; -import net.minecraft.world.GameMode; import net.saltymc.eaa.function.TagFunction; +import net.saltymc.eaa.mixin.PlayerListHudInvoker; /** * By: https://github.com/vladmarica/better-ping-display-fabric/ @@ -34,225 +16,58 @@ import net.saltymc.eaa.function.TagFunction; public final class CustomPlayerListHud { public static final PingConfig config = new PingConfig(); - - private static final Ordering ENTRY_ORDERING = Ordering.from(new EntryOrderComparator()); private static final int PING_TEXT_RENDER_OFFSET = -13; - private static final int PLAYER_SLOT_EXTRA_WIDTH = 45; - private static final int PLAYER_ICON_WIDTH = 9; private static final int PING_BARS_WIDTH = 11; + private static final int OFFSET = 1; - public static void render(PlayerListHud hud, MatrixStack stack, int width, Scoreboard scoreboard, ScoreboardObjective obj) { - MinecraftClient mc = MinecraftClient.getInstance(); - TextRenderer textRenderer = mc.textRenderer; - Text header = PlayerListHudUtil.getHeader(hud); - Text footer = PlayerListHudUtil.getFooter(hud); + public static void renderPingDisplay( + MinecraftClient client, PlayerListHud hud, MatrixStack matrixStack, int width, int x, int y, PlayerListEntry player) { + TextRenderer textRenderer = client.textRenderer; - ClientPlayNetworkHandler clientPlayNetworkHandler = mc.player.networkHandler; - List playerList = ENTRY_ORDERING.sortedCopy(clientPlayNetworkHandler.getPlayerList()); - int i = 0; - int j = 0; - Iterator playerListIterator = playerList.iterator(); + String pingString = String.format(config.getTextFormatString(), player.getLatency()); + int pingStringWidth = textRenderer.getWidth(pingString); + int pingTextColor = config.shouldAutoColorPingText() ? PingColors.getColor(player.getLatency()) : config.getTextColor(); + int textX = width + x - pingStringWidth + PING_TEXT_RENDER_OFFSET; - int n; - while(playerListIterator.hasNext()) { - PlayerListEntry playerListEntry = (PlayerListEntry)playerListIterator.next(); - n = mc.textRenderer.getWidth(hud.getPlayerName(playerListEntry)); - i = Math.max(i, n); - if (obj != null && obj.getRenderType() != ScoreboardCriterion.RenderType.HEARTS) { - n = textRenderer.getWidth(" " + scoreboard.getPlayerScore(playerListEntry.getProfile().getName(), obj).getScore()); - j = Math.max(j, n); - } + if (!config.shouldRenderPingBars()) { + textX += PING_BARS_WIDTH; } - playerList = playerList.subList(0, Math.min(playerList.size(), 80)); - int l = playerList.size(); - int m = l; + // Draw the ping text for the given player + textRenderer.drawWithShadow(matrixStack, pingString, (float) textX, (float) y, pingTextColor); - for(n = 1; m > 20; m = (l + n - 1) / n) { - ++n; - } + /* + * PLAYER TAG + */ + // Calculate position before ping display + String pingStringWith3Digits = String.format(config.getTextFormatString(), 900); // Generate pingtext for 900ms + int pingStringWith3DigitsWidth = textRenderer.getWidth(pingStringWith3Digits); // calculate legth of text + int newX = x + width - pingStringWith3DigitsWidth + PING_TEXT_RENDER_OFFSET; // fix offset looks nicer should be right before ping text if 3 digits long + int twoDigits = textRenderer.getWidth("10") + OFFSET ; - boolean displayPlayerIcons = mc.isInSingleplayer() || mc.getNetworkHandler().getConnection().isEncrypted(); - int q; - if (obj != null) { - if (obj.getRenderType() == ScoreboardCriterion.RenderType.HEARTS) { - q = 90; - } else { - q = j; - } + int offset_tag_playername = newX - twoDigits; // behind ping - length of grade text + TagDTO playerTAG = TagFunction.getScoreboardTag(player.getProfile().getId().toString()); // retrieve Tag object + + //float tmp_x = offset_tag_playername - ((twoDigits - textRenderer.getWidth(playerTAG.getGrade() < 1 ? "|" : playerTAG.getGrade() +"")) / 2.0f); + String gradeText = playerTAG.getGrade() < 1 ? "|" : playerTAG.getGrade() +""; // if not given draw a pipe + textRenderer.drawWithShadow(matrixStack, + gradeText, + (float) offset_tag_playername + ((float)twoDigits - (textRenderer.getWidth(gradeText) / 2.0F )), (float) y, playerTAG.getGradeColor()); + + offset_tag_playername -= textRenderer.getWidth(playerTAG.getType().getTag()) + OFFSET; // subtract tag name length to offset + + textRenderer.drawWithShadow(matrixStack, playerTAG.getType().getTag(), (float)offset_tag_playername, (float)y, playerTAG.getType().getColor()); // draw tag name + + /* + * END + */ + + if (config.shouldRenderPingBars()) { + ((PlayerListHudInvoker) hud).invokeRenderLatencyIcon(matrixStack, width, x, y, player); } else { - q = 0; - } - int r = Math.min(n * ((displayPlayerIcons ? PLAYER_ICON_WIDTH : 0) + i + q + 13 + PLAYER_SLOT_EXTRA_WIDTH), width - 50) / n; - int s = width / 2 - (r * n + (n - 1) * 5) / 2; - int t = 10; - int u = r * n + (n - 1) * 5; - List headerLines = null; - if (header != null) { - headerLines = mc.textRenderer.wrapLines(header, width - 50); - - for (OrderedText headerLine : headerLines) { - u = Math.max(u, mc.textRenderer.getWidth(headerLine)); - } - } - - List footerLines = null; - if (footer != null) { - footerLines = mc.textRenderer.wrapLines(footer, width - 50); - - for (OrderedText footerLine : footerLines) { - u = Math.max(u, mc.textRenderer.getWidth(footerLine)); - } - } - - int var10000; - int var10001; - int var10002; - int var10004; - int y; - if (headerLines != null) { - var10000 = width / 2 - u / 2 - 1; - var10001 = t - 1; - var10002 = width / 2 + u / 2 + 1; - var10004 = headerLines.size(); - DrawableHelper.fill(stack, var10000, var10001, var10002, t + var10004 * 9, Integer.MIN_VALUE); - - for (OrderedText headerLine : headerLines) { - y = mc.textRenderer.getWidth(headerLine); - mc.textRenderer.drawWithShadow(stack, headerLine, (float)(width / 2 - y / 2), (float)t, -1); - t += 9; - } - - ++t; - } - - DrawableHelper.fill(stack, width / 2 - u / 2 - 1, t - 1, width / 2 + u / 2 + 1, t + m * 9, Integer.MIN_VALUE); - int w = mc.options.getTextBackgroundColor(553648127); - - int ai; - for(int x = 0; x < l; ++x) { - y = x / m; - ai = x % m; - int aa = s + y * r + y * 5; - int ab = t + ai * 9; - DrawableHelper.fill(stack, aa, ab, aa + r, ab + 8, w); - //RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.clearColor(1.0F, 1.0F, 1.0F, 1.0F); - //RenderSystem.enableAlphaTest(); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - if (x < playerList.size()) { - PlayerListEntry player = playerList.get(x); - GameProfile gameProfile = player.getProfile(); - int ah; - if (displayPlayerIcons) { - PlayerEntity playerEntity = mc.world.getPlayerByUuid(gameProfile.getId()); - boolean bl2 = playerEntity != null && playerEntity.isPartVisible(PlayerModelPart.CAPE) && ("Dinnerbone".equals(gameProfile.getName()) || "Grumm".equals(gameProfile.getName())); - mc.getTextureManager().bindTexture(player.getSkinTexture()); - ah = 8 + (bl2 ? 8 : 0); - int ad = 8 * (bl2 ? -1 : 1); - DrawableHelper.drawTexture(stack, aa, ab, 8, 8, 8.0F, (float)ah, 8, ad, 64, 64); - if (playerEntity != null && playerEntity.isPartVisible(PlayerModelPart.HAT)) { - int ae = 8 + (bl2 ? 8 : 0); - int af = 8 * (bl2 ? -1 : 1); - DrawableHelper.drawTexture(stack, aa, ab, 8, 8, 40.0F, (float)ae, 8, af, 64, 64); - } - - aa += 9; - } - - /* - * PLAYER TAG - */ - int offset_tag_playername = aa; // safe current x offset -> - TagDTO playerTAG = TagFunction.getScoreboardTag(player.getProfile().getId().toString()); // retrieve Tag object - mc.textRenderer.drawWithShadow(stack, playerTAG.getType().getTag(), (float)aa, (float)ab, playerTAG.getType().getColor()); // draw tag name - - offset_tag_playername += mc.textRenderer.getWidth(playerTAG.getType().getTag()) + 1; // add tag name length to offset - - // current offset plus amount to center grade text - float tmp_x = offset_tag_playername - + ((mc.textRenderer.getWidth("10") - mc.textRenderer.getWidth(playerTAG.getGrade() < 1 ? "|" : playerTAG.getGrade() +"")) - / 2.0f); - mc.textRenderer.drawWithShadow(stack, - playerTAG.getGrade() < 1 ? "|" : playerTAG.getGrade() +"", // if not given draw a pipe - (float) tmp_x, (float) ab, playerTAG.getGradeColor()); - - offset_tag_playername += mc.textRenderer.getWidth("10") + 2; // add offset of largest character - - - Text playerName = hud.getPlayerName(player); - if (player.getGameMode() == GameMode.SPECTATOR) { - mc.textRenderer.drawWithShadow(stack, playerName, (float)offset_tag_playername, (float)ab, -1862270977); - } else { - mc.textRenderer.drawWithShadow(stack, playerName, (float)offset_tag_playername, (float)ab, -1); - } - - if (obj != null && player.getGameMode() != GameMode.SPECTATOR) { - int ag = offset_tag_playername + i + 1; - ah = ag + q; - if (ah - ag > 5) { - PlayerListHudUtil.renderScoreboardObjective(hud, stack, obj, ab, gameProfile.getName(), ag, ah, player); - } - } - - // Here is the magic, rendering the ping text - String pingString = String.format(config.getTextFormatString(), player.getLatency()); - int pingStringWidth = textRenderer.getWidth(pingString); - int textX = r + aa - pingStringWidth + PING_TEXT_RENDER_OFFSET; - - if (displayPlayerIcons) { - textX -= PLAYER_ICON_WIDTH; - } - - if (!config.shouldRenderPingBars()) { - textX += PING_BARS_WIDTH; - } - - int pingTextColor = config.shouldAutoColorPingText() - ? PingColors.getColor(player.getLatency()) - : config.getTextColor(); - - textRenderer.drawWithShadow(stack, pingString, (float) textX, (float) ab, pingTextColor); - - if (config.shouldRenderPingBars()) { - PlayerListHudUtil.renderLatencyIcon( - hud, stack, r, aa - (displayPlayerIcons ? PLAYER_ICON_WIDTH : 0), ab, player); - } else { - // If we don't render ping bars, we need to reset the render system color so the rest - // of the player list renders properly - // RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.clearColor(1.0F, 1.0F, 1.0F, 1.0F); - } - } - } - - if (footerLines != null) { - t += m * 9 + 1; - var10000 = width / 2 - u / 2 - 1; - var10001 = t - 1; - var10002 = width / 2 + u / 2 + 1; - var10004 = footerLines.size(); - DrawableHelper.fill(stack, var10000, var10001, var10002, t + var10004 * 9, Integer.MIN_VALUE); - - for (OrderedText footerLine : footerLines) { - ai = textRenderer.getWidth(footerLine); - textRenderer.drawWithShadow(stack, footerLine, (float)(width / 2 - ai / 2), (float)t, -1); - t += 9; - } - } - } - - @Environment(EnvType.CLIENT) - static class EntryOrderComparator implements Comparator { - public int compare(PlayerListEntry p1, PlayerListEntry p2) { - Team team = p1.getScoreboardTeam(); - Team team2 = p2.getScoreboardTeam(); - return ComparisonChain.start() - .compareTrueFirst(p1.getGameMode() != GameMode.SPECTATOR, p2.getGameMode() != GameMode.SPECTATOR) - .compare(team != null ? team.getName() : "", team2 != null ? team2.getName() : "") - .compare(p1.getProfile().getName(), p2.getProfile().getName(), String::compareToIgnoreCase) - .result(); + // If we don't render ping bars, we need to reset the render system color so the rest + // of the player list renders properly + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); } } } diff --git a/src/main/java/net/saltymc/eaa/custom/ping/PlayerListHudUtil.java b/src/main/java/net/saltymc/eaa/custom/ping/PlayerListHudUtil.java deleted file mode 100644 index c6bc0de..0000000 --- a/src/main/java/net/saltymc/eaa/custom/ping/PlayerListHudUtil.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.saltymc.eaa.custom.ping; - -import net.minecraft.client.gui.hud.PlayerListHud; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.scoreboard.ScoreboardObjective; -import net.minecraft.text.Text; -import net.saltymc.eaa.mixin.PlayerListHudAccessor; - -/** - * By: https://github.com/vladmarica/better-ping-display-fabric/ - */ -public class PlayerListHudUtil { - /** Calls {@link net.minecraft.client.gui.hud.PlayerListHud#renderLatencyIcon}. */ - static void renderLatencyIcon(PlayerListHud hud, MatrixStack stack, int x, int offsetX, int y, PlayerListEntry player) { - ((PlayerListHudAccessor) hud).invokeRenderLatencyIcon(stack, x, offsetX, y, player); - } - - /** Calls {@link net.minecraft.client.gui.hud.PlayerListHud#renderScoreboardObjective} */ - static void renderScoreboardObjective(PlayerListHud hud, MatrixStack stack, ScoreboardObjective obj, int i, String str, int j, int k, PlayerListEntry player) { - ((PlayerListHudAccessor) hud).invokeRenderScoreboardObjective(obj, i, str, j, k, player, stack); - } - - static Text getHeader(PlayerListHud hud) { - return ((PlayerListHudAccessor) hud).getHeader(); - } - - static Text getFooter(PlayerListHud hud) { - return ((PlayerListHudAccessor) hud).getFooter(); - } -} diff --git a/src/main/java/net/saltymc/eaa/mixin/InGameHudMixin.java b/src/main/java/net/saltymc/eaa/mixin/InGameHudMixin.java deleted file mode 100644 index 256ff99..0000000 --- a/src/main/java/net/saltymc/eaa/mixin/InGameHudMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.saltymc.eaa.mixin; - -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.gui.hud.PlayerListHud; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.scoreboard.Scoreboard; -import net.minecraft.scoreboard.ScoreboardObjective; -import net.saltymc.eaa.custom.ping.CustomPlayerListHud; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -/** - * By: https://github.com/vladmarica/better-ping-display-fabric/ - */ -@Mixin(InGameHud.class) -abstract class InGameHudMixin { - @Redirect(method = "render", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/PlayerListHud;render(Lnet/minecraft/client/util/math/MatrixStack;ILnet/minecraft/scoreboard/Scoreboard;Lnet/minecraft/scoreboard/ScoreboardObjective;)V")) - private void render(PlayerListHud hud, MatrixStack stack, int width, Scoreboard scoreboard, ScoreboardObjective objective) { - CustomPlayerListHud.render(hud, stack, width, scoreboard, objective); - } -} diff --git a/src/main/java/net/saltymc/eaa/mixin/PlayerListHudAccessor.java b/src/main/java/net/saltymc/eaa/mixin/PlayerListHudAccessor.java deleted file mode 100644 index 2c578b3..0000000 --- a/src/main/java/net/saltymc/eaa/mixin/PlayerListHudAccessor.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.saltymc.eaa.mixin; - -import net.minecraft.client.gui.hud.PlayerListHud; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.scoreboard.ScoreboardObjective; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import org.spongepowered.asm.mixin.gen.Invoker; - -/** - * By: https://github.com/vladmarica/better-ping-display-fabric/ - */ - -@Mixin(PlayerListHud.class) -public interface PlayerListHudAccessor { - @Invoker - void invokeRenderLatencyIcon(MatrixStack stack, int x, int offsetX, int y, PlayerListEntry player); - - @Invoker - void invokeRenderScoreboardObjective(ScoreboardObjective obj, int i, String str, int j, int k, PlayerListEntry player, MatrixStack stack); - - @Accessor("header") - Text getHeader(); - - @Accessor("footer") - Text getFooter(); -} \ No newline at end of file diff --git a/src/main/java/net/saltymc/eaa/mixin/PlayerListHudInvoker.java b/src/main/java/net/saltymc/eaa/mixin/PlayerListHudInvoker.java new file mode 100644 index 0000000..2f49953 --- /dev/null +++ b/src/main/java/net/saltymc/eaa/mixin/PlayerListHudInvoker.java @@ -0,0 +1,16 @@ +package net.saltymc.eaa.mixin; + +import net.minecraft.client.gui.hud.PlayerListHud; +import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +/** + * By: https://github.com/vladmarica/better-ping-display-fabric/ + */ +@Mixin(PlayerListHud.class) +public interface PlayerListHudInvoker { + @Invoker("renderLatencyIcon") + void invokeRenderLatencyIcon(MatrixStack matrices, int width, int x, int y, PlayerListEntry entry); +} diff --git a/src/main/java/net/saltymc/eaa/mixin/PlayerListHudMixin.java b/src/main/java/net/saltymc/eaa/mixin/PlayerListHudMixin.java new file mode 100644 index 0000000..19d1123 --- /dev/null +++ b/src/main/java/net/saltymc/eaa/mixin/PlayerListHudMixin.java @@ -0,0 +1,50 @@ +package net.saltymc.eaa.mixin; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.hud.PlayerListHud; +import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.client.util.math.MatrixStack; +import net.saltymc.eaa.custom.ping.CustomPlayerListHud; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.*; + +/** + * By: https://github.com/vladmarica/better-ping-display-fabric/ + */ + +@Mixin(PlayerListHud.class) +public abstract class PlayerListHudMixin { + @Unique + @Final + private static final int PLAYER_SLOT_EXTRA_WIDTH = 70; // 45 + + @Shadow + @Final + private MinecraftClient client; + + /** + * Increases the int constant {@code 13} in the {@link PlayerListHud#render} method by + * {@value #PLAYER_SLOT_EXTRA_WIDTH}. This constant is used to define the width of the "slots" in the player list. + * In order to fit the ping text, this needs to be increased. + */ + @ModifyConstant(method = "render", constant = @Constant(intValue = 13)) + private int modifySlotWidthConstant(int original) { + return original + PLAYER_SLOT_EXTRA_WIDTH; + } + + /** + * Redirects the call to {@code renderLatencyIcon} in {@link PlayerListHud#render} to instead call + * {@link CustomPlayerListHud#renderPingDisplay}. + */ + @Redirect(method = "render", + at = @At(value = "INVOKE", target = "net/minecraft/client/gui/hud/PlayerListHud.renderLatencyIcon(Lnet/minecraft/client/util/math/MatrixStack;IIILnet/minecraft/client/network/PlayerListEntry;)V")) + private void redirectRenderLatencyIconCall( + PlayerListHud instance, MatrixStack matrices, int width, int x, int y, @NotNull PlayerListEntry entry) { + CustomPlayerListHud.renderPingDisplay(client, instance, matrices, width, x, y, entry); + } +} + diff --git a/src/main/resources/eaamod.mixins.json b/src/main/resources/eaamod.mixins.json index 2f18b97..22d7bc0 100644 --- a/src/main/resources/eaamod.mixins.json +++ b/src/main/resources/eaamod.mixins.json @@ -2,13 +2,13 @@ "required": true, "minVersion": "0.8", "package": "net.saltymc.eaa.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_8", "mixins": [ ], "client": [ "ExampleMixin", - "InGameHudMixin", - "PlayerListHudAccessor" + "PlayerListHudMixin", + "PlayerListHudInvoker" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 56cd81f..0b90b52 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -28,7 +28,7 @@ ], "depends": { - "fabricloader": ">=0.7.4", + "fabricloader": ">=0.14.6", "fabric": "*", "minecraft": "1.19.x", "java": ">=17"