LobbyServer Einfügen

This commit is contained in:
Luca Puderbach 2024-11-18 18:56:42 +01:00
parent 9e28deedf7
commit 0b46d14650
7 changed files with 118 additions and 199 deletions

View File

@ -7,22 +7,21 @@
package pp.battleship.client; package pp.battleship.client;
import java.io.File;
import java.io.IOException;
import java.util.prefs.Preferences;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Checkbox; import com.simsilica.lemur.Checkbox;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import static pp.battleship.Resources.lookup;
import pp.battleship.client.gui.GameMusic; import pp.battleship.client.gui.GameMusic;
import pp.battleship.client.gui.VolumeSlider; import pp.battleship.client.gui.VolumeSlider;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.StateCheckboxModel; import pp.dialog.StateCheckboxModel;
import pp.dialog.TextInputDialog; import pp.dialog.TextInputDialog;
import java.io.File;
import java.io.IOException;
import java.util.prefs.Preferences;
import static pp.battleship.Resources.lookup;
import static pp.util.PreferencesUtils.getPreferences; import static pp.util.PreferencesUtils.getPreferences;
/** /**
@ -39,7 +38,7 @@ class Menu extends Dialog {
private final VolumeSlider slider; private final VolumeSlider slider;
/** /**
* Constructs the Menu dialog for the Battleship application. * Constructs the Menu dialog for the Battleship application.+
* *
* @param app the BattleshipApp instance * @param app the BattleshipApp instance
*/ */

View File

