mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 01:16:46 -04:00
Launcher: server list: option to edit and connect
This commit is contained in:
parent
ff4445d6b9
commit
eb2c1eff63
@ -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);
|
||||
|
@ -81,6 +81,9 @@ public class Version {
|
||||
if (super.equals(obj)) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (hashCode() != obj.hashCode()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class InByteBuffer {
|
||||
public byte readByte() {
|
||||
byte ret;
|
||||
ret = bytes[pos];
|
||||
pos = pos + 1;
|
||||
pos++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
20
src/main/resources/layout/main.fxml
Normal file
20
src/main/resources/layout/main.fxml
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user