Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Pelayori committed Apr 26, 2024
2 parents aceb858 + f68cfeb commit 89ba08b
Show file tree
Hide file tree
Showing 64 changed files with 2,253 additions and 210 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ jobs:
kill $(cat spring-boot-app.pid)
- name: Collect Jacoco report and send to Sonar
run: |
./mvnw org.jacoco:jacoco-maven-plugin:report sonar:sonar -Dsonar.projectKey=Arquisoft_wiq_es04b -Dsonar.organization=arquisoft -Dsonar.branch.name=${{ github.ref }} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${{ secrets.SONAR_TOKEN }} -Dspring.profiles.active=test
./mvnw org.jacoco:jacoco-maven-plugin:report sonar:sonar -Dsonar.projectKey=Arquisoft_wiq_es04b -Dsonar.organization=arquisoft -Dsonar.branch.name=${{ github.head_ref || github.ref_name }} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${{ secrets.SONAR_TOKEN }} -Dspring.profiles.active=test
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 89ba08b

Please sign in to comment.