169 lines
5.4 KiB
Java
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;
|
|
}
|
|
}
|