removed bodged server connection

This commit is contained in:
Johannes Schmelz 2024-11-24 18:03:22 +01:00
parent 437114704a
commit c7bd7d18b7
6 changed files with 235 additions and 381 deletions

View File

@ -27,7 +27,8 @@ import pp.monopoly.game.client.ServerConnection;
import pp.monopoly.model.fields.BoardManager;
import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.InfoTextEvent;
import pp.monopoly.server.MonopolyServer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MonopolyApp extends SimpleApplication implements MonopolyClient, GameEventListener {
@ -37,13 +38,12 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
private final MonopolyAppConfig config;
private final ActionListener escapeListener = (name, isPressed, tpf) -> handleEscape(isPressed);
private final DialogManager dialogManager = new DialogManager(this);
private final ExecutorService executor = Executors.newCachedThreadPool();
private ExecutorService executor;
private final Draw draw;
private SettingsMenu settingsMenu;
private TestWorld testWorld;
private boolean isSettingsMenuOpen = false;
private boolean inputBlocked = false;
private MonopolyServer monopolyServer;
private NetworkSupport networkSupport;
private BoardManager boardManager = new BoardManager();
@ -72,14 +72,35 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
public MonopolyApp() {
this.draw = new Draw(assetManager);
config = new MonopolyAppConfig();
networkSupport = new NetworkSupport(this); // Initialize NetworkSupport
serverConnection = networkSupport;
serverConnection = new NetworkSupport(this); // Initialize NetworkSupport
logic = new ClientGameLogic(serverConnection);
logic.addListener(this);
setShowSettings(config.getShowSettings());
setSettings(makeSettings());
}
/**
* Returns the executor service used for handling multithreaded tasks.
*
* @return The {@link ExecutorService} instance.
*/
public ExecutorService getExecutor() {
if (executor == null)
executor = Executors.newCachedThreadPool();
return executor;
}
/**
* Stops the application, shutting down the executor service and halting execution.
*
* @param waitFor If true, waits for the application to stop before returning.
*/
@Override
public void stop(boolean waitFor) {
if (executor != null) executor.shutdownNow();
super.stop(waitFor);
}
@Override
public MonopolyAppConfig getConfig() {
return config;
@ -202,13 +223,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
setInfoText(event.key());
}
@Override
public void stop(boolean waitFor) {
if (executor != null) executor.shutdownNow();
serverConnection.disconnect();
super.stop(waitFor);
}
public DialogManager getDialogManager() {
return dialogManager;
}
@ -217,10 +231,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
return draw;
}
public ExecutorService getExecutor() {
return executor;
}
public void closeApp() {
stop();
}
@ -267,23 +277,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
StartMenu.createStartMenu(this); // Zeige das Startmenü erneut
}
/**
* Startet den Server in einem neuen Thread.
*/
public void startServer() {
new Thread(() -> {
try {
MonopolyServer.main(new String[0]); // Startet den MonopolyServer
} catch (Exception e) {
errorDialog("Fehler: Server konnte nicht gestartet werden.");
}
}).start();
}
public MonopolyServer getMonopolyServer() {
return monopolyServer;
}
public ServerConnection getServerConnection() {
return serverConnection;
}

View File