@ -1,7 +1,11 @@
package pp.monopoly.client.gui; package pp.monopoly.client.gui;
import javax.swing.JOptionPane;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.network.Client;
import com.jme3.network.Network;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
@ -14,7 +18,7 @@ import com.simsilica.lemur.component.SpringGridLayout;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.StartMenu; import pp.monopoly.client.StartMenu;
import pp.monopoly.client.server.MonopolyServer; import pp.monopoly.server.MonopolyServer;
/** /**
* CreateGameMenu class represents the menu for creating a new game. * CreateGameMenu class represents the menu for creating a new game.
@ -26,6 +30,7 @@ public class CreateGameMenu {
private Geometry background; private Geometry background;
private Label serverStatusLabel; private Label serverStatusLabel;
private MonopolyServer monopolyServer; private MonopolyServer monopolyServer;
private Client client;
public CreateGameMenu(MonopolyApp app) { public CreateGameMenu(MonopolyApp app) {
this.app = app; this.app = app;
@ -130,7 +135,6 @@ public class CreateGameMenu {
new Thread(() -> { new Thread(() -> {
try { try {
monopolyServer = new MonopolyServer(); // Erstelle Serverinstanz monopolyServer = new MonopolyServer(); // Erstelle Serverinstanz
monopolyServer.run(); // Starte Serverlogik
serverStatusLabel.setText("Serverstatus: Läuft auf Port " + monopolyServer.getConfig().getPort()); serverStatusLabel.setText("Serverstatus: Läuft auf Port " + monopolyServer.getConfig().getPort());
} catch (Exception e) { } catch (Exception e) {
serverStatusLabel.setText("Serverstatus: Fehler beim Starten"); serverStatusLabel.setText("Serverstatus: Fehler beim Starten");
@ -141,4 +145,17 @@ public class CreateGameMenu {
serverStatusLabel.setText("Serverstatus: Bereits gestartet!"); serverStatusLabel.setText("Serverstatus: Bereits gestartet!");
} }
} }
private void joinGame(String host, String port) {
try {
int portNumber = Integer.parseInt(port);
client = Network.connectToServer(host, portNumber); // Verbindet sich mit Server
client.start();
JOptionPane.showMessageDialog(null, "Erfolgreich mit dem Server verbunden: " + host + ":" + port);
// Hier kannst du zusätzliche Logik für das Verbinden hinzufügen
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Fehler beim Verbinden mit dem Server: " + e.getMessage(),
"Verbindungsfehler", JOptionPane.ERROR_MESSAGE);
}
}
} }

View File

@ -0,0 +1,89 @@
package pp.monopoly.client.gui;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class ServerScreen {
private JFrame frame;
private JTextField inputField;
private JLabel label;
private JButton startButton;
private JButton stopButton;
public ServerScreen() {
initialize();
}
private void initialize() {
// Erstelle das Hauptfenster
frame = new JFrame("Server Placeholder"); // Setze den Titel
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
// Eingabefeld und Label im oberen Bereich
JPanel topPanel = new JPanel();
topPanel.setLayout(new FlowLayout());
label = new JLabel("Server-Port:");
inputField = new JTextField("42069", 10);
topPanel.add(label);
topPanel.add(inputField);
// Buttons im unteren Bereich
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout());
startButton = new JButton("Start Server");
stopButton = new JButton("Stop Server");
stopButton.setEnabled(false); // Stop-Button ist anfangs deaktiviert
bottomPanel.add(startButton);
bottomPanel.add(stopButton);
// Füge die Panels zum Hauptfenster hinzu
frame.add(topPanel, BorderLayout.NORTH);
frame.add(bottomPanel, BorderLayout.SOUTH);
// Aktion für Start-Button
startButton.addActionListener(e -> startServer());
// Aktion für Stop-Button
stopButton.addActionListener(e -> stopServer());
// Zeige das Fenster
frame.setVisible(true);
}
private void startServer() {
String port = inputField.getText();
try {
int portNumber = Integer.parseInt(port);
// Server-Startlogik hier einfügen
JOptionPane.showMessageDialog(frame, "Server gestartet auf Port " + portNumber);
startButton.setEnabled(false); // Deaktiviere den Start-Button
stopButton.setEnabled(true); // Aktiviere den Stop-Button
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(frame, "Ungültiger Port: " + port, "Fehler", JOptionPane.ERROR_MESSAGE);
}
}
private void stopServer() {
// Server-Stoplogik hier einfügen
JOptionPane.showMessageDialog(frame, "Server gestoppt.");
startButton.setEnabled(true); // Aktiviere den Start-Button
stopButton.setEnabled(false); // Deaktiviere den Stop-Button
}
public static void main(String[] args) {
SwingUtilities.invokeLater(ServerScreen::new);
}
}

View File

@ -56,6 +56,7 @@ public class SettingsMenu extends Dialog {
Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button"))); Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.addClickCommands(source -> app.stop()); quitButton.addClickCommands(source -> app.stop());
// Zentriere das Menü // Zentriere das Menü
settingsContainer.setLocalTranslation( settingsContainer.setLocalTranslation(

View File

@ -1,167 +0,0 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
package pp.monopoly.client.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
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
*/
public class MonopolyServer implements MessageListener<HostedConnection>, ConnectionListener, ServerSender {
private static final Logger LOGGER = System.getLogger(MonopolyServer.class.getName());
private static final File CONFIG_FILE = new File("server.properties");
private final MonopolyConfig config = new MonopolyConfig();
private Server myServer;
private final ServerGameLogic logic;
private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
static {
// Configure logging
LogManager manager = LogManager.getLogManager();
try {
manager.readConfiguration(new FileInputStream("logging.properties"));
LOGGER.log(Level.INFO, "Successfully read logging properties"); //NON-NLS
}
catch (IOException e) {
LOGGER.log(Level.INFO, e.getMessage());
}
}
/**
* Starts the Monopolys server.
*/
public static void main(String[] args) {
new MonopolyServer().run();
}
/**
* Creates the server.
*/
public MonopolyServer() {
config.readFromIfExists(CONFIG_FILE);
LOGGER.log(Level.INFO, "Configuration: {0}", config); //NON-NLS
logic = new ServerGameLogic(this, config);
}
public void run() {
startServer();
while (true)
processNextMessage();
}
private void startServer() {
try {
LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS
myServer = Network.createServer(config.getPort());
initializeSerializables();
myServer.start();
registerListeners();
LOGGER.log(Level.INFO, "Server started: {0}", myServer.isRunning()); //NON-NLS
}
catch (IOException e) {
LOGGER.log(Level.ERROR, "Couldn't start server: {0}", e.getMessage()); //NON-NLS
exit(1);
}
}
private void processNextMessage() {
try {
pendingMessages.take().process(logic);
}
catch (InterruptedException ex) {
LOGGER.log(Level.INFO, "Interrupted while waiting for messages"); //NON-NLS
Thread.currentThread().interrupt();
}
}
private void initializeSerializables() {
Serializer.registerClass(IntPoint.class);
}
private void registerListeners() {
myServer.addConnectionListener(this);
}
@Override
public void messageReceived(HostedConnection source, Message message) {
LOGGER.log(Level.INFO, "message received from {0}: {1}", source.getId(), message); //NON-NLS
if (message instanceof ClientMessage clientMessage)
pendingMessages.add(new ReceivedMessage(clientMessage, source.getId()));
}
@Override
public void connectionAdded(Server server, HostedConnection hostedConnection) {
LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS
logic.addPlayer(hostedConnection.getId());
}
@Override
public void connectionRemoved(Server server, HostedConnection hostedConnection) {
LOGGER.log(Level.INFO, "connection closed: {0}", hostedConnection); //NON-NLS
final Player player = logic.getPlayerById(hostedConnection.getId());
if (player == null)
LOGGER.log(Level.INFO, "closed connection does not belong to an active player"); //NON-NLS
else { //NON-NLS
LOGGER.log(Level.INFO, "closed connection belongs to {0}", player); //NON-NLS
exit(0);
}
}
private void exit(int exitValue) { //NON-NLS
LOGGER.log(Level.INFO, "close request"); //NON-NLS
if (myServer != null)
for (HostedConnection client : myServer.getConnections()) //NON-NLS
if (client != null) client.close("Game over"); //NON-NLS
System.exit(exitValue);
}
/**
* Send the specified message to the specified connection.
*
* @param id the connection id
* @param message the message
*/
public void send(int id, ServerMessage message) {
if (myServer == null || !myServer.isRunning()) {
LOGGER.log(Level.ERROR, "no server running when trying to send {0}", message); //NON-NLS
return;
}
final HostedConnection connection = myServer.getConnection(id);
if (connection != null)
connection.send(message);
else
LOGGER.log(Level.ERROR, "there is no connection with id={0}", id); //NON-NLS
}
public MonopolyConfig getConfig() {
return config;
}
}

View File

@ -1,17 +0,0 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
package pp.monopoly.client.server;
import pp.monopoly.message.client.ClientInterpreter;
import pp.monopoly.message.client.ClientMessage;
record ReceivedMessage(ClientMessage message, int from) {
void process(ClientInterpreter interpreter) {
message.accept(interpreter, from);
}
}

View File

@ -7,13 +7,10 @@
package pp.monopoly; package pp.monopoly;
import pp.util.config.Config;
import java.util.Map;
import java.util.TreeMap;
import static java.lang.Math.max; import static java.lang.Math.max;
import pp.util.config.Config;
/** /**
* Provides access to the configuration settings for the Monopoly game. * Provides access to the configuration settings for the Monopoly game.
* <p> * <p>
@ -31,7 +28,7 @@ public class MonopolyConfig extends Config {
* The default port number for the Monopoly server. * The default port number for the Monopoly server.
*/ */
@Property("port") @Property("port")
private int port = 1234; private int port = 42069;
/** /**
* The width of the game map in terms of grid units. * The width of the game map in terms of grid units.