diff --git a/documents/docs/networking/commands/protocol-document.md b/documents/docs/networking/commands/protocol-document.md index 2a5aca9..f4177c3 100644 --- a/documents/docs/networking/commands/protocol-document.md +++ b/documents/docs/networking/commands/protocol-document.md @@ -1111,4 +1111,58 @@ GET_LOBBY_STATUS ID=1 CODE=LOBBY_NOT_FOUND MESSAGE=Lobby not found 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 ``` \ No newline at end of file diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java index 6d43f19..9f6f4a8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java @@ -41,8 +41,25 @@ public class LobbyClient { * @return The id of the newly created lobby, as returned by the server. */ public int createLobby() { - String response = client.processCommand("CREATE_LOBBY").getFirst(); - return Integer.parseInt(response); + List lines = client.processCommand("CREATE_LOBBY"); + + List 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); } /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index 5dedaf3..b693217 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -239,6 +239,20 @@ public class ServerApp { .get_lobby_status.GetLobbyStatusHandler( 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 parserDispatcher.register( "JOIN_LOBBY", diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyHandler.java new file mode 100644 index 0000000..b86b145 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyHandler.java @@ -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 { + 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())); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyParser.java new file mode 100644 index 0000000..00040f8 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyParser.java @@ -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 { + @Override + public CreateLobbyRequest parse(PrimitiveRequest primitiveRequest) { + return new CreateLobbyRequest(primitiveRequest.context()); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyRequest.java new file mode 100644 index 0000000..669a0d0 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyRequest.java @@ -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); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyResponse.java new file mode 100644 index 0000000..cb7371f --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/lobby/create_lobby/CreateLobbyResponse.java @@ -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()); + } +}