Skip to content

Commit

Permalink
Merge pull request #219 from Arquisoft/multiplayer-bugs-fixing
Browse files Browse the repository at this point in the history
Multiplayer bugs fixing
  • Loading branch information
Pelayori authored Apr 27, 2024
2 parents aceb858 + 929a7b2 commit 6da2da1
Show file tree
Hide file tree
Showing 63 changed files with 2,249 additions and 208 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@Component
public interface QuestionGenerator {
List<Question> getQuestions(String language) throws IOException;
List<Question> getQuestions(String language) throws IOException, InterruptedException;

List<Question> getQuestions(String language, JsonNode question, Category cat) throws IOException;
List<Question> getQuestions(String language, JsonNode question, Category cat) throws IOException, InterruptedException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class QuestionGeneratorV2 implements QuestionGenerator{

Expand All @@ -27,6 +29,8 @@ public class QuestionGeneratorV2 implements QuestionGenerator{
private String answer_placeholder;
private String language;

private Random random = new SecureRandom();

public QuestionGeneratorV2(JsonNode jsonNode) {
this.jsonNode = jsonNode;
this.language_placeholder = jsonNode.get("language_placeholder").textValue();
Expand All @@ -35,7 +39,7 @@ public QuestionGeneratorV2(JsonNode jsonNode) {
}

@Override
public List<Question> getQuestions(String language) throws IOException {
public List<Question> getQuestions(String language) throws IOException, InterruptedException {
this.language = language;
List<Question> questions = new ArrayList<>();
JsonNode categories = jsonNode.findValue("categories");
Expand All @@ -51,12 +55,12 @@ public List<Question> getQuestions(String language) throws IOException {
}

@Override
public List<Question> getQuestions(String language, JsonNode question, Category cat) throws IOException {
public List<Question> getQuestions(String language, JsonNode question, Category cat) throws IOException, InterruptedException {
this.language = language;
return this.generateQuestion(question, cat);
}

private List<Question> generateQuestion(JsonNode question, Category cat) throws IOException {
private List<Question> generateQuestion(JsonNode question, Category cat) throws IOException, InterruptedException {
// Get the SPARQL query from the JSON
String query = question.get("sparqlQuery").textValue();

Expand Down Expand Up @@ -85,14 +89,16 @@ private List<Question> generateQuestion(JsonNode question, Category cat) throws
List<Answer> options = this.generateOptions(results, correctAnswer, answerLabel);
options.add(correct);

// Generate the question statement
String questionStatement = statement.replace(question_placeholder, result.path(questionLabel).path("value").asText());
if (statement != null) {
// Generate the question statement
String questionStatement = statement.replace(question_placeholder, result.path(questionLabel).path("value").asText());

// Generate the question
Question q = new Question(questionStatement, options, correct, cat, language);
// Generate the question
Question q = new Question(questionStatement, options, correct, cat, language);

// Add the question to the list
questions.add(q);
// Add the question to the list
questions.add(q);
}
}
return questions;
}
Expand All @@ -103,8 +109,8 @@ private List<Answer> generateOptions(JsonNode results, String correctAnswer, Str
int size = results.size();
int tries = 0;

while (options.size() < 3 && tries < 10){
int random = (int) (Math.random() * size);
while (options.size() < 3 && tries < 10) {
int random = (int) (this.random.nextFloat() * size);
String option = results.get(random).path(answerLabel).path("value").asText();
if (!option.equals(correctAnswer) && !usedOptions.contains(option) ) {
usedOptions.add(option);
Expand All @@ -130,41 +136,28 @@ private String prepareStatement(JsonNode question) {
return null;
}

private JsonNode getQueryResult(String query) throws IOException {
private JsonNode getQueryResult(String query) throws IOException, InterruptedException {

System.out.println("Query: " + query);
HttpClient client = HttpClient.newHttpClient();
JsonNode resultsNode;
try {

String endpointUrl = "https://query.wikidata.org/sparql?query=" +
URLEncoder.encode(query, StandardCharsets.UTF_8) +
"&format=json";
String endpointUrl = "https://query.wikidata.org/sparql?query=" +
URLEncoder.encode(query, StandardCharsets.UTF_8) +
"&format=json";

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(endpointUrl))
.header("Accept", "application/json")
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(endpointUrl))
.header("Accept", "application/json")
.build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

// Process the JSON response using Jackson ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonResponse = objectMapper.readTree(response.body());
// Process the JSON response using Jackson ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonResponse = objectMapper.readTree(response.body());

// Access the data from the JSON response
resultsNode = jsonResponse.path("results").path("bindings");

} catch (InterruptedException e) {
throw new QuestionGeneratorException("Generation of questions was interrupted");
}
// Access the data from the JSON response
resultsNode = jsonResponse.path("results").path("bindings");
return resultsNode;

}

private static class QuestionGeneratorException extends RuntimeException {
public QuestionGeneratorException(String message) {
super(message);
}
}
}
3 changes: 3 additions & 0 deletions src/main/java/com/uniovi/configuration/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestMatchers("/signup/**").permitAll()
.requestMatchers("/api/**").permitAll()
.requestMatchers("/game/**").authenticated()
.requestMatchers("/multiplayerGame/**").authenticated()
.requestMatchers("/lobby/**").authenticated()
.requestMatchers("/ranking/playerRanking").authenticated()
.requestMatchers("/player/admin/**").hasAuthority("ROLE_ADMIN")
.requestMatchers("/**").permitAll()
).formLogin(
form -> form
Expand Down
146 changes: 131 additions & 15 deletions src/main/java/com/uniovi/controllers/GameController.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.uniovi.controllers;

import com.uniovi.entities.GameSession;
import com.uniovi.entities.MultiplayerSession;
import com.uniovi.entities.Player;
import com.uniovi.entities.Question;
import com.uniovi.services.GameSessionService;
import com.uniovi.services.MultiplayerSessionService;
import com.uniovi.services.PlayerService;
import com.uniovi.services.QuestionService;
import jakarta.servlet.http.HttpSession;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -16,19 +20,24 @@
import java.security.Principal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.*;

@Controller
public class GameController {
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) {
PlayerService playerService, MultiplayerSessionService multiplayerSessionService) {
this.questionService = questionService;
this.gameSessionService = gameSessionService;
this.playerService = playerService;
this.multiplayerSessionService = multiplayerSessionService;
}


Expand All @@ -46,6 +55,60 @@ public String getGame(HttpSession session, Model model, Principal principal) {
}
} else {
gameSession = gameSessionService.startNewGame(getLoggedInPlayer(principal));
playerService.deleteMultiplayerCode(gameSession.getPlayer().getId());
session.setAttribute("gameSession", gameSession);

}

model.addAttribute("question", gameSession.getCurrentQuestion());
model.addAttribute("questionDuration", getRemainingTime(gameSession));
return "game/basicGame";
}

@GetMapping("/multiplayerGame")
public String getMultiplayerGame() {
return "game/multiplayerGame";
}

@GetMapping("/multiplayerGame/{code}")
public String joinMultiplayerGame(@PathVariable String code, HttpSession session, Principal principal, Model model) {
Optional<Player> 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);
session.setAttribute("multiplayerCode",code);
return "redirect:/game/lobby";
} else {
return "redirect:/multiplayerGame";
}
}

@GetMapping("/multiplayerGame/createGame")
public String createMultiplayerGame(HttpSession session, Principal principal, Model model) {
Optional<Player> player = playerService.getUserByUsername(principal.getName());
Player p = player.orElse(null);
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 (checkUpdateGameSession(gameSession, session)) {
return "game/fragments/gameFinished";
}
} else {
gameSession = gameSessionService.startNewMultiplayerGame(getLoggedInPlayer(principal),
playerService.getUserByUsername(principal.getName()).get().getMultiplayerCode());
session.setAttribute("gameSession", gameSession);
}

Expand All @@ -54,6 +117,53 @@ public String getGame(HttpSession session, Model model, Principal principal) {
return "game/basicGame";
}

@GetMapping("/multiplayerGame/endGame/{code}")
public String endMultiplayerGame(Model model,@PathVariable String code) {
model.addAttribute("code",code);
return "ranking/multiplayerRanking";
}
@GetMapping("/endGameList/{code}")
@ResponseBody
public Map<String, String> endMultiplayerGameTable(@PathVariable String code) {
Map<Player, Integer> playerScores = multiplayerSessionService.getPlayersWithScores(Integer.parseInt(code));
Map<String, String> playersNameWithScore=new HashMap<>();
for (Map.Entry<Player, Integer> player : playerScores.entrySet()) {
String playerName = player.getKey().getUsername();
String playerScoreValue;
if(player.getValue()==-1){
playerScoreValue="N/A";
}else{
playerScoreValue=""+player.getValue();
}
playersNameWithScore.put(playerName, playerScoreValue);
}
return playersNameWithScore;
}

@GetMapping("/game/lobby/{code}")
@ResponseBody
public List<String> updatePlayerList(@PathVariable String code) {
Map<Player,Integer> players= multiplayerSessionService.getPlayersWithScores(Integer.parseInt(code));
List<String> playerNames = new ArrayList<>();
for (Map.Entry<Player, Integer> player : players.entrySet()) {
playerNames.add(player.getKey().getUsername());
}
Collections.sort(playerNames);
return playerNames;
}
@GetMapping("/game/lobby")
public String createLobby( HttpSession session, Model model) {
int code = Integer.parseInt((String)session.getAttribute("multiplayerCode"));
List<Player> 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
Expand All @@ -65,7 +175,7 @@ public String getGame(HttpSession session, Model model, Principal principal) {
* shown or the timeOutFailure view is shown.
*/
@GetMapping("/game/{idQuestion}/{idAnswer}")
public String getCheckResult(@PathVariable Long idQuestion, @PathVariable Long idAnswer, Model model, HttpSession session) {
public String getCheckResult(@PathVariable Long idQuestion, @PathVariable Long idAnswer, Model model, HttpSession session,Principal principal) {
GameSession gameSession = (GameSession) session.getAttribute("gameSession");
if (gameSession == null) {
return "redirect:/game";
Expand All @@ -79,39 +189,45 @@ public String getCheckResult(@PathVariable Long idQuestion, @PathVariable Long i

if(idAnswer == -1
|| getRemainingTime(gameSession) <= 0) {
//model.addAttribute("correctAnswer", gameSession.getCurrentQuestion().getCorrectAnswer());
//model.addAttribute("messageKey", "timeRunOut.result");
//model.addAttribute("logoImage", "/images/logo_incorrect.svg");
gameSession.addAnsweredQuestion(gameSession.getCurrentQuestion());
gameSession.addQuestion(false, 0);
}
else if(questionService.checkAnswer(idQuestion, idAnswer)) {
//model.addAttribute("messageKey", "correctAnswer.result");
//model.addAttribute("logoImage", "/images/logo_correct.svg");

if (!gameSession.isAnswered(gameSession.getCurrentQuestion())) {
gameSession.addQuestion(true, getRemainingTime(gameSession));
gameSession.addAnsweredQuestion(gameSession.getCurrentQuestion());
}

} else {
//model.addAttribute("correctAnswer", gameSession.getCurrentQuestion().getCorrectAnswer());
//model.addAttribute("messageKey", "failedAnswer.result");
//model.addAttribute("logoImage", "/images/logo_incorrect.svg");
gameSession.addAnsweredQuestion(gameSession.getCurrentQuestion());
gameSession.addQuestion(false, 0);
}

session.setAttribute("hasJustAnswered", true);
gameSession.getNextQuestion();
//return "game/fragments/questionResult";
return updateGame(model, session);
return updateGame(model, session, principal);
}

@GetMapping("/game/update")
public String updateGame(Model model, HttpSession session) {
public String updateGame(Model model, HttpSession session, Principal principal) {
GameSession gameSession = (GameSession) session.getAttribute("gameSession");
Question nextQuestion = gameSession.getCurrentQuestion();
if(nextQuestion == null && isMultiPlayer/*gameSession.getPlayer().getMultiplayerCode()!=null session.getAttribute("multiplayerCode") !=null*/){
gameSessionService.endGame(gameSession);

int code = Integer.parseInt((String)session.getAttribute("multiplayerCode"));
List<Player> players=playerService.getUsersByMultiplayerCode(code);
model.addAttribute("players",players);
model.addAttribute("code",session.getAttribute("multiplayerCode"));
session.removeAttribute("gameSession");

Optional<Player> 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";
}
if (nextQuestion == null) {
gameSessionService.endGame(gameSession);
session.removeAttribute("gameSession");
Expand Down
Loading

0 comments on commit 6da2da1

Please sign in to comment.