Feat: Added lobby-level player rename handling and mapping synchronization

This commit is contained in:
Jona Walpert
2026-04-15 21:04:57 +02:00
parent ec916aa98c
commit 7ff274269e
2 changed files with 75 additions and 0 deletions
@@ -70,6 +70,30 @@ public class Lobby {
return playerNames.remove(playerName); 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) { public void initGame(GameController controller) {
this.gameController = controller; this.gameController = controller;
} }
@@ -1,5 +1,6 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby; 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 ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby.Lobby.AddResult;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; 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}. * 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 * This is a small helper that keeps iteration logic centralized and avoids leaking internal