diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakadexEntryModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakadexEntryModel.java index 7d165b5..ddc3919 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakadexEntryModel.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakadexEntryModel.java @@ -1,6 +1,5 @@ package fr.epita.assistants.yakamon.data.model; -import fr.epita.assistants.yakamon.utils.ElementType; import jakarta.persistence.*; @Entity diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/ItemEntity.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/ItemEntity.java index 97f8f22..3395967 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/ItemEntity.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/ItemEntity.java @@ -1,7 +1,6 @@ package fr.epita.assistants.yakamon.domain.entity; import fr.epita.assistants.yakamon.utils.tile.ItemType; -import java.util.Objects; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/PlayerEntity.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/PlayerEntity.java index 7788d6d..012bbe0 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/PlayerEntity.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/PlayerEntity.java @@ -1,9 +1,15 @@ package fr.epita.assistants.yakamon.domain.entity; import java.time.LocalDateTime; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +@NoArgsConstructor +@AllArgsConstructor public class PlayerEntity { + public UUID uuid; public String name; public Integer posX; public Integer posY; diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/InventoryService.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/InventoryService.java new file mode 100644 index 0000000..f9a4993 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/InventoryService.java @@ -0,0 +1,24 @@ +package fr.epita.assistants.yakamon.domain.service; + +import fr.epita.assistants.yakamon.data.model.ItemModel; +import fr.epita.assistants.yakamon.data.repository.ItemRepository; +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.utils.ErrorCode; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.List; + +@ApplicationScoped +public class InventoryService { + + @Inject + ItemRepository itemRepository; + + public List getInventory() { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + return itemRepository.listAll(); + } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/PlayerService.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/PlayerService.java index edc7d3e..d8bd07c 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/PlayerService.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/PlayerService.java @@ -9,13 +9,16 @@ import fr.epita.assistants.yakamon.data.repository.PlayerRepository; import fr.epita.assistants.yakamon.data.repository.YakadexRepository; import fr.epita.assistants.yakamon.data.repository.YakamonRepository; import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.PlayerEntity; import fr.epita.assistants.yakamon.domain.entity.TileEntity; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; import fr.epita.assistants.yakamon.utils.Direction; import fr.epita.assistants.yakamon.utils.ErrorCode; import fr.epita.assistants.yakamon.utils.Point; import fr.epita.assistants.yakamon.utils.tile.Collectible; import fr.epita.assistants.yakamon.utils.tile.CollectibleUtils; import fr.epita.assistants.yakamon.utils.tile.ItemType; +import fr.epita.assistants.yakamon.utils.tile.TerrainType; import fr.epita.assistants.yakamon.utils.tile.YakamonInfo; import fr.epita.assistants.yakamon.utils.tile.YakamonType; import jakarta.enterprise.context.ApplicationScoped; @@ -25,7 +28,8 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; -import java.util.UUID; +import java.util.HashMap; +import java.util.Map; @ApplicationScoped public class PlayerService { @@ -92,7 +96,7 @@ public class PlayerService { } @Transactional - public YakamonModel catchYakamon() { + public YakamonEntity catchYakamon() { if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { ErrorCode.GAME_NOT_STARTED.throwException(); } @@ -183,7 +187,12 @@ public class PlayerService { player.lastCatch = LocalDateTime.now(); playerRepository.persist(player); - return newYakamon; + return new YakamonEntity( + newYakamon.id, + newYakamon.nickname, + newYakamon.yakadex_entry_id.id, + newYakamon.energy_points + ); } private void checkMovementDelay(PlayerModel player) { @@ -237,4 +246,120 @@ public class PlayerService { ); } } + + private void checkCollectDelay(PlayerModel player) { + String tickDurationStr = System.getenv("JWS_TICK_DURATION"); + String collectDelayStr = System.getenv("JWS_COLLECT_DELAY"); + + if (tickDurationStr == null || collectDelayStr == null) { + return; + } + + try { + long tickDuration = Long.parseLong(tickDurationStr); + long collectDelay = Long.parseLong(collectDelayStr); + long requiredDelay = tickDuration * collectDelay; + + LocalDateTime now = LocalDateTime.now(); + long elapsed = ChronoUnit.MILLIS.between(player.lastCollect, now); + + if (elapsed < requiredDelay) { + throw new WebApplicationException(Response.status(429).build()); + } + } catch (NumberFormatException e) { + ErrorCode.BAD_REQUEST.throwException( + "Invalid environment variables" + ); + } + } + + @Transactional + public PlayerEntity getPlayerInfo() { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + PlayerModel player = playerRepository.findAll().firstResult(); + if (player == null) { + ErrorCode.BAD_REQUEST.throwException("Player not found"); + } + + return new PlayerEntity( + player.id, + player.name, + player.posX, + player.posY, + player.lastMove, + player.lastCatch, + player.lastCollect, + player.lastFeed + ); + } + + @Transactional + public Map collect() { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + PlayerModel player = playerRepository.findAll().firstResult(); + if (player == null) { + ErrorCode.BAD_REQUEST.throwException("Player not found"); + } + + checkCollectDelay(player); + + TileEntity[][] map = GameEntity.INSTANCE.map; + if (map == null) { + ErrorCode.INVALID_MAP.throwException("Map not loaded"); + } + + int x = player.posX; + int y = player.posY; + + if (y < 0 || y >= map.length || x < 0 || x >= map[y].length) { + ErrorCode.BAD_REQUEST.throwException("Invalid position"); + } + + TileEntity tile = map[y][x]; + if ( + tile == null || tile.collectible == null || tile.collectible == 'N' + ) { + throw new WebApplicationException( + Response.status(400) + .entity("No collectible at this position") + .build() + ); + } + + Collectible collectible = CollectibleUtils.getCollectible( + tile.collectible + ); + if (collectible instanceof ItemType) { + ItemType itemType = (ItemType) collectible; + ItemModel item = itemRepository + .find("type", itemType) + .firstResult(); + if (item == null) { + item = new ItemModel(); + item.type = itemType; + item.quantity = 1; + itemRepository.persist(item); + } else { + item.quantity += 1; + itemRepository.persist(item); + } + } + + tile.collectible = 'N'; + player.lastCollect = LocalDateTime.now(); + playerRepository.persist(player); + + Map response = new HashMap<>(); + Map tileData = new HashMap<>(); + tileData.put("terrainType", TerrainType.getTerrain(tile.terrain)); + tileData.put("collectible", collectible); + response.put("tileType", tileData); + return response; + } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/TeamService.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/TeamService.java index 3f12a02..60ea6c7 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/TeamService.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/TeamService.java @@ -1,3 +1,149 @@ package fr.epita.assistants.yakamon.domain.service; -public class TeamService {} +import fr.epita.assistants.yakamon.data.model.YakadexEntryModel; +import fr.epita.assistants.yakamon.data.model.YakamonModel; +import fr.epita.assistants.yakamon.data.repository.YakadexRepository; +import fr.epita.assistants.yakamon.data.repository.YakamonRepository; +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; +import fr.epita.assistants.yakamon.utils.ErrorCode; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@ApplicationScoped +public class TeamService { + + @Inject + YakamonRepository yakamonRepository; + + @Inject + YakadexRepository yakadexRepository; + + public List getTeam() { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + List models = yakamonRepository.listAll(); + List entities = new ArrayList<>(); + + for (YakamonModel model : models) { + entities.add( + new YakamonEntity( + model.id, + model.nickname, + model.yakadex_entry_id.id, + model.energy_points + ) + ); + } + + return entities; + } + + @Transactional + public YakamonEntity evolve(UUID uuid) { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + YakamonModel yakamon = yakamonRepository.find("id", uuid).firstResult(); + if (yakamon == null) { + ErrorCode.BAD_REQUEST.throwException("Yakamon not found"); + } + + YakadexEntryModel entry = yakamon.yakadex_entry_id; + if (entry.evolution_id == null) { + ErrorCode.BAD_REQUEST.throwException("This yakamon cannot evolve"); + } + + if (yakamon.energy_points < entry.evolve_threshold) { + ErrorCode.BAD_REQUEST.throwException( + "Not enough energy points to evolve" + ); + } + + YakadexEntryModel evolution = yakadexRepository + .find("id", entry.evolution_id.id) + .firstResult(); + yakamon.yakadex_entry_id = evolution; + yakamonRepository.persist(yakamon); + + return new YakamonEntity( + yakamon.id, + yakamon.nickname, + yakamon.yakadex_entry_id.id, + yakamon.energy_points + ); + } + + @Transactional + public YakamonEntity feed(UUID uuid, Integer quantity) { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + if (quantity == null || quantity <= 0) { + ErrorCode.BAD_REQUEST.throwException("Invalid quantity"); + } + + YakamonModel yakamon = yakamonRepository.find("id", uuid).firstResult(); + if (yakamon == null) { + ErrorCode.BAD_REQUEST.throwException("Yakamon not found"); + } + + yakamon.energy_points += quantity; + yakamonRepository.persist(yakamon); + + return new YakamonEntity( + yakamon.id, + yakamon.nickname, + yakamon.yakadex_entry_id.id, + yakamon.energy_points + ); + } + + @Transactional + public void release(UUID uuid) { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + YakamonModel yakamon = yakamonRepository.find("id", uuid).firstResult(); + if (yakamon == null) { + ErrorCode.BAD_REQUEST.throwException("Yakamon not found"); + } + + yakamonRepository.delete(yakamon); + } + + @Transactional + public YakamonEntity rename(UUID uuid, String newName) { + if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) { + ErrorCode.GAME_NOT_STARTED.throwException(); + } + + if (newName == null || newName.isBlank()) { + ErrorCode.BAD_REQUEST.throwException("Invalid name"); + } + + YakamonModel yakamon = yakamonRepository.find("id", uuid).firstResult(); + if (yakamon == null) { + ErrorCode.BAD_REQUEST.throwException("Yakamon not found"); + } + + yakamon.nickname = newName; + yakamonRepository.persist(yakamon); + + return new YakamonEntity( + yakamon.id, + yakamon.nickname, + yakamon.yakadex_entry_id.id, + yakamon.energy_points + ); + } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/YakadexService.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/YakadexService.java index 42285af..2476b00 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/YakadexService.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/YakadexService.java @@ -2,9 +2,8 @@ package fr.epita.assistants.yakamon.domain.service; import fr.epita.assistants.yakamon.data.model.YakadexEntryModel; import fr.epita.assistants.yakamon.data.repository.YakadexRepository; -import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; -import fr.epita.assistants.yakamon.presentation.api.response.YakadexAllInfosResponse; -import fr.epita.assistants.yakamon.presentation.api.response.YakadexInfosResponse; +import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity; +import fr.epita.assistants.yakamon.utils.ElementType; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import java.util.ArrayList; @@ -16,7 +15,7 @@ public class YakadexService { @Inject YakadexRepository yakadexRepository; - public YakadexAllInfosResponse getAllEntries(Boolean onlyMissing) { + public List getAllEntries(Boolean onlyMissing) { List entries; if (onlyMissing != null && onlyMissing) { @@ -25,25 +24,29 @@ public class YakadexService { entries = yakadexRepository.listAll(); } - List dtos = new ArrayList<>(); + List entities = new ArrayList<>(); for (YakadexEntryModel entry : entries) { - YakadexEntry dto = new YakadexInfosResponse( + YakadexEntryEntity entity = new YakadexEntryEntity( entry.id, entry.name, - entry.first_type, - entry.second_type, + entry.first_type != null + ? ElementType.valueOf(entry.first_type) + : null, + entry.second_type != null + ? ElementType.valueOf(entry.second_type) + : null, entry.evolve_threshold, null, entry.caught, entry.description ); - dtos.add(dto); + entities.add(entity); } - return new YakadexAllInfosResponse(dtos.toArray(new YakadexEntry[0])); + return entities; } - public YakadexInfosResponse getEntryById(Integer id) { + public YakadexEntryEntity getEntryById(Integer id) { YakadexEntryModel entry = yakadexRepository .find("id = ?1", id) .firstResult(); @@ -52,11 +55,15 @@ public class YakadexService { return null; } - return new YakadexInfosResponse( + return new YakadexEntryEntity( entry.id, entry.name, - entry.first_type, - entry.second_type, + entry.first_type != null + ? ElementType.valueOf(entry.first_type) + : null, + entry.second_type != null + ? ElementType.valueOf(entry.second_type) + : null, entry.evolve_threshold, null, entry.caught, diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/GameResource.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/GameResource.java index dd8218c..e6d167e 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/GameResource.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/GameResource.java @@ -1,15 +1,22 @@ package fr.epita.assistants.yakamon.presentation.rest; import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.TileEntity; import fr.epita.assistants.yakamon.domain.service.GameService; import fr.epita.assistants.yakamon.presentation.api.request.StartGameRequest; -import fr.epita.assistants.yakamon.presentation.api.response.StartGameResponse; +import fr.epita.assistants.yakamon.utils.tile.Collectible; +import fr.epita.assistants.yakamon.utils.tile.CollectibleUtils; +import fr.epita.assistants.yakamon.utils.tile.ItemType; +import fr.epita.assistants.yakamon.utils.tile.YakamonType; +import jakarta.inject.Inject; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import java.util.HashMap; +import java.util.Map; import java.util.logging.Logger; @Path("/start") @@ -21,6 +28,9 @@ public class GameResource { GameResource.class.getName() ); + @Inject + private GameService gameService; + @POST @Path("/") public Response start(StartGameRequest request) { @@ -48,24 +58,87 @@ public class GameResource { ); try { - GameService gameService = new GameService(); - GameEntity startedGame = gameService.startGame( - request.mapPath, - request.playerName - ); - LOGGER.info( - "Game started at: " + - (startedGame != null ? startedGame.startTime : "unknown") - ); + gameService.startGame(request.mapPath, request.playerName); + LOGGER.info("Game started successfully"); - // StartGameResponse response = new StartGameResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + TileEntity[][] map = GameEntity.INSTANCE.map; + Map[][] tiles = new Map[map.length][]; + + for (int y = 0; y < map.length; y++) { + tiles[y] = new Map[map[y].length]; + for (int x = 0; x < map[y].length; x++) { + TileEntity tile = map[y][x]; + Map tileData = new HashMap<>(); + tileData.put("terrainType", getTerrainType(tile.terrain)); + + Map collectibleData = new HashMap<>(); + String collectibleType = getCollectibleType( + tile.collectible + ); + String collectibleValue = getCollectibleValue( + tile.collectible + ); + + if (collectibleType != null) { + collectibleData.put("type", collectibleType); + collectibleData.put("value", collectibleValue); + } + + tileData.put("collectible", collectibleData); + tiles[y][x] = tileData; + } + } + + Map response = new HashMap<>(); + response.put("tiles", tiles); + return Response.ok(response).build(); } catch (Exception e) { - return Response.status( - 400, - "Invalid path or invalid name provided." - ).build(); + LOGGER.severe("Failed to start game: " + e.getMessage()); + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid path or invalid name provided.") + .build(); } } + + private String getTerrainType(Character terrain) { + return switch (terrain) { + case 'G' -> "GRASS"; + case 'M' -> "MOUNTAIN"; + case 'R' -> "ROCK"; + case 'S' -> "SAND"; + case 'W' -> "WATER"; + case 'L' -> "LAVA"; + default -> "GRASS"; + }; + } + + private String getCollectibleType(Character collectible) { + if (collectible == 'N') { + return null; + } + + Collectible c = CollectibleUtils.getCollectible(collectible); + if (c instanceof ItemType) { + return "ITEM"; + } else if (c instanceof YakamonType) { + return "YAKAMON"; + } + + return null; + } + + private String getCollectibleValue(Character collectible) { + if (collectible == 'N') { + return null; + } + + Collectible c = CollectibleUtils.getCollectible(collectible); + if (c instanceof ItemType) { + return ((ItemType) c).name(); + } else if (c instanceof YakamonType) { + return ((YakamonType) c).name(); + } + + return null; + } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/HelloWorldResource.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/HelloWorldResource.java deleted file mode 100644 index fb62d4b..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/HelloWorldResource.java +++ /dev/null @@ -1,22 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.rest; - -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; - -@Path("/hello") -@Produces(MediaType.TEXT_PLAIN) -@Consumes(MediaType.TEXT_PLAIN) -public class HelloWorldResource { - - @GET - @Path("/") - public String helloWorld() { - return "Hello, world!"; - } - - @GET - @Path("/{name}") - public String helloWorld(@PathParam("name") String name) { - return "Hello " + name + "!"; - } -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/InventoryResource.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/InventoryResource.java index 757b215..ff1c655 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/InventoryResource.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/InventoryResource.java @@ -1,20 +1,29 @@ package fr.epita.assistants.yakamon.presentation.rest; +import fr.epita.assistants.yakamon.data.model.ItemModel; import fr.epita.assistants.yakamon.domain.service.GameService; +import fr.epita.assistants.yakamon.domain.service.InventoryService; import fr.epita.assistants.yakamon.presentation.api.response.GetInventoryResponse; +import jakarta.inject.Inject; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; @Path("/inventory") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class InventoryResource { - private final GameService gameService = new GameService(); + @Inject + private GameService gameService; + + @Inject + private InventoryService inventoryService; @GET public Response getInventory() { @@ -23,9 +32,30 @@ public class InventoryResource { .entity("Game not started") .build(); } - // TODO service - // GetInventoryResponse response = inventoryService.getInventory(); - // return Response.ok(response).build(); - return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + + try { + List items = inventoryService.getInventory(); + List responseItems = new ArrayList<>(); + GetInventoryResponse temp = new GetInventoryResponse(responseItems); + + for (ItemModel item : items) { + GetInventoryResponse.Items responseItem = temp.new Items(); + GetInventoryResponse.ItemType itemType = temp.new ItemType(); + itemType.type = item.type.name(); + itemType.value = item.type.name(); + responseItem.itemType = itemType; + responseItem.quantity = item.quantity; + responseItems.add(responseItem); + } + + GetInventoryResponse response = new GetInventoryResponse( + responseItems + ); + return Response.ok(response).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/PlayerResource.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/PlayerResource.java index 2ac486c..fdfd8e4 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/PlayerResource.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/PlayerResource.java @@ -1,17 +1,17 @@ package fr.epita.assistants.yakamon.presentation.rest; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; import fr.epita.assistants.yakamon.domain.service.GameService; import fr.epita.assistants.yakamon.domain.service.PlayerService; import fr.epita.assistants.yakamon.presentation.api.request.PlayerMoveRequest; -import fr.epita.assistants.yakamon.presentation.api.response.GetInventoryResponse; import fr.epita.assistants.yakamon.presentation.api.response.PlayerCatchResponse; -import fr.epita.assistants.yakamon.presentation.api.response.PlayerCollectResponse; import fr.epita.assistants.yakamon.presentation.api.response.PlayerInfosResponse; import fr.epita.assistants.yakamon.presentation.api.response.PlayerMoveResponse; import jakarta.inject.Inject; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import java.time.format.DateTimeFormatter; @Path("/") @Consumes(MediaType.APPLICATION_JSON) @@ -34,12 +34,12 @@ public class PlayerResource { } try { - var yakamon = playerService.catchYakamon(); + YakamonEntity yakamon = playerService.catchYakamon(); var response = new PlayerCatchResponse( - yakamon.id.toString(), + yakamon.uuid.toString(), yakamon.nickname, - yakamon.yakadex_entry_id.id, - yakamon.energy_points + yakamon.yakadexId, + yakamon.energyPoints ); return Response.ok(response).build(); } catch (jakarta.ws.rs.WebApplicationException e) { @@ -59,8 +59,17 @@ public class PlayerResource { .entity("Game not started") .build(); } - // TODO service - return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + + try { + var tileData = playerService.collect(); + return Response.ok(tileData).build(); + } catch (jakarta.ws.rs.WebApplicationException e) { + return e.getResponse(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } @POST @@ -103,9 +112,34 @@ public class PlayerResource { .build(); } - // TODO service - // PlayerInfosResponse response = playerService.getInfos(...); - // return Response.ok(response).build(); - return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + try { + var player = playerService.getPlayerInfo(); + DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; + var response = new PlayerInfosResponse( + player.uuid.toString(), + player.name, + player.posX, + player.posY, + player.lastMove != null + ? player.lastMove.format(formatter) + : null, + player.lastCatch != null + ? player.lastCatch.format(formatter) + : null, + player.lastCollect != null + ? player.lastCollect.format(formatter) + : null, + player.lastFeed != null + ? player.lastFeed.format(formatter) + : null + ); + return Response.ok(response).build(); + } catch (jakarta.ws.rs.WebApplicationException e) { + return e.getResponse(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/TeamResource.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/TeamResource.java index 9f429b5..c52b5f9 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/TeamResource.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/TeamResource.java @@ -1,22 +1,32 @@ package fr.epita.assistants.yakamon.presentation.rest; +import fr.epita.assistants.yakamon.converter.EntityToDtoConverter; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; import fr.epita.assistants.yakamon.domain.service.GameService; +import fr.epita.assistants.yakamon.domain.service.TeamService; import fr.epita.assistants.yakamon.presentation.api.request.TeamFeedRequest; import fr.epita.assistants.yakamon.presentation.api.request.TeamRenameRequest; import fr.epita.assistants.yakamon.presentation.api.response.TeamEvolveResponse; import fr.epita.assistants.yakamon.presentation.api.response.TeamFeedResponse; import fr.epita.assistants.yakamon.presentation.api.response.TeamInfosResponse; import fr.epita.assistants.yakamon.presentation.api.response.TeamRenameResponse; +import jakarta.inject.Inject; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import java.util.List; +import java.util.UUID; @Path("/team") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public class TeamResource { - private final GameService gameService = new GameService(); + @Inject + private GameService gameService; + + @Inject + private TeamService teamService; @GET public Response getTeam() { @@ -25,10 +35,21 @@ public class TeamResource { .entity("Game not started") .build(); } - // TODO service - // TeamInfosResponse response = new TeamInfosResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + + try { + List team = teamService.getTeam(); + var actions = EntityToDtoConverter.toYakamonActions(team); + TeamInfosResponse response = new TeamInfosResponse( + actions.toArray( + new fr.epita.assistants.yakamon.presentation.api.YakamonAction[0] + ) + ); + return Response.ok(response).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } @POST @@ -45,10 +66,26 @@ public class TeamResource { .build(); } - // TODO service - // TeamEvolveResponse response = new TeamEvolveResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + try { + UUID yakemonId = UUID.fromString(uuid); + YakamonEntity evolved = teamService.evolve(yakemonId); + var action = EntityToDtoConverter.toYakamonAction(evolved); + TeamEvolveResponse response = new TeamEvolveResponse( + action.uuid, + action.nickname, + action.yakadexId, + action.energyPoints + ); + return Response.ok(response).build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid uuid format") + .build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } @POST @@ -75,10 +112,26 @@ public class TeamResource { .build(); } - // TODO service - // TeamFeedResponse response = new TeamFeedResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + try { + UUID yakemonId = UUID.fromString(uuid); + YakamonEntity fed = teamService.feed(yakemonId, request.quantity); + var action = EntityToDtoConverter.toYakamonAction(fed); + TeamFeedResponse response = new TeamFeedResponse( + action.uuid, + action.nickname, + action.yakadexId, + action.energyPoints + ); + return Response.ok(response).build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid uuid format") + .build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } @DELETE @@ -95,9 +148,19 @@ public class TeamResource { .build(); } - // TODO service - // return 204 (No Content) to match the subject - return Response.noContent().build(); + try { + UUID yakemonId = UUID.fromString(uuid); + teamService.release(yakemonId); + return Response.noContent().build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid uuid format") + .build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } @PATCH @@ -116,15 +179,38 @@ public class TeamResource { .entity("Missing or invalid uuid") .build(); } - if (request == null) { + if ( + request == null || + request.newNickname == null || + request.newNickname.isBlank() + ) { return Response.status(Response.Status.BAD_REQUEST) - .entity("Missing request body") + .entity("Missing or invalid name") .build(); } - // TODO service - // TeamRenameResponse response = new TeamRenameResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + try { + UUID yakemonId = UUID.fromString(uuid); + YakamonEntity renamed = teamService.rename( + yakemonId, + request.newNickname + ); + var action = EntityToDtoConverter.toYakamonAction(renamed); + TeamRenameResponse response = new TeamRenameResponse( + action.uuid, + action.nickname, + action.yakadexId, + action.energyPoints + ); + return Response.ok(response).build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid uuid format") + .build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/YakadexResource.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/YakadexResource.java index 54c7102..dd3f0bc 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/YakadexResource.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/YakadexResource.java @@ -1,13 +1,16 @@ package fr.epita.assistants.yakamon.presentation.rest; +import fr.epita.assistants.yakamon.converter.EntityToDtoConverter; +import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity; import fr.epita.assistants.yakamon.domain.service.GameService; import fr.epita.assistants.yakamon.domain.service.YakadexService; +import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; import fr.epita.assistants.yakamon.presentation.api.response.YakadexAllInfosResponse; -import fr.epita.assistants.yakamon.presentation.api.response.YakadexInfosResponse; import jakarta.inject.Inject; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import java.util.List; @Path("/yakadex") @Produces(MediaType.APPLICATION_JSON) @@ -30,9 +33,15 @@ public class YakadexResource { .build(); } - YakadexAllInfosResponse response = yakadexService.getAllEntries( + List entries = yakadexService.getAllEntries( onlyMissing ); + List dtos = EntityToDtoConverter.toYakadexEntries( + entries + ); + YakadexAllInfosResponse response = new YakadexAllInfosResponse( + dtos.toArray(new YakadexEntry[0]) + ); return Response.ok(response).build(); } @@ -45,12 +54,13 @@ public class YakadexResource { .build(); } - YakadexInfosResponse response = yakadexService.getEntryById(id); + YakadexEntryEntity entry = yakadexService.getEntryById(id); - if (response == null) { + if (entry == null) { return Response.status(Response.Status.NOT_FOUND).build(); } - return Response.ok(response).build(); + YakadexEntry dto = EntityToDtoConverter.toYakadexEntry(entry); + return Response.ok(dto).build(); } }