Launcher: server list: option to edit and connect

This commit is contained in:
Bixilon 2020-08-26 20:21:06 +02:00
parent ff4445d6b9
commit eb2c1eff63
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
9 changed files with 159 additions and 13 deletions

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft;
import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Version;
import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Versions;
import de.bixilon.minosoft.gui.main.GUITools;
import de.bixilon.minosoft.gui.main.Server;
import de.bixilon.minosoft.gui.main.ServerListCell;
@ -24,6 +26,9 @@ import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.util.Comparator;
import java.util.Map;
public class Launcher extends Application {
@ -33,6 +38,18 @@ public class Launcher extends Application {
@Override
public void start(Stage primaryStage) {
GUITools.versions.add(Versions.getLowestVersionSupported());
for (Map.Entry<Integer, Version> version : Versions.getVersionMap().entrySet()) {
GUITools.versions.add(version.getValue());
}
Comparator<Version> comparator = Comparator.comparingInt(Version::getProtocolVersion);
FXCollections.sort(GUITools.versions, comparator);
GUITools.versions.sort((a, b) -> {
if (a.getProtocolVersion() == -1) {
return -Integer.MAX_VALUE;
}
return (b.getProtocolVersion() - a.getProtocolVersion());
});
ListView<Server> listView = new ListView<>();
listView.setCellFactory((lv) -> ServerListCell.newInstance());
@ -40,7 +57,7 @@ public class Launcher extends Application {
servers.addAll(Minosoft.serverList);
listView.setItems(servers);
Scene scene = new Scene(new BorderPane(listView), 400, 450);
Scene scene = new Scene(new BorderPane(listView), 550, 800);
primaryStage.setScene(scene);
primaryStage.setTitle("Minosoft");
primaryStage.getIcons().add(GUITools.logo);

View File

@ -81,6 +81,9 @@ public class Version {
if (super.equals(obj)) {
return true;
}
if (obj == null) {
return false;
}
if (hashCode() != obj.hashCode()) {
return false;
}

View File

@ -151,6 +151,10 @@ public class Versions {
}
public static Version getLowestVersionSupported() {
return new Version("13w41b", 0, null, null);
return new Version("Automatic", -1, null, null);
}
public static HashBiMap<Integer, Version> getVersionMap() {
return versionMap;
}
}

View File

@ -13,6 +13,9 @@
package de.bixilon.minosoft.gui.main;
import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Version;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.image.Image;
import java.io.ByteArrayInputStream;
@ -20,6 +23,7 @@ import java.util.Base64;
public class GUITools {
public final static Image logo = new Image(GUITools.class.getResourceAsStream("/icons/windowIcon.png"));
public final static ObservableList<Version> versions = FXCollections.observableArrayList();
public static Image getImageFromBase64(String base64) {
if (base64 == null) {

View File

@ -17,19 +17,24 @@ import de.bixilon.minosoft.Minosoft;
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.protocol.network.Connection;
import de.bixilon.minosoft.protocol.protocol.ConnectionReasons;
import de.bixilon.minosoft.util.DNSUtil;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.MenuItem;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.util.Callback;
import javafx.util.Pair;
import java.io.IOException;
import java.net.URL;
@ -57,7 +62,7 @@ public class ServerListCell extends ListCell<Server> implements Initializable {
private Label serverName;
@FXML
private AnchorPane root;
private Server model;
private Server server;
public static ServerListCell newInstance() {
FXMLLoader loader = new FXMLLoader(ServerListCell.class.getResource("/layout/cells/server.fxml"));
@ -87,15 +92,21 @@ public class ServerListCell extends ListCell<Server> implements Initializable {
protected void updateItem(Server server, boolean empty) {
super.updateItem(server, empty);
getRoot().getChildrenUnmodifiable().forEach(c -> c.setVisible(!empty));
if (!empty && server != null && !server.equals(this.model)) {
if (!empty && server != null && !server.equals(this.server)) {
this.server = server;
serverName.setText(server.getName());
Image favicon = server.getFavicon();
if (favicon == null) {
favicon = GUITools.logo;
}
icon.setImage(favicon);
optionsConnect.setOnAction(e -> {
Connection connection = new Connection(Connection.lastConnectionId++, server.getAddress(), new Player(Minosoft.accountList.get(0)));
connection.resolve(ConnectionReasons.CONNECT);
});
optionsEdit.setOnAction(e -> edit());
Connection connection = new Connection(server.getId(), server.getAddress(), new Player(Minosoft.accountList.get(0)));
Connection connection = new Connection(Connection.lastConnectionId++, server.getAddress(), null);
connection.addPingCallback(ping -> Platform.runLater(() -> {
if (ping == null) {
// Offline
@ -105,7 +116,12 @@ public class ServerListCell extends ListCell<Server> implements Initializable {
return;
}
players.setText(String.format("%d/%d", ping.getPlayerOnline(), ping.getMaxPlayers()));
Version serverVersion = Versions.getVersionById(ping.getProtocolNumber());
Version serverVersion;
if (server.getDesiredVersion() == -1) {
serverVersion = Versions.getVersionById(ping.getProtocolNumber());
} else {
serverVersion = Versions.getVersionById(server.getDesiredVersion());
}
if (serverVersion == null) {
version.setText(ping.getServerVersion());
version.setTextFill(Color.RED);
@ -120,13 +136,93 @@ public class ServerListCell extends ListCell<Server> implements Initializable {
icon.setImage(ping.getFavicon());
}
}));
connection.resolve(ConnectionReasons.PING); // resolve dns address and connect
connection.resolve(ConnectionReasons.PING); // resolve dns address and ping
}
this.model = server;
}
@Override
public void updateSelected(boolean selected) {
super.updateSelected(selected);
}
public void edit() {
// Create the custom dialog.
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("Edit server: " + server.getName());
dialog.setHeaderText("Edit the details of the server");
// Set the button types.
ButtonType loginButtonType = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL);
// Create the username and password labels and fields.
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 300, 10, 10));
TextField serverName = new TextField();
serverName.setPromptText("Servername");
serverName.setText(server.getName());
TextField serverAddress = new TextField();
serverAddress.setPromptText("Server address");
serverAddress.setText(server.getAddress());
ComboBox<Version> versionList = new ComboBox<>(GUITools.versions);
versionList.setCellFactory(new Callback<>() {
@Override
public ListCell<Version> call(ListView<Version> p) {
return new ListCell<>() {
@Override
protected void updateItem(Version version, boolean empty) {
super.updateItem(version, empty);
if (!empty && version != null) {
setText(String.format("%s (%d)", version.getVersionName(), version.getProtocolVersion()));
}
}
};
}
});
if (server.getDesiredVersion() == -1) {
versionList.getSelectionModel().select(Versions.getLowestVersionSupported());
} else {
versionList.getSelectionModel().select(Versions.getVersionById(server.getDesiredVersion()));
}
grid.add(new Label("Servername:"), 0, 0);
grid.add(serverName, 1, 0);
grid.add(new Label("Server address:"), 0, 1);
grid.add(serverAddress, 1, 1);
grid.add(new Label("Version:"), 0, 2);
grid.add(versionList, 1, 2);
// Enable/Disable login button depending on whether a username was entered.
Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType);
// Do some validation (using the Java 8 lambda syntax).
serverAddress.textProperty().addListener((observable, oldValue, newValue) -> {
loginButton.setDisable(newValue.trim().isEmpty());
});
dialog.getDialogPane().setContent(grid);
// Request focus on the username field by default.
Platform.runLater(serverName::requestFocus);
// Convert the result to a username-password-pair when the login button is clicked.
dialog.setResultConverter(dialogButton -> {
if (dialogButton == loginButtonType) {
ServerListCell.this.serverName.setText(serverName.getText());
ServerListCell.this.server.setName(serverName.getText());
ServerListCell.this.server.setDesiredVersion(versionList.getSelectionModel().getSelectedItem().getProtocolVersion());
ServerListCell.this.server.setAddress(DNSUtil.correctHostName(serverAddress.getText()));
ServerListCell.this.server.saveToConfig();
Log.info(String.format("Edited and saved server (serverName=%s, serverAddress=%s, version=%d)", server.getName(), server.getAddress(), server.getDesiredVersion()));
}
return null;
});
dialog.showAndWait();
}
}

View File

@ -41,6 +41,7 @@ import org.xbill.DNS.TextParseException;
import java.util.ArrayList;
public class Connection {
public static int lastConnectionId;
final ArrayList<ServerAddress> addresses;
final Network network = new Network(this);
final PacketHandler handler = new PacketHandler(this);
@ -352,4 +353,5 @@ public class Connection {
callback.handle(ping);
}
}
}

View File

@ -54,7 +54,7 @@ public class InByteBuffer {
public byte readByte() {
byte ret;
ret = bytes[pos];
pos = pos + 1;
pos++;
return ret;
}

View File

@ -52,7 +52,7 @@ public final class DNSUtil {
}
public String correctHostName(String hostname) {
public static String correctHostName(String hostname) {
// replaces invalid chars to avoid copy and paste issues (like spaces, ...)
hostname = hostname.replaceAll("\\s", "");
return hostname;

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1">
<MenuBar VBox.vgrow="NEVER">
<Menu mnemonicParsing="false" text="File">
<MenuItem mnemonicParsing="false" text="Preferences…"/>
<SeparatorMenuItem mnemonicParsing="false"/>
<MenuItem mnemonicParsing="false" text="Quit"/>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<MenuItem id="menu_help_about" mnemonicParsing="false" text="About"/>
</Menu>
</MenuBar>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<ListView id="servers" layoutX="14.0" layoutY="14.0" prefHeight="327.0" prefWidth="402.0"/>
</AnchorPane>
</VBox>