diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java index 9bfea69..4adde8d 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java @@ -9,10 +9,8 @@ import com.jme3.font.BitmapText; import com.jme3.input.KeyInput; import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.KeyTrigger; - import com.jme3.system.AppSettings; import com.simsilica.lemur.GuiGlobals; -import com.simsilica.lemur.Label; import com.simsilica.lemur.style.BaseStyles; import pp.dialog.DialogBuilder; @@ -28,6 +26,7 @@ import pp.monopoly.notification.InfoTextEvent; import pp.monopoly.server.MonopolyServer; public class MonopolyApp extends SimpleApplication implements MonopolyClient, GameEventListener { + private BitmapText topText; private final ServerConnection serverConnection; private final ClientGameLogic logic; @@ -41,16 +40,16 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga private boolean isSettingsMenuOpen = false; private boolean inputBlocked = false; private MonopolyServer monopolyServer; + private NetworkSupport networkSupport; /** * Path to the styles script for GUI elements. */ - private static final String STYLES_SCRIPT = "Interface/Lemur/pp-styles.groovy"; //NON-NLS + private static final String STYLES_SCRIPT = "Interface/Lemur/pp-styles.groovy"; // NON-NLS /** * Path to the font resource used in the GUI. */ - private static final String FONT = "Interface/Fonts/Default.fnt"; //NON-NLS - + private static final String FONT = "Interface/Fonts/Default.fnt"; // NON-NLS public static void main(String[] args) { new MonopolyApp().start(); @@ -59,7 +58,8 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga public MonopolyApp() { this.draw = new Draw(assetManager); config = new MonopolyAppConfig(); - serverConnection = new NetworkSupport(this); + networkSupport = new NetworkSupport(this); // Initialize NetworkSupport + serverConnection = networkSupport; logic = new ClientGameLogic(serverConnection); logic.addListener(this); setShowSettings(config.getShowSettings()); @@ -76,6 +76,10 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga return logic; } + public NetworkSupport getNetworkSupport() { + return networkSupport; + } + private AppSettings makeSettings() { final AppSettings settings = new AppSettings(true); settings.setTitle("Monopoly Game"); @@ -88,8 +92,8 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga public void simpleInitApp() { GuiGlobals.initialize(this); BaseStyles.loadStyleResources(STYLES_SCRIPT); - GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); //NON-NLS - final BitmapFont normalFont = assetManager.loadFont(FONT); //NON-NLS + GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); // NON-NLS + final BitmapFont normalFont = assetManager.loadFont(FONT); // NON-NLS setupInput(); setupGui(); @@ -129,18 +133,16 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga } } } - - private void blockInputs() { if (!inputBlocked) { System.out.println("Blockiere Eingaben..."); inputManager.setCursorVisible(true); // Cursor sichtbar machen - inputManager.clearMappings(); // Alle Mappings entfernen + inputManager.clearMappings(); // Alle Mappings entfernen inputBlocked = true; } } - + public void unblockInputs() { if (inputBlocked) { System.out.println("Aktiviere Eingaben..."); @@ -204,7 +206,7 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga public void startTestWorld() { guiNode.detachAllChildren(); // Entferne GUI testWorld = new TestWorld(this); // Erstelle eine Instanz von TestWorld - testWorld.initializeScene(); // Initialisiere die Szene + testWorld.initializeScene(); // Initialisiere die Szene } public void returnToMenu() { @@ -218,9 +220,9 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga public void startServer() { new Thread(() -> { try { - monopolyServer = new MonopolyServer(); // Erstelle Serverinstanz + MonopolyServer.main(new String[0]); // Startet den MonopolyServer } catch (Exception e) { - e.printStackTrace(); + errorDialog("Fehler: Server konnte nicht gestartet werden."); } }).start(); } diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java index 3ea11b0..6ae24fd 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java @@ -18,7 +18,7 @@ import pp.monopoly.message.server.ServerMessage; * Manages the network connection for the Monopoly application. * Handles connecting to and disconnecting from the server, and sending messages. */ -class NetworkSupport implements MessageListener, ClientStateListener, ServerConnection { +public class NetworkSupport implements MessageListener, ClientStateListener, ServerConnection { private static final Logger LOGGER = System.getLogger(NetworkSupport.class.getName()); private final MonopolyApp app; private Client client; @@ -141,4 +141,40 @@ class NetworkSupport implements MessageListener, ClientStateListener, Se 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."); + } + } } \ No newline at end of file diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java index cd10d18..c406272 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java @@ -15,13 +15,16 @@ import com.simsilica.lemur.component.SpringGridLayout; import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.StartMenu; + +/** + * CreateGameMenu class represents the menu for creating a new game. + */ public class CreateGameMenu { private final MonopolyApp app; private final Container menuContainer; private Geometry background; - private TextField serverAddressField; - private TextField portField; + private Label serverStatusLabel; public CreateGameMenu(MonopolyApp app) { this.app = app; @@ -43,12 +46,12 @@ public class CreateGameMenu { inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand inputContainer.addChild(new Label("Server-Adresse:")); - serverAddressField = inputContainer.addChild(new TextField("localhost")); - serverAddressField.setPreferredWidth(400); // Breite des Textfelds + TextField playerNameField = inputContainer.addChild(new TextField("localhost")); + playerNameField.setPreferredWidth(400); // Breite des Textfelds inputContainer.addChild(new Label("Port:")); - portField = inputContainer.addChild(new TextField("42069")); - portField.setPreferredWidth(400); // Breite des Textfelds + 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))); @@ -63,15 +66,29 @@ public class CreateGameMenu { // "Selber hosten"-Button Button hostButton = buttonContainer.addChild(new Button("Selber hosten")); hostButton.setPreferredSize(new Vector3f(120, 40, 0)); - // hostButton.addClickCommands(source -> startServerAndJoin()); + hostButton.addClickCommands(source -> app.getNetworkSupport().startServerAndJoin()); - // "Beitreten"-Button (vorerst funktionslos) + // "Beitreten"-Button Button joinButton = buttonContainer.addChild(new Button("Beitreten")); joinButton.setPreferredSize(new Vector3f(120, 40, 0)); - // joinButton.addClickCommands(source -> joinServer()); + joinButton.addClickCommands(source -> { + 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."); + } + }); // Serverstatus-Label - Label serverStatusLabel = menuContainer.addChild(new Label("Serverstatus: Noch nicht gestartet")); + serverStatusLabel = menuContainer.addChild(new Label("Serverstatus: Noch nicht gestartet")); serverStatusLabel.setFontSize(24); // Zentrierung des Containers @@ -116,38 +133,4 @@ public class CreateGameMenu { app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild StartMenu.createStartMenu(app); } - - /** - * Startet den Server und tritt nach 2 Sekunden der Lobby bei. - */ - //private void startServerAndJoin() { - // new Thread(() -> { - // app.start(); - // app.startServer(); -// - // // Warte 2 Sekunden - // try { - // Thread.sleep(2000); - // } catch (InterruptedException e) { - // Thread.currentThread().interrupt(); - // } -// - // // Verbinde mit dem Server - // app.enqueue(() -> joinServer()); - // }).start(); - //} - - /** - * Tritt dem Server basierend auf den Eingaben bei. - */ - //private void joinServer() { - // String serverAddress = serverAddressField.getText(); - // int port = Integer.parseInt(portField.getText()); - // app.getServerConnection().connect(serverAddress, port); - - // // Öffnet die Lobby - // app.getGuiNode().detachChild(menuContainer); - // app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild - // new LobbyMenu(app); - //} } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java index 62cdd72..a65b791 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java @@ -1,7 +1,17 @@ package pp.monopoly.game.server; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; + import pp.monopoly.MonopolyConfig; -import pp.monopoly.message.client.*; +import pp.monopoly.message.client.BuyPropertyRequest; +import pp.monopoly.message.client.ClientInterpreter; +import pp.monopoly.message.client.EndTurn; +import pp.monopoly.message.client.PlayerReady; +import pp.monopoly.message.client.RollDice; +import pp.monopoly.message.client.TradeOffer; +import pp.monopoly.message.client.TradeResponse; +import pp.monopoly.message.client.ViewAssetsRequest; import pp.monopoly.message.server.ServerMessage; import pp.monopoly.message.server.TradeReply; import pp.monopoly.message.server.TradeRequest; @@ -9,13 +19,6 @@ import pp.monopoly.message.server.ViewAssetsResponse; import pp.monopoly.model.fields.BoardManager; import pp.monopoly.model.fields.PropertyField; -import java.lang.System.Logger; -import java.lang.System.Logger.Level; - -import pp.monopoly.MonopolyConfig; -import pp.monopoly.message.client.ClientInterpreter; -import pp.monopoly.message.server.ServerMessage; - /** * Controls the server-side game logic for Monopoly. * Manages game states, player interactions, and message handling. @@ -26,7 +29,7 @@ public class ServerGameLogic implements ClientInterpreter { private final MonopolyConfig config; private final PlayerHandler playerHandler = new PlayerHandler(this); private final ServerSender serverSender; - private ServerState state = ServerState.CREATEGAME; + private ServerState state = ServerState.LOBBY; private static final int MAX_PLAYERS = 6; private BoardManager boardManager = new BoardManager(); diff --git a/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java b/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java index f02f48d..f4bfa7e 100644 --- a/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java +++ b/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java @@ -7,21 +7,6 @@ package pp.monopoly.server; -import com.jme3.network.ConnectionListener; -import com.jme3.network.HostedConnection; -import com.jme3.network.Message; -import com.jme3.network.MessageListener; -import com.jme3.network.Network; -import com.jme3.network.Server; -import com.jme3.network.serializing.Serializer; -import pp.monopoly.MonopolyConfig; -import pp.monopoly.game.server.Player; -import pp.monopoly.game.server.ServerGameLogic; -import pp.monopoly.game.server.ServerSender; -import pp.monopoly.message.client.ClientMessage; -import pp.monopoly.message.server.ServerMessage; -import pp.monopoly.model.IntPoint; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -31,6 +16,22 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.logging.LogManager; +import com.jme3.network.ConnectionListener; +import com.jme3.network.HostedConnection; +import com.jme3.network.Message; +import com.jme3.network.MessageListener; +import com.jme3.network.Network; +import com.jme3.network.Server; +import com.jme3.network.serializing.Serializer; + +import pp.monopoly.MonopolyConfig; +import pp.monopoly.game.server.Player; +import pp.monopoly.game.server.ServerGameLogic; +import pp.monopoly.game.server.ServerSender; +import pp.monopoly.message.client.ClientMessage; +import pp.monopoly.message.server.ServerMessage; +import pp.monopoly.model.IntPoint; + /** * Server implementing the visitor pattern as MessageReceiver for ClientMessages */ @@ -119,8 +120,9 @@ public class MonopolyServer implements MessageListener, Connec @Override public void connectionAdded(Server server, HostedConnection hostedConnection) { - LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS + LOGGER.log(Level.INFO, "New connection established: {0}", hostedConnection); //NON-NLS logic.addPlayer(hostedConnection.getId()); + System.out.println("Spieler verbunden: ID = " + hostedConnection.getId()); } @Override