From 7ff274269e4892317559aab2dc108b39a3e212b4 Mon Sep 17 00:00:00 2001 From: Jona Walpert Date: Wed, 15 Apr 2026 21:04:57 +0200 Subject: [PATCH] Feat: Added lobby-level player rename handling and mapping synchronization --- .../casono/server/domain/lobby/Lobby.java | 24 +++++++++ .../server/domain/lobby/LobbyManager.java | 51 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/Lobby.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/Lobby.java index 7653685..7aec356 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/Lobby.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/Lobby.java @@ -70,6 +70,30 @@ public class Lobby { return playerNames.remove(playerName); } + /** + * Renames a player in this lobby's player list. + * + * @param oldName old username + * @param newName new username + * @return true if renamed successfully + */ + public boolean renamePlayer(String oldName, String newName) { + if (oldName == null || newName == null) { + return false; + } + synchronized (playerNames) { + if (oldName.equals(newName)) { + return playerNames.contains(oldName); + } + int idx = playerNames.indexOf(oldName); + if (idx < 0 || playerNames.contains(newName)) { + return false; + } + playerNames.set(idx, newName); + return true; + } + } + public void initGame(GameController controller) { this.gameController = controller; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/LobbyManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/LobbyManager.java index cdeb574..0e58adf 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/LobbyManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/lobby/LobbyManager.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby; +import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId; import ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby.Lobby.AddResult; import java.time.Duration; import java.time.Instant; @@ -170,6 +171,56 @@ public class LobbyManager { } } + /** + * Renames a player across lobby mapping, lobby player list and running game ids. + * + * @param oldUsername old username + * @param newUsername new username + * @return true if rename was applied + */ + public synchronized boolean renamePlayer(String oldUsername, String newUsername) { + if (oldUsername == null || newUsername == null) { + return false; + } + if (oldUsername.equals(newUsername)) { + return true; + } + + LobbyId lobbyId = playerToLobby.get(oldUsername); + if (lobbyId == null) { + return true; + } + if (playerToLobby.containsKey(newUsername)) { + return false; + } + + Lobby lobby = activeLobbies.get(lobbyId); + if (lobby == null) { + playerToLobby.remove(oldUsername); + return true; + } + + boolean lobbyRenamed = lobby.renamePlayer(oldUsername, newUsername); + if (!lobbyRenamed) { + return false; + } + + if (lobby.getGameController() != null) { + boolean gameRenamed = + lobby.getGameController() + .renamePlayer(PlayerId.of(oldUsername), PlayerId.of(newUsername)); + if (!gameRenamed) { + // Best-effort rollback to keep structures consistent. + lobby.renamePlayer(newUsername, oldUsername); + return false; + } + } + + playerToLobby.remove(oldUsername); + playerToLobby.put(newUsername, lobbyId); + return true; + } + /** * Apply the given action to every player username in the lobby identified by {@code lobbyId}. * This is a small helper that keeps iteration logic centralized and avoids leaking internal