diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ClientApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ClientApp.java index 6b7267b..41fa767 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ClientApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ClientApp.java @@ -1,26 +1,44 @@ package ch.unibas.dmi.dbis.cs108.casono.client; -/** - * Entry point for the Casono client application. Handles client startup and connection parameters. - */ +import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService; +import ch.unibas.dmi.dbis.cs108.casono.client.network.LobbyClient; +import ch.unibas.dmi.dbis.cs108.casono.client.network.LoginResult; import ch.unibas.dmi.dbis.cs108.casono.client.ui.Launcher; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** - * Entry point for the Casono client application. Handles client startup and connection parameters. + * Entry point and bootstrap helper for the Casono client application. * - *
Default constructor for the application. + *
This class is responsible for two tasks: - performing an optional startup LOGIN when a
+ * username is supplied on the command line, and - providing a shared {@link ClientService} instance
+ * that the UI can reuse so the initial connection remains active.
*/
public class ClientApp {
private static final Logger LOGGER = LogManager.getLogger(ClientApp.class);
+ /** Shared client connection used when a username is provided at startup. */
+ private static volatile ClientService sharedClientService;
+
/** Default constructor. */
public ClientApp() {
// Default constructor
}
+ /**
+ * Returns the shared {@link ClientService} instance created during startup, or {@code null} if
+ * none exists. The UI may call this to reuse the connection that already performed the initial
+ * LOGIN.
+ */
+ public static ClientService getSharedClientService() {
+ return sharedClientService;
+ }
+
+ private static void setSharedClientService(ClientService cs) {
+ sharedClientService = cs;
+ }
+
/**
* Starts the client application with the given address.
*
@@ -36,12 +54,69 @@ public class ClientApp {
int port = Integer.parseInt(parts[1]);
LOGGER.info("You've selected the client. It will connect port {} at host {}", port, host);
- // Pass connection defaults and optional username to the UI via system properties
System.setProperty("casono.server.host", host);
System.setProperty("casono.server.port", String.valueOf(port));
+ // If a username was provided, create a shared connection and perform
+ // the initial LOGIN asynchronously on that connection. The connection
+ // is intentionally NOT closed so the UI can reuse it.
if (username != null && !username.isBlank()) {
- System.setProperty("casono.username", username);
+ try {
+ ClientService clientService = new ClientService(host, port);
+ setSharedClientService(clientService);
+
+ java.util.concurrent.ExecutorService bg =
+ java.util.concurrent.Executors.newSingleThreadExecutor(
+ r -> {
+ Thread t = new Thread(r);
+ t.setDaemon(true);
+ t.setName("casono-startup-login");
+ return t;
+ });
+ bg.submit(
+ () -> {
+ try {
+ LobbyClient lobbyClient = new LobbyClient(clientService);
+ LoginResult res = lobbyClient.login(username);
+ LOGGER.info(
+ "Assigned username='{}' id={}",
+ res.getUsername(),
+ res.getId());
+ } catch (RuntimeException e) {
+ LOGGER.warn("Startup login failed: {}", e.getMessage());
+ } catch (Exception e) {
+ LOGGER.warn("Unexpected error during startup login", e);
+ } finally {
+ bg.shutdown();
+ }
+ });
+ } catch (RuntimeException e) {
+ LOGGER.warn(
+ "Could not establish initial connection for startup login: {}",
+ e.getMessage());
+ // UI will create its own connection when it initializes
+ }
}
- Launcher.main(new String[] {});
+
+ if (username != null && !username.isBlank()) {
+ Launcher.main(new String[] {arg, username});
+ } else {
+ Launcher.main(new String[] {arg});
+ }
+ }
+
+ /**
+ * Main entry point. Usage: If a username is provided the application attempts a startup LOGIN on the shared
+ * connection; the UI will still start and will reuse the connection when possible. The username
+ * is not propagated via a system property for UI display.
+ */
+ public static void main(String[] args) {
+ if (args == null || args.length == 0) {
+ throw new IllegalArgumentException("Address argument required: