From 7be22292804b8a731ad223ac65984bde1c22d153 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 14 Mar 2026 13:33:46 +0100 Subject: [PATCH 01/11] Style: Sort imports --- .../cs108/casono/server/network/NetworkManager.java | 12 +++++------- .../casono/server/network/sessions/Session.java | 9 ++++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java index 50b53d9..cd2f677 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java @@ -1,17 +1,15 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.Session; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TcpTransport; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /** * Creates and manages the server socket. Accepts new incoming connections and creates sessions. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index d2464f1..11b57d5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -1,13 +1,12 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; -import java.io.EOFException; -import java.io.IOException; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; +import java.io.EOFException; +import java.io.IOException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /** * Represents a client session in the network server. From 573c5fd36d67aaf66c49d294a1f535005cc55655 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 14 Mar 2026 13:37:04 +0100 Subject: [PATCH 02/11] Style: Singleline JavaDoc comments --- .../dmi/dbis/cs108/casono/server/ServerApp.java | 4 +--- .../casono/server/network/NetworkManager.java | 12 +++--------- .../server/network/events/DisconnectEvent.java | 4 +--- .../casono/server/network/events/Event.java | 4 +--- .../casono/server/network/events/EventBus.java | 4 +--- .../casono/server/network/sessions/Session.java | 16 +++++----------- .../server/network/sessions/SessionId.java | 8 ++------ .../server/network/sessions/SessionManager.java | 8 ++------ .../server/network/transport/TcpTransport.java | 4 +--- .../server/network/transport/TransportLayer.java | 4 +--- 10 files changed, 18 insertions(+), 50 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index a7814b0..d4cc99b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -5,9 +5,7 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; -/** - * Application class for starting the server. - */ +/** Application class for starting the server. */ public class ServerApp { public static void start(String arg) { int port = Integer.parseInt(arg); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java index cd2f677..016cd47 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java @@ -11,9 +11,7 @@ import java.net.Socket; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * Creates and manages the server socket. Accepts new incoming connections and creates sessions. - */ +/** Creates and manages the server socket. Accepts new incoming connections and creates sessions. */ public class NetworkManager implements Runnable { private Integer port; private Logger logger; @@ -39,9 +37,7 @@ public class NetworkManager implements Runnable { this.eventBus.subscribe(DisconnectEvent.class, event -> clientDisconnected(event)); } - /** - * Starts the internal thread to accept new connections. - */ + /** Starts the internal thread to accept new connections. */ public void start() { logger.debug("Starting server at port " + port); thread.start(); @@ -56,9 +52,7 @@ public class NetworkManager implements Runnable { logger.info("Session " + event.sessionId().value() + " disconnected adhasghd"); } - /** - * Runs the network manager loop, accepting connections. - */ + /** Runs the network manager loop, accepting connections. */ @Override public void run() { try (ServerSocket serverSocket = new ServerSocket(port)) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/DisconnectEvent.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/DisconnectEvent.java index b6b0d78..a866d56 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/DisconnectEvent.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/DisconnectEvent.java @@ -2,7 +2,5 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.events; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; -/** - * Represents a disconnect event for a session. - */ +/** Represents a disconnect event for a session. */ public record DisconnectEvent(SessionId sessionId) implements Event {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/Event.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/Event.java index 75c0954..1a8fc4b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/Event.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/Event.java @@ -1,6 +1,4 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.events; -/** - * Marker interface for events in the event bus system. - */ +/** Marker interface for events in the event bus system. */ interface Event {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java index 4141ab8..85b8ff8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java @@ -7,9 +7,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; -/** - * A simple event bus for publishing and subscribing to events. - */ +/** A simple event bus for publishing and subscribing to events. */ public class EventBus { private final Map, List>> handlers = new ConcurrentHashMap<>(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 11b57d5..d716ac0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -8,9 +8,7 @@ import java.io.IOException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * Represents a client session in the network server. - */ +/** Represents a client session in the network server. */ public class Session implements Runnable { private SessionId id; private Thread thread; @@ -18,12 +16,12 @@ public class Session implements Runnable { private Logger logger; private Boolean running; private EventBus eventBus; - + /** * Creates a new Session with the given transport and event bus. * * @param transport the transport layer for communication - * @param eventBus the event bus for publishing events + * @param eventBus the event bus for publishing events * @throws IOException if an I/O error occurs during initialization */ public Session(TransportLayer transport, EventBus eventBus) throws IOException { @@ -46,9 +44,7 @@ public class Session implements Runnable { return this.id; } - /** - * Starts the session thread. - */ + /** Starts the session thread. */ public void start() { thread.start(); } @@ -63,9 +59,7 @@ public class Session implements Runnable { this.running = false; } - /** - * Runs the session loop, reading from the transport. - */ + /** Runs the session loop, reading from the transport. */ @Override public void run() { while (running) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionId.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionId.java index 431ebdc..2645323 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionId.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionId.java @@ -2,15 +2,11 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import java.util.UUID; -/** - * Represents a unique identifier for a session. - */ +/** Represents a unique identifier for a session. */ public class SessionId { private final UUID value; - /** - * Creates a new SessionId with a randomly generated UUID. - */ + /** Creates a new SessionId with a randomly generated UUID. */ public SessionId() { this.value = UUID.randomUUID(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 42bc4ac..e12b319 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -3,15 +3,11 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -/** - * Manages active sessions in the server. - */ +/** Manages active sessions in the server. */ public class SessionManager { private Map sessions; - /** - * Constructs a new SessionManager. - */ + /** Constructs a new SessionManager. */ public SessionManager() { this.sessions = new ConcurrentHashMap<>(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java index 3f80d6c..bd754bd 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java @@ -6,9 +6,7 @@ import java.io.IOException; import java.net.Socket; import java.nio.charset.StandardCharsets; -/** - * Implements TCP-based transport layer for network communication. - */ +/** Implements TCP-based transport layer for network communication. */ public class TcpTransport implements TransportLayer { private Socket socket; private DataInputStream in; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TransportLayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TransportLayer.java index f487a9c..4bd9e36 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TransportLayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TransportLayer.java @@ -2,9 +2,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.transport; import java.io.IOException; -/** - * Interface for transport layer implementations. - */ +/** Interface for transport layer implementations. */ public interface TransportLayer { /** * Reads data from the transport layer. From 34c89b671e3961e8f20cd47e2cac3eacc7622041 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 14 Mar 2026 13:44:58 +0100 Subject: [PATCH 03/11] Style: Unnecessary spaces in JavaDoc parameter and return value labels --- .../dmi/dbis/cs108/casono/server/network/NetworkManager.java | 4 ++-- .../dmi/dbis/cs108/casono/server/network/events/EventBus.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java index 016cd47..d962139 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java @@ -23,9 +23,9 @@ public class NetworkManager implements Runnable { /** * Creates a new NetworkManager with the given port, session manager, and event bus. * - * @param port the port to listen on + * @param port the port to listen on * @param sessionManager the session manager to use - * @param eventBus the event bus for events + * @param eventBus the event bus for events */ public NetworkManager(Integer port, SessionManager sessionManager, EventBus eventBus) { this.port = port; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java index 85b8ff8..b5e3457 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java @@ -15,7 +15,7 @@ public class EventBus { * Subscribes a handler to a specific event type. * * @param eventType the class of the event to subscribe to - * @param handler the consumer to handle the event + * @param handler the consumer to handle the event */ @SuppressWarnings("unchecked") // This cast is safe, because handlers only get passed the type they subscribed to public void subscribe(Class eventType, Consumer handler) { From 59494ea2d4c8dc6591d78ba47f707c1a99d8f6ea Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 14 Mar 2026 13:45:29 +0100 Subject: [PATCH 04/11] Style: Line length --- .../ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 6 ++++-- .../dbis/cs108/casono/server/network/NetworkManager.java | 5 +++-- .../dbis/cs108/casono/server/network/events/EventBus.java | 4 +++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index d4cc99b..ad90416 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -9,11 +9,13 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; public class ServerApp { public static void start(String arg) { int port = Integer.parseInt(arg); - System.out.println("You've selected the server. It will accept connections at port " + port); + System.out.println( + "You've selected the server. It will accept connections at port " + port); EventBus eventBus = new EventBus(); SessionManager sessionManager = new SessionManager(); - eventBus.subscribe(DisconnectEvent.class, event -> sessionManager.removeSession(event.sessionId())); + eventBus.subscribe( + DisconnectEvent.class, event -> sessionManager.removeSession(event.sessionId())); NetworkManager networkManager = new NetworkManager(port, sessionManager, eventBus); networkManager.start(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java index d962139..faa2ebd 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java @@ -58,8 +58,9 @@ public class NetworkManager implements Runnable { try (ServerSocket serverSocket = new ServerSocket(port)) { while (running) { Socket clientSocket = serverSocket.accept(); - - System.out.println("Accepted connection from " + clientSocket.getRemoteSocketAddress()); + + System.out.println( + "Accepted connection from " + clientSocket.getRemoteSocketAddress()); Session session = new Session(new TcpTransport(clientSocket), eventBus); sessionManager.addSession(session); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java index b5e3457..eb4293d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/events/EventBus.java @@ -17,7 +17,9 @@ public class EventBus { * @param eventType the class of the event to subscribe to * @param handler the consumer to handle the event */ - @SuppressWarnings("unchecked") // This cast is safe, because handlers only get passed the type they subscribed to + @SuppressWarnings( + "unchecked") // This cast is safe, because handlers only get passed the type they + // subscribed to public void subscribe(Class eventType, Consumer handler) { handlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()) .add((Consumer) (Consumer) handler); From 3ce0a44a189f8b14187bd5ab3662c9894da03fa5 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 14 Mar 2026 13:46:11 +0100 Subject: [PATCH 05/11] Style: Trailing whitespace --- .../cs108/casono/server/network/transport/TcpTransport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java index bd754bd..a7867d3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/transport/TcpTransport.java @@ -47,7 +47,7 @@ public class TcpTransport implements TransportLayer { byte[] rawPayload = payload.getBytes(StandardCharsets.UTF_8); out.writeInt(rawPayload.length); out.write(rawPayload); - out.flush(); + out.flush(); } /** From 1aafc0bc4b26f39a7b9a0407feef6005e6808a5f Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 14 Mar 2026 14:20:01 +0100 Subject: [PATCH 06/11] Style: Use logger instead of System.out.println --- .../ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 7 +++++-- .../dbis/cs108/casono/server/network/NetworkManager.java | 7 +++---- .../dbis/cs108/casono/server/network/sessions/Session.java | 2 +- .../casono/server/network/sessions/SessionManager.java | 2 -- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index ad90416..702d1c8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -4,13 +4,16 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /** Application class for starting the server. */ public class ServerApp { public static void start(String arg) { int port = Integer.parseInt(arg); - System.out.println( - "You've selected the server. It will accept connections at port " + port); + + Logger logger = LogManager.getLogger(ServerApp.class); + logger.info("Starting server at port {}", port); EventBus eventBus = new EventBus(); SessionManager sessionManager = new SessionManager(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java index faa2ebd..ad2e5b3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java @@ -39,7 +39,7 @@ public class NetworkManager implements Runnable { /** Starts the internal thread to accept new connections. */ public void start() { - logger.debug("Starting server at port " + port); + logger.debug("Starting at port {}", port); thread.start(); } @@ -49,7 +49,7 @@ public class NetworkManager implements Runnable { * @param event the disconnect event */ public void clientDisconnected(DisconnectEvent event) { - logger.info("Session " + event.sessionId().value() + " disconnected adhasghd"); + logger.info("Session {} disconnected", event.sessionId().value()); } /** Runs the network manager loop, accepting connections. */ @@ -59,8 +59,7 @@ public class NetworkManager implements Runnable { while (running) { Socket clientSocket = serverSocket.accept(); - System.out.println( - "Accepted connection from " + clientSocket.getRemoteSocketAddress()); + logger.debug("Accepted connection from {}", clientSocket.getRemoteSocketAddress()); Session session = new Session(new TcpTransport(clientSocket), eventBus); sessionManager.addSession(session); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index d716ac0..3ed8f88 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -64,7 +64,7 @@ public class Session implements Runnable { public void run() { while (running) { try { - System.out.println("Recieved: " + transport.read()); + logger.debug("Recieved: {}", transport.read()); } catch (EOFException e) { logger.info("Client disconnected"); eventBus.publish(new DisconnectEvent(id)); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index e12b319..6702543 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -19,7 +19,6 @@ public class SessionManager { */ public void addSession(Session session) { sessions.put(session.getId(), session); - System.out.println("Added session " + session.getId().value() + " to session manager"); } /** @@ -29,7 +28,6 @@ public class SessionManager { * @return the removed session, or null if not found */ public Session removeSession(SessionId id) { - System.out.println("Removed session " + id.value() + " from session manager"); return sessions.remove(id); } From d8bfc1c8e951ad4e72c4f4919f3e61fa0d5c7fee Mon Sep 17 00:00:00 2001 From: Julian Kropff Date: Sat, 14 Mar 2026 16:46:28 +0100 Subject: [PATCH 07/11] style: apply Checkstyle fixes --- .../gameuicomponents/TaskbarController.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java index cb25954..79f1615 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java @@ -18,11 +18,18 @@ import javafx.scene.layout.HBox; */ public class TaskbarController { + private static final org.apache.logging.log4j.Logger LOGGER = + org.apache.logging.log4j.LogManager.getLogger(CasinoBrowserController.class); + @FXML private HBox taskbar; @FXML private TextField taskbarInput; private double xOffset = 0; private double yOffset = 0; + private static final double TASKBAR_SCALE = 0.9; + private static final int MIN_CREDITS = 5; + private static final int MAX_CREDITS = 100000; + private static final int CREDIT_STEP = 5; /** * Wird aufgerufen, wenn die Taskleiste mit der Maus gedrückt wird. @@ -40,7 +47,8 @@ public class TaskbarController { * Wird aufgerufen, während die Taskleiste mit der Maus gezogen wird. * Aktualisiert die Position und skaliert die Taskleiste leicht zur visuellen Rückmeldung. * - * TODO: Es muss noch gefixt werden, dass die Taskleiste nicht aus dem Fenster verschwinden kann. + * TODO: Es muss noch gefixt werden, dass die Taskleiste nicht aus dem + * Fenster verschwinden kann. * * @param event Das Mausereignis */ @@ -49,8 +57,8 @@ public class TaskbarController { taskbar.setLayoutX(event.getSceneX() - xOffset); taskbar.setLayoutY(event.getSceneY() - yOffset); - taskbar.setScaleX(0.9); - taskbar.setScaleY(0.9); + taskbar.setScaleX(TASKBAR_SCALE); + taskbar.setScaleY(TASKBAR_SCALE); } /** @@ -108,15 +116,15 @@ public class TaskbarController { try { int credits = Integer.parseInt(input.trim()); - if (credits >= 5 && credits <= 100000 && credits % 5 == 0) { + if (credits >= MIN_CREDITS && credits <= MAX_CREDITS && credits % CREDIT_STEP == 0) { // TODO: Credits müssen an die GameEngine gesendet werden - System.out.println("Einsatz gesetzt: " + credits + " Casono Credits"); + LOGGER.info("Einsatz gesetzt: {} Casono Credits", credits); taskbarInput.clear(); } else { - System.out.println("Fehler: Nur 5er-Schritte (5, 10, ... 100.000) erlaubt!"); + LOGGER.info("Fehler: Nur 5er-Schritte (5, 10, ... 100.000) erlaubt!"); } } catch (NumberFormatException e) { - System.out.println("Fehler: Bitte nur eine Zahl eingeben!"); + LOGGER.info("Fehler: Bitte nur eine Zahl eingeben!"); } } From cb98c70562d825350c5a5b71b28bedb1e70edfc0 Mon Sep 17 00:00:00 2001 From: Julian Kropff Date: Sat, 14 Mar 2026 16:46:44 +0100 Subject: [PATCH 08/11] style: apply Checkstyle fixes --- .../casono/client/ui/chatui/ChatController.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/chatui/ChatController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/chatui/ChatController.java index 563d912..437c689 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/chatui/ChatController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/chatui/ChatController.java @@ -1,13 +1,13 @@ package ch.unibas.dmi.dbis.cs108.casono.client.ui.chatui; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.TextField; -import javafx.scene.layout.VBox; -import javafx.scene.control.Label; import java.time.LocalTime; import java.time.format.DateTimeFormatter; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.layout.VBox; /** * Controller-Klasse für das Chat-System innerhalb der Spieloberfläche. @@ -39,6 +39,8 @@ public class ChatController { @FXML private ScrollPane chatScrollPane; + private static final int CHAT_PADDING = 20; + /** * Initialisiert den ChatController nach dem Laden der FXML. */ @@ -73,7 +75,7 @@ public class ChatController { Label label = new Label("[" + time + "] " + player + ": " + message); label.getStyleClass().add("info-text"); label.setWrapText(true); // Zeilenumbruch aktivieren - label.maxWidthProperty().bind(chatVBox.widthProperty().subtract(20)); + label.maxWidthProperty().bind(chatVBox.widthProperty().subtract(CHAT_PADDING)); chatVBox.getChildren().add(label); } From 9376b1d40642a8d4e61722e3e23a3b365e28ba6b Mon Sep 17 00:00:00 2001 From: Julian Kropff Date: Sat, 14 Mar 2026 16:48:06 +0100 Subject: [PATCH 09/11] style: apply Checkstyle fixes --- .../casono/client/ui/gameui/CasinoGameUI.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameUI.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameUI.java index af94daf..c280e3f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameUI.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameUI.java @@ -1,12 +1,11 @@ package ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui; +import java.io.IOException; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; -import java.io.IOException; - /** * Hauptklasse für das Casino-Spiel-UI. * @@ -20,6 +19,9 @@ import java.io.IOException; */ public class CasinoGameUI extends Application { + private static final int DEFAULT_WIDTH = 1200; + private static final int DEFAULT_HEIGHT = 800; + /** * Startet die Haupt-Stage der Anwendung. * @@ -28,11 +30,13 @@ public class CasinoGameUI extends Application { */ @Override public void start(Stage stage) throws IOException { - FXMLLoader fxmlLoader = new FXMLLoader(CasinoGameUI.class.getResource("/ui-structure/casinogameui.fxml")); - Scene scene = new Scene(fxmlLoader.load(), 1200, 800); + FXMLLoader fxmlLoader = + new FXMLLoader(CasinoGameUI.class.getResource("/ui-structure/casinogameui.fxml")); + Scene scene = new Scene(fxmlLoader.load(), DEFAULT_WIDTH, DEFAULT_HEIGHT); stage.setTitle("Casono (GAME)"); - stage.getIcons().add(new javafx.scene.image.Image(getClass().getResource("/images/logoinverted.png").toExternalForm())); + String iconPath = getClass().getResource("/images/logoinverted.png").toExternalForm(); + stage.getIcons().add(new javafx.scene.image.Image(iconPath)); stage.setScene(scene); stage.setFullScreen(true); stage.show(); From 1c5c4c8a3457d1bd890abd82dd3bf5ecc177ddb4 Mon Sep 17 00:00:00 2001 From: Julian Kropff Date: Sat, 14 Mar 2026 16:48:20 +0100 Subject: [PATCH 10/11] style: apply Checkstyle fixes --- .../client/ui/gameui/CasinoGameController.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java index 2862c99..91e3075 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java @@ -1,18 +1,8 @@ package ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui; -// import javafx.application.Platform; import javafx.fxml.FXML; import javafx.scene.control.Label; -// import javafx.scene.control.TextField; -// import javafx.scene.input.KeyCode; -// import javafx.scene.input.KeyEvent; -// import javafx.scene.input.MouseEvent; -// import javafx.scene.layout.HBox; -// import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; -// import javafx.stage.Stage; -// import javafx.scene.Scene; -// import javafx.scene.web.WebView; /** * Controller für die Casino-Spielfläche. @@ -32,7 +22,8 @@ public class CasinoGameController { @FXML private Label welcomeText; @FXML private VBox casinoTable; - // TODO: Test-Logik: wird durch echte Spielinteraktionen ersetzt, sobald die GameEngine fertig ist + // TODO: Test-Logik: wird durch echte Spielinteraktionen ersetzt, + // sobald die GameEngine fertig ist @FXML public void onTableClick() { welcomeText.setText("Einsatz akzeptiert!"); From c411e9c560d6012c89ddde959473ae6b1d29089f Mon Sep 17 00:00:00 2001 From: Julian Kropff Date: Sat, 14 Mar 2026 16:51:18 +0100 Subject: [PATCH 11/11] style: apply Checkstyle fixes --- .../CasinoBrowserController.java | 560 ++++++++++++------ 1 file changed, 370 insertions(+), 190 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/CasinoBrowserController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/CasinoBrowserController.java index d650221..282582a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/CasinoBrowserController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/CasinoBrowserController.java @@ -1,23 +1,33 @@ package ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.gameuicomponents; +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.CookiePolicy; +import java.net.URI; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; -import javafx.scene.control.*; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.layout.*; +import javafx.scene.input.KeyCode; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; import javafx.scene.shape.Rectangle; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import javafx.stage.Stage; -import java.net.*; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; - /** * Experimenteller integrierter Browser für Casono. * @@ -49,10 +59,27 @@ import java.util.Set; * - Automatische Cookie-Löschung beim Schließen */ public class CasinoBrowserController { + private static final Set TRUSTED_DOMAINS = new HashSet<>(); + private static final CookieManager COOKIE_MANAGER = new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER); + private static final org.apache.logging.log4j.Logger LOGGER = + org.apache.logging.log4j.LogManager.getLogger(CasinoBrowserController.class); + + private static final int LOGO_HEIGHT = 40; + private static final int CORNER_RADIUS = 40; + private static final int HBOX_SPACIN = 10; + private static final int VBOX_SPACING = 10; + private static final int PADDING_SIZE = 10; + private static final int WINDOW_WIDTH = 1200; + private static final int WINDOW_HEIGHT = 800; + private static final int ALERT_WIDTH = 600; + private static final int ALERT_HEIGHT = 300; + private static final String LOGO_PATH = "/images/logoinverted.png"; + private static final String LOGO_PATH_MAIN = "/images/logo.png"; + static { CookieHandler.setDefault(COOKIE_MANAGER); @@ -104,174 +131,44 @@ public class CasinoBrowserController { engine.setJavaScriptEnabled(false); - // Popup Blocker - engine.setCreatePopupHandler(config -> { - Alert alert = new Alert(Alert.AlertType.WARNING); - alert.setTitle("Popup blockiert"); - alert.setHeaderText(null); - alert.setContentText("Popup wurde aus Sicherheitsgründen blockiert."); - - try { - Image logo = - new Image(CasinoBrowserController.class.getResourceAsStream("/images/logoinverted.png")); - Image logomain = - new Image(CasinoBrowserController.class.getResourceAsStream("/images/logo.png")); - - if (logo != null) { - Stage alertStage = (Stage) alert.getDialogPane().getScene().getWindow(); - if (alertStage != null) { - alertStage.getIcons().add(logo); - } - } - - if (logomain != null) { - ImageView logoView = new ImageView(logomain); - logoView.setFitHeight(40); - logoView.setPreserveRatio(true); - alert.setGraphic(logoView); - } - } catch (Exception e) { - System.err.println("Logo konnte nicht geladen werden"); - } - - alert.showAndWait(); - return null; - }); + configurePopupBlocker(engine); webView.getStyleClass().add("web-view"); - StackPane webContainer = new StackPane(webView); - webContainer.getStyleClass().add("browser-web-view"); - VBox.setVgrow(webContainer, Priority.ALWAYS); + StackPane webContainer = createWebContainer(webView); Rectangle clip = new Rectangle(); - clip.setArcWidth(40); - clip.setArcHeight(40); + clip.setArcWidth(CORNER_RADIUS); + clip.setArcHeight(CORNER_RADIUS); webView.setClip(clip); - webView.widthProperty().addListener((o,a,b)->clip.setWidth(b.doubleValue())); - webView.heightProperty().addListener((o,a,b)->clip.setHeight(b.doubleValue())); + webView.widthProperty().addListener((o, a, b) -> + clip.setWidth(b.doubleValue())); + webView.heightProperty().addListener((o, a, b) -> + clip.setHeight(b.doubleValue())); - ImageView browserLogo = new ImageView(); + ImageView browserLogo = loadLogos(stage); - try { - Image logo = - new Image(CasinoBrowserController.class.getResourceAsStream("/images/logoinverted.png")); - Image logomain = - new Image(CasinoBrowserController.class.getResourceAsStream("/images/logo.png")); + TextField urlField = createUrlField(url); + Label securityLabel = createSecurityLabel(); - if (logo != null) { - stage.getIcons().add(logo); - } + Button jsToggle = createJsToggle(engine); + Button backBtn = createBackButton(engine); + Button fwdBtn = createForwardButton(engine); + Button reloadBtn = createReloadButton(engine); + Button closeBtn = createCloseButton(stage, webView); + configureUrlEvents(engine, urlField, securityLabel); - if (logomain != null) { - browserLogo.setImage(logomain); - browserLogo.setFitHeight(30); - browserLogo.setPreserveRatio(true); - } - } catch (Exception e) { - System.err.println("Logo konnte nicht geladen werden"); - } - - // URL Feld - TextField urlField = new TextField(url); - urlField.getStyleClass().add("gray-input-field"); - HBox.setHgrow(urlField, Priority.ALWAYS); - - Label securityLabel = new Label("SICHER"); - securityLabel.getStyleClass().add("security-label"); - - // JS Toggle - Button jsToggle = new Button("JS EINSCHALTEN"); - jsToggle.getStyleClass().add("red-button"); - - jsToggle.setOnAction(e -> { - javascriptEnabled = !javascriptEnabled; - engine.setJavaScriptEnabled(javascriptEnabled); - - if (javascriptEnabled) { - jsToggle.setText("JS AUSSCHALTEN"); - jsToggle.getStyleClass().removeAll("red-button"); - jsToggle.getStyleClass().add("yellow-button"); - - } else { - jsToggle.setText("JS EINSCHALTEN"); - jsToggle.getStyleClass().removeAll("yellow-button"); - jsToggle.getStyleClass().add("red-button"); - } - }); - - // Navigation - Button backBtn = new Button("<"); - backBtn.getStyleClass().add("gray-button"); - backBtn.setOnAction(e -> { - if(engine.getHistory().getCurrentIndex() > 0){ - engine.getHistory().go(-1); - } - }); - - Button fwdBtn = new Button(">"); - fwdBtn.getStyleClass().add("gray-button"); - fwdBtn.setOnAction(e -> { - if(engine.getHistory().getCurrentIndex() < - engine.getHistory().getEntries().size()-1){ - engine.getHistory().go(1); - } - }); - - // Reload Button - Button reloadBtn = new Button("⟳"); - reloadBtn.getStyleClass().add("gray-button"); - reloadBtn.setOnAction(e -> engine.reload()); - - // Close - Button closeBtn = new Button("X"); - closeBtn.getStyleClass().add("red-button"); - closeBtn.setOnAction(e -> { - webView.getEngine().load("about:blank"); - clearCookies(); - stage.close(); - - }); - - // URL Enter - urlField.setOnAction(e -> - loadUrlSafely(engine, urlField.getText(), securityLabel)); - engine.locationProperty().addListener((obs,o,n)->urlField.setText(n)); - - // Taskbar - HBox taskbar = new HBox( - 10, - browserLogo, - backBtn, - fwdBtn, - reloadBtn, - urlField, - jsToggle, - securityLabel, - closeBtn + HBox taskbar = new HBox(HBOX_SPACIN, browserLogo, backBtn, fwdBtn, + reloadBtn, urlField, jsToggle, securityLabel, closeBtn ); taskbar.getStyleClass().add("taskbar-browser"); taskbar.setAlignment(Pos.CENTER_LEFT); - // Root - VBox root = new VBox(10, taskbar, webContainer); - root.getStyleClass().add("browser-root"); - root.setPadding(new Insets(10)); - Scene scene = new Scene(root,1200,800); - var css = CasinoBrowserController.class.getResource("/ui-structure/casinogameui.css"); + Scene scene = createScene(taskbar, webContainer); - if(css != null) { - scene.getStylesheets().add(css.toExternalForm()); - } - - // F5 Reload - scene.setOnKeyPressed(event -> { - switch (event.getCode()) { - case F5 -> engine.reload(); - } - }); + configureKeyEvents(scene, engine); stage.setScene(scene); stage.setTitle("Casono Browser"); @@ -280,6 +177,276 @@ public class CasinoBrowserController { }); } + /** + * WebView Container + * + * @param webView WebView Inhalt + * @return StackPane Container + */ + public static StackPane createWebContainer(WebView webView) { + StackPane webContainer = new StackPane(webView); + webContainer.getStyleClass().add("browser-web-view"); + VBox.setVgrow(webContainer, Priority.ALWAYS); + + return webContainer; + } + + /** + * Popup Blocker + * + * @param engine WebEngine nutzen + */ + public static void configurePopupBlocker(WebEngine engine) { + engine.setCreatePopupHandler(config -> { + Alert alert = new Alert(Alert.AlertType.WARNING); + alert.setTitle("Popup blockiert"); + alert.setHeaderText(null); + alert.setContentText("Popup wurde aus Sicherheitsgründen blockiert."); + + try { + var stream = CasinoBrowserController.class.getResourceAsStream(LOGO_PATH); + Image logo = new Image(stream); + + // Variable 'streamM' abgekürzt, um das 100-Zeichen-Limit (LineLength) + // einzuhalten + var streamM = CasinoBrowserController.class.getResourceAsStream(LOGO_PATH_MAIN); + Image logomain = new Image(streamM); + + if (logo != null) { + Stage alertStage = (Stage) alert.getDialogPane().getScene().getWindow(); + if (alertStage != null) { + alertStage.getIcons().add(logo); + } + } + + if (logomain != null) { + ImageView logoView = new ImageView(logomain); + logoView.setFitHeight(LOGO_HEIGHT); + logoView.setPreserveRatio(true); + alert.setGraphic(logoView); + } + } catch (Exception e) { + LOGGER.error("Logo konnte nicht geladen werden"); + } + + alert.showAndWait(); + return null; + }); + } + + /** + * Logos laden + * + * @param stage Fenster Stage + * @return ImageView Logo + */ + private static ImageView loadLogos(Stage stage) { + ImageView browserLogo = new ImageView(); + + try { + var stream = CasinoBrowserController.class.getResourceAsStream(LOGO_PATH); + Image logo = new Image(stream); + + // Variable 'streamM' abgekürzt, um das 100-Zeichen-Limit (LineLength) + // einzuhalten + var streamM = CasinoBrowserController.class.getResourceAsStream(LOGO_PATH_MAIN); + Image logomain = new Image(streamM); + + if (logo != null) { + stage.getIcons().add(logo); + } + + if (logomain != null) { + browserLogo.setImage(logomain); + browserLogo.setFitHeight(LOGO_HEIGHT); + browserLogo.setPreserveRatio(true); + } + } catch (Exception e) { + LOGGER.error("Logo konnte nicht geladen werden"); + } + + return browserLogo; + } + + /** + * URL Feld + * + * @param url Start URL + * @return TextField Eingabe + */ + public static TextField createUrlField(String url) { + TextField urlField = new TextField(url); + urlField.getStyleClass().add("gray-input-field"); + HBox.setHgrow(urlField, Priority.ALWAYS); + + return urlField; + } + + /** + * Sicherheits Label + * + * @return Label Anzeige + */ + public static Label createSecurityLabel() { + Label securityLabel = new Label("SICHER"); + securityLabel.getStyleClass().add("security-label"); + + return securityLabel; + } + + /** + * JS Toggle + * + * @param engine WebEngine nutzen + * @return Button Umschalten + */ + public static Button createJsToggle(WebEngine engine){ + Button jsToggle = new Button("JS EINSCHALTEN"); + jsToggle.getStyleClass().add("red-button"); + + jsToggle.setOnAction(e -> { + javascriptEnabled = !javascriptEnabled; + engine.setJavaScriptEnabled(javascriptEnabled); + + if (javascriptEnabled) { + jsToggle.setText("JS AUSSCHALTEN"); + jsToggle.getStyleClass().removeAll("red-button"); + jsToggle.getStyleClass().add("yellow-button"); + + } else { + jsToggle.setText("JS EINSCHALTEN"); + jsToggle.getStyleClass().removeAll("yellow-button"); + jsToggle.getStyleClass().add("red-button"); + } + }); + + return jsToggle; + } + + /** + * Zurück Button + * + * @param engine WebEngine nutzen + * @return Button Zurück + */ + public static Button createBackButton(WebEngine engine) { + Button backBtn = new Button("<"); + backBtn.getStyleClass().add("gray-button"); + backBtn.setOnAction(e -> { + if (engine.getHistory().getCurrentIndex() > 0) { + engine.getHistory().go(-1); + } + }); + + return backBtn; + } + + /** + * Vorwärts Button + * + * @param engine WebEngine nutzen + * @return Button Vorwärts + */ + public static Button createForwardButton(WebEngine engine) { + Button fwdBtn = new Button(">"); + fwdBtn.getStyleClass().add("gray-button"); + fwdBtn.setOnAction(e -> { + if (engine.getHistory().getCurrentIndex() < + engine.getHistory().getEntries().size() - 1) { + engine.getHistory().go(1); + } + }); + + return fwdBtn; + } + + /** + * Reload Button + * + * @param engine WebEngine nutzen + * @return Button Reload + */ + public static Button createReloadButton(WebEngine engine) { + Button reloadBtn = new Button("⟳"); + reloadBtn.getStyleClass().add("gray-button"); + reloadBtn.setOnAction(e -> engine.reload()); + return reloadBtn; + } + + /** + * Close Button + * + * @param stage Fenster Stage + * @param webView WebView Inhalt + * @return Button Schließen + */ + public static Button createCloseButton(Stage stage, WebView webView) { + Button closeBtn = new Button("X"); + closeBtn.getStyleClass().add("red-button"); + closeBtn.setOnAction(e -> { + webView.getEngine().load("about:blank"); + clearCookies(); + stage.close(); + + }); + + return closeBtn; + } + + /** + * URL Events + * + * @param engine WebEngine nutzen + * @param urlField URL Textfeld + * @param securityLabel Sicherheits Label + */ + public static void configureUrlEvents(WebEngine engine, + TextField urlField, + Label securityLabel) { + urlField.setOnAction(e -> + loadUrlSafely(engine, urlField.getText(), securityLabel)); + engine.locationProperty().addListener((obs, o, n) -> + urlField.setText(n)); + } + + /** + * Scene erstellen + * + * @param taskbar Taskbar HBox + * @param webContainer Web Container + * @return Scene Fenster + */ + public static Scene createScene(HBox taskbar, StackPane webContainer) { + VBox root = new VBox(VBOX_SPACING, taskbar, webContainer); + root.getStyleClass().add("browser-root"); + root.setPadding(new Insets(PADDING_SIZE)); + + Scene scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT); + + var css = CasinoBrowserController.class + .getResource("/ui-structure/casinogameui.css"); + + if (css != null) { + scene.getStylesheets().add(css.toExternalForm()); + } + + return scene; + } + + /** + * Key Events + * + * @param scene Scene Fenster + * @param engine WebEngine nutzen + */ + public static void configureKeyEvents(Scene scene, WebEngine engine) { + scene.setOnKeyPressed(event -> { + if (event.getCode() == KeyCode.F5) { + engine.reload(); + } + }); + } + /** * Lädt eine URL in den Browser, nachdem grundlegende Sicherheitsprüfungen * durchgeführt wurden. @@ -299,20 +466,20 @@ public class CasinoBrowserController { */ private static void loadUrlSafely(WebEngine engine, String url, Label securityLabel) { try { - if(!url.startsWith("http")) { + if (!url.startsWith("http")) { url = "https://" + url; } URI uri = new URI(url); // HTTPS Pflicht - if(!"https".equalsIgnoreCase(uri.getScheme())) { + if (!"https".equalsIgnoreCase(uri.getScheme())) { securityLabel.setText("BLOCKIERT"); return; } String host = uri.getHost(); - if(host == null) { + if (host == null) { securityLabel.setText("ERROR"); return; } @@ -321,44 +488,57 @@ public class CasinoBrowserController { boolean trusted = TRUSTED_DOMAINS.stream().anyMatch(domain -> host.equals(domain) || host.endsWith("." + domain)); - if(!trusted) { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - - alert.setTitle("Unbekannte Website"); - alert.setHeaderText("Diese Website ist nicht bekannt"); - alert.setContentText( - host + "\n\nDiese Seite ist nicht vom Casono Browser verifiziert.\nMöchten Sie sie trotzdem öffnen?" - ); - - Image logo = new Image(CasinoBrowserController.class.getResourceAsStream("/images/logoinverted.png")); - if (logo != null) { - Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); - if(stage != null) { - stage.getIcons().add(logo); - } - ImageView logomain = new ImageView(logo); - logomain.setFitHeight(50); - logomain.setPreserveRatio(true); - alert.setGraphic(logomain); - } - - alert.getDialogPane().setPrefSize(600,300); - Optional result = alert.showAndWait(); - - if(result.isEmpty() || result.get() != ButtonType.OK) { + if (!trusted) { + if (!showUnknownWebsiteAlert(host)) { securityLabel.setText("BLOCKIERT"); return; } - securityLabel.setText("UNBEKANNT"); } else { securityLabel.setText("SICHER"); } engine.load(uri.toString()); - } - - catch (Exception e) { + } catch (Exception e) { securityLabel.setText("ERROR"); } } + + /** + * Zeigt Warnung an. + * + * @param host Website Host + * @return OK gedrückt + */ + private static boolean showUnknownWebsiteAlert(String host) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + + alert.setTitle("Unbekannte Website"); + alert.setHeaderText("Diese Website ist nicht bekannt"); + alert.setContentText( + host + "\n\nDiese Seite ist nicht vom " + + "Casono Browser verifiziert.\nMöchten Sie sie trotzdem öffnen?" + ); + + var stream = CasinoBrowserController.class.getResourceAsStream(LOGO_PATH); + Image logo = new Image(stream); + if (logo != null) { + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + if (stage != null) { + stage.getIcons().add(logo); + } + ImageView logomain = new ImageView(logo); + logomain.setFitHeight(LOGO_HEIGHT); + logomain.setPreserveRatio(true); + alert.setGraphic(logomain); + } + + alert.getDialogPane().setPrefSize(ALERT_WIDTH, ALERT_HEIGHT); + Optional result = alert.showAndWait(); + + if (result.isEmpty() || result.get() != ButtonType.OK) { + return false; + } + + return true; + } } \ No newline at end of file