Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cfd13b43fc | |||
| 5916c26b86 | |||
| d734f815e8 | |||
| c5518d64a3 | |||
| f1e09cb328 | |||
| b06cd571b0 | |||
| 3ee1e63577 | |||
| 8f4ce1db80 | |||
| 066d4ee8c3 | |||
| 5ed455c20d | |||
| 938ef71c2a | |||
| 09e8822bef | |||
| 35297775dc | |||
| 77dad54c84 |
@@ -0,0 +1,16 @@
|
|||||||
|
## Milestone Achievement
|
||||||
|
<!-- The recommended type is: Task -->
|
||||||
|
|
||||||
|
### Category
|
||||||
|
<!-- Category of the milestone (Process, Product, Presentation) -->
|
||||||
|
|
||||||
|
### Title
|
||||||
|
<!-- Title of the milestone (equal to the title in the milestone catalog (https://p9.dmi.unibas.ch/cs108/2026) -->
|
||||||
|
|
||||||
|
### Rewarded points on completion
|
||||||
|
<!-- Number of points rewarded on completion of the milestone -->
|
||||||
|
|
||||||
|
### Description of milestone
|
||||||
|
<!-- Description of the milestone (equal to the description in the milestone catalog (https://p9.dmi.unibas.ch/cs108/2026) -->
|
||||||
|
|
||||||
|
/label ~achievement
|
||||||
@@ -12,6 +12,7 @@ Since this project is part of a course at the University of Basel, the [Code of
|
|||||||
- [Creating an issue](#creating-an-issue)
|
- [Creating an issue](#creating-an-issue)
|
||||||
- [During implementation](#during-implementation)
|
- [During implementation](#during-implementation)
|
||||||
- [Collaborative work](#collaborative-work)
|
- [Collaborative work](#collaborative-work)
|
||||||
|
- [Milestone Achievements](#milestone-achievements)
|
||||||
- [Git Workflow](#git-workflow)
|
- [Git Workflow](#git-workflow)
|
||||||
- [Creating a branch](#creating-a-branch)
|
- [Creating a branch](#creating-a-branch)
|
||||||
- [Working on a branch](#working-on-a-branch)
|
- [Working on a branch](#working-on-a-branch)
|
||||||
@@ -49,6 +50,20 @@ Issue or Task in GitLab **before** any implementation begins.
|
|||||||
centrally visible and searchable.
|
centrally visible and searchable.
|
||||||
- Before starting work that overlaps with an existing issue, check its comment thread first to avoid duplicating effort.
|
- Before starting work that overlaps with an existing issue, check its comment thread first to avoid duplicating effort.
|
||||||
|
|
||||||
|
### Milestone Achievements
|
||||||
|
For every process and product-related milestone achievement, there is a dedicated milestone task.
|
||||||
|
|
||||||
|
- **Do not create a branch directly from a milestone task.**
|
||||||
|
- Instead, create a normal implementation task (using the regular task template) and reference the milestone task there.
|
||||||
|
- In the merge request, reference the milestone task again.
|
||||||
|
- If the milestone condition is fully met, you may use `Closing #<id>` to close the milestone task.
|
||||||
|
- If it is only partially addressed, use `Relates to #<id>` or `Contributes to #<id>` so the milestone task stays open.
|
||||||
|
|
||||||
|
Milestone tasks may, but do not have to, be assigned to a specific person.
|
||||||
|
|
||||||
|
- If multiple people are involved, contribution is tracked through linked tasks that reference the milestone task.
|
||||||
|
- For small topics, a Milestone Achievement may be assigned to one person. Others should only contribute on request and should not modify components introduced under that achievement without coordination.
|
||||||
|
|
||||||
|
|
||||||
## Git Workflow
|
## Git Workflow
|
||||||
We use a **feature branch -> main** strategy. The `main` branch is always in a releasable state.
|
We use a **feature branch -> main** strategy. The `main` branch is always in a releasable state.
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.server;
|
package ch.unibas.dmi.dbis.cs108.casono.server;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.add_player.AddPlayerHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.add_player.AddPlayerParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.add_player.AddPlayerRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.bet.PlayerBetHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.bet.PlayerBetParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.bet.PlayerBetRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.call.PlayerCallHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.call.PlayerCallParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.call.PlayerCallRequest;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameParser;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameParser;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameRequest;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameRequest;
|
||||||
@@ -15,6 +24,9 @@ import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.logout.LogoutRequest;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingParser;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingParser;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingRequest;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.raise.PlayerRaiseHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.raise.PlayerRaiseParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.raise.PlayerRaiseRequest;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserCleanupJob;
|
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserCleanupJob;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager;
|
||||||
@@ -85,9 +97,12 @@ public class ServerApp {
|
|||||||
/**
|
/**
|
||||||
* Registers command parsers and handlers.
|
* Registers command parsers and handlers.
|
||||||
*
|
*
|
||||||
* @param parserDispatcher the dispatcher responsible for parsing incoming commands
|
* @param parserDispatcher the dispatcher responsible for parsing incoming
|
||||||
* @param commandRouter the router that dispatches parsed commands to appropriate handlers
|
* commands
|
||||||
* @param responseDispatcher the dispatcher responsible for sending responses back to clients
|
* @param commandRouter the router that dispatches parsed commands to
|
||||||
|
* appropriate handlers
|
||||||
|
* @param responseDispatcher the dispatcher responsible for sending responses
|
||||||
|
* back to clients
|
||||||
*/
|
*/
|
||||||
private static void registerCommands(
|
private static void registerCommands(
|
||||||
CommandParserDispatcher parserDispatcher,
|
CommandParserDispatcher parserDispatcher,
|
||||||
@@ -113,5 +128,25 @@ public class ServerApp {
|
|||||||
parserDispatcher.register("LIST_USERS", new ListUsersParser());
|
parserDispatcher.register("LIST_USERS", new ListUsersParser());
|
||||||
commandRouter.register(
|
commandRouter.register(
|
||||||
ListUsersRequest.class, new ListUsersHandler(responseDispatcher, userRegistry));
|
ListUsersRequest.class, new ListUsersHandler(responseDispatcher, userRegistry));
|
||||||
|
|
||||||
|
// ADD_PLAYER
|
||||||
|
parserDispatcher.register("ADD_PLAYER", new AddPlayerParser());
|
||||||
|
commandRouter.register(AddPlayerRequest.class,
|
||||||
|
new AddPlayerHandler(userRegistry, responseDispatcher));
|
||||||
|
|
||||||
|
// BET
|
||||||
|
parserDispatcher.register("BET", new PlayerBetParser());
|
||||||
|
commandRouter.register(PlayerBetRequest.class,
|
||||||
|
new PlayerBetHandler(responseDispatcher));
|
||||||
|
|
||||||
|
// CALL
|
||||||
|
parserDispatcher.register("CALL", new PlayerCallParser());
|
||||||
|
commandRouter.register(PlayerCallRequest.class,
|
||||||
|
new PlayerCallHandler(responseDispatcher));
|
||||||
|
|
||||||
|
// RAISE
|
||||||
|
parserDispatcher.register("RAISE", new PlayerRaiseParser());
|
||||||
|
commandRouter.register(PlayerRaiseRequest.class,
|
||||||
|
new PlayerRaiseHandler(responseDispatcher));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.add_player;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.User;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.OkResponse;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the ADD_PLAYER command.
|
||||||
|
*/
|
||||||
|
public class AddPlayerHandler extends CommandHandler<AddPlayerRequest> {
|
||||||
|
private final UserRegistry userRegistry;
|
||||||
|
|
||||||
|
public AddPlayerHandler(UserRegistry userRegistry, ResponseDispatcher responseDispatcher) {
|
||||||
|
super(responseDispatcher);
|
||||||
|
this.userRegistry = userRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(AddPlayerRequest request) {
|
||||||
|
Optional<User> created = userRegistry.registerIfAvailable(request.getName(), request.getContext().sessionId());
|
||||||
|
if (created.isEmpty()) {
|
||||||
|
responseDispatcher.dispatch(new ErrorResponse(request.getContext(), "NAME_TAKEN", "Name already taken"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
responseDispatcher.dispatch(new OkResponse(request.getContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.add_player;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor.RequestParameterAccessor;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor.ParameterParseException;
|
||||||
|
|
||||||
|
/** Parser for the ADD_PLAYER command. */
|
||||||
|
public class AddPlayerParser implements CommandParser<AddPlayerRequest> {
|
||||||
|
@Override
|
||||||
|
public AddPlayerRequest parse(PrimitiveRequest primitiveRequest) {
|
||||||
|
RequestParameterAccessor accessor = new RequestParameterAccessor(primitiveRequest.parameters());
|
||||||
|
|
||||||
|
String name = accessor.require("NAME");
|
||||||
|
|
||||||
|
int chips = accessor.require("CHIPS", Integer::parseInt);
|
||||||
|
|
||||||
|
return new AddPlayerRequest(primitiveRequest.context(), name, chips);
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.add_player;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext;
|
||||||
|
|
||||||
|
/** Request data for the ADD_PLAYER command. */
|
||||||
|
public class AddPlayerRequest extends Request {
|
||||||
|
private final String name;
|
||||||
|
private final int chips;
|
||||||
|
|
||||||
|
public AddPlayerRequest(RequestContext context, String name, int chips) {
|
||||||
|
super(context);
|
||||||
|
this.name = name;
|
||||||
|
this.chips = chips;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChips() {
|
||||||
|
return chips;
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.bet;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.OkResponse;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the BET command.
|
||||||
|
*/
|
||||||
|
public class PlayerBetHandler extends CommandHandler<PlayerBetRequest> {
|
||||||
|
|
||||||
|
public PlayerBetHandler(ResponseDispatcher responseDispatcher) {
|
||||||
|
super(responseDispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PlayerBetRequest request) {
|
||||||
|
if (request.getAmount() < 0) {
|
||||||
|
responseDispatcher
|
||||||
|
.dispatch(new ErrorResponse(request.getContext(), "INVALID_AMOUNT", "Amount must be non-negative"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
responseDispatcher.dispatch(new OkResponse(request.getContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.bet;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor.RequestParameterAccessor;
|
||||||
|
|
||||||
|
/** Parser for the BET command. */
|
||||||
|
public class PlayerBetParser implements CommandParser<PlayerBetRequest> {
|
||||||
|
@Override
|
||||||
|
public PlayerBetRequest parse(PrimitiveRequest primitiveRequest) {
|
||||||
|
RequestParameterAccessor accessor = new RequestParameterAccessor(primitiveRequest.parameters());
|
||||||
|
|
||||||
|
int amount = accessor.require("AMOUNT", Integer::parseInt);
|
||||||
|
|
||||||
|
return new PlayerBetRequest(primitiveRequest.context(), amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.bet;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext;
|
||||||
|
|
||||||
|
/** Request for BET command. */
|
||||||
|
public class PlayerBetRequest extends Request {
|
||||||
|
private final int amount;
|
||||||
|
|
||||||
|
public PlayerBetRequest(RequestContext context, int amount) {
|
||||||
|
super(context);
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.call;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.OkResponse;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal handler for CALL: acknowledges the command.
|
||||||
|
*/
|
||||||
|
public class PlayerCallHandler extends CommandHandler<PlayerCallRequest> {
|
||||||
|
|
||||||
|
public PlayerCallHandler(ResponseDispatcher responseDispatcher) {
|
||||||
|
super(responseDispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PlayerCallRequest request) {
|
||||||
|
// TODO: integrate with game engine to process call.
|
||||||
|
responseDispatcher.dispatch(new OkResponse(request.getContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.call;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest;
|
||||||
|
|
||||||
|
/** Parser for the CALL command (no parameters). */
|
||||||
|
public class PlayerCallParser implements CommandParser<PlayerCallRequest> {
|
||||||
|
@Override
|
||||||
|
public PlayerCallRequest parse(PrimitiveRequest primitiveRequest) {
|
||||||
|
return new PlayerCallRequest(primitiveRequest.context());
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.call;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext;
|
||||||
|
|
||||||
|
/** Request for CALL command. */
|
||||||
|
public class PlayerCallRequest extends Request {
|
||||||
|
public PlayerCallRequest(RequestContext context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.fold;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.OkResponse;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
||||||
|
|
||||||
|
/** Minimal handler for FOLD: acknowledges the command. */
|
||||||
|
public class PlayerFoldHandler extends CommandHandler<PlayerFoldRequest> {
|
||||||
|
|
||||||
|
public PlayerFoldHandler(ResponseDispatcher responseDispatcher) {
|
||||||
|
super(responseDispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PlayerFoldRequest request) {
|
||||||
|
// TODO: integrate with game engine to process call.
|
||||||
|
responseDispatcher.dispatch(new OkResponse(request.getContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.fold;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest;
|
||||||
|
|
||||||
|
/** Parser for the FOLD command (no parameters). */
|
||||||
|
public class PlayerFoldParser implements CommandParser<PlayerFoldRequest> {
|
||||||
|
@Override
|
||||||
|
public PlayerFoldRequest parse(PrimitiveRequest primitiveRequest) {
|
||||||
|
return new PlayerFoldRequest(primitiveRequest.context());
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.fold;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext;
|
||||||
|
|
||||||
|
/** Request for FOLD command. */
|
||||||
|
public class PlayerFoldRequest extends Request {
|
||||||
|
public PlayerFoldRequest(RequestContext context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.raise;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.OkResponse;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal handler for RAISE: validates and acknowledges the command.
|
||||||
|
*/
|
||||||
|
public class PlayerRaiseHandler extends CommandHandler<PlayerRaiseRequest> {
|
||||||
|
|
||||||
|
public PlayerRaiseHandler(ResponseDispatcher responseDispatcher) {
|
||||||
|
super(responseDispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PlayerRaiseRequest request) {
|
||||||
|
int amount = request.getAmount();
|
||||||
|
|
||||||
|
if (amount < 0) {
|
||||||
|
responseDispatcher
|
||||||
|
.dispatch(new ErrorResponse(request.getContext(), "INVALID_AMOUNT", "Amount must be non-negative"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
responseDispatcher.dispatch(new OkResponse(request.getContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.raise;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor.RequestParameterAccessor;
|
||||||
|
|
||||||
|
/** Parser for the RAISE command. */
|
||||||
|
public class PlayerRaiseParser implements CommandParser<PlayerRaiseRequest> {
|
||||||
|
@Override
|
||||||
|
public PlayerRaiseRequest parse(PrimitiveRequest primitiveRequest) {
|
||||||
|
RequestParameterAccessor accessor = new RequestParameterAccessor(primitiveRequest.parameters());
|
||||||
|
|
||||||
|
int amount = accessor.require("AMOUNT", Integer::parseInt);
|
||||||
|
|
||||||
|
return new PlayerRaiseRequest(primitiveRequest.context(), amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.raise;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext;
|
||||||
|
|
||||||
|
/** Request for RAISE command. */
|
||||||
|
public class PlayerRaiseRequest extends Request {
|
||||||
|
private final int amount;
|
||||||
|
|
||||||
|
public PlayerRaiseRequest(RequestContext context, int amount) {
|
||||||
|
super(context);
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -6,7 +6,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor
|
|||||||
* @param <T> target type produced by the parser
|
* @param <T> target type produced by the parser
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
interface ThrowingParser<T> {
|
public interface ThrowingParser<T> {
|
||||||
/**
|
/**
|
||||||
* Parses the provided raw parameter value.
|
* Parses the provided raw parameter value.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user