peer-at-code-backend/src/dev/peerat/backend/routes/PuzzleResponse.java
2025-01-24 23:16:06 +01:00

169 lines
5.4 KiB
Java

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<Completion> leaderboard;
public PuzzleResponse(DatabaseRepository databaseRepo, Configuration config, @Injection("leaderboard") Locker<Completion> locker){
this.databaseRepo = databaseRepo;
usersFilesPath = config.getUsersFiles();
this.leaderboard = locker;
}
@RouteDoc(path = "/puzzleResponse/<id>", 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.getScore(user.getId(), received.getPuzzleId()) > 0){
context.response(403);
return;
}
Puzzle currentPuzzle = databaseRepo.getPuzzle(received.getPuzzleId());
if(!currentPuzzle.hasStarted()){
context.response(423);
return;
}
Chapter chapter = this.databaseRepo.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.getPlayerGroup(user.getId(), chapter.getId());
if(group == null){
context.response(423);
return;
}
}
Completion completion = databaseRepo.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<String> 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;
}
}