Merge branch 'fix/143-client-rejoin-flow' into 'main'

fix: add client leave-lobby rejoin flow

Closes #143

See merge request cs108-fs26/Gruppe-13!175
This commit was merged in pull request #331.
This commit is contained in:
Jona Walpert
2026-05-13 21:33:11 +00:00
3 changed files with 110 additions and 79 deletions
@@ -127,6 +127,15 @@ public class LobbyClient {
client.processCommand("JOIN_LOBBY ID=" + lobbyId); client.processCommand("JOIN_LOBBY ID=" + lobbyId);
} }
/**
* Request the server to mark the current user as absent from the given lobby.
*
* @param lobbyId the lobby to leave
*/
public void leaveLobby(int lobbyId) {
client.processCommand("LEAVE_LOBBY ID=" + lobbyId);
}
/** /**
* Logs in to the server with the given username by sending a "LOGIN" command. * Logs in to the server with the given username by sending a "LOGIN" command.
* *
@@ -393,91 +393,92 @@ public class CasinoGameController {
// Test method to demonstrate the UI functionality with sample data. // Test method to demonstrate the UI functionality with sample data.
// @FXML // @FXML
// public void uiTest() { // public void uiTest() {
// if (communityCardsBox == null) { // if (communityCardsBox == null) {
// LOGGER.info("communityCardsBox is NULL"); // LOGGER.info("communityCardsBox is NULL");
// return; // return;
// } // }
// //
// try { // try {
// renderCommunityCards( // renderCommunityCards(
// List.of( // List.of(
// new Card("ace", "hearts"), // new Card("ace", "hearts"),
// new Card("king", "spades"), // new Card("king", "spades"),
// new Card("10", "diamonds"))); // new Card("10", "diamonds")));
// //
// renderPlayerCards(List.of(new Card("10", "spades"), new Card("king", "spades"))); // renderPlayerCards(List.of(new Card("10", "spades"), new Card("king",
// } catch (Exception e) { // "spades")));
// e.printStackTrace(); // } catch (Exception e) {
// } // e.printStackTrace();
// }
// //
// Player mathis = new Player(PlayerId.of("Mathis"), 20000); // Player mathis = new Player(PlayerId.of("Mathis"), 20000);
// mathis.setState(PlayerState.ACTIVE); // mathis.setState(PlayerState.ACTIVE);
// //
// Player jona = new Player(PlayerId.of("Jona"), 20000); // Player jona = new Player(PlayerId.of("Jona"), 20000);
// jona.setState(PlayerState.FOLDED); // jona.setState(PlayerState.FOLDED);
// //
// Player lars = new Player(PlayerId.of("Lars"), 20000); // Player lars = new Player(PlayerId.of("Lars"), 20000);
// lars.setState(PlayerState.ACTIVE); // lars.setState(PlayerState.ACTIVE);
// //
// player1Controller.setPlayer(mathis); // player1Controller.setPlayer(mathis);
// player2Controller.setPlayer(jona); // player2Controller.setPlayer(jona);
// player3Controller.setPlayer(lars); // player3Controller.setPlayer(lars);
// //
// LOGGER.info( // LOGGER.info(
// "Player 1: " // "Player 1: "
// + mathis.getName() // + mathis.getName()
// + " | $" // + " | $"
// + mathis.getChips() // + mathis.getChips()
// + " | " // + " | "
// + mathis.getState()); // + mathis.getState());
// LOGGER.info( // LOGGER.info(
// "Player 2: " // "Player 2: "
// + jona.getName() // + jona.getName()
// + " | $" // + " | $"
// + jona.getChips() // + jona.getChips()
// + " | " // + " | "
// + jona.getState()); // + jona.getState());
// LOGGER.info( // LOGGER.info(
// "Player 3: " // "Player 3: "
// + lars.getName() // + lars.getName()
// + " | $" // + " | $"
// + lars.getChips() // + lars.getChips()
// + " | " // + " | "
// + lars.getState()); // + lars.getState());
// //
// if (playerStatusController != null) { // if (playerStatusController != null) {
// playerStatusController.setPlayer(mathis); // playerStatusController.setPlayer(mathis);
// } else { // } else {
// LOGGER.warning("PlayerStatusController is NULL"); // LOGGER.warning("PlayerStatusController is NULL");
// } // }
// //
// javafx.stage.Screen screen = javafx.stage.Screen.getPrimary(); // javafx.stage.Screen screen = javafx.stage.Screen.getPrimary();
// double screenHeight = screen.getBounds().getHeight(); // double screenHeight = screen.getBounds().getHeight();
// //
// casinoTableInnerBox.setTranslateY(-screenHeight * 0.08); // casinoTableInnerBox.setTranslateY(-screenHeight * 0.08);
// playerCardsBox.setTranslateY(screenHeight * 0.35); // playerCardsBox.setTranslateY(screenHeight * 0.35);
// //
// renderPot(500); // renderPot(500);
// //
// lars.removeChips(500); // lars.removeChips(500);
// LOGGER.info("Lars: $" + lars.getChips()); // LOGGER.info("Lars: $" + lars.getChips());
// //
// player3Controller.refresh(); // player3Controller.refresh();
// //
// mathis.fall(); // mathis.fall();
// player1Controller.refresh(); // player1Controller.refresh();
// //
// GameState s = new GameState(); // GameState s = new GameState();
// s.dealer = 3; // s.dealer = 3;
// highlightDealer(s); // highlightDealer(s);
// //
// s.phase = "FLOP"; // s.phase = "FLOP";
// //
// updateGameInfo(s); // updateGameInfo(s);
// //
// s.winnerIndex = 1; // s.winnerIndex = 1;
// //
// updateGameInfo(s); // updateGameInfo(s);
// } // }
/** Start the UI update loop. */ /** Start the UI update loop. */
@@ -1747,22 +1748,22 @@ public class CasinoGameController {
*/ */
// private void animateCardHover(ImageView view, boolean hover) { // private void animateCardHover(ImageView view, boolean hover) {
// //
// double scale = hover ? HOVER_SCALE_ON : HOVER_SCALE_OFF; // double scale = hover ? HOVER_SCALE_ON : HOVER_SCALE_OFF;
// double lift = hover ? HOVER_LIFT_ON : HOVER_LIFT_OFF; // double lift = hover ? HOVER_LIFT_ON : HOVER_LIFT_OFF;
// //
// javafx.animation.ScaleTransition st = // javafx.animation.ScaleTransition st =
// new javafx.animation.ScaleTransition( // new javafx.animation.ScaleTransition(
// javafx.util.Duration.millis(HOVER_DURATION_MS), view); // javafx.util.Duration.millis(HOVER_DURATION_MS), view);
// st.setToX(scale); // st.setToX(scale);
// st.setToY(scale); // st.setToY(scale);
// //
// javafx.animation.TranslateTransition tt = // javafx.animation.TranslateTransition tt =
// new javafx.animation.TranslateTransition( // new javafx.animation.TranslateTransition(
// javafx.util.Duration.millis(HOVER_DURATION_MS), view); // javafx.util.Duration.millis(HOVER_DURATION_MS), view);
// tt.setToY(lift); // tt.setToY(lift);
// //
// st.play(); // st.play();
// tt.play(); // tt.play();
// } // }
/** /**
@@ -2156,6 +2157,9 @@ public class CasinoGameController {
if (controller == null) { if (controller == null) {
return; return;
} }
if (chatClientService != null && chatLobbyId >= 0) {
controller.setLobbyContext(new LobbyClient(chatClientService), chatLobbyId);
}
controller.setLobbyActionAnnouncer(this::sendLobbyActionMessage); controller.setLobbyActionAnnouncer(this::sendLobbyActionMessage);
} }
@@ -52,6 +52,8 @@ public class TaskbarController {
@FXML private Label moneyLabel; @FXML private Label moneyLabel;
private GameService gameService; private GameService gameService;
private LobbyClient lobbyClient;
private int lobbyId = -1;
private PlayerId myPlayerId; private PlayerId myPlayerId;
private String myPlayerName; private String myPlayerName;
private GameState lastState; private GameState lastState;
@@ -242,6 +244,12 @@ public class TaskbarController {
this.myPlayerName = myPlayerId != null ? normalizeIdentifier(myPlayerId.value()) : null; this.myPlayerName = myPlayerId != null ? normalizeIdentifier(myPlayerId.value()) : null;
} }
/** Sets the lobby context so Exit can notify the server before closing. */
public void setLobbyContext(LobbyClient lobbyClient, int lobbyId) {
this.lobbyClient = lobbyClient;
this.lobbyId = lobbyId;
}
/** Sets the NotebookController reference for showing/hiding tips. */ /** Sets the NotebookController reference for showing/hiding tips. */
public void setNotebookController(NotebookController notebookController) { public void setNotebookController(NotebookController notebookController) {
this.notebookController = notebookController; this.notebookController = notebookController;
@@ -1622,6 +1630,16 @@ public class TaskbarController {
SoundManager.getInstance().playButtonClick(); SoundManager.getInstance().playButtonClick();
javafx.application.Platform.runLater( javafx.application.Platform.runLater(
() -> { () -> {
if (lobbyClient != null && lobbyId > 0) {
try {
lobbyClient.leaveLobby(lobbyId);
} catch (RuntimeException e) {
LOGGER.warn(
"Could not notify server about lobby leave: {}",
e.getMessage());
}
}
// Close game stage // Close game stage
javafx.stage.Stage currentStage = javafx.stage.Stage currentStage =
(javafx.stage.Stage) taskbar.getScene().getWindow(); (javafx.stage.Stage) taskbar.getScene().getWindow();