Merge branch 'feat/93-add-serverside-create-lobby-command' into 'main'

Feat: Add createLobby command on server side

Closes #93

See merge request cs108-fs26/Gruppe-13!117
This commit was merged in pull request #273.
This commit is contained in:
Jona Walpert
2026-04-12 10:10:41 +00:00
7 changed files with 154 additions and 2 deletions
@@ -1111,4 +1111,58 @@ GET_LOBBY_STATUS ID=1
CODE=LOBBY_NOT_FOUND CODE=LOBBY_NOT_FOUND
MESSAGE=Lobby not found MESSAGE=Lobby not found
END END
```
## CREATE_LOBBY command
The `CREATE_LOBBY` command requests the server to create a new lobby and return its identifier.
### Required pre-execution checks
None.
### Request Parameters
No parameters.
### Implementation notes
- Parser: CreateLobbyParser — constructs a CreateLobbyRequest from the incoming PrimitiveRequest context (no parameters are read).
- Handler: CreateLobbyHandler — calls LobbyManager.createNewLobby(null).
- If the returned LobbyId is null, the handler dispatches an ErrorResponse with code `LOBBIES_FULL` and message "Maximum number of 8 lobbies reached".
- On success, the handler dispatches a CreateLobbyResponse containing the new lobby id.
### Success Response
| Field | Type | Description |
| :-------- | :--- | :---------- |
| `LOBBY_ID`| `int`| Numeric id of the newly created lobby |
### Error Response
| Code | Description |
| :---------- | :--------------------------------------------------------------------- |
| `LOBBIES_FULL` | The server cannot create a new lobby because the maximum number of lobbies has been reached |
### Example Request
```
CREATE_LOBBY
```
### Example Success Response
```
+OK
LOBBY_ID=1
END
```
### Example Error Response
```
-ERR
CODE=LOBBIES_FULL
MESSAGE=Maximum number of 8 lobbies reached
END
``` ```
@@ -41,8 +41,25 @@ public class LobbyClient {
* @return The id of the newly created lobby, as returned by the server. * @return The id of the newly created lobby, as returned by the server.
*/ */
public int createLobby() { public int createLobby() {
String response = client.processCommand("CREATE_LOBBY").getFirst(); List<String> lines = client.processCommand("CREATE_LOBBY");
return Integer.parseInt(response);
List<RequestParameter> params = ClientService.convertToRequestParameters(lines);
for (RequestParameter p : params) {
if ("LOBBY_ID".equalsIgnoreCase(p.key())) {
return Integer.parseInt(p.value());
}
}
// Fallback for simple legacy/test servers that return the id as a single plain
// line
if (!lines.isEmpty()) {
try {
return Integer.parseInt(lines.get(0));
} catch (NumberFormatException ignored) {
}
}
throw new RuntimeException("No LOBBY_ID in response: " + lines);
} }
/** /**
@@ -239,6 +239,20 @@ public class ServerApp {
.get_lobby_status.GetLobbyStatusHandler( .get_lobby_status.GetLobbyStatusHandler(
responseDispatcher, lobbyManager, userRegistry)); responseDispatcher, lobbyManager, userRegistry));
// CREATE_LOBBY registration
parserDispatcher.register(
"CREATE_LOBBY",
new ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby.create_lobby
.CreateLobbyParser());
commandRouter.register(
ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby.create_lobby
.CreateLobbyRequest.class,
(ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler<
ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby
.create_lobby.CreateLobbyRequest>)
new ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby.create_lobby
.CreateLobbyHandler(responseDispatcher, lobbyManager));
// JOIN_LOBBY registration // JOIN_LOBBY registration
parserDispatcher.register( parserDispatcher.register(
"JOIN_LOBBY", "JOIN_LOBBY",
@@ -0,0 +1,32 @@
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby.create_lobby;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby.LobbyId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby.LobbyManager;
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.ErrorResponse;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
public class CreateLobbyHandler extends CommandHandler<CreateLobbyRequest> {
private final LobbyManager lobbyManager;
public CreateLobbyHandler(ResponseDispatcher responseDispatcher, LobbyManager lobbyManager) {
super(responseDispatcher);
this.lobbyManager = lobbyManager;
}
@Override
public void execute(CreateLobbyRequest request) {
LobbyId id = lobbyManager.createNewLobby(null);
if (id == null) {
responseDispatcher.dispatch(
new ErrorResponse(
request.getContext(),
"LOBBIES_FULL",
"Maximum number of 8 lobbies reached"));
return;
}
responseDispatcher.dispatch(new CreateLobbyResponse(request.getContext(), id.value()));
}
}
@@ -0,0 +1,11 @@
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby.create_lobby;
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest;
public class CreateLobbyParser implements CommandParser<CreateLobbyRequest> {
@Override
public CreateLobbyRequest parse(PrimitiveRequest primitiveRequest) {
return new CreateLobbyRequest(primitiveRequest.context());
}
}
@@ -0,0 +1,10 @@
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby.create_lobby;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext;
public class CreateLobbyRequest extends Request {
public CreateLobbyRequest(RequestContext context) {
super(context);
}
}
@@ -0,0 +1,14 @@
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.lobby.create_lobby;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.SuccessResponse;
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBodyBuilder;
/** Sends ID of newly created lobby back to client. */
public class CreateLobbyResponse extends SuccessResponse {
public CreateLobbyResponse(RequestContext context, int lobbyId) {
super(
context,
new ResponseBodyBuilder().param("LOBBY_ID", String.valueOf(lobbyId)).build());
}
}