package net.minecraft.client.gui.screens.multiplayer; import com.mojang.logging.LogUtils; import java.util.List; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.layouts.EqualSpacingLayout; import net.minecraft.client.gui.layouts.FrameLayout; import net.minecraft.client.gui.layouts.LinearLayout; import net.minecraft.client.gui.layouts.SpacerElement; import net.minecraft.client.gui.layouts.EqualSpacingLayout.Orientation; import net.minecraft.client.gui.navigation.CommonInputs; import net.minecraft.client.gui.screens.ConfirmScreen; import net.minecraft.client.gui.screens.ConnectScreen; import net.minecraft.client.gui.screens.DirectJoinServerScreen; import net.minecraft.client.gui.screens.EditServerScreen; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.Entry; import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.LANHeader; import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.NetworkServerEntry; import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList.OnlineServerEntry; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.multiplayer.ServerList; import net.minecraft.client.multiplayer.ServerStatusPinger; import net.minecraft.client.multiplayer.resolver.ServerAddress; import net.minecraft.client.resources.language.I18n; import net.minecraft.client.server.LanServer; import net.minecraft.client.server.LanServerDetection.LanServerDetector; import net.minecraft.client.server.LanServerDetection.LanServerList; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @Environment(EnvType.CLIENT) public class JoinMultiplayerScreen extends Screen { public static final int BUTTON_ROW_WIDTH = 308; public static final int TOP_ROW_BUTTON_WIDTH = 100; public static final int LOWER_ROW_BUTTON_WIDTH = 74; public static final int FOOTER_HEIGHT = 64; private static final Logger LOGGER = LogUtils.getLogger(); private final ServerStatusPinger pinger = new ServerStatusPinger(); private final Screen lastScreen; protected ServerSelectionList serverSelectionList; private ServerList servers; private Button editButton; private Button selectButton; private Button deleteButton; private ServerData editingServer; private LanServerList lanServerList; @Nullable private LanServerDetector lanServerDetector; private boolean initedOnce; public JoinMultiplayerScreen(Screen lastScreen) { super(Component.translatable("multiplayer.title")); this.lastScreen = lastScreen; } @Override protected void init() { if (this.initedOnce) { this.serverSelectionList.setRectangle(this.width, this.height - 64 - 32, 0, 32); } else { this.initedOnce = true; this.servers = new ServerList(this.minecraft); this.servers.load(); this.lanServerList = new LanServerList(); try { this.lanServerDetector = new LanServerDetector(this.lanServerList); this.lanServerDetector.start(); } catch (Exception var8) { LOGGER.warn("Unable to start LAN server detection: {}", var8.getMessage()); } this.serverSelectionList = new ServerSelectionList(this, this.minecraft, this.width, this.height - 64 - 32, 32, 36); this.serverSelectionList.updateOnlineServers(this.servers); } this.addRenderableWidget(this.serverSelectionList); this.selectButton = this.addRenderableWidget( Button.builder(Component.translatable("selectServer.select"), buttonx -> this.joinSelectedServer()).width(100).build() ); Button button = this.addRenderableWidget(Button.builder(Component.translatable("selectServer.direct"), buttonx -> { this.editingServer = new ServerData(I18n.get("selectServer.defaultName"), "", ServerData.Type.OTHER); this.minecraft.setScreen(new DirectJoinServerScreen(this, this::directJoinCallback, this.editingServer)); }).width(100).build()); Button button2 = this.addRenderableWidget(Button.builder(Component.translatable("selectServer.add"), buttonx -> { this.editingServer = new ServerData(I18n.get("selectServer.defaultName"), "", ServerData.Type.OTHER); this.minecraft.setScreen(new EditServerScreen(this, this::addServerCallback, this.editingServer)); }).width(100).build()); this.editButton = this.addRenderableWidget(Button.builder(Component.translatable("selectServer.edit"), buttonx -> { Entry entry = this.serverSelectionList.getSelected(); if (entry instanceof OnlineServerEntry) { ServerData serverData = ((OnlineServerEntry)entry).getServerData(); this.editingServer = new ServerData(serverData.name, serverData.ip, ServerData.Type.OTHER); this.editingServer.copyFrom(serverData); this.minecraft.setScreen(new EditServerScreen(this, this::editServerCallback, this.editingServer)); } }).width(74).build()); this.deleteButton = this.addRenderableWidget(Button.builder(Component.translatable("selectServer.delete"), buttonx -> { Entry entry = this.serverSelectionList.getSelected(); if (entry instanceof OnlineServerEntry) { String string = ((OnlineServerEntry)entry).getServerData().name; if (string != null) { Component component = Component.translatable("selectServer.deleteQuestion"); Component component2 = Component.translatable("selectServer.deleteWarning", string); Component component3 = Component.translatable("selectServer.deleteButton"); Component component4 = CommonComponents.GUI_CANCEL; this.minecraft.setScreen(new ConfirmScreen(this::deleteCallback, component, component2, component3, component4)); } } }).width(74).build()); Button button3 = this.addRenderableWidget( Button.builder(Component.translatable("selectServer.refresh"), buttonx -> this.refreshServerList()).width(74).build() ); Button button4 = this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, buttonx -> this.onClose()).width(74).build()); LinearLayout linearLayout = LinearLayout.vertical(); EqualSpacingLayout equalSpacingLayout = linearLayout.addChild(new EqualSpacingLayout(308, 20, Orientation.HORIZONTAL)); equalSpacingLayout.addChild(this.selectButton); equalSpacingLayout.addChild(button); equalSpacingLayout.addChild(button2); linearLayout.addChild(SpacerElement.height(4)); EqualSpacingLayout equalSpacingLayout2 = linearLayout.addChild(new EqualSpacingLayout(308, 20, Orientation.HORIZONTAL)); equalSpacingLayout2.addChild(this.editButton); equalSpacingLayout2.addChild(this.deleteButton); equalSpacingLayout2.addChild(button3); equalSpacingLayout2.addChild(button4); linearLayout.arrangeElements(); FrameLayout.centerInRectangle(linearLayout, 0, this.height - 64, this.width, 64); this.onSelectedChange(); } @Override public void onClose() { this.minecraft.setScreen(this.lastScreen); } @Override public void tick() { super.tick(); List list = this.lanServerList.takeDirtyServers(); if (list != null) { this.serverSelectionList.updateNetworkServers(list); } this.pinger.tick(); } @Override public void removed() { if (this.lanServerDetector != null) { this.lanServerDetector.interrupt(); this.lanServerDetector = null; } this.pinger.removeAll(); this.serverSelectionList.removed(); } private void refreshServerList() { this.minecraft.setScreen(new JoinMultiplayerScreen(this.lastScreen)); } private void deleteCallback(boolean confirmed) { Entry entry = this.serverSelectionList.getSelected(); if (confirmed && entry instanceof OnlineServerEntry) { this.servers.remove(((OnlineServerEntry)entry).getServerData()); this.servers.save(); this.serverSelectionList.setSelected(null); this.serverSelectionList.updateOnlineServers(this.servers); } this.minecraft.setScreen(this); } private void editServerCallback(boolean confirmed) { Entry entry = this.serverSelectionList.getSelected(); if (confirmed && entry instanceof OnlineServerEntry) { ServerData serverData = ((OnlineServerEntry)entry).getServerData(); serverData.name = this.editingServer.name; serverData.ip = this.editingServer.ip; serverData.copyFrom(this.editingServer); this.servers.save(); this.serverSelectionList.updateOnlineServers(this.servers); } this.minecraft.setScreen(this); } private void addServerCallback(boolean confirmed) { if (confirmed) { ServerData serverData = this.servers.unhide(this.editingServer.ip); if (serverData != null) { serverData.copyNameIconFrom(this.editingServer); this.servers.save(); } else { this.servers.add(this.editingServer, false); this.servers.save(); } this.serverSelectionList.setSelected(null); this.serverSelectionList.updateOnlineServers(this.servers); } this.minecraft.setScreen(this); } private void directJoinCallback(boolean confirmed) { if (confirmed) { ServerData serverData = this.servers.get(this.editingServer.ip); if (serverData == null) { this.servers.add(this.editingServer, true); this.servers.save(); this.join(this.editingServer); } else { this.join(serverData); } } else { this.minecraft.setScreen(this); } } @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (super.keyPressed(keyCode, scanCode, modifiers)) { return true; } else if (keyCode == 294) { this.refreshServerList(); return true; } else if (this.serverSelectionList.getSelected() != null) { if (CommonInputs.selected(keyCode)) { this.joinSelectedServer(); return true; } else { return this.serverSelectionList.keyPressed(keyCode, scanCode, modifiers); } } else { return false; } } @Override public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { super.render(guiGraphics, mouseX, mouseY, partialTick); guiGraphics.drawCenteredString(this.font, this.title, this.width / 2, 20, 16777215); } public void joinSelectedServer() { Entry entry = this.serverSelectionList.getSelected(); if (entry instanceof OnlineServerEntry) { this.join(((OnlineServerEntry)entry).getServerData()); } else if (entry instanceof NetworkServerEntry) { LanServer lanServer = ((NetworkServerEntry)entry).getServerData(); this.join(new ServerData(lanServer.getMotd(), lanServer.getAddress(), ServerData.Type.LAN)); } } private void join(ServerData server) { ConnectScreen.startConnecting(this, this.minecraft, ServerAddress.parseString(server.ip), server, false, null); } public void setSelected(Entry selected) { this.serverSelectionList.setSelected(selected); this.onSelectedChange(); } protected void onSelectedChange() { this.selectButton.active = false; this.editButton.active = false; this.deleteButton.active = false; Entry entry = this.serverSelectionList.getSelected(); if (entry != null && !(entry instanceof LANHeader)) { this.selectButton.active = true; if (entry instanceof OnlineServerEntry) { this.editButton.active = true; this.deleteButton.active = true; } } } public ServerStatusPinger getPinger() { return this.pinger; } public ServerList getServers() { return this.servers; } }