package dev.encode42.myserver.mixin; import dev.encode42.myserver.MyServer; import dev.encode42.myserver.config.MyServerConfig; import eu.midnightdust.lib.config.MidnightConfig; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.SpriteIconButton; import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.ConnectScreen; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.multiplayer.resolver.ServerAddress; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(TitleScreen.class) public class TitleScreenMixin extends Screen { @Unique private static final int JOIN_BUTTON_WIDTH = 180; @Unique private static final int JOIN_BUTTON_PADDING = 4; protected TitleScreenMixin(Minecraft minecraft, Font font, Component title) { super(minecraft, font, title); } @Inject( method = "createNormalMenuOptions", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/TitleScreen;addRenderableWidget(Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener;", ordinal = 2 ) ) private void addJoinButton(int topPos, int spacing, CallbackInfoReturnable callbackInfoReturnable) { ServerData data = MyServerConfig.getServerData(); boolean hasAddress = !data.ip.isBlank(); Button joinServerButton = Button.builder( Component.translatable("selectServer.select"), (_) -> { Screen joinMultiplayerScreen = new JoinMultiplayerScreen(this); if (!hasAddress) { this.minecraft.gui.setScreen(MidnightConfig.getScreen(this, MyServer.MOD_ID)); return; } ConnectScreen.startConnecting(joinMultiplayerScreen, this.minecraft, ServerAddress.parseString(data.ip), data, false, null); } ) .width(TitleScreenMixin.JOIN_BUTTON_WIDTH - TitleScreenMixin.JOIN_BUTTON_PADDING) .pos(this.width / 2 - 100, topPos) .build(); if (!hasAddress) { Tooltip tooltip = Tooltip.create(Component.translatable("title.multiplayer.disabled.not-configured")); joinServerButton.setTooltip(tooltip); } this.addRenderableWidget(joinServerButton); } @ModifyArg( method = "createNormalMenuOptions", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/TitleScreen;addRenderableWidget(Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener;", ordinal = 2 ), index = 0 ) private GuiEventListener wrapMultiplayerButton(GuiEventListener guiEventListener) { if (guiEventListener instanceof Button button) { Button.OnPress onPress = ((ButtonAccessor) button).myserver$getOnPress(); SpriteIconButton spriteIconButton = SpriteIconButton.builder(button.getMessage(), onPress, true) .sprite(Identifier.withDefaultNamespace("icon/search"), 15, 15) .width(button.getHeight()) .build(); spriteIconButton.setPosition(button.getX() + TitleScreenMixin.JOIN_BUTTON_WIDTH, button.getY()); spriteIconButton.active = button.isActive(); return spriteIconButton; } return guiEventListener; } }