From 8b22faf696a825185abc757beb0ec17d89ee4c04 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Tue, 1 Sep 2020 20:29:14 +0200 Subject: [PATCH] Launcher: server info modal --- .../bixilon/minosoft/gui/main/GUITools.java | 7 +- .../bixilon/minosoft/gui/main/MainWindow.java | 9 +- .../minosoft/gui/main/ServerListCell.java | 89 ++++++++++++++++++- .../bixilon/minosoft/ping/ForgeModInfo.java | 16 +++- .../bixilon/minosoft/ping/ServerModItem.java | 37 ++++++++ .../minosoft/protocol/network/Connection.java | 6 +- src/main/resources/layout/cells/server.fxml | 5 +- 7 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/ping/ServerModItem.java diff --git a/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java b/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java index 2f951a7f0..b0ab91101 100644 --- a/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java +++ b/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java @@ -31,6 +31,11 @@ public class GUITools { if (base64 == null) { return null; } - return new Image(new ByteArrayInputStream(Base64.getDecoder().decode(base64))); + try { + return new Image(new ByteArrayInputStream(Base64.getDecoder().decode(base64))); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return null; + } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java b/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java index 21158b02f..2135adf62 100644 --- a/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java +++ b/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java @@ -45,8 +45,8 @@ public class MainWindow implements Initializable { dialog.setTitle("Add server"); dialog.setHeaderText("Enter the details of the server"); - ButtonType loginButtonType = new ButtonType("Add", ButtonBar.ButtonData.OK_DONE); - dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL); + ButtonType addButtonType = new ButtonType("Add", ButtonBar.ButtonData.OK_DONE); + dialog.getDialogPane().getButtonTypes().addAll(addButtonType, ButtonType.CANCEL); GridPane grid = new GridPane(); grid.setHgap(10); @@ -60,6 +60,7 @@ public class MainWindow implements Initializable { serverAddress.setPromptText("Server address"); GUITools.versionList.getSelectionModel().select(Versions.getLowestVersionSupported()); + GUITools.versionList.setEditable(true); grid.add(new Label("Servername:"), 0, 0); grid.add(serverName, 1, 0); @@ -68,7 +69,7 @@ public class MainWindow implements Initializable { grid.add(new Label("Version:"), 0, 2); grid.add(GUITools.versionList, 1, 2); - Node addButton = dialog.getDialogPane().lookupButton(loginButtonType); + Node addButton = dialog.getDialogPane().lookupButton(addButtonType); serverAddress.textProperty().addListener((observable, oldValue, newValue) -> addButton.setDisable(newValue.trim().isEmpty())); addButton.setDisable(true); @@ -78,7 +79,7 @@ public class MainWindow implements Initializable { Platform.runLater(serverName::requestFocus); dialog.setResultConverter(dialogButton -> { - if (dialogButton == loginButtonType) { + if (dialogButton == addButtonType) { Server server = new Server(Server.getNextServerId(), serverName.getText(), DNSUtil.correctHostName(serverAddress.getText()), GUITools.versionList.getSelectionModel().getSelectedItem().getProtocolVersion()); Minosoft.serverList.add(server); server.saveToConfig(); diff --git a/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java b/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java index 0837f822e..48abde4b1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java +++ b/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java @@ -18,6 +18,8 @@ import de.bixilon.minosoft.game.datatypes.Player; import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Version; import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Versions; import de.bixilon.minosoft.logging.Log; +import de.bixilon.minosoft.ping.ForgeModInfo; +import de.bixilon.minosoft.ping.ServerListPing; import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.util.DNSUtil; import javafx.application.Platform; @@ -175,8 +177,8 @@ public class ServerListCell extends ListCell implements Initializable { dialog.setTitle("Edit server: " + server.getName()); dialog.setHeaderText("Edit the details of the server"); - ButtonType loginButtonType = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE); - dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL); + ButtonType saveButtonType = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE); + dialog.getDialogPane().getButtonTypes().addAll(saveButtonType, ButtonType.CANCEL); GridPane grid = new GridPane(); grid.setHgap(10); @@ -196,6 +198,7 @@ public class ServerListCell extends ListCell implements Initializable { } else { GUITools.versionList.getSelectionModel().select(Versions.getVersionById(server.getDesiredVersion())); } + GUITools.versionList.setEditable(true); grid.add(new Label("Servername:"), 0, 0); grid.add(serverName, 1, 0); @@ -204,7 +207,7 @@ public class ServerListCell extends ListCell implements Initializable { grid.add(new Label("Version:"), 0, 2); grid.add(GUITools.versionList, 1, 2); - Node saveButton = dialog.getDialogPane().lookupButton(loginButtonType); + Node saveButton = dialog.getDialogPane().lookupButton(saveButtonType); serverAddress.textProperty().addListener((observable, oldValue, newValue) -> saveButton.setDisable(newValue.trim().isEmpty())); @@ -213,7 +216,7 @@ public class ServerListCell extends ListCell implements Initializable { Platform.runLater(serverName::requestFocus); dialog.setResultConverter(dialogButton -> { - if (dialogButton == loginButtonType) { + if (dialogButton == saveButtonType) { serverName.setText(serverName.getText()); server.setName(serverName.getText()); server.setDesiredVersion(GUITools.versionList.getSelectionModel().getSelectedItem().getProtocolVersion()); @@ -288,4 +291,82 @@ public class ServerListCell extends ListCell implements Initializable { } } } + + public void showInfo() { + + Dialog> dialog = new Dialog<>(); + dialog.setTitle("View server info: " + server.getName()); + + ButtonType loginButtonType = ButtonType.CLOSE; + dialog.getDialogPane().getButtonTypes().add(loginButtonType); + + GridPane grid = new GridPane(); + grid.setHgap(10); + grid.setVgap(10); + grid.setPadding(new Insets(20, 300, 10, 10)); + + Label serverNameLabel = new Label(server.getName()); + Label serverAddressLabel = new Label(server.getAddress()); + Label forcedVersionLabel = new Label(); + + + if (server.getDesiredVersion() == -1) { + forcedVersionLabel.setText(Versions.getLowestVersionSupported().getVersionName()); + } else { + forcedVersionLabel.setText(Versions.getVersionById(server.getDesiredVersion()).getVersionName()); + } + + int column = 0; + grid.add(new Label("Servername:"), 0, ++column); + grid.add(serverNameLabel, 1, column); + grid.add(new Label("Server address:"), 0, ++column); + grid.add(serverAddressLabel, 1, column); + grid.add(new Label("Forced version:"), 0, ++column); + grid.add(forcedVersionLabel, 1, column); + + if (server.getLastPing() != null && server.getLastPing().getLastPing() != null) { + ServerListPing lastPing = server.getLastPing().getLastPing(); + Version serverVersion = Versions.getVersionById(lastPing.getProtocolId()); + String serverVersionString; + if (serverVersion == null) { + serverVersionString = String.format("Unknown (%d)", lastPing.getProtocolId()); + } else { + serverVersionString = serverVersion.getVersionName(); + } + Label realServerAddressLabel = new Label(server.getLastPing().getAddress().toString()); + Label serverVersionLabel = new Label(serverVersionString); + Label serverBrandLabel = new Label(lastPing.getServerBrand()); + Label playersOnlineMaxLabel = new Label(String.format("%d/%d", lastPing.getPlayerOnline(), lastPing.getMaxPlayers())); + Label motdLabel = new Label(lastPing.getMotd().getRawMessage()); + Label moddedBrandLabel = new Label(lastPing.getServerModInfo().getBrand()); + + + grid.add(new Label("Real server address:"), 0, ++column); + grid.add(realServerAddressLabel, 1, column); + grid.add(new Label("Server version:"), 0, ++column); + grid.add(serverVersionLabel, 1, column); + grid.add(new Label("Server brand:"), 0, ++column); + grid.add(serverBrandLabel, 1, column); + grid.add(new Label("Players online:"), 0, ++column); + grid.add(playersOnlineMaxLabel, 1, column); + grid.add(new Label("MotD:"), 0, ++column); + grid.add(motdLabel, 1, column); + grid.add(new Label("Modded brand:"), 0, ++column); + grid.add(moddedBrandLabel, 1, column); + + if (lastPing.getServerModInfo() instanceof ForgeModInfo) { + ForgeModInfo modInfo = (ForgeModInfo) lastPing.getServerModInfo(); + Label moddedModsLabel = new Label(modInfo.getModList().toString()); + moddedModsLabel.setWrapText(true); + + grid.add(new Label("Mod list:"), 0, ++column); + grid.add(moddedModsLabel, 1, column); + } + } + + + dialog.getDialogPane().setContent(grid); + + dialog.showAndWait(); + } } \ No newline at end of file diff --git a/src/main/java/de/bixilon/minosoft/ping/ForgeModInfo.java b/src/main/java/de/bixilon/minosoft/ping/ForgeModInfo.java index 9a043c9b6..bc008324f 100644 --- a/src/main/java/de/bixilon/minosoft/ping/ForgeModInfo.java +++ b/src/main/java/de/bixilon/minosoft/ping/ForgeModInfo.java @@ -13,15 +13,25 @@ package de.bixilon.minosoft.ping; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import java.util.ArrayList; + public class ForgeModInfo implements ServerModInfo { final JsonObject modInfo; String info; + ArrayList modList = new ArrayList<>(); public ForgeModInfo(JsonObject modInfo) { this.modInfo = modInfo; - info = String.format("Modded server, %d mods present", modInfo.getAsJsonArray("modList").size()); + JsonArray mods = modInfo.getAsJsonArray("modList"); + info = String.format("Modded server, %d mods present", mods.size()); + for (JsonElement mod : mods) { + JsonObject mod2 = (JsonObject) mod; + modList.add(new ServerModItem(mod2.get("modid").getAsString(), mod2.get("version").getAsString())); + } } @Override @@ -34,6 +44,10 @@ public class ForgeModInfo implements ServerModInfo { return info; } + public ArrayList getModList() { + return modList; + } + @Override public ServerModTypes getType() { return ServerModTypes.FORGE; diff --git a/src/main/java/de/bixilon/minosoft/ping/ServerModItem.java b/src/main/java/de/bixilon/minosoft/ping/ServerModItem.java new file mode 100644 index 000000000..9b5aae74b --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/ping/ServerModItem.java @@ -0,0 +1,37 @@ +/* + * Codename Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.ping; + +public class ServerModItem { + final String modId; + final String modVersion; + + public ServerModItem(String modId, String modVersion) { + this.modId = modId; + this.modVersion = modVersion; + } + + public String getModId() { + return modId; + } + + public String getModVersion() { + return modVersion; + } + + @Override + public String toString() { + return String.format("%s (%s)", modId, modVersion); + } +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java index 2b8eff035..7403f725b 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java +++ b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java @@ -15,7 +15,6 @@ package de.bixilon.minosoft.protocol.network; import de.bixilon.minosoft.Minosoft; import de.bixilon.minosoft.PingCallback; -import de.bixilon.minosoft.ServerListPing; import de.bixilon.minosoft.config.GameConfiguration; import de.bixilon.minosoft.game.datatypes.Player; import de.bixilon.minosoft.game.datatypes.VelocityHandler; @@ -24,6 +23,7 @@ import de.bixilon.minosoft.game.datatypes.objectLoader.recipes.Recipes; import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Version; import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Versions; import de.bixilon.minosoft.logging.Log; +import de.bixilon.minosoft.ping.ServerListPing; import de.bixilon.minosoft.protocol.modding.channels.DefaultPluginChannels; import de.bixilon.minosoft.protocol.modding.channels.PluginChannelHandler; import de.bixilon.minosoft.protocol.packets.ClientboundPacket; @@ -376,4 +376,8 @@ public class Connection { public Exception getLastConnectionException() { return network.lastException; } + + public ServerListPing getLastPing() { + return lastPing; + } } diff --git a/src/main/resources/layout/cells/server.fxml b/src/main/resources/layout/cells/server.fxml index 37ecebd5b..8fb383a61 100644 --- a/src/main/resources/layout/cells/server.fxml +++ b/src/main/resources/layout/cells/server.fxml @@ -27,10 +27,11 @@ - + + - +