From c7629264b47e4f6b78912b77d06d3652230347f8 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Thu, 12 Feb 2026 18:03:15 +0100 Subject: [PATCH 1/9] Submission exercise-endpoints-20ab7bc --- .../presentation/rest/Endpoints.java | 27 ++++++++++++++++++- .../rest/request/ReverseRequest.java | 5 +++- .../rest/response/HelloResponse.java | 18 ++++--------- .../rest/response/ReverseResponse.java | 10 +++++++ 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java index 748799b..014cafb 100644 --- a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java +++ b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java @@ -1,5 +1,30 @@ package fr.epita.assistants.presentation.rest; -public class Endpoints { +import fr.epita.assistants.presentation.rest.request.ReverseRequest; +import fr.epita.assistants.presentation.rest.response.HelloResponse; +import fr.epita.assistants.presentation.rest.response.ReverseResponse; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +@Path("/") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class Endpoints { + String content; + @Path("/hello/{name}") + @GET + public Response greeting(@PathParam("name") String name) { + if (name == null || name.isEmpty()) { + return Response.status(400).build(); + } + HelloResponse response = new HelloResponse("Hello " + name); + return Response.ok(response).build(); + } + + @Path("/reverse") + @POST + public Response reverse(ReverseRequest r) { + return Response.ok(new ReverseResponse(r.content)).build(); + } } diff --git a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/request/ReverseRequest.java b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/request/ReverseRequest.java index 7311dad..8f42af8 100644 --- a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/request/ReverseRequest.java +++ b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/request/ReverseRequest.java @@ -1,5 +1,8 @@ package fr.epita.assistants.presentation.rest.request; -public class ReverseRequest { +import lombok.AllArgsConstructor; +@AllArgsConstructor +public class ReverseRequest { + public String content; } diff --git a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/HelloResponse.java b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/HelloResponse.java index 0a8c052..dc011e9 100644 --- a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/HelloResponse.java +++ b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/HelloResponse.java @@ -1,20 +1,12 @@ package fr.epita.assistants.presentation.rest.response; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; +import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import lombok.AllArgsConstructor; +import lombok.ToString; -@Path("/hello") -@Consumes(MediaType.TEXT_PLAIN) -@Produces(MediaType.TEXT_PLAIN) +@AllArgsConstructor public class HelloResponse { - @Path("/{name}") - @GET - public String greeting(@PathParam("name") String name) { - String content - Response.accepted(); - } + public String content; } diff --git a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/ReverseResponse.java b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/ReverseResponse.java index 9b3379d..147e217 100644 --- a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/ReverseResponse.java +++ b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/response/ReverseResponse.java @@ -1,5 +1,15 @@ package fr.epita.assistants.presentation.rest.response; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class ReverseResponse { + public String original; + public String reverse; + + public ReverseResponse(String original) { + this.original = original; + this.reverse = new StringBuilder(original).reverse().toString(); + } } From 43bdb74698b5897374ca995ecaf8e7ed886cbe52 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Thu, 12 Feb 2026 18:07:53 +0100 Subject: [PATCH 2/9] Submission exercises-database-c762926 --- .../main/java/fr/epita/assistants/data/model/CourseModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/src/main/java/fr/epita/assistants/data/model/CourseModel.java b/database/src/main/java/fr/epita/assistants/data/model/CourseModel.java index 5fe1cfb..428b667 100644 --- a/database/src/main/java/fr/epita/assistants/data/model/CourseModel.java +++ b/database/src/main/java/fr/epita/assistants/data/model/CourseModel.java @@ -8,5 +8,5 @@ import java.util.List; public class CourseModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) protected Long id; public String name; - public @ElementCollection @CollectionTable(name = "course_model_tags") @JoinColumn(name="course_id") List tag; + public @ElementCollection @CollectionTable(name = "course_model_tags", joinColumns = @JoinColumn(name = "course_id")) List tag; } From 8dca2f10c6d2935765d91f436878f31e635ae2ed Mon Sep 17 00:00:00 2001 From: Guillem George Date: Thu, 12 Feb 2026 19:44:18 +0100 Subject: [PATCH 3/9] models and archi --- .gitignore | 4 ++++ .../presentation/rest/Endpoints.java | 2 +- .../yakamon/data/model/GameModel.java | 10 ++++++++++ .../yakamon/data/model/ItemModel.java | 14 +++++++++++++ .../yakamon/data/model/PlayerModel.java | 19 ++++++++++++++++++ .../yakamon/data/model/YakadexEntryModel.java | 20 +++++++++++++++++++ .../yakamon/data/model/YakamonModel.java | 15 ++++++++++++++ .../yakamon/data/repository/.gitkeep | 0 .../assistants/yakamon/domain/entity/.gitkeep | 0 .../yakamon/domain/service/.gitkeep | 0 .../api/request/GetInventoryRequest.java | 7 +++++++ .../api/request/PlayerCatchRequest.java | 5 +++++ .../api/request/PlayerCollectRequest.java | 7 +++++++ .../api/request/PlayerInfosRequest.java | 4 ++++ .../api/request/PlayerMoveRequest.java | 7 +++++++ .../api/request/StartGameRequest.java | 6 ++++++ .../api/request/TeamEvolveRequest.java | 4 ++++ .../api/request/TeamFeedRequest.java | 5 +++++ .../api/request/TeamInfosRequest.java | 4 ++++ .../api/request/TeamReleaseRequest.java | 4 ++++ .../api/request/TeamRenameRequest.java | 4 ++++ .../api/request/YakadexAllInfosRequest.java | 4 ++++ .../api/request/YakadexInfosRequest.java | 4 ++++ .../api/response/GetInventoryResponse.java | 18 +++++++++++++++++ .../api/response/PlayerCatchResponse.java | 8 ++++++++ .../api/response/PlayerCollectResponse.java | 20 +++++++++++++++++++ .../api/response/PlayerInfosResponse.java | 6 ++++++ .../api/response/PlayerMoveResponse.java | 6 ++++++ .../api/response/StartGameResponse.java | 4 ++++ .../api/response/TeamEvolveResponse.java | 4 ++++ .../api/response/TeamFeedResponse.java | 4 ++++ .../api/response/TeamInfosResponse.java | 4 ++++ .../api/response/TeamReleaseResponse.java | 4 ++++ .../api/response/TeamRenameResponse.java | 4 ++++ .../api/response/YakadexAllInfosResponse.java | 4 ++++ .../api/response/YakadexInfosResponse.java | 4 ++++ 36 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakadexEntryModel.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/.gitkeep create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/.gitkeep create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/.gitkeep create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java diff --git a/.gitignore b/.gitignore index 96ef862..50cf3af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ target/ .idea/ +.classpath +.factorypath +.project +.settings/ diff --git a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java index 014cafb..2895254 100644 --- a/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java +++ b/endpoints/src/main/java/fr/epita/assistants/presentation/rest/Endpoints.java @@ -18,7 +18,7 @@ public class Endpoints { if (name == null || name.isEmpty()) { return Response.status(400).build(); } - HelloResponse response = new HelloResponse("Hello " + name); + HelloResponse response = new HelloResponse("hello " + name); return Response.ok(response).build(); } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java new file mode 100644 index 0000000..c2f3caa --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java @@ -0,0 +1,10 @@ +package fr.epita.assistants.yakamon.data.model; + +import jakarta.persistence.*; + +@Entity @Table(name="game") +public class GameModel { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) protected Long id; + public String map; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java new file mode 100644 index 0000000..74826b0 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java @@ -0,0 +1,14 @@ +package fr.epita.assistants.yakamon.data.model; + +import fr.epita.assistants.yakamon.utils.tile.ItemType; +import jakarta.persistence.*; + +@Entity +@Table(name="item") +public class ItemModel { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) protected Integer id; + public ItemType type; + public Integer quantity; + +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java new file mode 100644 index 0000000..67b121d --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java @@ -0,0 +1,19 @@ +package fr.epita.assistants.yakamon.data.model; + +import jakarta.persistence.*; + +import java.sql.Timestamp; +import java.util.UUID; + +@Entity +@Table(name="player") +public class PlayerModel { + @Id @GeneratedValue(strategy = GenerationType.UUID) protected UUID id; + public String name; + public Integer posX; + public Integer posY; + public Timestamp lastMove; + public Timestamp lastCatch; + public Timestamp lastCollect; + public Timestamp lastFeed; +} 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 new file mode 100644 index 0000000..292e2cf --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakadexEntryModel.java @@ -0,0 +1,20 @@ +package fr.epita.assistants.yakamon.data.model; + + +import fr.epita.assistants.yakamon.utils.ElementType; +import jakarta.persistence.*; + +@Entity +@Table(name="yakadex_entry") +public class YakadexEntryModel { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) protected Integer id; + + public String name; + public Boolean caught; + public ElementType firstType; + public ElementType secondType; + public String description; + @OneToOne @JoinColumn(name="evolution_id") public YakadexEntryModel evolutionId; + public Integer evolveThreshold; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java new file mode 100644 index 0000000..73505f2 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java @@ -0,0 +1,15 @@ +package fr.epita.assistants.yakamon.data.model; + +import jakarta.persistence.*; + +import java.util.UUID; + +@Entity +@Table(name="yakamon") +public class YakamonModel { + @Id + @GeneratedValue(strategy = GenerationType.UUID) protected UUID id; + public String nickname; + public Integer energyPoints; + @ManyToOne @JoinColumn(name="yakadex_id") public YakadexEntryModel yakadexEntryId; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/.gitkeep b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/.gitkeep b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/.gitkeep b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java new file mode 100644 index 0000000..40c1ee4 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +import java.util.List; + +public class GetInventoryRequest { + +} \ No newline at end of file diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java new file mode 100644 index 0000000..dbb9f43 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java @@ -0,0 +1,5 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class PlayerCatchRequest { + +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java new file mode 100644 index 0000000..bbc9584 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +import fr.epita.assistants.yakamon.utils.tile.ItemType; +import fr.epita.assistants.yakamon.utils.tile.TerrainType; + +public class PlayerCollectRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java new file mode 100644 index 0000000..98c1f6b --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class PlayerInfosRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java new file mode 100644 index 0000000..0cf8f5d --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +import fr.epita.assistants.yakamon.utils.Direction; + +public class PlayerMoveRequest { + Direction direction; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java new file mode 100644 index 0000000..9102914 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java @@ -0,0 +1,6 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class StartGameRequest { + public String mapPath; + public String playerName; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java new file mode 100644 index 0000000..2210ffa --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class TeamEvolveRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java new file mode 100644 index 0000000..df041f0 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java @@ -0,0 +1,5 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class TeamFeedRequest { + public Integer quantity; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java new file mode 100644 index 0000000..925e29c --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class TeamInfosRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java new file mode 100644 index 0000000..a241449 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class TeamReleaseRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java new file mode 100644 index 0000000..43bc114 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class TeamRenameRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java new file mode 100644 index 0000000..d5e9467 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class YakadexAllInfosRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java new file mode 100644 index 0000000..3a2648d --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.request; + +public class YakadexInfosRequest { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java new file mode 100644 index 0000000..a4c630c --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java @@ -0,0 +1,18 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +import java.util.List; + +public class GetInventoryResponse { + + public class ItemType { + public String type; + public String value; + } + + public class Items { + public ItemType itemType; + public Integer quantity; + } + + List items; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java new file mode 100644 index 0000000..2752c1c --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java @@ -0,0 +1,8 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class PlayerCatchResponse { + public String uuid; + public String nickname; + public Integer yakadexId; + public Integer energyPoints; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java new file mode 100644 index 0000000..f1111f0 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java @@ -0,0 +1,20 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +import fr.epita.assistants.yakamon.utils.tile.ItemType; +import fr.epita.assistants.yakamon.utils.tile.TerrainType; + +public class PlayerCollectResponse { + + public class TileType { + + public class Collectible { + ItemType type; + String value; + } + + TerrainType terrainType; + Collectible collectible; + } + + public TileType tileType; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java new file mode 100644 index 0000000..e980b92 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java @@ -0,0 +1,6 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class PlayerInfosResponse { + //TODO + // Player model +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java new file mode 100644 index 0000000..4ac3735 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java @@ -0,0 +1,6 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class PlayerMoveResponse { + public Integer posX; + public Integer posY; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java new file mode 100644 index 0000000..822fd96 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class StartGameResponse { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java new file mode 100644 index 0000000..ead3165 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class TeamEvolveResponse { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java new file mode 100644 index 0000000..47f93af --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class TeamFeedResponse { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java new file mode 100644 index 0000000..4d061f9 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class TeamInfosResponse { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java new file mode 100644 index 0000000..5b5aa0a --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class TeamReleaseResponse { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java new file mode 100644 index 0000000..19d9300 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class TeamRenameResponse { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java new file mode 100644 index 0000000..765c60c --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class YakadexAllInfosResponse { +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java new file mode 100644 index 0000000..aee0b54 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +public class YakadexInfosResponse { +} From e6dfbfbe03c0e0767a2ed9f4574d662a65365b3d Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Sat, 14 Feb 2026 11:14:20 +0100 Subject: [PATCH 4/9] oups... bah beaucoup de choses --- .../converter/DtoToEntityConverter.java | 78 +++++++++++ .../converter/EntityToDtoConverter.java | 71 ++++++++++ .../converter/EntityToModelConverter.java | 67 +++++++++ .../yakamon/data/model/GameModel.java | 11 +- .../yakamon/data/model/PlayerModel.java | 19 +-- .../yakamon/data/model/YakadexEntryModel.java | 13 +- .../yakamon/data/repository/.gitkeep | 0 .../data/repository/GameRepository.java | 3 + .../data/repository/PlayerRepository.java | 3 + .../data/repository/TeamRepository.java | 3 + .../data/repository/YakadexRepository.java | 3 + .../assistants/yakamon/domain/entity/.gitkeep | 0 .../yakamon/domain/entity/GameEntity.java | 38 +++++ .../yakamon/domain/entity/ItemEntity.java | 31 +++++ .../domain/entity/YakadexEntryEntity.java | 19 +++ .../yakamon/domain/entity/YakamonEntity.java | 15 ++ .../yakamon/domain/service/.gitkeep | 0 .../yakamon/domain/service/GameService.java | 37 +++++ .../yakamon/domain/service/PlayerService.java | 3 + .../yakamon/domain/service/TeamService.java | 3 + .../domain/service/YakadexService.java | 3 + .../presentation/api/YakadexEntry.java | 16 +++ .../presentation/api/YakamonAction.java | 12 ++ .../api/request/GetInventoryRequest.java | 7 - .../api/request/PlayerCatchRequest.java | 5 - .../api/request/PlayerCollectRequest.java | 7 - .../api/request/PlayerInfosRequest.java | 4 - .../api/request/PlayerMoveRequest.java | 3 + .../api/request/StartGameRequest.java | 4 + .../api/request/TeamEvolveRequest.java | 4 - .../api/request/TeamFeedRequest.java | 4 + .../api/request/TeamInfosRequest.java | 4 - .../api/request/TeamReleaseRequest.java | 4 - .../api/request/TeamRenameRequest.java | 5 + .../api/request/YakadexAllInfosRequest.java | 4 - .../api/request/YakadexInfosRequest.java | 4 - .../api/response/ErrorResponse.java | 9 ++ .../api/response/GetInventoryResponse.java | 4 + .../api/response/PlayerCatchResponse.java | 17 ++- .../api/response/PlayerCollectResponse.java | 3 + .../api/response/PlayerInfosResponse.java | 14 +- .../api/response/PlayerMoveResponse.java | 4 + .../api/response/StartGameResponse.java | 17 +++ .../api/response/TeamEvolveResponse.java | 13 +- .../api/response/TeamFeedResponse.java | 13 +- .../api/response/TeamInfosResponse.java | 6 + .../api/response/TeamReleaseResponse.java | 4 - .../api/response/TeamRenameResponse.java | 13 +- .../api/response/YakadexAllInfosResponse.java | 6 + .../api/response/YakadexInfosResponse.java | 26 +++- .../presentation/rest/GameResource.java | 62 +++++++++ .../presentation/rest/InventoryResource.java | 22 +++ .../presentation/rest/PlayerResource.java | 96 +++++++++++++ .../presentation/rest/TeamResource.java | 130 ++++++++++++++++++ .../presentation/rest/YakadexResource.java | 49 +++++++ 55 files changed, 943 insertions(+), 72 deletions(-) create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToDtoConverter.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/.gitkeep create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/.gitkeep create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/ItemEntity.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakadexEntryEntity.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakamonEntity.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/.gitkeep create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/PlayerService.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/TeamService.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/YakadexService.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakadexEntry.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/ErrorResponse.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/GameResource.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/InventoryResource.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/PlayerResource.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/TeamResource.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/YakadexResource.java diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java new file mode 100644 index 0000000..45534db --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java @@ -0,0 +1,78 @@ +package fr.epita.assistants.yakamon.converter; + +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; +import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import fr.epita.assistants.yakamon.presentation.api.request.StartGameRequest; +import fr.epita.assistants.yakamon.utils.ElementType; +import java.time.LocalDateTime; +import java.util.UUID; + +public final class DtoToEntityConverter { + + public static YakamonEntity toYakamonEntity(YakamonAction dto) { + if (dto == null) return null; + + YakamonEntity entity = new YakamonEntity(); + // may be null / invalid + if (dto.uuid != null) { + try { + entity.uuid = UUID.fromString(dto.uuid); + } catch (IllegalArgumentException ignored) { + entity.uuid = null; + } + } else { + entity.uuid = null; + } + + entity.nickname = dto.nickname; + entity.yakadexId = dto.yakadexId; + entity.energyPoints = dto.energyPoints; + return entity; + } + + public static YakadexEntryEntity toYakadexEntryEntity(YakadexEntry dto) { + if (dto == null) return null; + + YakadexEntryEntity e = new YakadexEntryEntity(); + e.id = dto.id; + e.name = dto.name; + e.description = dto.description; + e.evolveThreshold = dto.evolveThreshold; + e.evolutionId = dto.evolutionId; + e.caught = dto.caught; + + // map element type strings to enum + if (dto.firstType != null) { + try { + e.firstType = ElementType.valueOf(dto.firstType); + } catch (IllegalArgumentException ex) { + e.firstType = null; + } + } else { + e.firstType = null; + } + + if (dto.secondType != null) { + try { + e.secondType = ElementType.valueOf(dto.secondType); + } catch (IllegalArgumentException ex) { + e.secondType = null; + } + } else { + e.secondType = null; + } + + return e; + } + + public static GameEntity toGameEntity(StartGameRequest request) { + if (request == null) return null; + GameEntity g = new GameEntity(); + g.mapPath = request.mapPath; + g.start(LocalDateTime.now()); + return g; + } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToDtoConverter.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToDtoConverter.java new file mode 100644 index 0000000..c64ee8d --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToDtoConverter.java @@ -0,0 +1,71 @@ +package fr.epita.assistants.yakamon.converter; + +import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; +import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import java.util.ArrayList; +import java.util.List; + +public final class EntityToDtoConverter { + + public static YakamonAction toYakamonAction(YakamonEntity e) { + if (e == null) return null; + String uuid = null; + if (e.uuid != null) { + uuid = e.uuid.toString(); + } + return new YakamonAction(uuid, e.nickname, e.yakadexId, e.energyPoints); + } + + public static YakadexEntry toYakadexEntry(YakadexEntryEntity e) { + if (e == null) return null; + + String firstType = null; + if (e.firstType != null) { + firstType = e.firstType.name(); + } + + String secondType = null; + if (e.secondType != null) { + secondType = e.secondType.name(); + } + + Integer evolutionId = e.evolutionId; + + return new YakadexEntry( + e.id, + e.name, + firstType, + secondType, + e.evolveThreshold, + evolutionId, + e.caught, + e.description + ); + } + + public static List toYakadexEntries( + List entries + ) { + List out = new ArrayList<>(); + if (entries == null || entries.isEmpty()) return out; + for (YakadexEntryEntity e : entries) { + YakadexEntry dto = toYakadexEntry(e); + if (dto != null) out.add(dto); + } + return out; + } + + public static List toYakamonActions( + List yakamons + ) { + List out = new ArrayList<>(); + if (yakamons == null || yakamons.isEmpty()) return out; + for (YakamonEntity y : yakamons) { + YakamonAction a = toYakamonAction(y); + if (a != null) out.add(a); + } + return out; + } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java new file mode 100644 index 0000000..7e84bd4 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java @@ -0,0 +1,67 @@ +package fr.epita.assistants.yakamon.converter; + +import fr.epita.assistants.yakamon.data.model.GameModel; +import fr.epita.assistants.yakamon.data.model.PlayerModel; +import fr.epita.assistants.yakamon.data.model.YakadexEntryModel; +import fr.epita.assistants.yakamon.data.model.YakamonModel; +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.PlayerEntity; +import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; +import java.time.LocalDateTime; + +public final class EntityToModelConverter { + + public static GameModel toGameModel(GameEntity e) { + if (e == null) return null; + GameModel m = new GameModel(); + m.map = e.mapPath; + m.started = e.started; + m.startTime = e.startTime; + return m; + } + + public static PlayerModel toPlayerModel(PlayerEntity e) { + if (e == null) return null; + PlayerModel m = new PlayerModel(); + m.name = e.name; + m.posX = e.posX; + m.posY = e.posY; + m.lastMove = e.lastMove; + m.lastCatch = e.lastCatch; + m.lastCollect = e.lastCollect; + m.lastFeed = e.lastFeed; + return m; + } + + public static YakamonModel toYakamonModel(YakamonEntity e) { + if (e == null) return null; + YakamonModel m = new YakamonModel(); + m.nickname = e.nickname; + m.energyPoints = e.energyPoints; + if (e.yakadexId != null) { + YakadexEntryModel yakadex = new YakadexEntryModel(); + yakadex.name = null; + yakadex.caught = null; + yakadex.firstType = null; + yakadex.secondType = null; + yakadex.description = null; + yakadex.evolveThreshold = null; + m.yakadexEntryId = yakadex; + } + return m; + } + + public static YakadexEntryModel toYakadexEntryModel(YakadexEntryEntity e) { + if (e == null) return null; + YakadexEntryModel m = new YakadexEntryModel(); + m.name = e.name; + m.caught = e.caught; + m.firstType = e.firstType; + m.secondType = e.secondType; + m.description = e.description; + m.evolveThreshold = e.evolveThreshold; + m.evolutionId = null; // don't know yet + return m; + } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java index c2f3caa..2180c6e 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/GameModel.java @@ -1,10 +1,17 @@ package fr.epita.assistants.yakamon.data.model; import jakarta.persistence.*; +import java.time.LocalDateTime; -@Entity @Table(name="game") +@Entity +@Table(name = "game") public class GameModel { + @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) protected Long id; + @GeneratedValue(strategy = GenerationType.IDENTITY) + public Long id; + public String map; + public boolean started; + public LocalDateTime startTime; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java index 67b121d..272971f 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/PlayerModel.java @@ -1,19 +1,22 @@ package fr.epita.assistants.yakamon.data.model; import jakarta.persistence.*; - -import java.sql.Timestamp; +import java.time.LocalDateTime; import java.util.UUID; @Entity -@Table(name="player") +@Table(name = "player") public class PlayerModel { - @Id @GeneratedValue(strategy = GenerationType.UUID) protected UUID id; + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + public UUID id; + public String name; public Integer posX; public Integer posY; - public Timestamp lastMove; - public Timestamp lastCatch; - public Timestamp lastCollect; - public Timestamp lastFeed; + public LocalDateTime lastMove; + public LocalDateTime lastCatch; + public LocalDateTime lastCollect; + public LocalDateTime lastFeed; } 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 292e2cf..0977be4 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,20 +1,25 @@ package fr.epita.assistants.yakamon.data.model; - import fr.epita.assistants.yakamon.utils.ElementType; import jakarta.persistence.*; @Entity -@Table(name="yakadex_entry") +@Table(name = "yakadex_entry") public class YakadexEntryModel { + @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) protected Integer id; + @GeneratedValue(strategy = GenerationType.IDENTITY) + public Integer id; public String name; public Boolean caught; public ElementType firstType; public ElementType secondType; public String description; - @OneToOne @JoinColumn(name="evolution_id") public YakadexEntryModel evolutionId; + + @OneToOne + @JoinColumn(name = "evolution_id") + public YakadexEntryModel evolutionId; + public Integer evolveThreshold; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/.gitkeep b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java new file mode 100644 index 0000000..0f81567 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java @@ -0,0 +1,3 @@ +package fr.epita.assistants.yakamon.data.repository; + +public class GameRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java new file mode 100644 index 0000000..8b12f13 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java @@ -0,0 +1,3 @@ +package fr.epita.assistants.yakamon.data.repository; + +public class PlayerRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java new file mode 100644 index 0000000..f45b646 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java @@ -0,0 +1,3 @@ +package fr.epita.assistants.yakamon.data.repository; + +public class TeamRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java new file mode 100644 index 0000000..26a32fe --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java @@ -0,0 +1,3 @@ +package fr.epita.assistants.yakamon.data.repository; + +public class YakadexRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/.gitkeep b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java new file mode 100644 index 0000000..75bb0e9 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java @@ -0,0 +1,38 @@ +package fr.epita.assistants.yakamon.domain.entity; + +import java.time.LocalDateTime; + +public class GameEntity { + + public Long id; + public String mapPath; + public boolean started; + public LocalDateTime startTime; + + public GameEntity() {} + + public GameEntity( + Long id, + String mapPath, + boolean started, + LocalDateTime startTime + ) { + this.id = id; + this.mapPath = mapPath; + this.started = started; + this.startTime = startTime; + } + + public GameEntity start(LocalDateTime startTime) { + // TODO + startTime = startTime == null ? LocalDateTime.now() : startTime; + started = true; + return this; + } + + public GameEntity stop() { + this.started = false; + this.startTime = null; + return this; + } +} 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 new file mode 100644 index 0000000..5114916 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/ItemEntity.java @@ -0,0 +1,31 @@ +package fr.epita.assistants.yakamon.domain.entity; + +import fr.epita.assistants.yakamon.utils.tile.ItemType; +import java.util.Objects; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class ItemEntity { + + public Integer id; + public ItemType type; + public Integer quantity; + + public ItemEntity(Integer id, ItemType type, Integer quantity) { + this.id = id; + if (type == null) { + System.err.println( + "Warning: attempted to pass null item type, using default 'NONE'" + ); + type = ItemType.NONE; + } + this.type = Objects.requireNonNull(type, "type must not be null"); + this.quantity = quantity != null ? quantity : 0; + } + + // public ItemEntity addQuantity(int amount) { + // int current = this.quantity != null ? this.quantity : 0; + // this.quantity = current + amount; + // return this; + // } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakadexEntryEntity.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakadexEntryEntity.java new file mode 100644 index 0000000..30a0873 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakadexEntryEntity.java @@ -0,0 +1,19 @@ +package fr.epita.assistants.yakamon.domain.entity; + +import fr.epita.assistants.yakamon.utils.ElementType; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +public class YakadexEntryEntity { + + public Integer id; + public String name; + public ElementType firstType; + public ElementType secondType; + public Integer evolveThreshold; + public Integer evolutionId; + public Boolean caught; + public String description; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakamonEntity.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakamonEntity.java new file mode 100644 index 0000000..d7627a5 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/YakamonEntity.java @@ -0,0 +1,15 @@ +package fr.epita.assistants.yakamon.domain.entity; + +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +public class YakamonEntity { + + public UUID uuid; + public String nickname; + public Integer yakadexId; + public Integer energyPoints; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/.gitkeep b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java new file mode 100644 index 0000000..4f0fc8b --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java @@ -0,0 +1,37 @@ +package fr.epita.assistants.yakamon.domain.service; + +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import java.time.LocalDateTime; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class GameService { + + public static GameEntity game = new GameEntity(); + public static final GameService INSTANCE = new GameService(); // TODO ? + + public GameEntity startGame(String mapPath) { + if (mapPath == null) { + throw new RuntimeException( + "Could not start game with null mapPath" + ); + } + if (game == null) { + game = new GameEntity(); + } + + game.start(LocalDateTime.now()); + return game; + } + + public boolean isStarted() { + return game != null && game.started; + } + + public void stopGame() { + if (game == null) { + game = new GameEntity(); + } + game.stop(); + } +} 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 new file mode 100644 index 0000000..57edfb4 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/PlayerService.java @@ -0,0 +1,3 @@ +package fr.epita.assistants.yakamon.domain.service; + +public class PlayerService {} 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 new file mode 100644 index 0000000..3f12a02 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/TeamService.java @@ -0,0 +1,3 @@ +package fr.epita.assistants.yakamon.domain.service; + +public class TeamService {} 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 new file mode 100644 index 0000000..97881ae --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/YakadexService.java @@ -0,0 +1,3 @@ +package fr.epita.assistants.yakamon.domain.service; + +public class YakadexService {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakadexEntry.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakadexEntry.java new file mode 100644 index 0000000..0720df5 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakadexEntry.java @@ -0,0 +1,16 @@ +package fr.epita.assistants.yakamon.presentation.api; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class YakadexEntry { + + public Integer id; + public String name; + public String firstType; + public String secondType; + public Integer evolveThreshold; + public Integer evolutionId; + public Boolean caught; + public String description; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java new file mode 100644 index 0000000..5b307d3 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java @@ -0,0 +1,12 @@ +package fr.epita.assistants.yakamon.presentation.api; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class YakamonAction { + + public String uuid; + public String nickname; + public Integer yakadexId; + public Integer energyPoints; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java deleted file mode 100644 index 40c1ee4..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/GetInventoryRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -import java.util.List; - -public class GetInventoryRequest { - -} \ No newline at end of file diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java deleted file mode 100644 index dbb9f43..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCatchRequest.java +++ /dev/null @@ -1,5 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -public class PlayerCatchRequest { - -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java deleted file mode 100644 index bbc9584..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerCollectRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -import fr.epita.assistants.yakamon.utils.tile.ItemType; -import fr.epita.assistants.yakamon.utils.tile.TerrainType; - -public class PlayerCollectRequest { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java deleted file mode 100644 index 98c1f6b..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerInfosRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -public class PlayerInfosRequest { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java index 0cf8f5d..e5228b6 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java @@ -1,7 +1,10 @@ package fr.epita.assistants.yakamon.presentation.api.request; import fr.epita.assistants.yakamon.utils.Direction; +import lombok.AllArgsConstructor; +@AllArgsConstructor public class PlayerMoveRequest { + Direction direction; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java index 9102914..97461d1 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java @@ -1,6 +1,10 @@ package fr.epita.assistants.yakamon.presentation.api.request; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class StartGameRequest { + public String mapPath; public String playerName; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java deleted file mode 100644 index 2210ffa..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamEvolveRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -public class TeamEvolveRequest { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java index df041f0..8d094b0 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java @@ -1,5 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.request; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class TeamFeedRequest { + public Integer quantity; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java deleted file mode 100644 index 925e29c..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamInfosRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -public class TeamInfosRequest { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java deleted file mode 100644 index a241449..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamReleaseRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -public class TeamReleaseRequest { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java index 43bc114..bceb7e2 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java @@ -1,4 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.request; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class TeamRenameRequest { + + public String newNickname; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java deleted file mode 100644 index d5e9467..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexAllInfosRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -public class YakadexAllInfosRequest { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java deleted file mode 100644 index 3a2648d..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/YakadexInfosRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.request; - -public class YakadexInfosRequest { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/ErrorResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/ErrorResponse.java new file mode 100644 index 0000000..0abf4ae --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/ErrorResponse.java @@ -0,0 +1,9 @@ +package fr.epita.assistants.yakamon.presentation.api.response; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class ErrorResponse { + + public String message; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java index a4c630c..8b4a708 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java @@ -1,15 +1,19 @@ package fr.epita.assistants.yakamon.presentation.api.response; import java.util.List; +import lombok.AllArgsConstructor; +@AllArgsConstructor public class GetInventoryResponse { public class ItemType { + public String type; public String value; } public class Items { + public ItemType itemType; public Integer quantity; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java index 2752c1c..499002b 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java @@ -1,8 +1,15 @@ package fr.epita.assistants.yakamon.presentation.api.response; -public class PlayerCatchResponse { - public String uuid; - public String nickname; - public Integer yakadexId; - public Integer energyPoints; +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; + +public class PlayerCatchResponse extends YakamonAction { + + public PlayerCatchResponse( + String uuid, + String nickname, + Integer yakadexId, + Integer energyPoints + ) { + super(uuid, nickname, yakadexId, energyPoints); + } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java index f1111f0..1ac932c 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java @@ -2,12 +2,15 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.utils.tile.ItemType; import fr.epita.assistants.yakamon.utils.tile.TerrainType; +import lombok.AllArgsConstructor; +@AllArgsConstructor public class PlayerCollectResponse { public class TileType { public class Collectible { + ItemType type; String value; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java index e980b92..7773e89 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java @@ -1,6 +1,16 @@ package fr.epita.assistants.yakamon.presentation.api.response; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class PlayerInfosResponse { - //TODO - // Player model + + public String uuid; + public String name; + public Integer posX; + public Integer posY; + public String lastMove; + public String lastCatch; + public String lastCollect; + public String lastFeed; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java index 4ac3735..bbd29d4 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerMoveResponse.java @@ -1,6 +1,10 @@ package fr.epita.assistants.yakamon.presentation.api.response; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class PlayerMoveResponse { + public Integer posX; public Integer posY; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java index 822fd96..f4b1ba4 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/StartGameResponse.java @@ -1,4 +1,21 @@ package fr.epita.assistants.yakamon.presentation.api.response; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class StartGameResponse { + + public class Collectible { + + public String item; + public String value; + } + + public class Tile { + + String terrainType; + Collectible collectible; + } + + Tile[][] tiles; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java index ead3165..5347429 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java @@ -1,4 +1,15 @@ package fr.epita.assistants.yakamon.presentation.api.response; -public class TeamEvolveResponse { +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; + +public class TeamEvolveResponse extends YakamonAction { + + public TeamEvolveResponse( + String uuid, + String nickname, + Integer yakadexId, + Integer energyPoints + ) { + super(uuid, nickname, yakadexId, energyPoints); + } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java index 47f93af..d13d43b 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java @@ -1,4 +1,15 @@ package fr.epita.assistants.yakamon.presentation.api.response; -public class TeamFeedResponse { +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; + +public class TeamFeedResponse extends YakamonAction { + + public TeamFeedResponse( + String uuid, + String nickname, + Integer yakadexId, + Integer energyPoints + ) { + super(uuid, nickname, yakadexId, energyPoints); + } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java index 4d061f9..e2444ea 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java @@ -1,4 +1,10 @@ package fr.epita.assistants.yakamon.presentation.api.response; +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class TeamInfosResponse { + + YakamonAction[] yakamons; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java deleted file mode 100644 index 5b5aa0a..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamReleaseResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.epita.assistants.yakamon.presentation.api.response; - -public class TeamReleaseResponse { -} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java index 19d9300..a1b7f28 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java @@ -1,4 +1,15 @@ package fr.epita.assistants.yakamon.presentation.api.response; -public class TeamRenameResponse { +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; + +public class TeamRenameResponse extends YakamonAction { + + public TeamRenameResponse( + String uuid, + String nickname, + Integer yakadexId, + Integer energyPoints + ) { + super(uuid, nickname, yakadexId, energyPoints); + } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java index 765c60c..0302209 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java @@ -1,4 +1,10 @@ package fr.epita.assistants.yakamon.presentation.api.response; +import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; +import lombok.AllArgsConstructor; + +@AllArgsConstructor public class YakadexAllInfosResponse { + + YakadexEntry[] entries; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java index aee0b54..cfe73f3 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexInfosResponse.java @@ -1,4 +1,28 @@ package fr.epita.assistants.yakamon.presentation.api.response; -public class YakadexInfosResponse { +import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; + +public class YakadexInfosResponse extends YakadexEntry { + + public YakadexInfosResponse( + Integer id, + String name, + String firstType, + String secondType, + Integer evolveThreshold, + Integer evolutionId, + Boolean caught, + String description + ) { + super( + id, + name, + firstType, + secondType, + evolveThreshold, + evolutionId, + caught, + description + ); + } } 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 new file mode 100644 index 0000000..a35c84a --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/GameResource.java @@ -0,0 +1,62 @@ +package fr.epita.assistants.yakamon.presentation.rest; + +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +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 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.logging.Logger; + +@Path("/start") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class GameResource { + + private static final Logger LOGGER = Logger.getLogger( + GameResource.class.getName() + ); + + @POST + @Path("/") + public Response start(StartGameRequest request) { + if ( + request == null || + request.mapPath == null || + request.mapPath.isBlank() || + request.playerName == null || + request.playerName.isBlank() + ) { + LOGGER.warning( + "Invalid start request: missing mapPath or playerName" + ); + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid mapPath or playerName") + .build(); + } + + LOGGER.info( + "Starting game for player='" + + request.playerName + + "' with map='" + + request.mapPath + + "'" + ); + + GameService gameService = new GameService(); + GameEntity startedGame = gameService.startGame(request.mapPath); + + LOGGER.info( + "Game started at: " + + (startedGame != null ? startedGame.startTime : "unknown") + ); + + // StartGameResponse response = new StartGameResponse(); + // return Response.ok(response).build(); + return Response.ok().build(); + } +} 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 new file mode 100644 index 0000000..6aab3fc --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/InventoryResource.java @@ -0,0 +1,22 @@ +package fr.epita.assistants.yakamon.presentation.rest; + +import fr.epita.assistants.yakamon.presentation.api.response.GetInventoryResponse; +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; + +@Path("/inventory") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class InventoryResource { + + @GET + public Response getInventory() { + // GetInventoryResponse response = new GetInventoryResponse(); + // return Response.ok(response).build(); + return Response.ok().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 new file mode 100644 index 0000000..a9f76b3 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/PlayerResource.java @@ -0,0 +1,96 @@ +package fr.epita.assistants.yakamon.presentation.rest; + +import fr.epita.assistants.yakamon.domain.service.GameService; +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.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +@Path("/") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class PlayerResource { + + private final GameService gameService = new GameService(); + + @POST + @Path("/catch") + public Response catchYakamon() { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + // TODO service + return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + } + + @POST + @Path("/collect") + public Response collect() { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + // TODO service + return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + } + + @GET + @Path("/inventory") + public Response getInventory() { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + // TODO service + // GetInventoryResponse response = inventoryService.getInventory(); + // return Response.ok(response).build(); + return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + } + + @POST + @Path("/move") + public Response move(PlayerMoveRequest request) { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + if (request == null) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Request body is required") + .build(); + } + + // if (request.direction == null) { + // return Response.status(Response.Status.BAD_REQUEST) + // .entity("Direction is required") + // .build(); + // } + // TODO service + return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + } + + @GET + @Path("/player") + public Response getPlayerInfos() { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + + // TODO service + // PlayerInfosResponse response = playerService.getInfos(...); + // return Response.ok(response).build(); + return Response.status(Response.Status.NOT_IMPLEMENTED).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 new file mode 100644 index 0000000..9f429b5 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/TeamResource.java @@ -0,0 +1,130 @@ +package fr.epita.assistants.yakamon.presentation.rest; + +import fr.epita.assistants.yakamon.domain.service.GameService; +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.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +@Path("/team") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class TeamResource { + + private final GameService gameService = new GameService(); + + @GET + public Response getTeam() { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + // TODO service + // TeamInfosResponse response = new TeamInfosResponse(); + // return Response.ok(response).build(); + return Response.ok().build(); + } + + @POST + @Path("/{uuid}/evolve") + public Response evolve(@PathParam("uuid") String uuid) { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + if (uuid == null || uuid.isBlank()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Missing or invalid uuid") + .build(); + } + + // TODO service + // TeamEvolveResponse response = new TeamEvolveResponse(); + // return Response.ok(response).build(); + return Response.ok().build(); + } + + @POST + @Path("/{uuid}/feed") + public Response feed( + @PathParam("uuid") String uuid, + TeamFeedRequest request + ) { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + if (uuid == null || uuid.isBlank()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Missing or invalid uuid") + .build(); + } + if ( + request == null || request.quantity == null || request.quantity <= 0 + ) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid quantity") + .build(); + } + + // TODO service + // TeamFeedResponse response = new TeamFeedResponse(); + // return Response.ok(response).build(); + return Response.ok().build(); + } + + @DELETE + @Path("/{uuid}/release") + public Response release(@PathParam("uuid") String uuid) { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + if (uuid == null || uuid.isBlank()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Missing or invalid uuid") + .build(); + } + + // TODO service + // return 204 (No Content) to match the subject + return Response.noContent().build(); + } + + @PATCH + @Path("/{uuid}/rename") + public Response rename( + @PathParam("uuid") String uuid, + TeamRenameRequest request + ) { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + if (uuid == null || uuid.isBlank()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Missing or invalid uuid") + .build(); + } + if (request == null) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Missing request body") + .build(); + } + + // TODO service + // TeamRenameResponse response = new TeamRenameResponse(); + // return Response.ok(response).build(); + return Response.ok().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 new file mode 100644 index 0000000..d3e51dd --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/YakadexResource.java @@ -0,0 +1,49 @@ +package fr.epita.assistants.yakamon.presentation.rest; + +import fr.epita.assistants.yakamon.domain.service.GameService; +import fr.epita.assistants.yakamon.presentation.api.response.YakadexAllInfosResponse; +import fr.epita.assistants.yakamon.presentation.api.response.YakadexInfosResponse; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +@Path("/yakadex") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class YakadexResource { + + private final GameService gameService = new GameService(); + + @GET + public Response getYakadex( + @QueryParam("only_missing") Boolean onlyMissing + ) { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game is not running") + .build(); + } + + // YakadexAllInfosResponse response = new YakadexAllInfosResponse(); + // return Response.ok(response).build(); + return Response.ok().build(); + } + + @GET + @Path("/{id}") + public Response getYakadexById(@PathParam("id") Integer id) { + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game is not running") + .build(); + } + + if (id == null || id < 0) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + + // YakadexInfosResponse response = new YakadexInfosResponse(); + // return Response.ok(response).build(); + return Response.ok().build(); + } +} From c55244202936286680262baad2028123387fa401 Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Fri, 3 Apr 2026 21:51:46 +0200 Subject: [PATCH 5/9] fin --- .../converter/DtoToEntityConverter.java | 6 - .../converter/EntityToModelConverter.java | 19 +- .../yakamon/data/model/ItemModel.java | 14 +- .../yakamon/data/model/YakadexEntryModel.java | 11 +- .../yakamon/data/model/YakamonModel.java | 15 +- .../data/repository/GameRepository.java | 7 +- .../data/repository/ItemRepository.java | 8 + .../data/repository/PlayerRepository.java | 7 +- .../data/repository/TeamRepository.java | 3 - .../data/repository/YakadexRepository.java | 8 +- .../data/repository/YakamonRepository.java | 8 + .../yakamon/domain/entity/GameEntity.java | 28 +- .../yakamon/domain/entity/ItemEntity.java | 15 +- .../yakamon/domain/entity/PlayerEntity.java | 14 + .../yakamon/domain/entity/TileEntity.java | 16 + .../yakamon/domain/service/GameService.java | 142 +++++- .../yakamon/domain/service/PlayerService.java | 239 ++++++++- .../domain/service/YakadexService.java | 65 ++- .../api/request/PlayerMoveRequest.java | 6 +- .../presentation/rest/GameResource.java | 33 +- .../presentation/rest/InventoryResource.java | 13 +- .../presentation/rest/PlayerResource.java | 67 ++- .../presentation/rest/YakadexResource.java | 23 +- .../assistants/yakamon/utils/ErrorCode.java | 22 +- .../yakamon_testsuite/ConverterTests.java | 239 +++++++++ .../yakamon_testsuite/GameResourceTest.java | 189 ++++++++ .../HelloWorldResourceTest.java | 79 +++ .../InventoryResourceTest.java | 116 +++++ .../yakamon_testsuite/MainTests.java | 7 + .../yakamon_testsuite/PlayerResourceTest.java | 210 ++++++++ .../yakamon_testsuite/ServiceLayerTests.java | 173 +++++++ .../yakamon_testsuite/TeamResourceTest.java | 457 ++++++++++++++++++ .../YakadexResourceTest.java | 328 +++++++++++++ 33 files changed, 2455 insertions(+), 132 deletions(-) create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/ItemRepository.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakamonRepository.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/PlayerEntity.java create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/TileEntity.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ConverterTests.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/GameResourceTest.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/HelloWorldResourceTest.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/InventoryResourceTest.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/MainTests.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/PlayerResourceTest.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ServiceLayerTests.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/TeamResourceTest.java create mode 100644 yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/YakadexResourceTest.java diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java index 45534db..941cc3c 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/DtoToEntityConverter.java @@ -16,7 +16,6 @@ public final class DtoToEntityConverter { if (dto == null) return null; YakamonEntity entity = new YakamonEntity(); - // may be null / invalid if (dto.uuid != null) { try { entity.uuid = UUID.fromString(dto.uuid); @@ -44,15 +43,12 @@ public final class DtoToEntityConverter { e.evolutionId = dto.evolutionId; e.caught = dto.caught; - // map element type strings to enum if (dto.firstType != null) { try { e.firstType = ElementType.valueOf(dto.firstType); } catch (IllegalArgumentException ex) { e.firstType = null; } - } else { - e.firstType = null; } if (dto.secondType != null) { @@ -61,8 +57,6 @@ public final class DtoToEntityConverter { } catch (IllegalArgumentException ex) { e.secondType = null; } - } else { - e.secondType = null; } return e; diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java index 7e84bd4..742f54a 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/converter/EntityToModelConverter.java @@ -8,7 +8,6 @@ import fr.epita.assistants.yakamon.domain.entity.GameEntity; import fr.epita.assistants.yakamon.domain.entity.PlayerEntity; import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity; import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; -import java.time.LocalDateTime; public final class EntityToModelConverter { @@ -38,16 +37,10 @@ public final class EntityToModelConverter { if (e == null) return null; YakamonModel m = new YakamonModel(); m.nickname = e.nickname; - m.energyPoints = e.energyPoints; + m.energy_points = e.energyPoints; if (e.yakadexId != null) { YakadexEntryModel yakadex = new YakadexEntryModel(); - yakadex.name = null; - yakadex.caught = null; - yakadex.firstType = null; - yakadex.secondType = null; - yakadex.description = null; - yakadex.evolveThreshold = null; - m.yakadexEntryId = yakadex; + m.yakadex_entry_id = yakadex; } return m; } @@ -57,11 +50,11 @@ public final class EntityToModelConverter { YakadexEntryModel m = new YakadexEntryModel(); m.name = e.name; m.caught = e.caught; - m.firstType = e.firstType; - m.secondType = e.secondType; + m.first_type = e.firstType != null ? e.firstType.name() : null; + m.second_type = e.secondType != null ? e.secondType.name() : null; m.description = e.description; - m.evolveThreshold = e.evolveThreshold; - m.evolutionId = null; // don't know yet + m.evolve_threshold = e.evolveThreshold; + m.evolution_id = null; return m; } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java index 74826b0..ff1a256 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java @@ -4,11 +4,15 @@ import fr.epita.assistants.yakamon.utils.tile.ItemType; import jakarta.persistence.*; @Entity -@Table(name="item") +@Table(name = "item") public class ItemModel { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) protected Integer id; - public ItemType type; - public Integer quantity; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + protected Integer id; + + @Enumerated + public ItemType type; + + public Integer quantity; } 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 0977be4..7d165b5 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 @@ -13,13 +13,16 @@ public class YakadexEntryModel { public String name; public Boolean caught; - public ElementType firstType; - public ElementType secondType; + + // Changed to string otherwise it doesn't work + public String first_type; + public String second_type; + public String description; @OneToOne @JoinColumn(name = "evolution_id") - public YakadexEntryModel evolutionId; + public YakadexEntryModel evolution_id; - public Integer evolveThreshold; + public Integer evolve_threshold; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java index 73505f2..a0373aa 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/YakamonModel.java @@ -1,15 +1,20 @@ package fr.epita.assistants.yakamon.data.model; import jakarta.persistence.*; - import java.util.UUID; @Entity -@Table(name="yakamon") +@Table(name = "yakamon") public class YakamonModel { + @Id - @GeneratedValue(strategy = GenerationType.UUID) protected UUID id; + @GeneratedValue(strategy = GenerationType.UUID) + public UUID id; + public String nickname; - public Integer energyPoints; - @ManyToOne @JoinColumn(name="yakadex_id") public YakadexEntryModel yakadexEntryId; + public Integer energy_points; + + @ManyToOne + @JoinColumn(name = "yakadex_id") + public YakadexEntryModel yakadex_entry_id; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java index 0f81567..53f6a1d 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/GameRepository.java @@ -1,3 +1,8 @@ package fr.epita.assistants.yakamon.data.repository; -public class GameRepository {} +import fr.epita.assistants.yakamon.data.model.GameModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class GameRepository implements PanacheRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/ItemRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/ItemRepository.java new file mode 100644 index 0000000..e1ef9ef --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/ItemRepository.java @@ -0,0 +1,8 @@ +package fr.epita.assistants.yakamon.data.repository; + +import fr.epita.assistants.yakamon.data.model.ItemModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ItemRepository implements PanacheRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java index 8b12f13..296a11b 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/PlayerRepository.java @@ -1,3 +1,8 @@ package fr.epita.assistants.yakamon.data.repository; -public class PlayerRepository {} +import fr.epita.assistants.yakamon.data.model.PlayerModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class PlayerRepository implements PanacheRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java deleted file mode 100644 index f45b646..0000000 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/TeamRepository.java +++ /dev/null @@ -1,3 +0,0 @@ -package fr.epita.assistants.yakamon.data.repository; - -public class TeamRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java index 26a32fe..ba2a4dc 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakadexRepository.java @@ -1,3 +1,9 @@ package fr.epita.assistants.yakamon.data.repository; -public class YakadexRepository {} +import fr.epita.assistants.yakamon.data.model.YakadexEntryModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class YakadexRepository + implements PanacheRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakamonRepository.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakamonRepository.java new file mode 100644 index 0000000..b38cf32 --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/repository/YakamonRepository.java @@ -0,0 +1,8 @@ +package fr.epita.assistants.yakamon.data.repository; + +import fr.epita.assistants.yakamon.data.model.YakamonModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class YakamonRepository implements PanacheRepository {} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java index 75bb0e9..8d327a9 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/GameEntity.java @@ -4,35 +4,37 @@ import java.time.LocalDateTime; public class GameEntity { - public Long id; + public static GameEntity INSTANCE = null; public String mapPath; public boolean started; public LocalDateTime startTime; + public TileEntity[][] map; - public GameEntity() {} + public GameEntity() { + this.start(null); + } - public GameEntity( - Long id, - String mapPath, - boolean started, - LocalDateTime startTime - ) { - this.id = id; + public GameEntity(String mapPath) { + this.start(null); this.mapPath = mapPath; - this.started = started; - this.startTime = startTime; + GameEntity.INSTANCE = this; } public GameEntity start(LocalDateTime startTime) { - // TODO + if (started || INSTANCE != null) { + this.stop(); + } startTime = startTime == null ? LocalDateTime.now() : startTime; - started = true; + this.startTime = startTime; + this.started = true; return this; } public GameEntity stop() { + GameEntity.INSTANCE = null; this.started = false; this.startTime = null; + this.map = null; return this; } } 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 5114916..97f8f22 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 @@ -2,26 +2,19 @@ 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; @NoArgsConstructor +@AllArgsConstructor public class ItemEntity { public Integer id; public ItemType type; public Integer quantity; - public ItemEntity(Integer id, ItemType type, Integer quantity) { - this.id = id; - if (type == null) { - System.err.println( - "Warning: attempted to pass null item type, using default 'NONE'" - ); - type = ItemType.NONE; - } - this.type = Objects.requireNonNull(type, "type must not be null"); - this.quantity = quantity != null ? quantity : 0; - } + // public ItemEntity(Integer id, ItemType type, Integer quantity) { + // } // public ItemEntity addQuantity(int amount) { // int current = this.quantity != null ? this.quantity : 0; 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 new file mode 100644 index 0000000..7788d6d --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/PlayerEntity.java @@ -0,0 +1,14 @@ +package fr.epita.assistants.yakamon.domain.entity; + +import java.time.LocalDateTime; + +public class PlayerEntity { + + public String name; + public Integer posX; + public Integer posY; + public LocalDateTime lastMove; + public LocalDateTime lastCatch; + public LocalDateTime lastCollect; + public LocalDateTime lastFeed; +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/TileEntity.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/TileEntity.java new file mode 100644 index 0000000..6f110ae --- /dev/null +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/entity/TileEntity.java @@ -0,0 +1,16 @@ +package fr.epita.assistants.yakamon.domain.entity; + +public class TileEntity { + + public Character terrain; + public Character collectible; + + public TileEntity(Character terrain, Character collectible) { + this.terrain = terrain; + this.collectible = collectible; + } + + public boolean isWalkable() { + return terrain == 'G' || terrain == 'R' || terrain == 'S'; + } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java index 4f0fc8b..0d4fd1c 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java @@ -1,26 +1,72 @@ package fr.epita.assistants.yakamon.domain.service; +import fr.epita.assistants.yakamon.converter.EntityToModelConverter; +import fr.epita.assistants.yakamon.data.model.GameModel; +import fr.epita.assistants.yakamon.data.model.ItemModel; +import fr.epita.assistants.yakamon.data.model.PlayerModel; +import fr.epita.assistants.yakamon.data.repository.GameRepository; +import fr.epita.assistants.yakamon.data.repository.ItemRepository; +import fr.epita.assistants.yakamon.data.repository.PlayerRepository; import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.TileEntity; +import fr.epita.assistants.yakamon.utils.ErrorCode; +import fr.epita.assistants.yakamon.utils.tile.ItemType; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.io.BufferedReader; +import java.io.InputStreamReader; import java.time.LocalDateTime; -import lombok.NoArgsConstructor; +import java.util.ArrayList; +import java.util.List; -@NoArgsConstructor +@ApplicationScoped public class GameService { - public static GameEntity game = new GameEntity(); - public static final GameService INSTANCE = new GameService(); // TODO ? + @Inject + GameRepository gameRepository; - public GameEntity startGame(String mapPath) { + @Inject + PlayerRepository playerRepository; + + @Inject + ItemRepository itemRepository; + + public static GameEntity game; + + public GameEntity startGame(String mapPath, String playerName) { if (mapPath == null) { - throw new RuntimeException( - "Could not start game with null mapPath" - ); - } - if (game == null) { - game = new GameEntity(); + ErrorCode.INVALID_MAP.throwException("Map is null"); } - game.start(LocalDateTime.now()); + // Initialize Game with mapPath + game = new GameEntity(mapPath); + GameModel gameModel = EntityToModelConverter.toGameModel(game); + + // Parse map and store in GameEntity + TileEntity[][] parsedMap = parseMapFile(mapPath); + game.map = parsedMap; + + // Initialize player + LocalDateTime now = LocalDateTime.now(); + PlayerModel player = new PlayerModel(); + player.name = playerName; + player.posX = 0; + player.posY = 0; + player.lastCatch = now; + player.lastCollect = now; + player.lastFeed = now; + player.lastMove = now; + + // Initialize player inventory + ItemModel yakaballs = new ItemModel(); + yakaballs.type = ItemType.YAKABALL; + yakaballs.quantity = 5; + + // Store + playerRepository.persist(player); + itemRepository.persist(yakaballs); + gameRepository.persist(gameModel); + return game; } @@ -30,8 +76,78 @@ public class GameService { public void stopGame() { if (game == null) { - game = new GameEntity(); + ErrorCode.GAME_NOT_STARTED.throwException(); } game.stop(); + gameRepository.deleteAll(); + playerRepository.deleteAll(); + } + + private TileEntity[][] parseMapFile(String mapPath) { + try { + String resourcePath = "maps/" + mapPath + ".epimap"; + BufferedReader reader = new BufferedReader( + new InputStreamReader( + GameService.class.getClassLoader().getResourceAsStream( + resourcePath + ) + ) + ); + + List> mapList = new ArrayList<>(); + String line; + + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (!line.isEmpty()) { + List row = parseLine(line); + mapList.add(row); + } + } + reader.close(); + + if (mapList.isEmpty()) { + ErrorCode.INVALID_MAP.throwException("Map file is empty"); + } + + TileEntity[][] map = new TileEntity[mapList.size()][]; + for (int i = 0; i < mapList.size(); i++) { + List row = mapList.get(i); + map[i] = row.toArray(new TileEntity[0]); + } + + return map; + } catch (Exception e) { + ErrorCode.INVALID_MAP.throwException("Failed to load map"); + } + return null; + } + + private List parseLine(String line) { + List row = new ArrayList<>(); + int i = 0; + + while (i < line.length()) { + // Parse count + int count = Character.getNumericValue(line.charAt(i)); + i++; + + // Parse terrain character + if (i >= line.length()) break; + char terrain = line.charAt(i); + i++; + + // Parse collectible character + if (i >= line.length()) break; + char collectible = line.charAt(i); + i++; + + // Add tiles + for (int j = 0; j < count; j++) { + row.add(new TileEntity(terrain, collectible)); + } + } + + return row; } } 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 57edfb4..edc7d3e 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 @@ -1,3 +1,240 @@ package fr.epita.assistants.yakamon.domain.service; -public class PlayerService {} +import fr.epita.assistants.yakamon.data.model.ItemModel; +import fr.epita.assistants.yakamon.data.model.PlayerModel; +import fr.epita.assistants.yakamon.data.model.YakadexEntryModel; +import fr.epita.assistants.yakamon.data.model.YakamonModel; +import fr.epita.assistants.yakamon.data.repository.ItemRepository; +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.TileEntity; +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.YakamonInfo; +import fr.epita.assistants.yakamon.utils.tile.YakamonType; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.UUID; + +@ApplicationScoped +public class PlayerService { + + @Inject + PlayerRepository playerRepository; + + @Inject + YakamonRepository yakamonRepository; + + @Inject + YakadexRepository yakadexRepository; + + @Inject + ItemRepository itemRepository; + + @Transactional + public Point move(Direction direction) { + 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"); + } + + checkMovementDelay(player); + + if (direction == null) { + ErrorCode.BAD_REQUEST.throwException("Invalid direction"); + } + + TileEntity[][] map = GameEntity.INSTANCE.map; + if (map == null) { + ErrorCode.INVALID_MAP.throwException("Map not loaded"); + } + + Point directionOffset = direction.getPoint(); + int newX = player.posX + directionOffset.getPosX(); + int newY = player.posY + directionOffset.getPosY(); + + if ( + newY < 0 || + newY >= map.length || + newX < 0 || + newX >= map[newY].length + ) { + ErrorCode.BAD_REQUEST.throwException( + "Cannot move outside map boundaries" + ); + } + + TileEntity tile = map[newY][newX]; + if (tile == null || !tile.isWalkable()) { + ErrorCode.BAD_REQUEST.throwException("Tile is not walkable"); + } + + player.posX = newX; + player.posY = newY; + player.lastMove = LocalDateTime.now(); + + return new Point(newX, newY); + } + + @Transactional + public YakamonModel catchYakamon() { + 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"); + } + + checkCatchDelay(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 yakamon at this position") + .build() + ); + } + + Collectible collectible = CollectibleUtils.getCollectible( + tile.collectible + ); + if (!(collectible instanceof YakamonType)) { + throw new WebApplicationException( + Response.status(400) + .entity("No yakamon at this position") + .build() + ); + } + + ItemModel yakaballItem = itemRepository + .find("type", ItemType.YAKABALL) + .firstResult(); + if (yakaballItem == null || yakaballItem.quantity < 1) { + throw new WebApplicationException( + Response.status(400).entity("Not enough Yakaballs").build() + ); + } + + long teamSize = yakamonRepository.count(); + if (teamSize >= 3) { + throw new WebApplicationException( + Response.status(400).entity("Team is full").build() + ); + } + + YakamonType yakamonType = (YakamonType) collectible; + YakamonInfo yakamonInfo = + (YakamonInfo) yakamonType.getCollectibleInfo(); + Integer yakadexId = yakamonInfo.getYakadexId(); + + YakadexEntryModel yakadex = yakadexRepository + .find("id", yakadexId) + .firstResult(); + if (yakadex == null) { + ErrorCode.BAD_REQUEST.throwException("Yakamon species not found"); + } + + yakaballItem.quantity -= 1; + itemRepository.persist(yakaballItem); + + YakamonModel newYakamon = new YakamonModel(); + newYakamon.nickname = yakamonType.name(); + newYakamon.energy_points = 0; + newYakamon.yakadex_entry_id = yakadex; + yakamonRepository.persist(newYakamon); + + yakadex.caught = true; + yakadexRepository.persist(yakadex); + + tile.collectible = 'N'; + + player.lastCatch = LocalDateTime.now(); + playerRepository.persist(player); + + return newYakamon; + } + + private void checkMovementDelay(PlayerModel player) { + String tickDurationStr = System.getenv("JWS_TICK_DURATION"); + String movementDelayStr = System.getenv("JWS_MOVEMENT_DELAY"); + + if (tickDurationStr == null || movementDelayStr == null) { + return; + } + + try { + long tickDuration = Long.parseLong(tickDurationStr); + long movementDelay = Long.parseLong(movementDelayStr); + long requiredDelay = tickDuration * movementDelay; + + LocalDateTime now = LocalDateTime.now(); + long elapsed = ChronoUnit.MILLIS.between(player.lastMove, now); + + if (elapsed < requiredDelay) { + throw new WebApplicationException(Response.status(429).build()); + } + } catch (NumberFormatException e) { + ErrorCode.BAD_REQUEST.throwException( + "Invalid environment variables" + ); + } + } + + private void checkCatchDelay(PlayerModel player) { + String tickDurationStr = System.getenv("JWS_TICK_DURATION"); + String catchDelayStr = System.getenv("JWS_CATCH_DELAY"); + + if (tickDurationStr == null || catchDelayStr == null) { + return; + } + + try { + long tickDuration = Long.parseLong(tickDurationStr); + long catchDelay = Long.parseLong(catchDelayStr); + long requiredDelay = tickDuration * catchDelay; + + LocalDateTime now = LocalDateTime.now(); + long elapsed = ChronoUnit.MILLIS.between(player.lastCatch, now); + + if (elapsed < requiredDelay) { + throw new WebApplicationException(Response.status(429).build()); + } + } catch (NumberFormatException e) { + ErrorCode.BAD_REQUEST.throwException( + "Invalid environment variables" + ); + } + } +} 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 97881ae..42285af 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 @@ -1,3 +1,66 @@ package fr.epita.assistants.yakamon.domain.service; -public class YakadexService {} +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 jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +@ApplicationScoped +public class YakadexService { + + @Inject + YakadexRepository yakadexRepository; + + public YakadexAllInfosResponse getAllEntries(Boolean onlyMissing) { + List entries; + + if (onlyMissing != null && onlyMissing) { + entries = yakadexRepository.find("caught = false").list(); + } else { + entries = yakadexRepository.listAll(); + } + + List dtos = new ArrayList<>(); + for (YakadexEntryModel entry : entries) { + YakadexEntry dto = new YakadexInfosResponse( + entry.id, + entry.name, + entry.first_type, + entry.second_type, + entry.evolve_threshold, + null, + entry.caught, + entry.description + ); + dtos.add(dto); + } + + return new YakadexAllInfosResponse(dtos.toArray(new YakadexEntry[0])); + } + + public YakadexInfosResponse getEntryById(Integer id) { + YakadexEntryModel entry = yakadexRepository + .find("id = ?1", id) + .firstResult(); + + if (entry == null) { + return null; + } + + return new YakadexInfosResponse( + entry.id, + entry.name, + entry.first_type, + entry.second_type, + entry.evolve_threshold, + null, + entry.caught, + entry.description + ); + } +} diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java index e5228b6..3e79362 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/PlayerMoveRequest.java @@ -2,9 +2,13 @@ package fr.epita.assistants.yakamon.presentation.api.request; import fr.epita.assistants.yakamon.utils.Direction; import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +@Data @AllArgsConstructor +@NoArgsConstructor public class PlayerMoveRequest { - Direction direction; + public Direction direction; } 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 a35c84a..dd8218c 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 @@ -40,23 +40,32 @@ public class GameResource { } LOGGER.info( - "Starting game for player='" + + "Starting game for player '" + request.playerName + - "' with map='" + + "' with map '" + request.mapPath + "'" ); - GameService gameService = new GameService(); - GameEntity startedGame = gameService.startGame(request.mapPath); + try { + GameService gameService = new GameService(); + GameEntity startedGame = gameService.startGame( + request.mapPath, + request.playerName + ); + LOGGER.info( + "Game started at: " + + (startedGame != null ? startedGame.startTime : "unknown") + ); - LOGGER.info( - "Game started at: " + - (startedGame != null ? startedGame.startTime : "unknown") - ); - - // StartGameResponse response = new StartGameResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + // StartGameResponse response = new StartGameResponse(); + // return Response.ok(response).build(); + return Response.ok().build(); + } catch (Exception e) { + return Response.status( + 400, + "Invalid path or invalid name provided." + ).build(); + } } } 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 6aab3fc..757b215 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,5 +1,6 @@ package fr.epita.assistants.yakamon.presentation.rest; +import fr.epita.assistants.yakamon.domain.service.GameService; import fr.epita.assistants.yakamon.presentation.api.response.GetInventoryResponse; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; @@ -13,10 +14,18 @@ import jakarta.ws.rs.core.Response; @Consumes(MediaType.APPLICATION_JSON) public class InventoryResource { + private final GameService gameService = new GameService(); + @GET public Response getInventory() { - // GetInventoryResponse response = new GetInventoryResponse(); + if (!gameService.isStarted()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Game not started") + .build(); + } + // TODO service + // GetInventoryResponse response = inventoryService.getInventory(); // return Response.ok(response).build(); - return Response.ok().build(); + return Response.status(Response.Status.NOT_IMPLEMENTED).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 a9f76b3..2ac486c 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,12 +1,14 @@ package fr.epita.assistants.yakamon.presentation.rest; 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; @@ -16,7 +18,11 @@ import jakarta.ws.rs.core.Response; @Produces(MediaType.APPLICATION_JSON) public class PlayerResource { - private final GameService gameService = new GameService(); + @Inject + private GameService gameService; + + @Inject + private PlayerService playerService; @POST @Path("/catch") @@ -26,8 +32,23 @@ public class PlayerResource { .entity("Game not started") .build(); } - // TODO service - return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + + try { + var yakamon = playerService.catchYakamon(); + var response = new PlayerCatchResponse( + yakamon.id.toString(), + yakamon.nickname, + yakamon.yakadex_entry_id.id, + yakamon.energy_points + ); + 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(); + } } @POST @@ -42,20 +63,6 @@ public class PlayerResource { return Response.status(Response.Status.NOT_IMPLEMENTED).build(); } - @GET - @Path("/inventory") - public Response getInventory() { - if (!gameService.isStarted()) { - return Response.status(Response.Status.BAD_REQUEST) - .entity("Game not started") - .build(); - } - // TODO service - // GetInventoryResponse response = inventoryService.getInventory(); - // return Response.ok(response).build(); - return Response.status(Response.Status.NOT_IMPLEMENTED).build(); - } - @POST @Path("/move") public Response move(PlayerMoveRequest request) { @@ -64,19 +71,27 @@ public class PlayerResource { .entity("Game not started") .build(); } - if (request == null) { + + if (request == null || request.direction == null) { return Response.status(Response.Status.BAD_REQUEST) - .entity("Request body is required") + .entity("Invalid direction") .build(); } - // if (request.direction == null) { - // return Response.status(Response.Status.BAD_REQUEST) - // .entity("Direction is required") - // .build(); - // } - // TODO service - return Response.status(Response.Status.NOT_IMPLEMENTED).build(); + try { + fr.epita.assistants.yakamon.utils.Point newPos = playerService.move( + request.direction + ); + return Response.ok( + new PlayerMoveResponse(newPos.getPosX(), newPos.getPosY()) + ).build(); + } catch (jakarta.ws.rs.WebApplicationException e) { + return e.getResponse(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } } @GET 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 d3e51dd..54c7102 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,8 +1,10 @@ package fr.epita.assistants.yakamon.presentation.rest; import fr.epita.assistants.yakamon.domain.service.GameService; +import fr.epita.assistants.yakamon.domain.service.YakadexService; 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; @@ -12,7 +14,11 @@ import jakarta.ws.rs.core.Response; @Consumes(MediaType.APPLICATION_JSON) public class YakadexResource { - private final GameService gameService = new GameService(); + @Inject + private GameService gameService; + + @Inject + private YakadexService yakadexService; @GET public Response getYakadex( @@ -24,9 +30,10 @@ public class YakadexResource { .build(); } - // YakadexAllInfosResponse response = new YakadexAllInfosResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + YakadexAllInfosResponse response = yakadexService.getAllEntries( + onlyMissing + ); + return Response.ok(response).build(); } @GET @@ -38,12 +45,12 @@ public class YakadexResource { .build(); } - if (id == null || id < 0) { + YakadexInfosResponse response = yakadexService.getEntryById(id); + + if (response == null) { return Response.status(Response.Status.NOT_FOUND).build(); } - // YakadexInfosResponse response = new YakadexInfosResponse(); - // return Response.ok(response).build(); - return Response.ok().build(); + return Response.ok(response).build(); } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/utils/ErrorCode.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/utils/ErrorCode.java index 5d89ce8..db0f9bf 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/utils/ErrorCode.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/utils/ErrorCode.java @@ -1,23 +1,31 @@ package fr.epita.assistants.yakamon.utils; +import static jakarta.ws.rs.core.Response.Status; + import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; import lombok.Getter; import lombok.RequiredArgsConstructor; -import static jakarta.ws.rs.core.Response.Status; - @Getter @RequiredArgsConstructor public enum ErrorCode { - EXAMPLE_ERROR(Status.INTERNAL_SERVER_ERROR, "This is an error example"); + EXAMPLE_ERROR(Status.INTERNAL_SERVER_ERROR, "This is an error example"), + BAD_REQUEST(Status.BAD_REQUEST, "Bad request"), + INVALID_MAP(Status.BAD_REQUEST, "Given map is invalid"), + GAME_NOT_STARTED(Status.CONFLICT, "Game has not been started"), + GAME_ALREADY_STARTED(Status.FORBIDDEN, "Game is already started"); private final Response.Status errorCode; private final String errorMessage; public WebApplicationException getException() { - return new WebApplicationException(Response.status(errorCode).entity(new ErrorInfo(errorMessage)).build()); + return new WebApplicationException( + Response.status(errorCode) + .entity(new ErrorInfo(errorMessage)) + .build() + ); } public void throwException() { @@ -25,6 +33,10 @@ public enum ErrorCode { } public void throwException(String prefix) { - throw new WebApplicationException(Response.status(errorCode).entity(new ErrorInfo(prefix + ": " + errorMessage)).build()); + throw new WebApplicationException( + Response.status(errorCode) + .entity(new ErrorInfo(prefix + ": " + errorMessage)) + .build() + ); } } diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ConverterTests.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ConverterTests.java new file mode 100644 index 0000000..c2d80d2 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ConverterTests.java @@ -0,0 +1,239 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static org.junit.jupiter.api.Assertions.*; + +import fr.epita.assistants.yakamon.converter.DtoToEntityConverter; +import fr.epita.assistants.yakamon.converter.EntityToDtoConverter; +import fr.epita.assistants.yakamon.converter.EntityToModelConverter; +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity; +import fr.epita.assistants.yakamon.domain.entity.YakamonEntity; +import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; +import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import fr.epita.assistants.yakamon.presentation.api.request.StartGameRequest; +import fr.epita.assistants.yakamon.utils.ElementType; +import java.util.UUID; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("ConverterTests") +public class ConverterTests { + + @Test + @DisplayName("ModelToYakamon: null returns null") + public void testNullYakamonToModel() { + assertNull(EntityToModelConverter.toYakamonModel(null)); + } + + @Test + @DisplayName("ModelToYakamon: valid conversion") + public void testYakamonToModel() { + YakamonEntity yakamon = new YakamonEntity(); + yakamon.uuid = UUID.randomUUID(); + yakamon.nickname = "Bastiedon"; + yakamon.yakadexId = 6; + yakamon.energyPoints = 50; + + var model = EntityToModelConverter.toYakamonModel(yakamon); + + assertNotNull(model); + assertEquals("Bastiedon", model.nickname); + assertEquals(50, model.energy_points); + } + + @Test + @DisplayName("ModelToYakadex: null returns null") + public void testNullYakadexToModel() { + assertNull(EntityToModelConverter.toYakadexEntryModel(null)); + } + + @Test + @DisplayName("ModelToYakadex: single type") + public void testYakadexSingleType() { + YakadexEntryEntity yakadex = new YakadexEntryEntity(); + yakadex.id = 1; + yakadex.name = "Yakimon"; + yakadex.firstType = ElementType.NORMAL; + yakadex.secondType = null; + yakadex.caught = true; + + var model = EntityToModelConverter.toYakadexEntryModel(yakadex); + + assertNotNull(model); + assertEquals("NORMAL", model.first_type); + assertNull(model.second_type); + } + + @Test + @DisplayName("ModelToYakadex: dual types") + public void testYakadexDualTypes() { + YakadexEntryEntity yakadex = new YakadexEntryEntity(); + yakadex.id = 25; + yakadex.name = "Pikachu"; + yakadex.firstType = ElementType.ELECTRIC; + yakadex.secondType = ElementType.FLYING; + yakadex.caught = false; + + var model = EntityToModelConverter.toYakadexEntryModel(yakadex); + + assertNotNull(model); + assertEquals("ELECTRIC", model.first_type); + assertEquals("FLYING", model.second_type); + } + + @Test + @DisplayName("DtoToYakamon: null returns null") + public void testNullYakamonAction() { + assertNull(DtoToEntityConverter.toYakamonEntity(null)); + } + + @Test + @DisplayName("DtoToYakamon: valid conversion") + public void testYakamonActionValid() { + UUID uuid = UUID.randomUUID(); + YakamonAction action = new YakamonAction( + uuid.toString(), + "Bastiedon", + 6, + 100 + ); + + YakamonEntity entity = DtoToEntityConverter.toYakamonEntity(action); + + assertNotNull(entity); + assertEquals(uuid, entity.uuid); + assertEquals("Bastiedon", entity.nickname); + } + + @Test + @DisplayName("DtoToYakamon: invalid uuid handled") + public void testYakamonInvalidUuid() { + YakamonAction action = new YakamonAction("not-a-uuid", "Test", 1, 0); + YakamonEntity entity = DtoToEntityConverter.toYakamonEntity(action); + + assertNotNull(entity); + assertNull(entity.uuid); + } + + @Test + @DisplayName("DtoToYakadex: null returns null") + public void testNullYakadexEntry() { + assertNull(DtoToEntityConverter.toYakadexEntryEntity(null)); + } + + @Test + @DisplayName("DtoToYakadex: valid types") + public void testYakadexTypesConvert() { + YakadexEntry dto = new YakadexEntry( + 1, + "Yakimon", + "NORMAL", + "FLYING", + 10, + 2, + true, + "A creature" + ); + YakadexEntryEntity entity = DtoToEntityConverter.toYakadexEntryEntity( + dto + ); + + assertNotNull(entity); + assertEquals(ElementType.NORMAL, entity.firstType); + assertEquals(ElementType.FLYING, entity.secondType); + } + + @Test + @DisplayName("DtoToYakadex: invalid enum handled") + public void testYakadexInvalidEnum() { + YakadexEntry dto = new YakadexEntry( + 1, + "Test", + "INVALID", + null, + 10, + null, + false, + "Test" + ); + YakadexEntryEntity entity = DtoToEntityConverter.toYakadexEntryEntity( + dto + ); + + assertNotNull(entity); + assertNull(entity.firstType); + } + + @Test + @DisplayName("DtoToGame: converts correctly") + public void testGameDtoConvert() { + StartGameRequest request = new StartGameRequest("test_map", "Player"); + GameEntity entity = DtoToEntityConverter.toGameEntity(request); + + assertNotNull(entity); + assertEquals("test_map", entity.mapPath); + assertTrue(entity.started); + } + + @Test + @DisplayName("EntityToYakamon: null returns null") + public void testNullYakamonDto() { + assertNull(EntityToDtoConverter.toYakamonAction(null)); + } + + @Test + @DisplayName("EntityToYakamon: valid conversion") + public void testYakamonDto() { + YakamonEntity yakamon = new YakamonEntity(); + yakamon.uuid = UUID.randomUUID(); + yakamon.nickname = "Bastiedon"; + yakamon.yakadexId = 6; + yakamon.energyPoints = 75; + + YakamonAction action = EntityToDtoConverter.toYakamonAction(yakamon); + + assertNotNull(action); + assertEquals("Bastiedon", action.nickname); + assertEquals(6, action.yakadexId); + } + + @Test + @DisplayName("EntityToYakadex: null returns null") + public void testNullYakadexDto() { + assertNull(EntityToDtoConverter.toYakadexEntry(null)); + } + + @Test + @DisplayName("EntityToYakadex: conversion") + public void testYakadexDto() { + YakadexEntryEntity yakadex = new YakadexEntryEntity(); + yakadex.id = 1; + yakadex.name = "Yakimon"; + yakadex.firstType = ElementType.NORMAL; + yakadex.secondType = null; + yakadex.caught = true; + + YakadexEntry entry = EntityToDtoConverter.toYakadexEntry(yakadex); + + assertNotNull(entry); + assertEquals("NORMAL", entry.firstType); + assertNull(entry.secondType); + } + + @Test + @DisplayName("EntityToYakamon: list conversion") + public void testYakamonListDto() { + YakamonEntity y1 = new YakamonEntity(); + y1.uuid = UUID.randomUUID(); + y1.nickname = "Yak1"; + y1.yakadexId = 1; + y1.energyPoints = 0; + + var result = EntityToDtoConverter.toYakamonActions( + java.util.List.of(y1) + ); + + assertEquals(1, result.size()); + assertEquals("Yak1", result.get(0).nickname); + } +} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/GameResourceTest.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/GameResourceTest.java new file mode 100644 index 0000000..148f4a6 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/GameResourceTest.java @@ -0,0 +1,189 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static io.restassured.RestAssured.given; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@QuarkusTest +@DisplayName("GameResourceTest") +public class GameResourceTest { + + @Test + @DisplayName("POST /start/ with valid request") + public void testStartGameWithValidRequest() { + String requestBody = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(200); + } + + @Test + @DisplayName("POST /start without trailing slash") + public void testStartGameWithoutTrailingSlash() { + String requestBody = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start") + .then() + .statusCode(200); + } + + @Test + @DisplayName("POST /start/ missing mapPath returns 400") + public void testStartGameWithoutMapPath() { + String requestBody = "{\"playerName\": \"Alice\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /start/ missing playerName returns 400") + public void testStartGameWithoutPlayerName() { + String requestBody = "{\"mapPath\": \"map1.txt\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /start/ blank mapPath returns 400") + public void testStartGameWithBlankMapPath() { + String requestBody = "{\"mapPath\": \"\", \"playerName\": \"Alice\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /start/ blank playerName returns 400") + public void testStartGameWithBlankPlayerName() { + String requestBody = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /start/ both fields blank returns 400") + public void testStartGameWithBothBlank() { + String requestBody = "{\"mapPath\": \"\", \"playerName\": \"\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /start/ whitespace mapPath returns 400") + public void testStartGameWithWhitespaceMapPath() { + String requestBody = + "{\"mapPath\": \" \", \"playerName\": \"Alice\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /start/ whitespace playerName returns 400") + public void testStartGameWithWhitespacePlayerName() { + String requestBody = + "{\"mapPath\": \"map1.txt\", \"playerName\": \" \"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /start/ with special characters in name") + public void testStartGameWithSpecialCharacterName() { + String requestBody = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice-Smith_123\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(200); + } + + @Test + @DisplayName("POST /start/ with complex map path") + public void testStartGameWithComplexMapPath() { + String requestBody = + "{\"mapPath\": \"maps/world/level1/forest.txt\", \"playerName\": \"TestPlayer\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .statusCode(200); + } + + @Test + @DisplayName("POST /start/ returns JSON") + public void testStartGameContentType() { + String requestBody = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/start/") + .then() + .contentType(ContentType.JSON); + } +} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/HelloWorldResourceTest.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/HelloWorldResourceTest.java new file mode 100644 index 0000000..ff72850 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/HelloWorldResourceTest.java @@ -0,0 +1,79 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static io.restassured.RestAssured.given; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@QuarkusTest +@DisplayName("HelloWorldResourceTest") +public class HelloWorldResourceTest { + + @Test + @DisplayName("GET /hello/") + public void testHelloWorldWithoutName() { + given() + .when() + .get("/hello/") + .then() + .statusCode(200) + .contentType(ContentType.TEXT); + } + + @Test + @DisplayName("GET /hello without trailing slash") + public void testHelloWorldWithoutTrailingSlash() { + given() + .when() + .get("/hello") + .then() + .statusCode(200) + .contentType(ContentType.TEXT); + } + + @Test + @DisplayName("GET /hello/{name}") + public void testHelloWorldWithName() { + given() + .when() + .get("/hello/Alice") + .then() + .statusCode(200) + .contentType(ContentType.TEXT); + } + + @Test + @DisplayName("GET /hello/{name} with different name") + public void testHelloWorldWithDifferentName() { + given() + .when() + .get("/hello/Bob") + .then() + .statusCode(200) + .contentType(ContentType.TEXT); + } + + @Test + @DisplayName("GET /hello/{name} with special characters") + public void testHelloWorldWithSpecialCharacters() { + given() + .when() + .get("/hello/John-Doe") + .then() + .statusCode(200) + .contentType(ContentType.TEXT); + } + + @Test + @DisplayName("GET /hello/{name} with numeric name") + public void testHelloWorldWithNumericName() { + given() + .when() + .get("/hello/123") + .then() + .statusCode(200) + .contentType(ContentType.TEXT); + } +} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/InventoryResourceTest.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/InventoryResourceTest.java new file mode 100644 index 0000000..4eac668 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/InventoryResourceTest.java @@ -0,0 +1,116 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static io.restassured.RestAssured.given; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@QuarkusTest +@DisplayName("InventoryResourceTest") +public class InventoryResourceTest { + + @Test + @DisplayName("GET /inventory returns 200") + public void testGetInventorySuccess() { + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /inventory returns JSON") + public void testGetInventoryContentType() { + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("GET /inventory without trailing slash") + public void testGetInventoryWithoutTrailingSlash() { + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(200) + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("GET /inventory multiple requests") + public void testGetInventoryMultipleCalls() { + for (int i = 0; i < 5; i++) { + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(200) + .contentType(ContentType.JSON); + } + } + + @Test + @DisplayName("GET /inventory with accept header") + public void testGetInventoryWithAcceptHeader() { + given() + .accept(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(200) + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("GET /inventory without body") + public void testGetInventoryNoBody() { + given().when().get("/inventory").then().statusCode(200); + } + + @Test + @DisplayName("GET /inventory with query params") + public void testGetInventoryWithQueryParams() { + given() + .contentType(ContentType.JSON) + .queryParam("filter", "all") + .when() + .get("/inventory") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /inventory rapid consecutive requests") + public void testGetInventoryRapidRequests() { + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(200); + + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(200); + + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(200); + } +} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/MainTests.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/MainTests.java new file mode 100644 index 0000000..64f5f98 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/MainTests.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.yakamon_testsuite; + +// import static org.junit.jupiter.api.Assertions.*; + +// import org.junit.jupiter.api.Test; + +public class MainTests {} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/PlayerResourceTest.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/PlayerResourceTest.java new file mode 100644 index 0000000..1e82eb0 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/PlayerResourceTest.java @@ -0,0 +1,210 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static io.restassured.RestAssured.given; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@QuarkusTest +@DisplayName("PlayerResourceTest") +public class PlayerResourceTest { + + @Test + @DisplayName("POST /catch without game returns 400") + public void testCatchYakamonWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .post("/catch") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /collect without game returns 400") + public void testCollectWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .post("/collect") + .then() + .statusCode(400); + } + + @Test + @DisplayName("GET /inventory without game returns 400") + public void testGetInventoryWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /move without game returns 400") + public void testMoveWithoutGameStarted() { + String requestBody = "{\"direction\": \"UP\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/move") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /move without body returns 400") + public void testMoveWithoutRequestBody() { + given() + .contentType(ContentType.JSON) + .when() + .post("/move") + .then() + .statusCode(400); + } + + @Test + @DisplayName("GET /player without game returns 400") + public void testGetPlayerInfosWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .get("/player") + .then() + .statusCode(400); + } + + @Test + @DisplayName("GET /inventory returns JSON") + public void testGetInventoryContentType() { + given() + .contentType(ContentType.JSON) + .when() + .get("/inventory") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("POST /move returns JSON") + public void testMoveContentType() { + String requestBody = "{\"direction\": \"UP\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/move") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("GET /player returns JSON") + public void testGetPlayerContentType() { + given() + .contentType(ContentType.JSON) + .when() + .get("/player") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("POST /catch returns JSON") + public void testCatchContentType() { + given() + .contentType(ContentType.JSON) + .when() + .post("/catch") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("POST /collect returns JSON") + public void testCollectContentType() { + given() + .contentType(ContentType.JSON) + .when() + .post("/collect") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("POST /move with UP direction") + public void testMoveWithUpDirection() { + String requestBody = "{\"direction\": \"UP\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/move") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /move with DOWN direction") + public void testMoveWithDownDirection() { + String requestBody = "{\"direction\": \"DOWN\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/move") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /move with LEFT direction") + public void testMoveWithLeftDirection() { + String requestBody = "{\"direction\": \"LEFT\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/move") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /move with RIGHT direction") + public void testMoveWithRightDirection() { + String requestBody = "{\"direction\": \"RIGHT\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/move") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /move with invalid direction") + public void testMoveWithInvalidDirection() { + String requestBody = "{\"direction\": \"INVALID\"}"; + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/move") + .then() + .statusCode(400); + } +} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ServiceLayerTests.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ServiceLayerTests.java new file mode 100644 index 0000000..be22cf8 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/ServiceLayerTests.java @@ -0,0 +1,173 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static org.junit.jupiter.api.Assertions.*; + +import fr.epita.assistants.yakamon.domain.entity.GameEntity; +import fr.epita.assistants.yakamon.domain.entity.TileEntity; +import fr.epita.assistants.yakamon.utils.Direction; +import fr.epita.assistants.yakamon.utils.Point; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("ServiceLayerTests") +public class ServiceLayerTests { + + @BeforeEach + public void setup() { + GameEntity.INSTANCE = null; + } + + @Test + @DisplayName("GameStart") + public void testGameStart() { + GameEntity game = new GameEntity("test_map"); + assertTrue(game.started); + assertEquals("test_map", game.mapPath); + } + + @Test + @DisplayName("GameStop") + public void testGameStop() { + GameEntity game = new GameEntity("map"); + game.stop(); + assertFalse(game.started); + assertNull(GameEntity.INSTANCE); + } + + @Test + @DisplayName("GameSetMap") + public void testGameSetMap() { + GameEntity game = new GameEntity("map"); + TileEntity[][] map = new TileEntity[2][2]; + game.map = map; + assertNotNull(game.map); + assertEquals(2, game.map.length); + } + + @Test + @DisplayName("TileGrassWalkable") + public void testGrassWalkable() { + TileEntity tile = new TileEntity('G', 'N'); + assertTrue(tile.isWalkable()); + } + + @Test + @DisplayName("TileSandWalkable") + public void testSandWalkable() { + TileEntity tile = new TileEntity('S', 'N'); + assertTrue(tile.isWalkable()); + } + + @Test + @DisplayName("TileRockWalkable") + public void testRockWalkable() { + TileEntity tile = new TileEntity('R', 'N'); + assertTrue(tile.isWalkable()); + } + + @Test + @DisplayName("TileWaterNotWalkable") + public void testWaterNotWalkable() { + TileEntity tile = new TileEntity('W', 'N'); + assertFalse(tile.isWalkable()); + } + + @Test + @DisplayName("TileMountainNotWalkable") + public void testMountainNotWalkable() { + TileEntity tile = new TileEntity('M', 'N'); + assertFalse(tile.isWalkable()); + } + + @Test + @DisplayName("TileLavaNotWalkable") + public void testLavaNotWalkable() { + TileEntity tile = new TileEntity('L', 'N'); + assertFalse(tile.isWalkable()); + } + + @Test + @DisplayName("TileCollectible") + public void testTileCollectible() { + TileEntity tile = new TileEntity('G', 'Y'); + assertEquals('Y', tile.collectible); + assertEquals('G', tile.terrain); + } + + @Test + @DisplayName("DirectionUp") + public void testDirectionUp() { + Point p = Direction.UP.getPoint(); + assertEquals(0, p.getPosX()); + assertEquals(-1, p.getPosY()); + } + + @Test + @DisplayName("DirectionDown") + public void testDirectionDown() { + Point p = Direction.DOWN.getPoint(); + assertEquals(0, p.getPosX()); + assertEquals(1, p.getPosY()); + } + + @Test + @DisplayName("DirectionLeft") + public void testDirectionLeft() { + Point p = Direction.LEFT.getPoint(); + assertEquals(-1, p.getPosX()); + assertEquals(0, p.getPosY()); + } + + @Test + @DisplayName("DirectionRight") + public void testDirectionRight() { + Point p = Direction.RIGHT.getPoint(); + assertEquals(1, p.getPosX()); + assertEquals(0, p.getPosY()); + } + + @Test + @DisplayName("PointCreation") + public void testPointCreation() { + Point p = new Point(5, 10); + assertEquals(5, p.getPosX()); + assertEquals(10, p.getPosY()); + } + + @Test + @DisplayName("GameInstance") + public void testGameInstance() { + GameEntity g1 = new GameEntity("map1"); + assertSame(GameEntity.INSTANCE, g1); + } + + @Test + @DisplayName("MapGrid") + public void testMapGrid() { + TileEntity[][] map = new TileEntity[3][3]; + map[0][0] = new TileEntity('G', 'N'); + map[1][1] = new TileEntity('W', 'N'); + map[2][2] = new TileEntity('R', 'Y'); + + assertTrue(map[0][0].isWalkable()); + assertFalse(map[1][1].isWalkable()); + assertTrue(map[2][2].isWalkable()); + } + + @Test + @DisplayName("YakamonTile") + public void testYakamonTile() { + TileEntity tile = new TileEntity('G', 'b'); + assertEquals('b', tile.collectible); + assertTrue(tile.isWalkable()); + } + + @Test + @DisplayName("ItemTile") + public void testItemTile() { + TileEntity tile = new TileEntity('S', 'S'); + assertEquals('S', tile.collectible); + assertTrue(tile.isWalkable()); + } +} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/TeamResourceTest.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/TeamResourceTest.java new file mode 100644 index 0000000..ba60b94 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/TeamResourceTest.java @@ -0,0 +1,457 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static io.restassured.RestAssured.given; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@QuarkusTest +@DisplayName("TeamResourceTest") +public class TeamResourceTest { + + private static final String VALID_UUID = + "550e8400-e29b-41d4-a716-446655440000"; + private static final String ANOTHER_UUID = + "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + + @Test + @DisplayName("GET /team without game returns 400") + public void testGetTeamWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .get("/team") + .then() + .statusCode(400); + } + + @Test + @DisplayName("GET /team returns JSON") + public void testGetTeamContentType() { + given() + .contentType(ContentType.JSON) + .when() + .get("/team") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("POST /team/{uuid}/evolve without game returns 400") + public void testEvolveWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .post("/team/" + VALID_UUID + "/evolve") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/evolve with blank uuid returns 400") + public void testEvolveWithBlankUuid() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .post("/team//evolve") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/evolve with valid uuid returns 200") + public void testEvolveWithValidUuid() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .post("/team/" + VALID_UUID + "/evolve") + .then() + .statusCode(200); + } + + @Test + @DisplayName("POST /team/{uuid}/evolve returns JSON") + public void testEvolveContentType() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .post("/team/" + VALID_UUID + "/evolve") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("POST /team/{uuid}/feed without game returns 400") + public void testFeedWithoutGameStarted() { + String requestBody = "{\"quantity\": 10}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/team/" + VALID_UUID + "/feed") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/feed with blank uuid returns 400") + public void testFeedWithBlankUuid() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"quantity\": 10}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/team//feed") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/feed with null quantity returns 400") + public void testFeedWithNullQuantity() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"quantity\": null}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/team/" + VALID_UUID + "/feed") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/feed with zero quantity returns 400") + public void testFeedWithZeroQuantity() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"quantity\": 0}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/team/" + VALID_UUID + "/feed") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/feed with negative quantity returns 400") + public void testFeedWithNegativeQuantity() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"quantity\": -5}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/team/" + VALID_UUID + "/feed") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/feed with valid quantity returns 200") + public void testFeedWithValidQuantity() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"quantity\": 10}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/team/" + VALID_UUID + "/feed") + .then() + .statusCode(200); + } + + @Test + @DisplayName("POST /team/{uuid}/feed without body returns 400") + public void testFeedWithMissingRequestBody() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .post("/team/" + VALID_UUID + "/feed") + .then() + .statusCode(400); + } + + @Test + @DisplayName("POST /team/{uuid}/feed returns JSON") + public void testFeedContentType() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"quantity\": 10}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/team/" + VALID_UUID + "/feed") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("DELETE /team/{uuid}/release without game returns 400") + public void testReleaseWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .delete("/team/" + VALID_UUID + "/release") + .then() + .statusCode(400); + } + + @Test + @DisplayName("DELETE /team/{uuid}/release with blank uuid returns 400") + public void testReleaseWithBlankUuid() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .delete("/team//release") + .then() + .statusCode(400); + } + + @Test + @DisplayName("DELETE /team/{uuid}/release with valid uuid returns 204") + public void testReleaseWithValidUuid() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .delete("/team/" + VALID_UUID + "/release") + .then() + .statusCode(204); + } + + @Test + @DisplayName("DELETE /team/{uuid}/release multiple times") + public void testReleaseWithMultipleUuids() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .delete("/team/" + VALID_UUID + "/release") + .then() + .statusCode(204); + + given() + .contentType(ContentType.JSON) + .when() + .delete("/team/" + ANOTHER_UUID + "/release") + .then() + .statusCode(204); + } + + @Test + @DisplayName("PATCH /team/{uuid}/rename without game returns 400") + public void testRenameWithoutGameStarted() { + String requestBody = "{\"newNickname\": \"NewName\"}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .patch("/team/" + VALID_UUID + "/rename") + .then() + .statusCode(400); + } + + @Test + @DisplayName("PATCH /team/{uuid}/rename with blank uuid returns 400") + public void testRenameWithBlankUuid() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"newNickname\": \"NewName\"}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .patch("/team//rename") + .then() + .statusCode(400); + } + + @Test + @DisplayName("PATCH /team/{uuid}/rename without body returns 400") + public void testRenameWithMissingRequestBody() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .patch("/team/" + VALID_UUID + "/rename") + .then() + .statusCode(400); + } + + @Test + @DisplayName("PATCH /team/{uuid}/rename with valid request returns 200") + public void testRenameWithValidRequest() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"newNickname\": \"NewName\"}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .patch("/team/" + VALID_UUID + "/rename") + .then() + .statusCode(200); + } + + @Test + @DisplayName("PATCH /team/{uuid}/rename returns JSON") + public void testRenameContentType() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"newNickname\": \"NewName\"}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .patch("/team/" + VALID_UUID + "/rename") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("PATCH /team/{uuid}/rename with special characters") + public void testRenameWithSpecialCharacters() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + String requestBody = "{\"newNickname\": \"New-Name_123\"}"; + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .patch("/team/" + VALID_UUID + "/rename") + .then() + .statusCode(200); + } +} diff --git a/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/YakadexResourceTest.java b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/YakadexResourceTest.java new file mode 100644 index 0000000..ebcadd5 --- /dev/null +++ b/yakamon/src/test/java/fr/epita/assistants/yakamon_testsuite/YakadexResourceTest.java @@ -0,0 +1,328 @@ +package fr.epita.assistants.yakamon_testsuite; + +import static io.restassured.RestAssured.given; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@QuarkusTest +@DisplayName("YakadexResourceTest") +public class YakadexResourceTest { + + @Test + @DisplayName("GET /yakadex without game returns 400") + public void testGetYakadexWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex") + .then() + .statusCode(400); + } + + @Test + @DisplayName("GET /yakadex returns 200 when game started") + public void testGetYakadexWithGameStarted() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex with only_missing=true") + public void testGetYakadexWithOnlyMissingTrue() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .queryParam("only_missing", true) + .when() + .get("/yakadex") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex with only_missing=false") + public void testGetYakadexWithOnlyMissingFalse() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .queryParam("only_missing", false) + .when() + .get("/yakadex") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex with only_missing=TRUE uppercase") + public void testGetYakadexWithOnlyMissingUppercase() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .queryParam("only_missing", "TRUE") + .when() + .get("/yakadex") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex returns JSON") + public void testGetYakadexContentType() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("GET /yakadex/{id} without game returns 400") + public void testGetYakadexByIdWithoutGameStarted() { + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/1") + .then() + .statusCode(400); + } + + @Test + @DisplayName("GET /yakadex/{id} with valid id") + public void testGetYakadexByIdWithGameStarted() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/1") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex/{id} with id=0") + public void testGetYakadexByIdWithZero() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/0") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex/{id} with negative id returns 404") + public void testGetYakadexByIdWithNegativeId() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/-1") + .then() + .statusCode(404); + } + + @Test + @DisplayName("GET /yakadex/{id} with large id") + public void testGetYakadexByIdWithLargeId() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/999999") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex/{id} returns JSON") + public void testGetYakadexByIdContentType() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/1") + .then() + .contentType(ContentType.JSON); + } + + @Test + @DisplayName("GET /yakadex/{id} multiple different ids") + public void testGetYakadexByIdMultipleIds() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + int[] ids = { 1, 2, 5, 10, 42, 100 }; + for (int id : ids) { + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/" + id) + .then() + .statusCode(200); + } + } + + @Test + @DisplayName("GET /yakadex/{id} with id=-2 returns 404") + public void testGetYakadexByIdWithAnotherNegativeId() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/-2") + .then() + .statusCode(404); + } + + @Test + @DisplayName("GET /yakadex/{id} with id=-100 returns 404") + public void testGetYakadexByIdWithLargeNegativeId() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex/-100") + .then() + .statusCode(404); + } + + @Test + @DisplayName("GET /yakadex without query params") + public void testGetYakadexWithoutQueryParams() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex") + .then() + .statusCode(200); + } + + @Test + @DisplayName("GET /yakadex multiple calls") + public void testGetYakadexMultipleCalls() { + String startRequest = + "{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}"; + given() + .contentType(ContentType.JSON) + .body(startRequest) + .when() + .post("/start/"); + + for (int i = 0; i < 3; i++) { + given() + .contentType(ContentType.JSON) + .when() + .get("/yakadex") + .then() + .statusCode(200); + } + } +} From 0b841e70a4b130db8fa1d4a18582b82dbe022f7f Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Fri, 3 Apr 2026 23:53:17 +0200 Subject: [PATCH 6/9] ah --- .../yakamon/data/model/YakadexEntryModel.java | 1 - .../yakamon/domain/entity/ItemEntity.java | 1 - .../yakamon/domain/entity/PlayerEntity.java | 6 + .../domain/service/InventoryService.java | 24 +++ .../yakamon/domain/service/PlayerService.java | 131 +++++++++++++++- .../yakamon/domain/service/TeamService.java | 148 +++++++++++++++++- .../domain/service/YakadexService.java | 35 +++-- .../presentation/rest/GameResource.java | 107 +++++++++++-- .../presentation/rest/HelloWorldResource.java | 22 --- .../presentation/rest/InventoryResource.java | 40 ++++- .../presentation/rest/PlayerResource.java | 58 +++++-- .../presentation/rest/TeamResource.java | 130 ++++++++++++--- .../presentation/rest/YakadexResource.java | 20 ++- 13 files changed, 620 insertions(+), 103 deletions(-) create mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/InventoryService.java delete mode 100644 yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/rest/HelloWorldResource.java 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(); } } From e1301f007b87c9e2b3fa07cee09b111746ecf68d Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Sat, 4 Apr 2026 00:01:13 +0200 Subject: [PATCH 7/9] trop tard --- .../yakamon/data/model/ItemModel.java | 30 +++++++++++++++++-- .../yakamon/domain/service/GameService.java | 4 +-- .../yakamon/domain/service/PlayerService.java | 10 +++---- .../presentation/rest/InventoryResource.java | 6 ++-- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java index ff1a256..e71d104 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/data/model/ItemModel.java @@ -9,10 +9,34 @@ public class ItemModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - protected Integer id; + private Integer id; @Enumerated - public ItemType type; + private ItemType type; - public Integer quantity; + private Integer quantity; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public ItemType getType() { + return type; + } + + public void setType(ItemType type) { + this.type = type; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java index 0d4fd1c..29abf6e 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/domain/service/GameService.java @@ -59,8 +59,8 @@ public class GameService { // Initialize player inventory ItemModel yakaballs = new ItemModel(); - yakaballs.type = ItemType.YAKABALL; - yakaballs.quantity = 5; + yakaballs.setType(ItemType.YAKABALL); + yakaballs.setQuantity(5); // Store playerRepository.persist(player); 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 d8bd07c..954eea4 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 @@ -145,7 +145,7 @@ public class PlayerService { ItemModel yakaballItem = itemRepository .find("type", ItemType.YAKABALL) .firstResult(); - if (yakaballItem == null || yakaballItem.quantity < 1) { + if (yakaballItem == null || yakaballItem.getQuantity() < 1) { throw new WebApplicationException( Response.status(400).entity("Not enough Yakaballs").build() ); @@ -170,7 +170,7 @@ public class PlayerService { ErrorCode.BAD_REQUEST.throwException("Yakamon species not found"); } - yakaballItem.quantity -= 1; + yakaballItem.setQuantity(yakaballItem.getQuantity() - 1); itemRepository.persist(yakaballItem); YakamonModel newYakamon = new YakamonModel(); @@ -342,11 +342,11 @@ public class PlayerService { .firstResult(); if (item == null) { item = new ItemModel(); - item.type = itemType; - item.quantity = 1; + item.setType(itemType); + item.setQuantity(1); itemRepository.persist(item); } else { - item.quantity += 1; + item.setQuantity(item.getQuantity() + 1); itemRepository.persist(item); } } 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 ff1c655..c8af0e9 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 @@ -41,10 +41,10 @@ public class InventoryResource { 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(); + itemType.type = item.getType().name(); + itemType.value = item.getType().name(); responseItem.itemType = itemType; - responseItem.quantity = item.quantity; + responseItem.quantity = item.getQuantity(); responseItems.add(responseItem); } From b3bdec10490656b252f61a05649b7dbe5af076d8 Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Sat, 4 Apr 2026 22:25:16 +0200 Subject: [PATCH 8/9] tar dur, jws demotivant --- .../presentation/api/YakamonAction.java | 2 ++ .../api/request/StartGameRequest.java | 2 ++ .../api/request/TeamFeedRequest.java | 2 ++ .../api/request/TeamRenameRequest.java | 2 ++ .../api/response/GetInventoryResponse.java | 18 +++++++++++++- .../api/response/PlayerCatchResponse.java | 2 ++ .../api/response/PlayerCollectResponse.java | 24 +++++++++++++++---- .../api/response/PlayerInfosResponse.java | 4 +++- .../api/response/TeamEvolveResponse.java | 2 ++ .../api/response/TeamFeedResponse.java | 2 ++ .../api/response/TeamInfosResponse.java | 4 +++- .../api/response/TeamRenameResponse.java | 2 ++ .../api/response/YakadexAllInfosResponse.java | 4 +++- .../presentation/rest/PlayerResource.java | 6 ++--- 14 files changed, 65 insertions(+), 11 deletions(-) diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java index 5b307d3..6faef97 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/YakamonAction.java @@ -1,7 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +@NoArgsConstructor @AllArgsConstructor public class YakamonAction { diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java index 97461d1..885e164 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/StartGameRequest.java @@ -1,7 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.request; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +@NoArgsConstructor @AllArgsConstructor public class StartGameRequest { diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java index 8d094b0..5c9fbfa 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamFeedRequest.java @@ -1,8 +1,10 @@ package fr.epita.assistants.yakamon.presentation.api.request; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; @AllArgsConstructor +@NoArgsConstructor public class TeamFeedRequest { public Integer quantity; diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java index bceb7e2..db76322 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/request/TeamRenameRequest.java @@ -1,8 +1,10 @@ package fr.epita.assistants.yakamon.presentation.api.request; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; @AllArgsConstructor +@NoArgsConstructor public class TeamRenameRequest { public String newNickname; diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java index 8b4a708..3a1cf7e 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/GetInventoryResponse.java @@ -2,21 +2,37 @@ package fr.epita.assistants.yakamon.presentation.api.response; import java.util.List; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; @AllArgsConstructor +@NoArgsConstructor public class GetInventoryResponse { public class ItemType { public String type; public String value; + + public ItemType() {} + + public ItemType(String type, String value) { + this.type = type; + this.value = value; + } } public class Items { public ItemType itemType; public Integer quantity; + + public Items() {} + + public Items(ItemType itemType, Integer quantity) { + this.itemType = itemType; + this.quantity = quantity; + } } - List items; + public List items; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java index 499002b..9ca2b4d 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCatchResponse.java @@ -1,7 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import lombok.NoArgsConstructor; +@NoArgsConstructor public class PlayerCatchResponse extends YakamonAction { public PlayerCatchResponse( diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java index 1ac932c..200336f 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerCollectResponse.java @@ -3,20 +3,36 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.utils.tile.ItemType; import fr.epita.assistants.yakamon.utils.tile.TerrainType; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; @AllArgsConstructor +@NoArgsConstructor public class PlayerCollectResponse { public class TileType { public class Collectible { - ItemType type; - String value; + public ItemType type; + public String value; + + public Collectible() {} + + public Collectible(ItemType type, String value) { + this.type = type; + this.value = value; + } } - TerrainType terrainType; - Collectible collectible; + public TerrainType terrainType; + public Collectible collectible; + + public TileType() {} + + public TileType(TerrainType terrainType, Collectible collectible) { + this.terrainType = terrainType; + this.collectible = collectible; + } } public TileType tileType; diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java index 7773e89..c4fa464 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/PlayerInfosResponse.java @@ -1,7 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.response; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +@NoArgsConstructor @AllArgsConstructor public class PlayerInfosResponse { @@ -10,7 +12,7 @@ public class PlayerInfosResponse { public Integer posX; public Integer posY; public String lastMove; - public String lastCatch; public String lastCollect; + public String lastCatch; public String lastFeed; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java index 5347429..7b97656 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamEvolveResponse.java @@ -1,7 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import lombok.NoArgsConstructor; +@NoArgsConstructor public class TeamEvolveResponse extends YakamonAction { public TeamEvolveResponse( diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java index d13d43b..d8b024b 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamFeedResponse.java @@ -1,7 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import lombok.NoArgsConstructor; +@NoArgsConstructor public class TeamFeedResponse extends YakamonAction { public TeamFeedResponse( diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java index e2444ea..cc56a45 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamInfosResponse.java @@ -2,9 +2,11 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.presentation.api.YakamonAction; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; @AllArgsConstructor +@NoArgsConstructor public class TeamInfosResponse { - YakamonAction[] yakamons; + public YakamonAction[] yakamons; } diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java index a1b7f28..2c46caf 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/TeamRenameResponse.java @@ -1,7 +1,9 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.presentation.api.YakamonAction; +import lombok.NoArgsConstructor; +@NoArgsConstructor public class TeamRenameResponse extends YakamonAction { public TeamRenameResponse( diff --git a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java index 0302209..5409a5e 100644 --- a/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java +++ b/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation/api/response/YakadexAllInfosResponse.java @@ -2,9 +2,11 @@ package fr.epita.assistants.yakamon.presentation.api.response; import fr.epita.assistants.yakamon.presentation.api.YakadexEntry; import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; @AllArgsConstructor +@NoArgsConstructor public class YakadexAllInfosResponse { - YakadexEntry[] entries; + public YakadexEntry[] entries; } 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 fdfd8e4..174f90e 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 @@ -123,12 +123,12 @@ public class PlayerResource { 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.lastCatch != null + ? player.lastCatch.format(formatter) + : null, player.lastFeed != null ? player.lastFeed.format(formatter) : null From c58c8725e8fe25204272b5b116da107f26a872cb Mon Sep 17 00:00:00 2001 From: guillm Date: Fri, 24 Apr 2026 21:03:48 +0200 Subject: [PATCH 9/9] Added README --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..bb23564 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# JWS + +> **Note** This is a school project, therefore it probably won't interest you if you are looking for something useful. + +## Overview + +JWS stands for Java Web Services and as its name doesn't suggest at all, it's basically a web server for a a pokemon-like game. It's written in Java and built onto Quarkus and Jakarta, providing a REST API with strict server-side rules like cooldowns and cheating prevention. + +## Architecture + +> **Note** Source code is located inside the `yakamon` folder, both others are school requirements and aren't important + +Each layer is strictly separated and can only communicate via to the one directly below or above it via converters. + +### Presentation Layer (REST & DTOs) +* located at `yakamon/jws/yakamon/src/main/java/fr/epita/assistants/yakamon/presentation` +* Handled by JAX-RS (Jakarta RESTful Web Services). +* Exposes standard HTTP endpoints (`/player`, `/move`, `/yakadex`, etc.). Full API specification can be found inside `yakamon/src/main/resources/openapi.yaml` +* Implements strict **Data Transfer Objects (DTOs)** for both Requests and Responses to ensure the internal database models are never exposed directly to the client. + +### Business Logic Layer (Services) +* located at `yakamon/jws/yakamon/src/main/java/fr/epita/assistants/yakamon/domain` +* Acts as the brain of the application. +* Implements complex game rules: validating if a target tile is walkable based on the terrain type, calculating cooldowns between moves, and managing creature capture probabilities. +* **Converters** are used to translate Entities from the Data Layer into DTOs for the Presentation Layer. + +### Data Access Layer (Hibernate ORM) +* located at `yakamon/jws/yakamon/src/main/java/fr/epita/assistants/yakamon/data` +* Manages persistence using **Hibernate ORM** with the Active Record / Repository pattern. +* Defines relational entities (Player, Game, Yakamon, Item) mapped to a PostgreSQL database. +