@ -1,146 +0,0 @@
package pp.monopoly.client;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.TextField;
import pp.dialog.Dialog;
import pp.dialog.DialogBuilder;
import pp.dialog.SimpleDialog;
/**
* Represents a dialog for setting up a network connection in the Monopoly game.
* Allows users to specify the host and port for connecting to a game server.
*/
class NetworkDialog extends SimpleDialog {
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
private static final String LOCALHOST = "localhost";
private static final String DEFAULT_PORT = "42069";
private final NetworkSupport network;
private final TextField host = new TextField(LOCALHOST);
private final TextField port = new TextField(DEFAULT_PORT);
private String hostname;
private int portNumber;
private Future<Object> connectionFuture;
private Dialog progressDialog;
/**
* Constructs a new NetworkDialog.
*
* @param network The NetworkSupport instance to be used for network operations.
*/
NetworkDialog(NetworkSupport network) {
super(network.getApp().getDialogManager());
this.network = network;
initializeDialog();
}
/**
* Initializes the dialog with input fields and connection buttons.
*/
private void initializeDialog() {
final MonopolyApp app = network.getApp();
Container inputContainer = new Container();
// Titel und Eingabefelder für Host und Port
inputContainer.addChild(new Label("Server-Adresse"));
inputContainer.addChild(host);
inputContainer.addChild(new Label("Port"));
inputContainer.addChild(port);
Button connectButton = inputContainer.addChild(new Button("Verbinden"));
connectButton.addClickCommands(source -> connect());
Button cancelButton = inputContainer.addChild(new Button("Abbrechen"));
cancelButton.addClickCommands(source -> app.closeApp());
app.getGuiNode().attachChild(inputContainer);
}
/**
* Initiates the connection attempt based on the entered host and port.
*/
private void connect() {
LOGGER.log(Level.INFO, "Connecting to host={0}, port={1}", host, port);
try {
hostname = host.getText().trim().isEmpty() ? LOCALHOST : host.getText();
portNumber = Integer.parseInt(port.getText());
openProgressDialog();
connectionFuture = network.getApp().getExecutor().submit(this::initNetwork);
} catch (NumberFormatException e) {
network.getApp().errorDialog("Port muss eine Zahl sein.");
}
}
/**
* Opens a progress dialog while connecting.
*/
private void openProgressDialog() {
progressDialog = DialogBuilder.simple(network.getApp().getDialogManager())
.setText("Verbinde zum Server...")
.build();
progressDialog.open();
}
/**
* Attempts to initialize the network connection.
*
* @throws RuntimeException If an error occurs when creating the client.
*/
private Object initNetwork() {
try {
network.initNetwork(hostname, portNumber);
return null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Updates the connection status and handles completion or failure.
*/
@Override
public void update(float delta) {
if (connectionFuture != null && connectionFuture.isDone()) {
try {
connectionFuture.get();
onSuccess();
} catch (ExecutionException e) {
onFailure(e.getCause());
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "Connection interrupted.", e);
Thread.currentThread().interrupt();
}
}
}
/**
* Handles a successful connection to the game server.
*/
private void onSuccess() {
connectionFuture = null;
progressDialog.close();
this.close();
network.getApp().setInfoText("Warte auf einen Gegner...");
}
/**
* Handles a failed connection attempt.
*
* @param e The cause of the failure.
*/
private void onFailure(Throwable e) {
connectionFuture = null;
progressDialog.close();
network.getApp().errorDialog("Verbindung zum Server fehlgeschlagen.");
network.getApp().setInfoText(e.getLocalizedMessage());
}
}

View File

@ -1,8 +1,11 @@
package pp.monopoly.client;
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
package pp.monopoly.client;
import com.jme3.network.Client;
import com.jme3.network.ClientStateListener;
@ -10,12 +13,19 @@ import com.jme3.network.Message;
import com.jme3.network.MessageListener;
import com.jme3.network.Network;
import pp.monopoly.client.gui.CreateGameMenu;
import pp.monopoly.game.client.ServerConnection;
import pp.monopoly.message.client.ClientMessage;
import pp.monopoly.message.server.ServerMessage;
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import static pp.monopoly.Resources.lookup;
/**
* Manages the network connection for the Monopoly application.
* Manages the network connection for the Battleship application.
* Handles connecting to and disconnecting from the server, and sending messages.
*/
public class NetworkSupport implements MessageListener<Client>, ClientStateListener, ServerConnection {
@ -24,28 +34,32 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
private Client client;
/**
* Constructs a NetworkSupport instance for the Monopoly application.
* Constructs a NetworkSupport instance for the given Battleship application.
*
* @param app The Monopoly application instance.
* @param app The Battleship application instance.
*/
public NetworkSupport(MonopolyApp app) {
this.app = app;
}
/**
* Returns the Monopoly application instance.
*
* @return Monopoly application instance
* Return the client connections Id
* @return the client id
*/
MonopolyApp getApp() {
return app;
}
public int getId() {
if (client == null) return 0;
return client.getId();
}
/**
* Returns the Battleship application instance.
*
* @return Battleship application instance
*/
public MonopolyApp getApp() {
return app;
}
/**
* Checks if there is a connection to the game server.
*
@ -62,9 +76,8 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
*/
@Override
public void connect() {
if (client == null) {
new NetworkDialog(this).open();
}
if (client == null)
new CreateGameMenu(this).open();
}
/**
@ -75,7 +88,7 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
if (client == null) return;
client.close();
client = null;
LOGGER.log(Level.INFO, "Client connection closed.");
LOGGER.log(Level.INFO, "client closed"); //NON-NLS
}
/**
@ -86,9 +99,8 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
* @throws IOException If an I/O error occurs when creating the client.
*/
public void initNetwork(String host, int port) throws IOException {
if (client != null) {
throw new IllegalStateException("Already connected to the game server.");
}
if (client != null)
throw new IllegalStateException("trying to join a game again");
client = Network.connectToServer(host, port);
client.start();
client.addMessageListener(this);
@ -103,11 +115,10 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
*/
@Override
public void messageReceived(Client client, Message message) {
LOGGER.log(Level.INFO, "Message received from server: {0}", message);
if (message instanceof ServerMessage serverMessage) {
LOGGER.log(Level.INFO, "message received from server: {0}", message); //NON-NLS
if (message instanceof ServerMessage serverMessage)
app.enqueue(() -> serverMessage.accept(app.getGameLogic()));
}
}
/**
* Called when the client has successfully connected to the server.
@ -116,7 +127,7 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
*/
@Override
public void clientConnected(Client client) {
LOGGER.log(Level.INFO, "Successfully connected to server: {0}", client);
LOGGER.log(Level.INFO, "Client connected: {0}", client); //NON-NLS
}
/**
@ -127,9 +138,13 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
*/
@Override
public void clientDisconnected(Client client, DisconnectInfo disconnectInfo) {
LOGGER.log(Level.INFO, "Disconnected from server: {0}", disconnectInfo);
LOGGER.log(Level.INFO, "Client {0} disconnected: {1}", client, disconnectInfo); //NON-NLS
if (this.client != client)
throw new IllegalArgumentException("parameter value must be client");
LOGGER.log(Level.INFO, "client still connected: {0}", client.isConnected()); //NON-NLS
this.client = null;
app.enqueue(() -> app.setInfoText("Verbindung zum Server verloren."));
disconnect();
app.enqueue(() -> app.setInfoText(lookup("lost.connection.to.server")));
}
/**
@ -139,47 +154,10 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
*/
@Override
public void send(ClientMessage message) {
LOGGER.log(Level.INFO, "Sending message to server: {0}", message);
if (client == null) {
app.errorDialog("Verbindung zum Server verloren.");
} else {
LOGGER.log(Level.INFO, "sending {0}", message); //NON-NLS
if (client == null)
app.errorDialog(lookup("lost.connection.to.server"));
else
client.send(message);
}
}
public void startServerAndJoin() {
new Thread(() -> {
// Server starten
app.startServer();
// Warten, bis der Server tatsächlich betriebsbereit ist
int retries = 5;
while (retries > 0) {
try {
initNetwork("localhost", app.getConfig().getPort());
app.enqueue(() -> app.setInfoText("Erfolgreich verbunden!"));
return; // Verbindung erfolgreich
} catch (IOException e) {
retries--;
try {
Thread.sleep(1000); // Eine Sekunde warten und erneut versuchen
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break; // Abbrechen, wenn der Thread unterbrochen wird
}
}
}
// Wenn alle Versuche fehlschlagen
app.enqueue(() -> app.errorDialog("Fehler: Verbindung zum Server fehlgeschlagen."));
}).start();
}
public void connectToServer(String host, int port) {
try {
initNetwork(host, port); // Verbindung initialisieren
app.setInfoText("Erfolgreich mit Server verbunden!");
} catch (IOException e) {
app.errorDialog("Fehler: Verbindung zum Server fehlgeschlagen.");
}
}
}

View File

@ -161,7 +161,7 @@ public class StartMenu extends Dialog {
*/
private static void startGame(MonopolyApp app) {
app.getGuiNode().detachAllChildren();
new CreateGameMenu(app);
app.getServerConnection().connect();
}
/**

View File

@ -1,151 +1,180 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
package pp.monopoly.client.gui;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture;
import com.simsilica.lemur.Axis;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.style.ElementId;
import static pp.monopoly.Resources.lookup;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.StartMenu;
import pp.monopoly.client.NetworkSupport;
import pp.monopoly.server.MonopolyServer;
import pp.dialog.Dialog;
import pp.dialog.DialogBuilder;
import pp.dialog.SimpleDialog;
/**
* CreateGameMenu class represents the menu for creating a new game.
* Represents a dialog for setting up a network connection in the Battleship game.
* Allows users to specify the host and port for connecting to a game server.
*/
public class CreateGameMenu {
public class CreateGameMenu extends SimpleDialog {
private static final Logger LOGGER = System.getLogger(CreateGameMenu.class.getName());
private static final String LOCALHOST = "localhost"; //NON-NLS
private static final String DEFAULT_PORT = "42069"; //NON-NLS
private final NetworkSupport network;
private final TextField host = new TextField(LOCALHOST);
private final TextField port = new TextField(DEFAULT_PORT);
// private final Button serverButton = new Button(lookup("client.server-star"));
private final Button serverButton = new Button(lookup("client.server-start"));
private String hostname;
private int portNumber;
private Future<Object> connectionFuture;
private Dialog progressDialog;
private final MonopolyApp app;
private final Container menuContainer;
private Geometry background;
private Label serverStatusLabel;
/**
* Constructs a new CreateGameMenu.
*
* @param network The NetworkSupport instance to be used for network operations.
*/
public CreateGameMenu(NetworkSupport network) {
super(network.getApp().getDialogManager());
this.network = network;
host.setSingleLine(true);
host.setPreferredWidth(400f);
port.setSingleLine(true);
public CreateGameMenu(MonopolyApp app) {
this.app = app;
final MonopolyApp app = network.getApp();
final Container input = new Container(new SpringGridLayout());
input.addChild(new Label(lookup("host.name") + ": "));
input.addChild(host, 1);
input.addChild(new Label(lookup("port.number") + ": "));
input.addChild(port, 1);
// Hintergrundbild laden und hinzufügen
addBackgroundImage();
DialogBuilder.simple(app.getDialogManager())
.setTitle(lookup("server.dialog"))
.setExtension(d -> d.addChild(input))
.setOkButton(lookup("button.connect"), d -> connect())
.setNoButton(lookup("button.cancel"), app::closeApp)
.setOkClose(false)
.setNoClose(false)
.build(this);
// Hauptcontainer für das Menü
menuContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
menuContainer.setPreferredSize(new Vector3f(600, 400, 0)); // Feste Größe des Containers
//Add the button to start the sever
addChild(serverButton).addClickCommands(s -> ifTopDialog(this::startServerInThread));
}
// Titel
Label title = menuContainer.addChild(new Label("Neues Spiel", new ElementId("header")));
title.setFont(app.getAssetManager().loadFont("Interface/Fonts/Metropolis/Metropolis-Bold-42.fnt"));
title.setFontSize(50);
// Eingabefelder-Container
Container inputContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
inputContainer.setPreferredSize(new Vector3f(200, 150, 0)); // Eingabefelder nicht ganz so breit
inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
inputContainer.addChild(new Label("Server-Adresse:"));
TextField playerNameField = inputContainer.addChild(new TextField("localhost"));
playerNameField.setPreferredWidth(400); // Breite des Textfelds
inputContainer.addChild(new Label("Port:"));
TextField serverAddressField = inputContainer.addChild(new TextField("42069"));
serverAddressField.setPreferredWidth(400); // Breite des Textfelds
// Button-Container
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
buttonContainer.setPreferredSize(new Vector3f(400, 50, 0));
buttonContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
// "Abbrechen"-Button
Button cancelButton = buttonContainer.addChild(new Button("Abbrechen"));
cancelButton.setPreferredSize(new Vector3f(120, 40, 0));
cancelButton.addClickCommands(source -> goBackToStartMenu());
// "Selber hosten"-Button
Button hostButton = buttonContainer.addChild(new Button("Selber hosten"));
hostButton.setPreferredSize(new Vector3f(120, 40, 0));
hostButton.addClickCommands(source -> app.getNetworkSupport().startServerAndJoin());
// "Beitreten"-Button
Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
joinButton.addClickCommands(source -> {
/**
* Handles the action for the connect button in the connection dialog.
* Tries to parse the port number and initiate connection to the server.
*/
private void connect() {
LOGGER.log(Level.INFO, "connect to host={0}, port={1}", host, port); //NON-NLS
try {
String host = playerNameField.getText().trim();
int port = Integer.parseInt(serverAddressField.getText().trim());
app.getNetworkSupport().connectToServer(host, port);
// LobbyMenu öffnen
app.enqueue(() -> {
app.getGuiNode().detachAllChildren(); // Bestehende GUI entfernen
new LobbyMenu(app); // LobbyMenu erstellen
});
} catch (NumberFormatException e) {
app.errorDialog("Port muss eine Zahl sein.");
hostname = host.getText().trim().isEmpty() ? LOCALHOST : host.getText();
portNumber = Integer.parseInt(port.getText());
openProgressDialog();
connectionFuture = network.getApp().getExecutor().submit(this::initNetwork);
}
});
// Serverstatus-Label
serverStatusLabel = menuContainer.addChild(new Label("Serverstatus: Noch nicht gestartet"));
serverStatusLabel.setFontSize(24);
// Zentrierung des Containers
menuContainer.setLocalTranslation(
(app.getCamera().getWidth() - menuContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + menuContainer.getPreferredSize().y) / 2,
1 // Höhere Z-Ebene für den Vordergrund
);
app.getInputManager().addMapping("OpenTestWorld", new com.jme3.input.controls.KeyTrigger(com.jme3.input.KeyInput.KEY_T));
app.getInputManager().addListener(new com.jme3.input.controls.ActionListener() {
@Override
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("OpenTestWorld") && isPressed) {
app.startTestWorld(); // Öffnet die TestWorld
catch (NumberFormatException e) {
network.getApp().errorDialog(lookup("port.must.be.integer"));
}
}
}, "OpenTestWorld");
// TODO später entfernen
app.getInputManager().addMapping("OpenBuyCard", new com.jme3.input.controls.KeyTrigger(com.jme3.input.KeyInput.KEY_B));
app.getInputManager().addListener(new com.jme3.input.controls.ActionListener() {
@Override
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("OpenBuyCard") && isPressed) {
app.startBuyCard(); // Öffnet die TestWorld
}
}
}, "OpenBuyCard");
app.getGuiNode().attachChild(menuContainer);
}
/**
* Lädt das Hintergrundbild und fügt es als geometrische Ebene hinzu.
* Creates a dialog indicating that the connection is in progress.
*/
private void addBackgroundImage() {
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
background = new Geometry("Background", quad);
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
backgroundMaterial.setTexture("ColorMap", backgroundImage);
background.setMaterial(backgroundMaterial);
background.setLocalTranslation(0, 0, -1); // Hintergrundebene
app.getGuiNode().attachChild(background);
private void openProgressDialog() {
progressDialog = DialogBuilder.simple(network.getApp().getDialogManager())
.setText(lookup("label.connecting"))
.build();
progressDialog.open();
}
/**
* Geht zum Startmenü zurück, wenn "Abbrechen" angeklickt wird.
* Tries to initialize the network connection.
*
* @throws RuntimeException If an error occurs when creating the client.
*/
private void goBackToStartMenu() {
app.getGuiNode().detachChild(menuContainer);
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
StartMenu.createStartMenu(app);
private Object initNetwork() {
try {
network.initNetwork(hostname, portNumber);
return null;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* This method is called by {@linkplain pp.dialog.DialogManager#update(float)} for periodically
* updating this dialog. T
*/
@Override
public void update(float delta) {
if (connectionFuture != null && connectionFuture.isDone())
try {
connectionFuture.get();
success();
}
catch (ExecutionException e) {
failure(e.getCause());
}
catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "Interrupted!", e); //NON-NLS
Thread.currentThread().interrupt();
}
}
/**
* Handles a successful connection to the game server.
*/
private void success() {
connectionFuture = null;
progressDialog.close();
this.close();
network.getApp().setInfoText(lookup("wait.for.an.opponent"));
}
/**
* Handles a failed connection attempt.
*
* @param e The cause of the failure.
*/
private void failure(Throwable e) {
connectionFuture = null;
progressDialog.close();
network.getApp().errorDialog(lookup("server.connection.failed"));
network.getApp().setInfoText(e.getLocalizedMessage());
}
/**
* Starts the server in a separate thread.
*/
private void startServerInThread() {
serverButton.setEnabled(false);
Thread serverThread = new Thread(() -> {
try {
MonopolyServer.main(null);
} catch (Exception e) {
serverButton.setEnabled(true);
LOGGER.log(Level.ERROR, "Server could not be started", e);
network.getApp().errorDialog("Could not start server: " + e.getMessage());
}
});
serverThread.start();
}
}

View File

@ -214,7 +214,7 @@ public class LobbyMenu {
app.getGuiNode().detachChild(circle);
app.getGuiNode().detachChild(lowerLeftMenu);
app.getGuiNode().detachChild(lowerRightMenu);
new CreateGameMenu(app);
app.getServerConnection().connect();
}
/**