package dev.peerat.backend.routes; import static dev.peerat.framework.RequestType.POST; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import dev.peerat.backend.Configuration; import dev.peerat.backend.bonus.extract.RouteDoc; import dev.peerat.backend.model.Chapter; import dev.peerat.backend.model.Completion; import dev.peerat.backend.model.Group; import dev.peerat.backend.model.PeerAtUser; import dev.peerat.backend.model.Player; import dev.peerat.backend.model.Puzzle; import dev.peerat.backend.repository.DatabaseRepository; import dev.peerat.framework.Context; import dev.peerat.framework.HttpReader; import dev.peerat.framework.HttpWriter; import dev.peerat.framework.Injection; import dev.peerat.framework.Locker; import dev.peerat.framework.Response; import dev.peerat.framework.Route; import dev.peerat.framework.utils.json.JsonMap; public class PuzzleResponse implements Response { private final DatabaseRepository databaseRepo; private final String usersFilesPath; private final Locker leaderboard; public PuzzleResponse(DatabaseRepository databaseRepo, Configuration config, @Injection("leaderboard") Locker locker){ this.databaseRepo = databaseRepo; usersFilesPath = config.getUsersFiles(); this.leaderboard = locker; } @RouteDoc(path = "/puzzleResponse/", responseCode = 200, responseDescription = "Bonne réponse, json contenant les points + tries") @RouteDoc(responseCode = 400, responseDescription = "Pas de réponse") @RouteDoc(responseCode = 403, responseDescription = "Déjà répondu") @RouteDoc(responseCode = 406, responseDescription = "Mauvaise réponse") @RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de répondre en dehors de l'event") @Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = POST, needLogin = true) public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{ ReceivedResponse received = new ReceivedResponse(matcher, reader); if (received.getResponse() == null){ context.response(400); return; } PeerAtUser user = context.getUser(); //saveSourceCode(received, databaseRepo.getPlayer(user.getId())); JsonMap responseJSON = new JsonMap(); if(this.databaseRepo.getCompletionRepository().getScore(user.getId(), received.getPuzzleId()) > 0){ context.response(403); return; } Puzzle currentPuzzle = databaseRepo.getPuzzleRepository().getPuzzle(received.getPuzzleId()); if(!currentPuzzle.hasStarted()){ context.response(423); return; } Chapter chapter = this.databaseRepo.getChapterRepository().getChapter(currentPuzzle); if(!chapter.hasStarted()){ context.response(423); return; } if(chapter.getEndDate() != null){ if(LocalDateTime.now().isAfter(chapter.getEndDate().toLocalDateTime())){ if(Arrays.equals(currentPuzzle.getSoluce(), received.getResponse())){ context.response(200, "Content-Type: application/json"); JsonMap theoSaisPasJusteRecevoir200 = new JsonMap(); theoSaisPasJusteRecevoir200.set("success", true); writer.write(theoSaisPasJusteRecevoir200.toString()); return; } context.response(423); return; } Group group = this.databaseRepo.getGroupRepository().getPlayerGroup(user.getId(), chapter.getId()); if(group == null){ context.response(423); return; } } Completion completion = databaseRepo.getCompletionRepository().insertOrUpdatePuzzleResponse(received.getPuzzleId(), user.getId(), received.getFileName(), received.getSourceCode(), received.getResponse(), currentPuzzle); if(completion == null){ context.response(400); return; } if(completion.getScore() > 0){ context.response(200, "Content-Type: application/json"); responseJSON.set("score", completion.getScore()); responseJSON.set("tries", completion.getTries()); }else{ context.response(406, "Content-Type: application/json"); responseJSON.set("tries", completion.getTries()); } writer.write(responseJSON.toString()); writer.flush(); leaderboard.setValue(completion); } private void saveSourceCode(ReceivedResponse received, Player player){ try{ Path path = Paths.get(String.format("%s/%s/puz%04d-%s", usersFilesPath, player.getPseudo(), received.getPuzzleId(), received.getFileName())); Files.write(path, received.getSourceCode()); }catch (IOException e){ System.err.println("ERREUR D'ENREGISTREMENT DU CODE POUR PUZZLE_RESPONSE : " + e.toString()); } } } class ReceivedResponse { private int puzzleId; private byte[] response; private String fileName; private byte[] sourceCode; public ReceivedResponse(Matcher matcher, HttpReader reader) throws Exception { puzzleId = Integer.parseInt(matcher.group(1)); List multiPartData = reader.readMultiPartData(); if (multiPartData != null && multiPartData.size() > 0){ this.response = multiPartData.get(0).getBytes(); System.out.println("Puzzle response:"); System.out.println(Arrays.toString(response)); System.out.println(new String(response)); if (multiPartData.size() == 3) { this.fileName = multiPartData.get(1); this.sourceCode = multiPartData.get(2).getBytes(); } } } public int getPuzzleId() { return puzzleId; } public byte[] getResponse() { return response; } public String getFileName() { return fileName; } public byte[] getSourceCode() { return sourceCode; } }