diff --git a/src/main/java/com/uniovi/configuration/SecurityConfig.java b/src/main/java/com/uniovi/configuration/SecurityConfig.java index 14586d1b..8cfbc8f3 100644 --- a/src/main/java/com/uniovi/configuration/SecurityConfig.java +++ b/src/main/java/com/uniovi/configuration/SecurityConfig.java @@ -48,6 +48,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/api/**").permitAll() .requestMatchers("/game/**").authenticated() .requestMatchers("/multiplayerGame/**").authenticated() + .requestMatchers("/startMultiplayerGame/**", "/endGameList/**").authenticated() .requestMatchers("/lobby/**").authenticated() .requestMatchers("/ranking/playerRanking").authenticated() .requestMatchers("/player/admin/**").hasAuthority("ROLE_ADMIN") diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index c147ea6e..c4f46423 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -25,15 +25,12 @@ @Controller public class GameController { private static final String GAMESESSION_STR = "gameSession"; - private final QuestionService questionService; private final GameSessionService gameSessionService; private final PlayerService playerService; private final MultiplayerSessionService multiplayerSessionService; - private boolean isMultiPlayer; - public GameController(QuestionService questionService, GameSessionService gameSessionService, PlayerService playerService, MultiplayerSessionService multiplayerSessionService) { this.questionService = questionService; @@ -50,7 +47,7 @@ public GameController(QuestionService questionService, GameSessionService gameSe @GetMapping("/game") public String getGame(HttpSession session, Model model, Principal principal) { GameSession gameSession = (GameSession) session.getAttribute(GAMESESSION_STR); - if (gameSession != null) { + if (gameSession != null && !gameSession.isFinished() && !gameSession.isMultiplayer()) { if (checkUpdateGameSession(gameSession, session)) { return "game/fragments/gameFinished"; } @@ -58,8 +55,6 @@ public String getGame(HttpSession session, Model model, Principal principal) { gameSession = gameSessionService.startNewGame(getLoggedInPlayer(principal)); session.setAttribute(GAMESESSION_STR, gameSession); playerService.deleteMultiplayerCode(gameSession.getPlayer().getId()); - session.setAttribute("gameSession", gameSession); - } model.addAttribute("question", gameSession.getCurrentQuestion()); @@ -81,7 +76,6 @@ public String joinMultiplayerGame(@PathVariable String code, HttpSession session Optional player = playerService.getUserByUsername(principal.getName()); Player p = player.orElse(null); - isMultiPlayer=true; if (playerService.changeMultiplayerCode(p.getId(),code)) { multiplayerSessionService.addToLobby(code,p.getId()); model.addAttribute("multiplayerGameCode",code); @@ -96,26 +90,39 @@ public String joinMultiplayerGame(@PathVariable String code, HttpSession session public String createMultiplayerGame(HttpSession session, Principal principal, Model model) { Optional player = playerService.getUserByUsername(principal.getName()); Player p = player.orElse(null); - String code=""+playerService.createMultiplayerGame(p.getId()); + String code="" + playerService.createMultiplayerGame(p.getId()); multiplayerSessionService.multiCreate(code,p.getId()); session.setAttribute("multiplayerCode",code); - isMultiPlayer=true; return "redirect:/game/lobby"; } @GetMapping("/startMultiplayerGame") public String startMultiplayerGame(HttpSession session, Model model, Principal principal) { GameSession gameSession = (GameSession) session.getAttribute("gameSession"); - if(! isMultiPlayer){ - return "index"; - } + if (gameSession != null) { + if (! gameSession.isMultiplayer()) { + session.removeAttribute("gameSession"); + return "redirect:/startMultiplayerGame"; + } + + if (gameSession.isFinished()) { + model.addAttribute("code", session.getAttribute("multiplayerCode")); + return "game/multiplayerFinished"; + } + if (checkUpdateGameSession(gameSession, session)) { return "game/fragments/gameFinished"; } } else { + Optional player = playerService.getUserByUsername(principal.getName()); + if (!player.isPresent()) { + return "redirect:/"; + } gameSession = gameSessionService.startNewMultiplayerGame(getLoggedInPlayer(principal), - playerService.getUserByUsername(principal.getName()).get().getMultiplayerCode()); + player.get().getMultiplayerCode()); + if (gameSession == null) + return "redirect:/multiplayerGame"; session.setAttribute("gameSession", gameSession); } @@ -129,6 +136,7 @@ public String endMultiplayerGame(Model model,@PathVariable String code) { model.addAttribute("code",code); return "ranking/multiplayerRanking"; } + @GetMapping("/endGameList/{code}") @ResponseBody public Map endMultiplayerGameTable(@PathVariable String code) { @@ -137,10 +145,10 @@ public Map endMultiplayerGameTable(@PathVariable String code) { for (Map.Entry player : playerScores.entrySet()) { String playerName = player.getKey().getUsername(); String playerScoreValue; - if(player.getValue()==-1){ - playerScoreValue="N/A"; - }else{ - playerScoreValue=""+player.getValue(); + if (player.getValue() == -1) { + playerScoreValue = "N/A"; + } else { + playerScoreValue = "" + player.getValue(); } playersNameWithScore.put(playerName, playerScoreValue); } @@ -162,17 +170,12 @@ public List updatePlayerList(@PathVariable String code) { @GetMapping("/game/lobby") public String createLobby( HttpSession session, Model model) { int code = Integer.parseInt((String)session.getAttribute("multiplayerCode")); - List players=playerService.getUsersByMultiplayerCode(code); + List players = playerService.getUsersByMultiplayerCode(code); model.addAttribute("players",players); model.addAttribute("code",session.getAttribute("multiplayerCode")); return "/game/lobby"; } - @GetMapping("/game/startMultiplayerGame") - public String startMultiplayerGame( HttpSession session, Model model) { - return "/game/lobby"; - } - /** * This method is used to check the answer for a specific question * @param idQuestion The id of the question. @@ -205,7 +208,6 @@ else if(questionService.checkAnswer(idQuestion, idAnswer)) { gameSession.addQuestion(true, getRemainingTime(gameSession)); gameSession.addAnsweredQuestion(gameSession.getCurrentQuestion()); } - } else { gameSession.addAnsweredQuestion(gameSession.getCurrentQuestion()); gameSession.addQuestion(false, 0); @@ -220,26 +222,38 @@ else if(questionService.checkAnswer(idQuestion, idAnswer)) { public String updateGame(Model model, HttpSession session, Principal principal) { GameSession gameSession = (GameSession) session.getAttribute(GAMESESSION_STR); Question nextQuestion = gameSession.getCurrentQuestion(); - if(nextQuestion == null && isMultiPlayer/*gameSession.getPlayer().getMultiplayerCode()!=null session.getAttribute("multiplayerCode") !=null*/){ - gameSessionService.endGame(gameSession); + if (nextQuestion == null && gameSession.isMultiplayer()) { + int code = Integer.parseInt((String) session.getAttribute("multiplayerCode")); + List players = playerService.getUsersByMultiplayerCode(code); + + if (!gameSession.isFinished()) { + gameSessionService.endGame(gameSession); - int code = Integer.parseInt((String)session.getAttribute("multiplayerCode")); - List players=playerService.getUsersByMultiplayerCode(code); - model.addAttribute("players",players); - model.addAttribute("code",session.getAttribute("multiplayerCode")); - session.removeAttribute("gameSession"); + model.addAttribute("players", players); + model.addAttribute("code", session.getAttribute("multiplayerCode")); + gameSession.setFinished(true); - Optional player = playerService.getUserByUsername(principal.getName()); - Player p = player.orElse(null); - playerService.setScoreMultiplayerCode(p.getId(),""+gameSession.getScore()); - multiplayerSessionService.changeScore(p.getMultiplayerCode()+"",p.getId(),gameSession.getScore()); - isMultiPlayer=false; - return "game/multiFinished"; + Optional player = playerService.getUserByUsername(principal.getName()); + Player p = player.orElse(null); + playerService.setScoreMultiplayerCode(p.getId(),"" + gameSession.getScore()); + multiplayerSessionService.changeScore(p.getMultiplayerCode()+"",p.getId(),gameSession.getScore()); + } else { + model.addAttribute("players", players); + + } + + model.addAttribute("code", session.getAttribute("multiplayerCode")); + return "ranking/multiplayerRanking"; } + if (nextQuestion == null) { - gameSessionService.endGame(gameSession); - session.removeAttribute(GAMESESSION_STR); - model.addAttribute("score", gameSession.getScore()); + if (!gameSession.isFinished()) { + gameSessionService.endGame(gameSession); + gameSession.setFinished(true); + } else { + session.removeAttribute(GAMESESSION_STR); + model.addAttribute("score", gameSession.getScore()); + } return "game/fragments/gameFinished"; } @@ -268,7 +282,7 @@ public String getPoints(HttpSession session) { public String getCurrentQuestion(HttpSession session) { GameSession gameSession = (GameSession) session.getAttribute(GAMESESSION_STR); if (gameSession != null) - return String.valueOf(gameSession.getAnsweredQuestions().size()+1); + return String.valueOf(Math.min(gameSession.getAnsweredQuestions().size()+1, GameSessionService.NORMAL_GAME_QUESTION_NUM)); else return "0"; } diff --git a/src/main/java/com/uniovi/entities/GameSession.java b/src/main/java/com/uniovi/entities/GameSession.java index a18b17a4..75ec5a51 100644 --- a/src/main/java/com/uniovi/entities/GameSession.java +++ b/src/main/java/com/uniovi/entities/GameSession.java @@ -45,6 +45,12 @@ public class GameSession implements JsonEntity, Serializable { @Transient private Question currentQuestion; + @Transient + private boolean isMultiplayer = false; + + @Transient + private boolean isFinished = false; + public GameSession(Player player, List questions) { this.player = player; this.questionsToAnswer = questions; @@ -75,7 +81,7 @@ public boolean isAnswered(Question question) { } public Question getNextQuestion() { - if(questionsToAnswer.isEmpty()) { + if (questionsToAnswer.isEmpty()) { currentQuestion = null; return null; } diff --git a/src/main/java/com/uniovi/entities/MultiplayerSession.java b/src/main/java/com/uniovi/entities/MultiplayerSession.java index e9b77a5c..e09597a4 100644 --- a/src/main/java/com/uniovi/entities/MultiplayerSession.java +++ b/src/main/java/com/uniovi/entities/MultiplayerSession.java @@ -5,10 +5,7 @@ import lombok.Setter; import org.springframework.stereotype.Service; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; @Getter // getters para todas las propiedades @Setter // setters para todas las propiedades @@ -29,7 +26,6 @@ public MultiplayerSession() {} public MultiplayerSession(String code, Player p) { this.multiplayerCode=code; playerScores.put(p,-1); - } public void addPlayer(Player p){ diff --git a/src/main/java/com/uniovi/entities/Question.java b/src/main/java/com/uniovi/entities/Question.java index 7704ef82..1fa2b9c2 100644 --- a/src/main/java/com/uniovi/entities/Question.java +++ b/src/main/java/com/uniovi/entities/Question.java @@ -25,7 +25,6 @@ public class Question implements JsonEntity { public static final String SPANISH = "es"; public static final String FRENCH = "fr"; - @Id @GeneratedValue private Long id; diff --git a/src/main/java/com/uniovi/services/GameSessionService.java b/src/main/java/com/uniovi/services/GameSessionService.java index d3ee5f67..83166040 100644 --- a/src/main/java/com/uniovi/services/GameSessionService.java +++ b/src/main/java/com/uniovi/services/GameSessionService.java @@ -8,6 +8,7 @@ import java.util.List; public interface GameSessionService { + Integer NORMAL_GAME_QUESTION_NUM = 4; /** * Return the list of GameSessions diff --git a/src/main/java/com/uniovi/services/MultiplayerSessionService.java b/src/main/java/com/uniovi/services/MultiplayerSessionService.java index 7b917458..d9e82736 100644 --- a/src/main/java/com/uniovi/services/MultiplayerSessionService.java +++ b/src/main/java/com/uniovi/services/MultiplayerSessionService.java @@ -3,6 +3,7 @@ import com.uniovi.entities.GameSession; import com.uniovi.entities.MultiplayerSession; import com.uniovi.entities.Player; +import com.uniovi.entities.Question; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -21,4 +22,6 @@ public interface MultiplayerSessionService { void changeScore(String code,Long id,int score); boolean existsCode(String code); + + List getQuestions(String code); } diff --git a/src/main/java/com/uniovi/services/QuestionService.java b/src/main/java/com/uniovi/services/QuestionService.java index 924f2c44..1cea8683 100644 --- a/src/main/java/com/uniovi/services/QuestionService.java +++ b/src/main/java/com/uniovi/services/QuestionService.java @@ -59,8 +59,6 @@ public interface QuestionService { */ List getRandomQuestions(int num); - List getRandomMultiplayerQuestions(int num, int code); - /** * Check if the answer is correct * @param idquestion The id of the question diff --git a/src/main/java/com/uniovi/services/impl/GameSessionImpl.java b/src/main/java/com/uniovi/services/impl/GameSessionImpl.java index aca3509e..2e665fa6 100644 --- a/src/main/java/com/uniovi/services/impl/GameSessionImpl.java +++ b/src/main/java/com/uniovi/services/impl/GameSessionImpl.java @@ -1,10 +1,9 @@ package com.uniovi.services.impl; -import com.uniovi.entities.Associations; -import com.uniovi.entities.Player; +import com.uniovi.entities.*; import com.uniovi.repositories.GameSessionRepository; -import com.uniovi.entities.GameSession; import com.uniovi.services.GameSessionService; +import com.uniovi.services.MultiplayerSessionService; import com.uniovi.services.QuestionService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -15,14 +14,16 @@ @Service public class GameSessionImpl implements GameSessionService { - public static final Integer NORMAL_GAME_QUESTION_NUM = 4; private final GameSessionRepository gameSessionRepository; private final QuestionService questionService; + private final MultiplayerSessionService multiplayerSessionService; - public GameSessionImpl(GameSessionRepository gameSessionRepository, QuestionService questionService) { + public GameSessionImpl(GameSessionRepository gameSessionRepository, QuestionService questionService, + MultiplayerSessionService multiplayerSessionService) { this.gameSessionRepository = gameSessionRepository; this.questionService = questionService; + this.multiplayerSessionService = multiplayerSessionService; } @Override @@ -32,7 +33,6 @@ public List getGameSessions() { @Override public List getGameSessionsByPlayer(Player player) { - return gameSessionRepository.findAllByPlayer(player); } @@ -52,7 +52,13 @@ public GameSession startNewGame(Player player) { @Override public GameSession startNewMultiplayerGame(Player player, int code) { - return new GameSession(player, questionService.getRandomMultiplayerQuestions(NORMAL_GAME_QUESTION_NUM,code)); + List qs = multiplayerSessionService.getQuestions(String.valueOf(code)); + if (qs == null) + return null; + + GameSession sess = new GameSession(player, qs); + sess.setMultiplayer(true); + return sess; } @Override diff --git a/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java b/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java index 4570b8ad..ecbf1a94 100644 --- a/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java +++ b/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java @@ -2,26 +2,31 @@ import com.uniovi.entities.MultiplayerSession; import com.uniovi.entities.Player; +import com.uniovi.entities.Question; import com.uniovi.repositories.MultiplayerSessionRepository; import com.uniovi.repositories.PlayerRepository; +import com.uniovi.services.GameSessionService; import com.uniovi.services.MultiplayerSessionService; +import com.uniovi.services.QuestionService; import jakarta.transaction.Transactional; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.*; -import java.util.stream.Collectors; @Service public class MultiplayerSessionImpl implements MultiplayerSessionService { private final PlayerRepository playerRepository; private final MultiplayerSessionRepository multiplayerSessionRepository; + private final QuestionService questionService; + private Map> multiplayerSessionQuestions = new HashMap<>(); - public MultiplayerSessionImpl(PlayerRepository playerRepository, MultiplayerSessionRepository multiplayerSessionRepository) { + + public MultiplayerSessionImpl(PlayerRepository playerRepository, MultiplayerSessionRepository multiplayerSessionRepository, + QuestionService questionService) { this.playerRepository = playerRepository; this.multiplayerSessionRepository = multiplayerSessionRepository; + this.questionService = questionService; } @Override @@ -47,8 +52,10 @@ public Map getPlayersWithScores(int multiplayerCode) { public void multiCreate(String code, Long id) { Player p = playerRepository.findById(id).orElse(null); - if (p != null) - multiplayerSessionRepository.save(new MultiplayerSession(code,p)); + if (p != null) { + multiplayerSessionRepository.save(new MultiplayerSession(code, p)); + multiplayerSessionQuestions.put(code, questionService.getRandomQuestions(GameSessionService.NORMAL_GAME_QUESTION_NUM)); + } } @Override @@ -79,4 +86,12 @@ public void changeScore(String code, Long id, int score) { public boolean existsCode(String code) { return multiplayerSessionRepository.findByMultiplayerCode(code) != null; } + + @Override + public List getQuestions(String code) { + if (!multiplayerSessionQuestions.containsKey(code)) { + return null; + } + return new ArrayList<>(multiplayerSessionQuestions.get(code)); + } } diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index c3c7e566..7e000354 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -181,7 +181,6 @@ public void setScoreMultiplayerCode(Long id, String score) { * with same multiplayerCode at the moment of the join * */ private boolean existsMultiplayerCode(String code){ - //return ! getUsersByMultiplayerCode(Integer.parseInt(code)).isEmpty(); return ! multiplayerSessionService.getPlayersWithScores(Integer.parseInt(code)).isEmpty(); } diff --git a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java index c5c8a656..aed0ceb0 100644 --- a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java @@ -113,39 +113,6 @@ public List getRandomQuestions(int num) { return res; } - - @Override - public List getRandomMultiplayerQuestions(int num, int code) { - List allQuestions = questionRepository.findAll().stream() - .filter(question -> question.getLanguage().equals(LocaleContextHolder.getLocale().getLanguage())).toList(); - List res = new ArrayList<>(); - int size= allQuestions.size(); - - int currentIndex = generateIndex(code, size) -4; - - for (int i = 0; i < num; i++) { - - Question question = allQuestions.get(currentIndex); - - while (question.hasEmptyOptions() || res.contains(question)) { - question = allQuestions.get(currentIndex); - } - - res.add(question); - currentIndex++; - } - return res; - } - private int generateIndex(int code, int size) { - int hashCode = combineHash(code, LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); - return Math.abs(hashCode) % size; - } - - private int combineHash(int code, String date) { - String combinedString = code + date; - return combinedString.hashCode(); - } - @Override public boolean checkAnswer(Long idquestion, Long idanswer) { Optional q = questionRepository.findById(idquestion); diff --git a/src/main/resources/templates/game/fragments/gameFrame.html b/src/main/resources/templates/game/fragments/gameFrame.html index b5d3afcb..86ae07ad 100644 --- a/src/main/resources/templates/game/fragments/gameFrame.html +++ b/src/main/resources/templates/game/fragments/gameFrame.html @@ -4,7 +4,7 @@

-
+
@@ -24,15 +24,12 @@

$("#continueBtn").hide(); function setupAnswers() { - //let questionId = [[${question.id}]]; - //let answers = /*[[${question.options}]]*/ []; - answers.forEach(answer => { $("#btn" + answer.id).click(function () { clearTimeout(timeoutId); clearInterval(interval); - //$("#gameFrame").load("/game/" + questionId + "/" + answer.id); - if (!(corrAnswerId == answer.id)) { + + if (corrAnswerId !== answer.id) { $("#btn" + answer.id).css("background-color", "red"); } respuesta(questionId, answer.id); @@ -43,8 +40,14 @@

setupAnswers(); function respuesta(qId, aId) { + $.ajax( + { + type: "GET", + url: "/game/" + qId + "/" + aId + + }); answers.forEach(answer => { - if (corrAnswerId == answer.id) { + if (corrAnswerId === answer.id) { $("#btn" + answer.id).css("background-color", "green"); } $("#btn" + answer.id).off("click"); @@ -99,7 +102,7 @@

clearTimeout(timeoutId); clearInterval(interval); } - $("#gameFrame").load("/game/" + qId + "/" + aId); + $("#gameFrame").load("/game/update"); }, timeoutPeriod); initStopwatch(timeoutPeriod / 1000); @@ -112,7 +115,7 @@

clearTimeout(timeoutId); clearInterval(interval); } - $("#gameFrame").load("/game/" + qId + "/" + aId); + $("#gameFrame").load("/game/update"); }); } } diff --git a/src/main/resources/templates/game/multiFinished.html b/src/main/resources/templates/game/multiFinished.html deleted file mode 100644 index 3aff9e76..00000000 --- a/src/main/resources/templates/game/multiFinished.html +++ /dev/null @@ -1,19 +0,0 @@ - -
- -

- -

- - - - - - - -
\ No newline at end of file diff --git a/src/main/resources/templates/game/multiplayerFinished.html b/src/main/resources/templates/game/multiplayerFinished.html new file mode 100644 index 00000000..9322906c --- /dev/null +++ b/src/main/resources/templates/game/multiplayerFinished.html @@ -0,0 +1,14 @@ + + + + + + + +
+ +
+ +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/ranking/multiplayerRanking.html b/src/main/resources/templates/ranking/multiplayerRanking.html index 459edbcf..e0eb59b0 100644 --- a/src/main/resources/templates/ranking/multiplayerRanking.html +++ b/src/main/resources/templates/ranking/multiplayerRanking.html @@ -1,31 +1,29 @@ - - - - - - -

- -
-
    +
    + + + + + + + + + + +
    -
    - -