mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-07-09 13:27:45 +00:00
refacto - restructure code
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package uppa.project;
|
||||
|
||||
public final class Global {
|
||||
|
||||
public static final String APP_NAME = "Cards Rush";
|
||||
public static final String PERSISTENCE_UNIT_NAME = "prod";
|
||||
public static final String MAIL_USERNAME = "cardsrushuppa@gmail.com";
|
||||
public static final String MAIL_PASSWORD = "aktr zity mayw kvek";
|
||||
public static final String MAIL_PORT = "587";
|
||||
public static final String MAIL_HOST = "smtp.gmail.com";
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* ForgottenPasswordBeen.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.bean;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Transport;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import uppa.project.Global;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
import static uppa.project.web.servlet.ForgottenPasswordServlet.CreateToken;
|
||||
|
||||
public class ForgottenPasswordBean implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String email;
|
||||
|
||||
private Translator translator;
|
||||
|
||||
public ForgottenPasswordBean() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation des paramètres de la requête & gestion de la création du token de réinitialisation de mot de passe
|
||||
*
|
||||
* @param requestPath le chemin de la requête
|
||||
* @return true si l'adresse e-mail est valide, false sinon
|
||||
*/
|
||||
public boolean validate(String requestPath) {
|
||||
Game_JPA_DAO_Factory factory = new Game_JPA_DAO_Factory();
|
||||
|
||||
try {
|
||||
DAO<User> userDao = factory.getDAOUser();
|
||||
User[] user = userDao.findByField("email", email);
|
||||
|
||||
for (User u : user) {
|
||||
if (u.getEmail().equals(email)) {
|
||||
sendTokenEmail(u, requestPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (DAOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param email l'adresse e-mail supposée de l'utilisateur ayant oublié son mot de passe.
|
||||
* @return this
|
||||
*/
|
||||
public ForgottenPasswordBean setEmail(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param translator le traducteur
|
||||
* @return this
|
||||
*/
|
||||
public ForgottenPasswordBean setTranslator(Translator translator) {
|
||||
this.translator = translator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Création et envoi d'un token de réinitialisation de mot de passe
|
||||
*
|
||||
* @param user l'utilisateur ayant oublié son mot de passe
|
||||
* @param requestPath le chemin de la requête
|
||||
*/
|
||||
private void sendTokenEmail(User user, String requestPath) {
|
||||
|
||||
String token = UUID.randomUUID().toString();
|
||||
RecoveryPasswordToken recoveryPasswordToken = new RecoveryPasswordToken(token, user);
|
||||
CreateToken(recoveryPasswordToken);
|
||||
sendRecoveryEmail(user.getEmail(), token, requestPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Envoi d'un e-mail de réinitialisation de mot de passe
|
||||
*
|
||||
* @param email l'adresse e-mail du destinataire
|
||||
* @param token le token de réinitialisation
|
||||
*/
|
||||
public void sendRecoveryEmail(String email, String token, String requestPath){
|
||||
String host = Global.MAIL_HOST;
|
||||
String port = Global.MAIL_PORT;
|
||||
String username = Global.MAIL_USERNAME;
|
||||
String password = Global.MAIL_PASSWORD;
|
||||
|
||||
Properties props = new Properties();
|
||||
props.put("mail.smtp.auth", "true");
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
props.put("mail.smtp.host", host);
|
||||
props.put("mail.smtp.port", port);
|
||||
|
||||
Session session = Session.getInstance(props, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
// Création du message
|
||||
Message message = new MimeMessage(session);
|
||||
message.setFrom(new InternetAddress(username));
|
||||
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
|
||||
message.setSubject(this.translator.translate("forgotten_email_object"));
|
||||
String contentTemplate = this.translator.translate("forgotten_email_content");
|
||||
String content = MessageFormat.format(contentTemplate, requestPath, token);
|
||||
message.setText(content);
|
||||
// Envoi du message
|
||||
Transport.send(message);
|
||||
|
||||
} catch (MessagingException e) {
|
||||
throw new RuntimeException("Erreur lors de l'envoi de l'e-mail", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* LoginBean.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.bean;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
public class LoginBean implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String username;
|
||||
private String password;
|
||||
private User user;
|
||||
private HttpResponse error;
|
||||
private Translator translator;
|
||||
public LoginBean() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation des paramètres de la requête
|
||||
*
|
||||
* @return true si le nom d'utilisateur et le mot de passe sont valides, false sinon
|
||||
*/
|
||||
public boolean validate() {
|
||||
|
||||
Game_JPA_DAO_Factory factory = new Game_JPA_DAO_Factory();
|
||||
|
||||
try {
|
||||
DAO<User> userDao = factory.getDAOUser();
|
||||
User[] user = userDao.findByField("username", username);
|
||||
|
||||
for (User u : user) {
|
||||
if (u.getUsername().equals(username) && u.verifyPassword(password)) {
|
||||
this.user = u;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (DAOException e) {
|
||||
error = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR,translator.translate("internal_error_1"));
|
||||
return false;
|
||||
}
|
||||
|
||||
error = new HttpResponse(HttpResponseCode.NOT_FOUND, translator.translate("login_error"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param username le nom d'utilisateur supposé de l'utilisateur qui souhaite se connecter
|
||||
* @return l'entité
|
||||
*/
|
||||
public LoginBean setUsername(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password le mot de passe supposé de l'utilisateur qui souhaite se connecter
|
||||
* @return l'entité
|
||||
*/
|
||||
public LoginBean setPassword(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param translator le traducteur
|
||||
* @return l'entité
|
||||
*/
|
||||
public LoginBean setTranslator(Translator translator) {
|
||||
this.translator = translator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return l'utilisateur connecté
|
||||
*/
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return l'erreur
|
||||
*/
|
||||
public HttpResponse getError() {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* NewGameBean.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
package uppa.project.bean;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
public class NewGameBean implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String difficulty;
|
||||
private String nbRounds;
|
||||
private String timer;
|
||||
private String nbValues;
|
||||
private String nbColors;
|
||||
private Translator translator;
|
||||
|
||||
private Game game;
|
||||
|
||||
private HttpResponse error;
|
||||
|
||||
public NewGameBean() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation des paramètres de la requête
|
||||
*
|
||||
* @return true si les paramètres sont valides, false sinon
|
||||
*/
|
||||
public boolean validate() {
|
||||
EntityManager entityManager = EntityManagerProvider.getInstance();
|
||||
|
||||
try {
|
||||
Game game = new Game(
|
||||
Game.Difficulty.valueOf(difficulty),
|
||||
Integer.parseInt(timer),
|
||||
Integer.parseInt(nbRounds),
|
||||
Integer.parseInt(nbColors),
|
||||
Integer.parseInt(nbValues)
|
||||
);
|
||||
|
||||
// Sauvegarder la game en base de données
|
||||
DAO<Game> gameDAO = new Game_JPA_DAO_Factory().getDAOGame();
|
||||
|
||||
entityManager.getTransaction().begin();
|
||||
this.game = gameDAO.create(game);
|
||||
entityManager.getTransaction().commit();
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
error = new HttpResponse(HttpResponseCode.BAD_REQUEST, translator.translate("newGame_invalid_param_values"));
|
||||
} catch (DAOException e) {
|
||||
entityManager.getTransaction().rollback();
|
||||
error = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR, translator.translate("newGame_error_creation"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param difficulty la difficulté de la partie
|
||||
* @return l'entité
|
||||
*/
|
||||
public NewGameBean setDifficulty(String difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nbRounds le nombre de tours de la partie
|
||||
* @return l'entité
|
||||
*/
|
||||
public NewGameBean setNbRounds(String nbRounds) {
|
||||
this.nbRounds = nbRounds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param timer le temps de jeu de la partie
|
||||
* @return l'entité
|
||||
*/
|
||||
public NewGameBean setTimer(String timer) {
|
||||
this.timer = timer;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nbValues le nombre de valeurs de la partie
|
||||
* @return l'entité
|
||||
*/
|
||||
public NewGameBean setNbValues(String nbValues) {
|
||||
this.nbValues = nbValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nbColors le nombre de couleurs de la partie
|
||||
* @return l'entité
|
||||
*/
|
||||
public NewGameBean setNbColors(String nbColors) {
|
||||
this.nbColors = nbColors;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param translator le traducteur
|
||||
* @return l'entité
|
||||
*/
|
||||
public NewGameBean setTranslator(Translator translator) {
|
||||
this.translator = translator;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return la partie créée
|
||||
*/
|
||||
public Game getGame() {
|
||||
return game;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return l'erreur
|
||||
*/
|
||||
public HttpResponse getError() {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* PlayerBean.java, 1/05/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
package uppa.project.bean;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
public class PlayerBean {
|
||||
private Player player;
|
||||
|
||||
public PlayerBean(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gestion des joueurs de la parties
|
||||
*
|
||||
* @return true si tous les joueurs sont gérés, false sinon
|
||||
*/
|
||||
public boolean validate() {
|
||||
EntityManager em = EntityManagerProvider.getInstance();
|
||||
em.getTransaction().begin();
|
||||
try {
|
||||
Player dbPlayer = new Player(player.getGame(), player.getUser());
|
||||
dbPlayer.setScore(player.getScore());
|
||||
if (player.isWinner()) dbPlayer.setWinner();
|
||||
dbPlayer.setClickCount(player.getClickCount());
|
||||
dbPlayer.setRapidClickCount(player.getRapidClickCount());
|
||||
dbPlayer.setRightClickCount(player.getRightClickCount());
|
||||
player.getGame().addPlayer(dbPlayer);
|
||||
player.getUser().addPlayedGame(dbPlayer);
|
||||
em.getTransaction().commit();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
em.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* ProfileBean.java, 01/05/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
package uppa.project.bean;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
public class ProfileBean {
|
||||
private String username;
|
||||
private String oldEmail;
|
||||
private String email;
|
||||
private String oldPassword;
|
||||
private String newPassword;
|
||||
private String confirmPassword;
|
||||
private String gender;
|
||||
private User user;
|
||||
private HttpResponse error;
|
||||
private Translator translator;
|
||||
|
||||
public ProfileBean() {}
|
||||
|
||||
/**
|
||||
* Validation des paramètres de la requête & mise à jour des informations de l'utilisateur
|
||||
*
|
||||
* @return true si les paramètres sont valides, false sinon
|
||||
*/
|
||||
public boolean validate() {
|
||||
EntityManager entityManager = EntityManagerProvider.getInstance();
|
||||
entityManager.getTransaction().begin();
|
||||
DAO<User> userDAO;
|
||||
String errorMessage = "";
|
||||
try {
|
||||
userDAO= new Game_JPA_DAO_Factory().getDAOUser();
|
||||
// Vérification de l'existence de l'utilisateur
|
||||
user = (userDAO.findByField("username",username).length == 0 ? null : userDAO.findByField("username",username)[0]);
|
||||
if (user == null) {
|
||||
error = new HttpResponse(HttpResponseCode.UNAUTHORIZED, translator.translate("profile_error_username_unknown"));
|
||||
entityManager.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
// Vérification de l'unicité de l'adresse e-mail
|
||||
User[] users = userDAO.findByField("email", email);
|
||||
if (!oldEmail.equals(email) && users.length > 0) {
|
||||
errorMessage += translator.translate("profile_error_email");
|
||||
}
|
||||
// Verification de l'ancien mot de passe
|
||||
if(!oldPassword.isEmpty() && !user.verifyPassword(oldPassword)) {
|
||||
errorMessage += "<br>" + translator.translate("profile_error_old_password");
|
||||
}
|
||||
if(!newPassword.equals(confirmPassword)) {
|
||||
errorMessage += "<br>" + translator.translate("profile_error_password");
|
||||
}
|
||||
if (!errorMessage.isEmpty()) {
|
||||
error = new HttpResponse(HttpResponseCode.UNAUTHORIZED, errorMessage);
|
||||
entityManager.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
} catch (DAOException e) {
|
||||
error = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR, translator.translate("internal_error_2"));
|
||||
entityManager.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
// Mise à jour des informations de l'utilisateur
|
||||
user.setEmail(email);
|
||||
if (!newPassword.isEmpty()) {
|
||||
user.setPassword(newPassword);
|
||||
}
|
||||
user.setGender(User.Gender.valueOf(gender));
|
||||
try {
|
||||
userDAO.update(user);
|
||||
entityManager.getTransaction().commit();
|
||||
return true;
|
||||
} catch (DAOException e) {
|
||||
error = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR, translator.translate("internal_error_2"));
|
||||
entityManager.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param username le pseudo de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setUsername(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param email l'adresse e-mail actuelle de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setOldEmail(String email) {
|
||||
this.oldEmail = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param email la nouvelle adresse e-mail de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setEmail(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param oldPassword l'ancien mot de passe de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setOldPassword(String oldPassword) {
|
||||
this.oldPassword = oldPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password le nouveau mot de passe de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setNewPassword(String password) {
|
||||
this.newPassword = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param confirmPassword la confirmation du nouveau mot de passe de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setConfirmPassword(String confirmPassword) {
|
||||
this.confirmPassword = confirmPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gender le genre de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setGender(String gender) {
|
||||
this.gender = gender;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param translator le traducteur
|
||||
* @return l'entité
|
||||
*/
|
||||
public ProfileBean setTranslator(Translator translator) {
|
||||
this.translator = translator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return l'erreur
|
||||
*/
|
||||
public HttpResponse getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return l'utilisateur
|
||||
*/
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package uppa.project.bean;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
public class RegisterBean implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String username;
|
||||
private String email;
|
||||
private String password;
|
||||
private String confirmPassword;
|
||||
private String birth;
|
||||
private String gender;
|
||||
|
||||
private HttpResponse error;
|
||||
private Translator translator;
|
||||
|
||||
public RegisterBean() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation des paramètres de la requête & création d'un nouvel utilisateur
|
||||
*
|
||||
* @return true si les paramètres sont valides, false sinon
|
||||
*/
|
||||
public boolean validate() {
|
||||
Game_JPA_DAO_Factory jpaDaoFactory = new Game_JPA_DAO_Factory();
|
||||
DAO<User> userDAO;
|
||||
|
||||
// Vérification de l'unicité du nom d'utilisateur et de l'adresse e-mail
|
||||
try {
|
||||
userDAO = jpaDaoFactory.getDAOUser();
|
||||
String errorMessage = "";
|
||||
// Vérification de l'unicité du nom d'utilisateur
|
||||
User[] users = userDAO.findByField("username", username);
|
||||
if (users.length > 0) {
|
||||
errorMessage += translator.translate("register_error_username");
|
||||
}
|
||||
|
||||
// Vérification de l'unicité de l'adresse e-mail
|
||||
users = userDAO.findByField("email", email);
|
||||
if (users.length > 0) {
|
||||
errorMessage += "<br>" + translator.translate("register_error_email");
|
||||
}
|
||||
// Vérification de la correspondance des mots de passe
|
||||
if (!password.equals(confirmPassword)) {
|
||||
errorMessage += "<br>" + translator.translate("register_error_password");
|
||||
}
|
||||
if (!errorMessage.isEmpty()) {
|
||||
error = new HttpResponse(HttpResponseCode.UNAUTHORIZED, errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (DAOException e) {
|
||||
error = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR, translator.translate("internal_error_1"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Creation de l'utilisateur
|
||||
User user = new User();
|
||||
user.setUsername(username);
|
||||
user.setPassword(password);
|
||||
user.setEmail(email);
|
||||
try {
|
||||
user.setGender(User.Gender.valueOf(gender));
|
||||
} catch (IllegalArgumentException e) {
|
||||
error = new HttpResponse(HttpResponseCode.UNAUTHORIZED, translator.translate("register_error_gender"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convertion de la date de naissance de String au format YYYY-MM-DD en objet Date
|
||||
try {
|
||||
LocalDate localDate = LocalDate.parse(birth);
|
||||
ZoneId defaultZoneId = ZoneId.systemDefault();
|
||||
Date date = Date.from(localDate.atStartOfDay(defaultZoneId).toInstant());
|
||||
user.setBirth(date);
|
||||
} catch (Exception e) {
|
||||
error = new HttpResponse(HttpResponseCode.UNAUTHORIZED, translator.translate("register_error_birthdate"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sauvegarde de l'utilisateur en base de données
|
||||
EntityManager entityManager = EntityManagerProvider.getInstance();
|
||||
entityManager.getTransaction().begin();
|
||||
try {
|
||||
userDAO = jpaDaoFactory.getDAOUser();
|
||||
userDAO.create(user);
|
||||
entityManager.getTransaction().commit();
|
||||
return true;
|
||||
} catch (DAOException e) {
|
||||
error = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR, translator.translate("internal_error_2"));
|
||||
entityManager.getTransaction().rollback();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param username le nom d'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public RegisterBean setUsername(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password le mot de passe
|
||||
* @return l'entité
|
||||
*/
|
||||
public RegisterBean setPassword(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param confirmPassword la confirmation du mot de passe
|
||||
* @return l'entité
|
||||
*/
|
||||
public RegisterBean setConfirmPassword(String confirmPassword) {
|
||||
this.confirmPassword = confirmPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param email l'adresse e-mail
|
||||
* @return l'entité
|
||||
*/
|
||||
public RegisterBean setEmail(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param birth la date de naissance
|
||||
* @return l'entité
|
||||
*/
|
||||
public RegisterBean setBirth(String birth) {
|
||||
this.birth = birth;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gender le genre de l'utilisateur
|
||||
* @return l'entité
|
||||
*/
|
||||
public RegisterBean setGender(String gender) {
|
||||
this.gender = gender;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param translator le traducteur
|
||||
* @return l'entité
|
||||
*/
|
||||
public RegisterBean setTranslator(Translator translator) {
|
||||
this.translator = translator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return l'erreur
|
||||
*/
|
||||
public HttpResponse getError() {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package uppa.project.bean;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
public class ResetPasswordBean implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String token;
|
||||
private String password;
|
||||
private String confirmPassword;
|
||||
private String errorMessage;
|
||||
private Translator translator;
|
||||
|
||||
public ResetPasswordBean() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation des paramètres de la requête & gestion de la réinitialisation du mot de passe
|
||||
*
|
||||
* @return true si le token est valide, false sinon
|
||||
*/
|
||||
public boolean validate() {
|
||||
Game_JPA_DAO_Factory jpaDaoFactory = new Game_JPA_DAO_Factory();
|
||||
DAO<User> userDAO;
|
||||
DAO<RecoveryPasswordToken> recoveryPasswordTokenDAO;
|
||||
|
||||
// Vérification du lien entre le token et un utilisateur
|
||||
EntityManager entityManager = EntityManagerProvider.getInstance();
|
||||
entityManager.getTransaction().begin();
|
||||
try {
|
||||
userDAO = jpaDaoFactory.getDAOUser();
|
||||
recoveryPasswordTokenDAO = jpaDaoFactory.getDAORecoveryPasswordToken();
|
||||
|
||||
// Vériier l'existence du token
|
||||
RecoveryPasswordToken[] tokens = recoveryPasswordTokenDAO.findByField("token", token);
|
||||
if (tokens.length == 0) {
|
||||
errorMessage = "Ce token n'est pas valide";
|
||||
entityManager.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
RecoveryPasswordToken token = tokens[0];
|
||||
|
||||
// Verifier la correspondance des mots de passe
|
||||
if (!password.equals(confirmPassword)) {
|
||||
errorMessage = "Les mots de passe ne correspondent pas";
|
||||
entityManager.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Récupéreration de l'utilisateur associé au token
|
||||
User user = token.getUser();
|
||||
if (user == null) {
|
||||
errorMessage = "Erreur: Aucun utilisateur associé à ce token";
|
||||
return false;
|
||||
}
|
||||
user.setPassword(password);
|
||||
|
||||
userDAO.update(user);
|
||||
entityManager.getTransaction().commit();
|
||||
} catch (DAOException e) {
|
||||
errorMessage = "Une erreur est survenue (DB_CONNECTION_ERROR)";
|
||||
entityManager.getTransaction().rollback();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param token le token de réinitialisation de mot de passe
|
||||
* @return this
|
||||
*/
|
||||
public ResetPasswordBean setToken(String token) {
|
||||
this.token = token;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password le nouveau mot de passe
|
||||
* @return this
|
||||
*/
|
||||
public ResetPasswordBean setPassword(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param confirmPassword la confirmation du nouveau mot de passe
|
||||
* @return this
|
||||
*/
|
||||
public ResetPasswordBean setConfirmPassword(String confirmPassword) {
|
||||
this.confirmPassword = confirmPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param translator le traducteur
|
||||
* @return this
|
||||
*/
|
||||
public ResetPasswordBean setTranslator(Translator translator) {
|
||||
this.translator = translator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return le message d'erreur
|
||||
*/
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* AbstractDAOFactory.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao;
|
||||
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
|
||||
/**
|
||||
* Factory renvoyant une factory de DAO en fonction du support de persistance choisi
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
public class AbstractDAOFactory {
|
||||
|
||||
/**
|
||||
* Renvoie une factory de DAO en fonction du support de persistance choisi
|
||||
*
|
||||
* @param type le support de persistance
|
||||
* @return la factory de DAO
|
||||
* @see PersistenceKind
|
||||
*/
|
||||
public static GameDAOFactory getDAOFactory(PersistenceKind type) {
|
||||
if (type.equals(PersistenceKind.JPA)) return new Game_JPA_DAO_Factory();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* DAO.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import java.util.List;
|
||||
import uppa.project.database.pojo.Player;
|
||||
|
||||
/**
|
||||
* DAO abstrait et générique pour tout type de données
|
||||
*
|
||||
* @param <D> la classe paramétrant le DAO
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
public abstract class DAO<D> {
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*
|
||||
* @throws DAOException si une erreur survient lors de la création du DAO
|
||||
*/
|
||||
public DAO() throws DAOException {}
|
||||
|
||||
/**
|
||||
* Retourne l'objet {@link D} en fonction de son identifiant
|
||||
*
|
||||
* @param id identifiant de l'objet
|
||||
* @return l'instance de l'objet {@link D}
|
||||
* @throws DAOException en cas de problème
|
||||
* @see D
|
||||
*/
|
||||
public abstract D findById(int id) throws DAOException;
|
||||
|
||||
/**
|
||||
* Retourne tous les objets {@link D} paramétrant le DAO
|
||||
*
|
||||
* @return un tableau d'objets {@link D}
|
||||
* @throws DAOException en cas de problème
|
||||
* @see D
|
||||
*/
|
||||
public abstract D[] findAll() throws DAOException;
|
||||
|
||||
/**
|
||||
* Rend persistant un objet {@link D} qui n'avait pas encore de réprésentation sur le support de persistance
|
||||
*
|
||||
* @param data l'objet {@link D} à rendre persistant
|
||||
* @throws DAOException en cas de problème
|
||||
* @see D
|
||||
*/
|
||||
public abstract D create(D data) throws DAOException;
|
||||
|
||||
/**
|
||||
* Met à jour le contenu correspondant à l'objet {@link D} sur le support persistant (l'objet
|
||||
* avait déjà une représentation sur le support persistant)
|
||||
*
|
||||
* @param data l'objet {@link D} modifié dont le contenu est à mettre à jour
|
||||
* @throws DAOException en cas de problème
|
||||
* @see D
|
||||
*/
|
||||
public abstract D update(D data) throws DAOException;
|
||||
|
||||
/**
|
||||
* Efface du support persistant le contenu équivalent à l'objet {@link D}
|
||||
*
|
||||
* @param data l'objet {@link D} à supprimer
|
||||
* @throws DAOException en cas de problème
|
||||
* @see D
|
||||
*/
|
||||
public abstract void delete(D data) throws DAOException;
|
||||
|
||||
/**
|
||||
* Retourne les objets {@link D} paramétrant le DAO en fonction d'un champ et d'une valeur
|
||||
*
|
||||
* @param field le champ à rechercher
|
||||
* @param value la valeur à rechercher
|
||||
* @return un tableau d'objets {@link D}
|
||||
* @throws DAOException en cas de problème
|
||||
* @see D
|
||||
*/
|
||||
public abstract D[] findByField(String field, Object value) throws DAOException;
|
||||
|
||||
public Player[] findPlayerForPagination(int userId, int firstData) throws DAOException {
|
||||
EntityManager entityManager = EntityManagerProvider.getInstance();
|
||||
TypedQuery<Player> query = entityManager.createQuery("SELECT p FROM Player p WHERE p.user.id = (:user) ORDER BY p.id DESC", Player.class);
|
||||
query.setParameter("user", userId);
|
||||
query.setFirstResult(firstData);
|
||||
query.setMaxResults(5);
|
||||
List<Player> results = query.getResultList();
|
||||
return results.toArray(new Player[0]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* DAOException.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao;
|
||||
|
||||
/**
|
||||
* Exception spécifique aux problèmes d'accès aux données via un DAO
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
* @see DAO
|
||||
*/
|
||||
public class DAOException extends Exception {
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*/
|
||||
public DAOException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur avec message
|
||||
*
|
||||
* @param message le message de l'exception
|
||||
*/
|
||||
public DAOException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* EntityManagerProvider.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import jakarta.persistence.FlushModeType;
|
||||
import jakarta.persistence.Persistence;
|
||||
import uppa.project.Global;
|
||||
|
||||
/**
|
||||
* Fournisseur d'EntityManager
|
||||
* Permet de récupérer une instance d'EntityManager
|
||||
* pour les DAO
|
||||
*
|
||||
* @see jakarta.persistence.EntityManager
|
||||
*/
|
||||
public final class EntityManagerProvider {
|
||||
private static String PERSISTENCE_UNIT_NAME = Global.PERSISTENCE_UNIT_NAME;
|
||||
|
||||
private static EntityManager instance;
|
||||
private static EntityManagerFactory factory;
|
||||
|
||||
public static EntityManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = getFactory().createEntityManager();
|
||||
instance.setFlushMode(FlushModeType.COMMIT);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static EntityManagerFactory getFactory() {
|
||||
if (factory == null) {
|
||||
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
public static void setPersitenceUnitName(String name) {
|
||||
PERSISTENCE_UNIT_NAME = name;
|
||||
}
|
||||
public static void close() {
|
||||
if (instance.isOpen()) instance.close();
|
||||
if (factory.isOpen()) factory.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* GameDAOFactory.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao;
|
||||
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||
import uppa.project.database.pojo.User;
|
||||
|
||||
/**
|
||||
* Fabrique abstraite de DAO pour le schéma du jeu
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
public abstract class GameDAOFactory {
|
||||
|
||||
protected DAO<User> daoUser = null;
|
||||
protected DAO<Game> daoGame = null;
|
||||
protected DAO<Player> daoPlayer = null;
|
||||
protected DAO<RecoveryPasswordToken> daoRecoveryPasswordToken = null;
|
||||
|
||||
/**
|
||||
* @return le DAO pour la classe/table User
|
||||
* @throws DAOException en cas de problème
|
||||
* @see User
|
||||
*/
|
||||
public abstract DAO<User> getDAOUser() throws DAOException;
|
||||
|
||||
/**
|
||||
* @return le DAO pour la classe/table Game
|
||||
* @throws DAOException en cas de problème
|
||||
* @see Game
|
||||
*/
|
||||
public abstract DAO<Game> getDAOGame() throws DAOException;
|
||||
|
||||
/**
|
||||
* @return le DAO pour la classe/table Player
|
||||
* @throws DAOException en cas de problème
|
||||
* @see Player
|
||||
*/
|
||||
public abstract DAO<Player> getDAOPlayer() throws DAOException;
|
||||
|
||||
/**
|
||||
* @return le DAO pour la classe/table RecoveryPasswordToken
|
||||
* @throws DAOException en cas de problème
|
||||
* @see RecoveryPasswordToken
|
||||
*/
|
||||
public abstract DAO<RecoveryPasswordToken> getDAORecoveryPasswordToken() throws DAOException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* PersistenceKind.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao;
|
||||
|
||||
/**
|
||||
* Type de support de persistance pour les données
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*
|
||||
* @see AbstractDAOFactory
|
||||
*/
|
||||
public enum PersistenceKind {
|
||||
JPA
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* DAO_JPA_Game.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao.jpa;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
|
||||
/**
|
||||
* DAO pour les parties de jeu
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
* @see Game
|
||||
* @see DAO
|
||||
*/
|
||||
public class DAO_JPA_Game extends DAO<Game> {
|
||||
|
||||
/**
|
||||
* Gestionnaire d'entités
|
||||
*/
|
||||
private final EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*
|
||||
* @throws DAOException si une erreur survient lors de la création du DAO
|
||||
*/
|
||||
public DAO_JPA_Game() throws DAOException {
|
||||
this.entityManager = EntityManagerProvider.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game findById(int id) throws DAOException {
|
||||
return entityManager.find(Game.class, new BigDecimal(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game[] findByField(String field, Object value) throws DAOException {
|
||||
String sqlQuery = String.format("SELECT u FROM Game u WHERE u.%s = (:val)", field);
|
||||
|
||||
TypedQuery<Game> query = entityManager.createQuery(sqlQuery, Game.class);
|
||||
query.setParameter("val", value);
|
||||
List<Game> results = query.getResultList();
|
||||
return results.toArray(new Game[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game[] findAll() throws DAOException {
|
||||
TypedQuery<Game> query = entityManager.createQuery("SELECT g FROM Game g", Game.class);
|
||||
List<Game> results = query.getResultList();
|
||||
return results.toArray(new Game[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game create(Game data) throws DAOException {
|
||||
return update(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game update(Game data) throws DAOException {
|
||||
return entityManager.merge(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Game data) throws DAOException {
|
||||
entityManager.remove(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* DAO_JPA_Player.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao.jpa;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.pojo.Player;
|
||||
|
||||
/**
|
||||
* DAO pour les joueurs
|
||||
*
|
||||
* @author Kévin Mitresse
|
||||
* @author Lucàs Vabre
|
||||
* @see Player
|
||||
* @see DAO
|
||||
*/
|
||||
public class DAO_JPA_Player extends DAO<Player> {
|
||||
|
||||
/**
|
||||
* Gestionnaire d'entités
|
||||
*/
|
||||
private final EntityManager entityManager;
|
||||
|
||||
public DAO_JPA_Player() throws DAOException {
|
||||
this.entityManager = EntityManagerProvider.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player findById(int id) throws DAOException {
|
||||
return entityManager.find(Player.class, new BigDecimal(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player[] findByField(String field, Object value) throws DAOException {
|
||||
String sqlQuery = String.format("SELECT p FROM Player p WHERE p.%s = (:val)", field);
|
||||
|
||||
TypedQuery<Player> query = entityManager.createQuery(sqlQuery, Player.class);
|
||||
query.setParameter("val", value);
|
||||
List<Player> results = query.getResultList();
|
||||
return results.toArray(new Player[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player[] findAll() throws DAOException {
|
||||
TypedQuery<Player> query = entityManager.createQuery("SELECT p FROM Player p", Player.class);
|
||||
List<Player> results = query.getResultList();
|
||||
return results.toArray(new Player[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player create(Player data) throws DAOException {
|
||||
return update(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player update(Player data) throws DAOException {
|
||||
return entityManager.merge(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Player data) throws DAOException {
|
||||
entityManager.remove(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* DAO_JPA_RecoveryPasswordToken.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao.jpa;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||
|
||||
/**
|
||||
* DAO pour les tokens de récupération de mot de passe
|
||||
*
|
||||
* @author Kévin Mitresse
|
||||
* @author Lucàs Vabre
|
||||
* @see RecoveryPasswordToken
|
||||
* @see DAO
|
||||
*/
|
||||
public class DAO_JPA_RecoveryPasswordToken extends DAO<RecoveryPasswordToken> {
|
||||
|
||||
/**
|
||||
* Gestionnaire d'entités
|
||||
*/
|
||||
private final EntityManager entityManager;
|
||||
|
||||
public DAO_JPA_RecoveryPasswordToken() throws DAOException {
|
||||
this.entityManager = EntityManagerProvider.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecoveryPasswordToken findById(int id) throws DAOException {
|
||||
return entityManager.find(RecoveryPasswordToken.class, new BigDecimal(id));
|
||||
}
|
||||
|
||||
public RecoveryPasswordToken[] findByField(String field, Object value) throws DAOException {
|
||||
String sqlQuery = String.format("SELECT r FROM RecoveryPasswordToken r WHERE r.%s = (:val)", field);
|
||||
|
||||
TypedQuery<RecoveryPasswordToken> query = entityManager.createQuery(sqlQuery, RecoveryPasswordToken.class);
|
||||
query.setParameter("val", value);
|
||||
List<RecoveryPasswordToken> results = query.getResultList();
|
||||
return results.toArray(new RecoveryPasswordToken[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecoveryPasswordToken[] findAll() throws DAOException {
|
||||
TypedQuery<RecoveryPasswordToken> query = entityManager.createQuery("SELECT r FROM RecoveryPasswordToken r", RecoveryPasswordToken.class);
|
||||
List<RecoveryPasswordToken> results = query.getResultList();
|
||||
return results.toArray(new RecoveryPasswordToken[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecoveryPasswordToken create(RecoveryPasswordToken data) throws DAOException {
|
||||
return update(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecoveryPasswordToken update(RecoveryPasswordToken data) throws DAOException {
|
||||
return entityManager.merge(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(RecoveryPasswordToken data) throws DAOException {
|
||||
entityManager.remove(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* DAO_JPA_User.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao.jpa;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
|
||||
/**
|
||||
* DAO pour les utilisateurs
|
||||
*
|
||||
* @author Kévin Mitresse
|
||||
* @author Lucàs Vabre
|
||||
* @see User
|
||||
* @see DAO
|
||||
*/
|
||||
public class DAO_JPA_User extends DAO<User> {
|
||||
|
||||
/**
|
||||
* Gestionnaire d'entités
|
||||
*/
|
||||
private final EntityManager entityManager;
|
||||
|
||||
public DAO_JPA_User() throws DAOException {
|
||||
this.entityManager = EntityManagerProvider.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User findById(int id) throws DAOException {
|
||||
return entityManager.find(User.class, new BigDecimal(id));
|
||||
}
|
||||
|
||||
public User[] findByField(String field, Object value) throws DAOException {
|
||||
String sqlQuery = String.format("SELECT u FROM User u WHERE u.%s = (:val)", field);
|
||||
|
||||
TypedQuery<User> query = entityManager.createQuery(sqlQuery, User.class);
|
||||
query.setParameter("val", value);
|
||||
List<User> results = query.getResultList();
|
||||
return results.toArray(new User[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User[] findAll() throws DAOException {
|
||||
TypedQuery<User> query = entityManager.createQuery("SELECT u FROM User u", User.class);
|
||||
List<User> results = query.getResultList();
|
||||
return results.toArray(new User[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User create(User data) throws DAOException {
|
||||
return update(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User update(User data) throws DAOException {
|
||||
return entityManager.merge(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(User data) throws DAOException {
|
||||
entityManager.remove(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Sports_JDBC_DAOFactory.java, 09/02/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.dao.jpa;
|
||||
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.GameDAOFactory;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
|
||||
/**
|
||||
* Fabrique concrète de DAO pour le schéma relationnel sports avec une implémentation en JDBC.
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
* @see GameDAOFactory
|
||||
*/
|
||||
public class Game_JPA_DAO_Factory extends GameDAOFactory {
|
||||
|
||||
@Override
|
||||
public DAO<User> getDAOUser() throws DAOException {
|
||||
if (daoUser == null) daoUser = new DAO_JPA_User();
|
||||
return daoUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DAO<Game> getDAOGame() throws DAOException {
|
||||
if (daoGame == null) daoGame = new DAO_JPA_Game();
|
||||
return daoGame;
|
||||
}
|
||||
@Override
|
||||
public DAO<Player> getDAOPlayer() throws DAOException {
|
||||
if (daoPlayer == null) daoPlayer = new DAO_JPA_Player();
|
||||
return daoPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DAO<RecoveryPasswordToken> getDAORecoveryPasswordToken() throws DAOException {
|
||||
if (daoRecoveryPasswordToken == null) daoRecoveryPasswordToken= new DAO_JPA_RecoveryPasswordToken();
|
||||
return daoRecoveryPasswordToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Card.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.pojo;
|
||||
|
||||
import jakarta.persistence.Transient;
|
||||
|
||||
/**
|
||||
* Représentation d'une carte
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
public class Card {
|
||||
|
||||
/**
|
||||
* Couleurs disponibles pour les cartes
|
||||
*/
|
||||
public enum Color{HEART, CLUBS, SPADES, DIAMONDS}
|
||||
|
||||
/**
|
||||
* Valeurs disponibles pour les cartes
|
||||
*/
|
||||
public enum Value{ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING}
|
||||
|
||||
/**
|
||||
* Couleur de la carte
|
||||
*/
|
||||
private final Color color;
|
||||
|
||||
/**
|
||||
* Valeur de la carte
|
||||
*/
|
||||
private final Value value;
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*
|
||||
* @param color couleur de la carte
|
||||
* @param value valeur de la carte
|
||||
*
|
||||
* @see Color
|
||||
* @see Value
|
||||
*/
|
||||
public Card(Color color, Value value) {
|
||||
if (color == null || value == null) {
|
||||
throw new IllegalArgumentException("Color cannot be null");
|
||||
}
|
||||
this.color = color;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return la couleur de la carte
|
||||
*/
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return la valeur de la carte
|
||||
*/
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Card{" +
|
||||
"color=" + color +
|
||||
", value=" + value +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Card card)) return false;
|
||||
return getColor() == card.getColor() && getValue() == card.getValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Deck.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.pojo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Représentation d'un paquet de cartes
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
public class Deck {
|
||||
|
||||
public static final int NB_COLORS_MIN = 2;
|
||||
|
||||
public static final int NB_COLORS_MAX = Card.Color.values().length;
|
||||
|
||||
public static final int NB_VALUES_PER_COLOR_MIN = 2;
|
||||
|
||||
public static final int NB_VALUES_PER_COLOR_MAX = Card.Value.values().length;
|
||||
|
||||
/**
|
||||
* Ensemble de cartes du paquet
|
||||
* @see Card
|
||||
*/
|
||||
private final List<Card> cards;
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*
|
||||
* @param nbColors nombre de couleurs (doit être compris entre 1 et le nombre de couleurs de {@link Card.Color})
|
||||
* @param nbValues nombre de valeurs (doit être compris entre 1 et le nombre de valeurs de {@link Card.Value})
|
||||
* @see Card.Color
|
||||
* @see Card.Value
|
||||
*/
|
||||
public Deck(int nbColors, int nbValues) {
|
||||
if (!Deck.isDeckValid(nbColors, nbValues)) {
|
||||
throw new IllegalArgumentException("Nombre de couleurs et/ou nombre de valeurs invalide(s)");
|
||||
}
|
||||
|
||||
this.cards = new ArrayList<>(nbColors * nbValues);
|
||||
|
||||
for (int nbCard = 0; nbCard < nbColors * nbValues; nbCard++) {
|
||||
int color = nbCard % nbColors;
|
||||
int value = nbCard / nbColors;
|
||||
|
||||
cards.add(new Card(Card.Color.values()[color], Card.Value.values()[value]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prédicat qui vérifie si un Deck est correctement initialisé
|
||||
*
|
||||
* @param nbColors Nombre de couleurs {@link Card.Color}
|
||||
* @param nbValues Nombre de valeurs {@link Card.Value}
|
||||
* @return true si le prédicat est vérifié, false sinon
|
||||
*/
|
||||
public static boolean isDeckValid(int nbColors, int nbValues) {
|
||||
return NB_COLORS_MIN <= nbColors && nbColors <= NB_COLORS_MAX
|
||||
&& NB_VALUES_PER_COLOR_MIN <= nbValues && nbValues <= NB_VALUES_PER_COLOR_MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return l'ensemble de cartes du paquet
|
||||
*/
|
||||
public List<Card> getCards() {
|
||||
return cards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mélange les cartes d'un paquet
|
||||
*/
|
||||
public void shuffle() {
|
||||
Collections.shuffle(this.cards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Deck deck = (Deck) o;
|
||||
boolean sameSize = cards.size() == deck.cards.size();
|
||||
int counter = 0;
|
||||
for (int i = 0; i < cards.size(); i++) {
|
||||
for (int j = 0; j < deck.cards.size(); j++) {
|
||||
if (cards.get(i).getColor() == deck.cards.get(j).getColor()
|
||||
&& cards.get(i).getValue() == deck.cards.get(j).getValue()) {
|
||||
counter++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sameSize && counter == cards.size();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* Game.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.pojo;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Temporal;
|
||||
import jakarta.persistence.TemporalType;
|
||||
import jakarta.persistence.Transient;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Représentation d'une partie de jeu
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "game")
|
||||
public class Game implements Serializable {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private BigDecimal id;
|
||||
|
||||
@Transient
|
||||
private int currentRound = 0;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "created_at")
|
||||
private Date createdAt;
|
||||
|
||||
|
||||
@Column(name = "difficulty")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Difficulty difficulty;
|
||||
|
||||
@Column(name = "nb_rounds")
|
||||
private int nbRounds;
|
||||
|
||||
@Column(name = "nb_colors")
|
||||
private int nbColors;
|
||||
|
||||
@Column(name = "nb_values_per_color")
|
||||
private int nbValuesPerColor;
|
||||
|
||||
@OneToMany(mappedBy = "game", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
private List<Player> players;
|
||||
|
||||
@Transient
|
||||
private Deck deck;
|
||||
|
||||
@Column(name = "timer")
|
||||
private int timer;
|
||||
|
||||
@Transient
|
||||
public static final int TIMER_MIN = 5;
|
||||
|
||||
@Transient
|
||||
public static final int TIMER_MAX = 60;
|
||||
|
||||
@Transient
|
||||
public static final int NB_ROUNDS_MIN = 3;
|
||||
|
||||
@Transient
|
||||
private GameState gameState = GameState.WAITING;
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*/
|
||||
public Game() {
|
||||
this.createdAt = new Date();
|
||||
this.players = new ArrayList<>();
|
||||
this.timer = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur avec la difficulté
|
||||
*
|
||||
* @param difficulty la difficulté de la partie
|
||||
* @see Difficulty
|
||||
* @param timer le timer de chaque round en seconde
|
||||
* @param nbRounds le nombre de tours de la partie
|
||||
* @param nbColors le nombre de couleurs présente dans le deck
|
||||
* @param nbValuesPerColor le nombre de valeurs par couleur
|
||||
*/
|
||||
public Game(Difficulty difficulty, int timer, int nbRounds, int nbColors, int nbValuesPerColor) {
|
||||
if (isValidNumberRound(nbRounds, nbColors, nbValuesPerColor)){
|
||||
throw new IllegalArgumentException("Le nombre de tours doit être compris entre 2 et " + nbColors * nbValuesPerColor);
|
||||
}
|
||||
if (timer < TIMER_MIN || timer > TIMER_MAX){
|
||||
throw new IllegalArgumentException("Le timer doit être compris entre" + TIMER_MIN + " et " + TIMER_MAX + " secondes");
|
||||
}
|
||||
this.difficulty = difficulty;
|
||||
this.nbRounds = nbRounds;
|
||||
this.nbColors = nbColors;
|
||||
this.nbValuesPerColor = nbValuesPerColor;
|
||||
this.deck = new Deck(nbColors, nbValuesPerColor);
|
||||
this.deck.shuffle();
|
||||
this.players = new ArrayList<>();
|
||||
this.createdAt = new Date();
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur d'une partie de jeu
|
||||
*
|
||||
* @param id l'identifiant de la partie
|
||||
* @param createdAt la date de création de la partie
|
||||
* @param difficulty la difficulté de la partie
|
||||
* @param nbRounds le nombre de tours de la partie
|
||||
* @param nbColors le nombre de couleurs présente dans le deck
|
||||
* @param nbValuesPerColor le nombre de valeurs par couleur
|
||||
* @param players les joueurs de la partie
|
||||
*/
|
||||
public Game(BigDecimal id, Date createdAt, Difficulty difficulty, int timer ,int nbRounds, int nbColors, int nbValuesPerColor, ArrayList<Player> players) {
|
||||
if (isValidNumberRound(nbRounds, nbColors, nbValuesPerColor)){
|
||||
throw new IllegalArgumentException("Le nombre de tours doit être compris entre 1 et " + nbColors * nbValuesPerColor);
|
||||
}
|
||||
if (timer < TIMER_MIN || timer > TIMER_MAX){
|
||||
throw new IllegalArgumentException("Le timer doit être compris entre" + TIMER_MIN + " et " + TIMER_MAX + " secondes");
|
||||
}
|
||||
this.id = id;
|
||||
this.createdAt = createdAt;
|
||||
this.difficulty = difficulty;
|
||||
this.nbRounds = nbRounds;
|
||||
this.nbColors = nbColors;
|
||||
this.nbValuesPerColor = nbValuesPerColor;
|
||||
this.players = players;
|
||||
this.deck = new Deck(nbColors, nbValuesPerColor);
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, createdAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return l'identifiant de la partie
|
||||
*/
|
||||
public BigDecimal getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return la date de création de la partie
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return la difficulté de la partie
|
||||
*/
|
||||
public Difficulty getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param difficulty la nouvelle difficulté de la partie
|
||||
* @see Difficulty
|
||||
*/
|
||||
public void setDifficulty(Difficulty difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de tours de la partie
|
||||
*/
|
||||
public int getNbRounds() {
|
||||
return nbRounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nbRounds le nouveau nombre de tours de la partie
|
||||
*/
|
||||
public void setNbRounds(int nbRounds) {
|
||||
if (nbRounds < NB_ROUNDS_MIN || nbRounds > nbColors * nbValuesPerColor){
|
||||
throw new IllegalArgumentException("Le nombre de tours doit être compris entre " + NB_ROUNDS_MIN + " et " + nbColors * nbValuesPerColor);
|
||||
}
|
||||
if (nbColors < Deck.NB_COLORS_MIN || nbColors > Deck.NB_COLORS_MAX) {
|
||||
throw new IllegalArgumentException("Le nombre de couleurs doit être compris entre" + NB_ROUNDS_MIN + " et " + Deck.NB_COLORS_MAX);
|
||||
}
|
||||
if (nbValuesPerColor < Deck.NB_VALUES_PER_COLOR_MIN || nbValuesPerColor > Deck.NB_VALUES_PER_COLOR_MAX) {
|
||||
throw new IllegalArgumentException("Le nombre de valeurs par couleur doit être compris entre " + Deck.NB_VALUES_PER_COLOR_MIN + " et " + Deck.NB_VALUES_PER_COLOR_MAX);
|
||||
}
|
||||
this.nbRounds = nbRounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de couleurs présente dans le deck
|
||||
*/
|
||||
public int getNbColors() {
|
||||
return nbColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nbColors le nouveau nombre de couleurs présente dans le deck
|
||||
*/
|
||||
public void setNbColors(int nbColors) {
|
||||
if (nbColors < Deck.NB_COLORS_MIN || nbColors > Deck.NB_COLORS_MAX) {
|
||||
throw new IllegalArgumentException("Le nombre de couleurs doit être compris entre " + Deck.NB_COLORS_MIN + " et " + Deck.NB_COLORS_MAX);
|
||||
}
|
||||
this.nbColors = nbColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de valeurs par couleur
|
||||
*/
|
||||
public int getNbValuesPerColor() {
|
||||
return nbValuesPerColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nbValuesPerColor le nouveau nombre de valeurs par couleur
|
||||
*/
|
||||
public void setNbValuesPerColor(int nbValuesPerColor) {
|
||||
if (nbValuesPerColor < Deck.NB_VALUES_PER_COLOR_MIN || nbValuesPerColor > Deck.NB_VALUES_PER_COLOR_MAX) {
|
||||
throw new IllegalArgumentException("Le nombre de valeurs par couleur doit être compris entre " + Deck.NB_VALUES_PER_COLOR_MIN + " et " + Deck.NB_VALUES_PER_COLOR_MAX);
|
||||
}
|
||||
this.nbValuesPerColor = nbValuesPerColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return les joueurs de la partie
|
||||
*/
|
||||
public List<Player> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie les joueurs de la partie
|
||||
*
|
||||
* @param players les nouveaux joueurs
|
||||
*/
|
||||
public void setPlayers(List<Player> players) {
|
||||
this.players = players;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de joueurs de la partie
|
||||
*/
|
||||
public int getNbPlayers() {
|
||||
return this.players.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute un joueur à la partie
|
||||
*
|
||||
* @param player le joueur à ajouter
|
||||
*/
|
||||
public void addPlayer(Player player) {
|
||||
this.players.add(player);
|
||||
}
|
||||
|
||||
public int getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
public void setTimer(int timer) {
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
public Deck getDeck() {
|
||||
if (deck == null) {
|
||||
deck = new Deck(nbColors, nbValuesPerColor);
|
||||
deck.shuffle();
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tri des joueurs de la partie par score puis par rapidité
|
||||
*/
|
||||
public void sortPlayersByScoreAndRapidity() {
|
||||
players.sort((p1, p2) -> {
|
||||
if (p1.getScore() == p2.getScore()) {
|
||||
return p2.getRapidClickCount() - p1.getRapidClickCount();
|
||||
}
|
||||
return p2.getScore() - p1.getScore();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le gagnant de la partie
|
||||
*
|
||||
* @return le nom du gagnant
|
||||
*/
|
||||
public Player getWinner(){
|
||||
this.sortPlayersByScoreAndRapidity();
|
||||
return players.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si le nombre de tours est valide
|
||||
*
|
||||
* @param nbRounds le nombre de tours
|
||||
* @param nbColors le nombre de couleurs
|
||||
* @param nbValuesPerColor le nombre de valeurs par couleur
|
||||
* @return true si le nombre de tours est valide, false sinon
|
||||
*/
|
||||
public boolean isValidNumberRound(int nbRounds, int nbColors, int nbValuesPerColor){
|
||||
return nbRounds < NB_ROUNDS_MIN || nbRounds > nbColors * nbValuesPerColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Game{id=%s, createdAt=%s, difficulty=%s, nbRounds=%d, nbColors=%d, nbValuesPerColor=%d}",
|
||||
id != null ? id.toString() : "null",
|
||||
createdAt != null ? createdAt.toString() : "null",
|
||||
difficulty != null ? difficulty.toString() : "null",
|
||||
nbRounds != 0 ? nbRounds : 0,
|
||||
nbColors != 0 ? nbColors : 0,
|
||||
nbValuesPerColor != 0 ? nbValuesPerColor : 0
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Game)) return false;
|
||||
Game game = (Game) o;
|
||||
return getNbRounds() == game.getNbRounds() && getNbColors() == game.getNbColors() && getNbValuesPerColor() == game.getNbValuesPerColor() && Objects.equals(getId(), game.getId()) && Objects.equals(getCreatedAt(), game.getCreatedAt()) && getDifficulty() == game.getDifficulty() && Objects.equals(getPlayers(), game.getPlayers()) && Objects.equals(getDeck(), game.getDeck());
|
||||
}
|
||||
|
||||
/**
|
||||
* Difficulté possible d'une partie
|
||||
*/
|
||||
public enum Difficulty {EASY, HARD}
|
||||
|
||||
public enum GameState {WAITING, STARTED, FINISHED}
|
||||
|
||||
public GameState getGameState() {
|
||||
return gameState;
|
||||
}
|
||||
|
||||
public void setGameState(GameState gameState) {
|
||||
this.gameState = gameState;
|
||||
}
|
||||
|
||||
public int getCurrentRound() {
|
||||
return currentRound;
|
||||
}
|
||||
|
||||
public boolean nextRound() {
|
||||
currentRound++;
|
||||
|
||||
if (currentRound >= nbRounds) gameState = GameState.FINISHED;
|
||||
return gameState != GameState.FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Player.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.pojo;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
import jakarta.websocket.Session;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Objects;
|
||||
import uppa.project.json.websocket.ClickChoice;
|
||||
|
||||
/**
|
||||
* Représentation d'un joueur
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "player")
|
||||
public class Player implements Serializable {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private BigDecimal id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "game_id", nullable = false)
|
||||
private Game game;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "user_id", nullable = false)
|
||||
private User user;
|
||||
|
||||
@Column(name = "score")
|
||||
private int score;
|
||||
|
||||
@Column(name = "winner")
|
||||
private boolean winner;
|
||||
|
||||
@Column(name = "click_count")
|
||||
private int clickCount;
|
||||
|
||||
|
||||
@Column(name = "right_click_count")
|
||||
private int rightClickCount;
|
||||
|
||||
@Transient
|
||||
private int tmpRightClickCount;
|
||||
|
||||
@Transient
|
||||
private int partialRightClickCount;
|
||||
|
||||
@Transient
|
||||
private int tmpPartialRightClickCount;
|
||||
|
||||
@Column(name = "rapid_click_count")
|
||||
private int rapidClickCount;
|
||||
|
||||
@Transient
|
||||
private Deck deck;
|
||||
|
||||
@Transient
|
||||
private Session session = null;
|
||||
|
||||
@Transient
|
||||
private ClickChoice currentClick = null;
|
||||
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*/
|
||||
public Player() {
|
||||
}
|
||||
|
||||
public Player(Game game, User user, Session session) {
|
||||
this.game = game;
|
||||
this.user = user;
|
||||
this.session = session;
|
||||
this.score = 0;
|
||||
this.winner = false;
|
||||
this.clickCount = 0;
|
||||
this.rightClickCount = 0;
|
||||
this.rapidClickCount = 0;
|
||||
this.deck = new Deck(game.getNbColors(), game.getNbValuesPerColor());
|
||||
this.deck.shuffle();
|
||||
this.partialRightClickCount = 0;
|
||||
this.tmpRightClickCount = 0;
|
||||
this.tmpPartialRightClickCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur d'un joueur
|
||||
*
|
||||
* @param game la partie de jeu
|
||||
* @param user l'utilisateur
|
||||
*/
|
||||
public Player(Game game, User user) {
|
||||
this.game = game;
|
||||
this.user = user;
|
||||
this.score = 0;
|
||||
this.winner = false;
|
||||
this.clickCount = 0;
|
||||
this.rightClickCount = 0;
|
||||
this.rapidClickCount = 0;
|
||||
this.deck = new Deck(game.getNbColors(), game.getNbValuesPerColor());
|
||||
this.deck.shuffle();
|
||||
this.partialRightClickCount = 0;
|
||||
this.tmpRightClickCount = 0;
|
||||
this.tmpPartialRightClickCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur d'un joueur
|
||||
*
|
||||
* @param game la partie de jeu
|
||||
* @param user l'utilisateur
|
||||
* @param score le score
|
||||
* @param winner si le joueur est gagnant
|
||||
* @param clickCount le nombre de clics
|
||||
* @param rightClickCount le nombre de clics corrects
|
||||
* @param rapidClickCount le nombre de clics rapides
|
||||
*/
|
||||
public Player(BigDecimal id, Game game, User user, int score, boolean winner, int clickCount, int rightClickCount, int rapidClickCount) {
|
||||
this.id = id;
|
||||
this.game = game;
|
||||
this.user = user;
|
||||
this.score = score;
|
||||
this.winner = winner;
|
||||
this.clickCount = clickCount;
|
||||
this.rightClickCount = rightClickCount;
|
||||
this.rapidClickCount = rapidClickCount;
|
||||
this.partialRightClickCount = 0;
|
||||
this.tmpRightClickCount = 0;
|
||||
this.tmpPartialRightClickCount = 0;
|
||||
|
||||
this.deck = new Deck(game.getNbColors(), game.getNbValuesPerColor());
|
||||
this.deck.shuffle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(game, user, score, winner, clickCount, rightClickCount, rapidClickCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return La partie de jeu du joueur
|
||||
*/
|
||||
public Game getGame() {
|
||||
return game;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie la partie de jeu du joueur
|
||||
*
|
||||
* @param game le nouveau jeu
|
||||
*/
|
||||
public void setGame(Game game) {
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return l'utilisateur
|
||||
*/
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie l'utilisateur
|
||||
*
|
||||
* @param user le nouvel utilisateur
|
||||
*/
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return l'identifiant
|
||||
*/
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le score
|
||||
*
|
||||
* @param score le nouveau score
|
||||
*/
|
||||
public void setScore(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute des points au score
|
||||
*
|
||||
* @param points les points à ajouter
|
||||
*/
|
||||
public void addToScore(int points) {
|
||||
this.score += points;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le score maximum possible
|
||||
*/
|
||||
public int getScoreMax(){
|
||||
return game.getNbRounds() * 3; // 2 points par bonne réponse + 1 point pour le clic rapide
|
||||
}
|
||||
/**
|
||||
* @return si le joueur est gagnant
|
||||
*/
|
||||
public boolean isWinner() {
|
||||
return winner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Déclare le joueur comme gagnant
|
||||
*/
|
||||
public void setWinner() {
|
||||
this.winner = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de clics
|
||||
*/
|
||||
public int getClickCount() {
|
||||
return clickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le nombre de clics
|
||||
*
|
||||
* @param clickCount le nouveau nombre de clics
|
||||
*/
|
||||
public void setClickCount(int clickCount) {
|
||||
this.clickCount = clickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente de 1 le nombre de clics
|
||||
*/
|
||||
public void incrementClickCount() {
|
||||
clickCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de clics corrects
|
||||
*/
|
||||
public int getRightClickCount() {
|
||||
return rightClickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le nombre de clics corrects
|
||||
*
|
||||
* @param rightClickCount le nouveau nombre de clics corrects
|
||||
*/
|
||||
public void setRightClickCount(int rightClickCount) {
|
||||
this.rightClickCount = rightClickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente de 1 le nombre de clics corrects
|
||||
*/
|
||||
public void incrementRightClickCount() {
|
||||
rightClickCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de clics corrects du joueur
|
||||
*/
|
||||
public int getTmpRightClickCount() {
|
||||
return tmpRightClickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente de 1 le nombre de clics corrects
|
||||
*/
|
||||
public void incrementTmpRightClickCount() {
|
||||
tmpRightClickCount++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return le pourcentage de clics corrects du joueur sur la partie courante
|
||||
*/
|
||||
public double getRatioRightClick() {
|
||||
if (clickCount == 0 || rightClickCount == 0) return 0;
|
||||
return (double) Math.abs(rightClickCount * 10000 / game.getNbRounds()) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de clics rapides
|
||||
*/
|
||||
public int getRapidClickCount() {
|
||||
return rapidClickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de clics partiels corrects
|
||||
*/
|
||||
public int getPartialRightClickCount() {
|
||||
return partialRightClickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente de 1 le nombre de clics partielement corrects
|
||||
*/
|
||||
public void incrementPartialRightClickCount() {
|
||||
partialRightClickCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le nombre de clics corrects du joueur
|
||||
*/
|
||||
public int getTmpPartialRightClickCount() {
|
||||
return tmpPartialRightClickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente de 1 le nombre de clics corrects
|
||||
*/
|
||||
public void incrementTmpPartialRightClickCount() {
|
||||
tmpPartialRightClickCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le nombre de clics rapides
|
||||
*
|
||||
* @param rapidClickCount le nouveau nombre de clics rapides
|
||||
*/
|
||||
public void setRapidClickCount(int rapidClickCount) {
|
||||
this.rapidClickCount = rapidClickCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrémente de 1 le nombre de clics rapides
|
||||
*/
|
||||
public void incrementRapidClickCount() {
|
||||
rapidClickCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le pourcentage de clics rapides du joueur sur la partie courante
|
||||
*/
|
||||
public double getRatioRapidClick() {
|
||||
if (clickCount == 0 || rapidClickCount == 0) return 0;
|
||||
return (double) Math.abs(rapidClickCount * 10000 / game.getNbRounds()) / 100;
|
||||
}
|
||||
|
||||
public Deck getDeck() {
|
||||
return deck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Player{id=%s, game=%s, user=%s, score=%d, winner=%b, clickCount=%d, rightClickCount=%d, rapidClickCount=%d}",
|
||||
id != null ? id.toString() : "null", game != null ? game.toString() : "null", user != null ? user.toString() : "null", score,
|
||||
winner, clickCount, rightClickCount, rapidClickCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Player)) return false;
|
||||
Player player = (Player) o;
|
||||
return getScore() == player.getScore() && isWinner() == player.isWinner() && getClickCount() == player.getClickCount() && getRightClickCount() == player.getRightClickCount() && getRapidClickCount() == player.getRapidClickCount() && Objects.equals(id, player.id) && Objects.equals(getGame(), player.getGame()) && Objects.equals(getUser(), player.getUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return l'identifiant
|
||||
*/
|
||||
public BigDecimal getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Session getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public ClickChoice getCurrentClick() {
|
||||
return currentClick;
|
||||
}
|
||||
|
||||
public void setCurrentClick(ClickChoice currentClick) {
|
||||
this.currentClick = currentClick;
|
||||
}
|
||||
|
||||
|
||||
public void setPartialRightClickCount(int tmpPartialRightClickCount) {
|
||||
this.partialRightClickCount = tmpPartialRightClickCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package uppa.project.database.pojo;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Temporal;
|
||||
import jakarta.persistence.TemporalType;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Représentation d'un token de réinitialisation de mot de passe
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "recovery_password_token")
|
||||
public class RecoveryPasswordToken {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private BigDecimal id;
|
||||
|
||||
@Column(name = "token")
|
||||
private String token;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "user_id", nullable = false)
|
||||
private User user;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "expires_at")
|
||||
private Date expiresAt;
|
||||
|
||||
public RecoveryPasswordToken() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
*
|
||||
* @param token
|
||||
* @param user
|
||||
*/
|
||||
public RecoveryPasswordToken(String token, User user) {
|
||||
this.token = token;
|
||||
this.user = user;
|
||||
this.expiresAt = new Date(new Date().getTime() + 600000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur depuis la base de données
|
||||
*
|
||||
* @param id
|
||||
* @param token
|
||||
* @param user
|
||||
*/
|
||||
public RecoveryPasswordToken(BigDecimal id, String token, User user, Date expiresAt) {
|
||||
this.id = id;
|
||||
this.token = token;
|
||||
this.user = user;
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère l'id de l'instance
|
||||
*
|
||||
* @return l'id
|
||||
*/
|
||||
public BigDecimal getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le token
|
||||
*
|
||||
* @return le token
|
||||
*/
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Définit le token
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère l'utilisateur associé au token
|
||||
*
|
||||
* @return l'utilisateur associé au token
|
||||
*/
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Définit l'utilisateur associé au token
|
||||
*
|
||||
* @param user
|
||||
*/
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la date d'expiration du token
|
||||
*
|
||||
* @return la date d'expiration du token
|
||||
*/
|
||||
public Date getExpiresAt() {
|
||||
return expiresAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Définit la date d'expiration du token
|
||||
*
|
||||
* @param expiresAt
|
||||
*/
|
||||
public void setExpiresAt(Date expiresAt) {
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId(), getToken(), getUser(), getExpiresAt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof RecoveryPasswordToken)) return false;
|
||||
RecoveryPasswordToken that = (RecoveryPasswordToken) o;
|
||||
return Objects.equals(getId(), that.getId()) && Objects.equals(getToken(), that.getToken()) && Objects.equals(getUser(), that.getUser()) && Objects.equals(getExpiresAt(), that.getExpiresAt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("RecoveryPasswordToken{id=%s, token=%s, user=%s, expiresAt=%s}",
|
||||
id != null ? id.toString() : "null",
|
||||
token != null ? token : "null",
|
||||
user != null ? user.toString() : "null",
|
||||
expiresAt != null ? expiresAt.toString() : "null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la date d'expiration du token
|
||||
*
|
||||
* @return la date d'expiration du token
|
||||
*/
|
||||
public Date getExpirationDate() {
|
||||
return expiresAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
* User.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.database.pojo;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Temporal;
|
||||
import jakarta.persistence.TemporalType;
|
||||
import jakarta.persistence.Transient;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Représentation d'un utilisateur
|
||||
*
|
||||
* @author Kevin Mitressé
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "user")
|
||||
public class User implements Serializable {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private BigDecimal id;
|
||||
|
||||
@Column(name = "username")
|
||||
private String username;
|
||||
|
||||
@Column(name = "email")
|
||||
private String email;
|
||||
|
||||
@Column(name = "password")
|
||||
private String password;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "birth")
|
||||
private Date birth;
|
||||
|
||||
@Column(name = "gender")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Gender gender;
|
||||
|
||||
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
private List<Player> playedGames;
|
||||
|
||||
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
private List<RecoveryPasswordToken> recoveryPasswordTokens;
|
||||
|
||||
@Transient
|
||||
private int nbPlayedGame;
|
||||
|
||||
@Transient
|
||||
private int nbWin;
|
||||
|
||||
@Transient
|
||||
private double winRate;
|
||||
|
||||
@Transient
|
||||
private int nbClicks;
|
||||
|
||||
@Transient
|
||||
private int nbRightClicks;
|
||||
|
||||
@Transient
|
||||
private double rightClickPercentRate;
|
||||
|
||||
@Transient
|
||||
private int nbRapidClicks;
|
||||
|
||||
@Transient
|
||||
private double rapidClickPercentRate;
|
||||
|
||||
/**
|
||||
* Constructeur par défaut
|
||||
*/
|
||||
public User() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur d'un utilisateur
|
||||
*
|
||||
* @param username le pseudonyme
|
||||
* @param email l'adresse email
|
||||
* @param password le mot de passe
|
||||
* @param birth la date de naissance
|
||||
* @param gender le genre
|
||||
*/
|
||||
public User(String username, String email, String password, Date birth, Gender gender) {
|
||||
if (!isValidBirthDate(birth)){
|
||||
throw new IllegalArgumentException("La date de naissance n'est pas valide");
|
||||
}
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
this.password = hashPassword(password);
|
||||
this.birth = birth;
|
||||
this.gender = gender;
|
||||
this.playedGames = new ArrayList<>();
|
||||
this.recoveryPasswordTokens = new ArrayList<>();
|
||||
this.nbPlayedGame = 0;
|
||||
this.nbWin = 0;
|
||||
this.winRate = 0;
|
||||
this.nbClicks = 0;
|
||||
this.nbRightClicks = 0;
|
||||
this.rightClickPercentRate = 0;
|
||||
this.nbRapidClicks = 0;
|
||||
this.rapidClickPercentRate = 0;
|
||||
}
|
||||
public User(BigDecimal id, String username, String email, String password, Date birth, Gender gender, List<Player> playedGames) {
|
||||
if (!isValidBirthDate(birth)){
|
||||
throw new IllegalArgumentException("La date de naissance n'est pas valide");
|
||||
}
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.birth = birth;
|
||||
this.gender = gender;
|
||||
this.playedGames = playedGames;
|
||||
this.nbPlayedGame = playedGames.size();
|
||||
this.nbWin = getNbWin();
|
||||
this.winRate = getWinRate();
|
||||
this.nbClicks = getNbClicks();
|
||||
this.nbRightClicks = getNbRightClicks();
|
||||
this.rightClickPercentRate = getRightClickPercentRate();
|
||||
this.nbRapidClicks = getNbRapidClicks();
|
||||
this.rapidClickPercentRate = getRapidClickPercentRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur d'un utilisateur
|
||||
*
|
||||
* @param id l'identifiant
|
||||
* @param username le pseudonyme
|
||||
* @param email l'adresse email
|
||||
* @param password le mot de passe
|
||||
* @param birth la date de naissance
|
||||
* @param gender le genre
|
||||
*/
|
||||
public User(BigDecimal id, String username, String email, String password, Date birth, Gender gender, List<Player> playedGames, List<RecoveryPasswordToken> recoveryPasswordToken) {
|
||||
if (!isValidBirthDate(birth)){
|
||||
throw new IllegalArgumentException("La date de naissance n'est pas valide");
|
||||
}
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.birth = birth;
|
||||
this.gender = gender;
|
||||
this.playedGames = playedGames;
|
||||
this.recoveryPasswordTokens = recoveryPasswordToken;
|
||||
this.nbPlayedGame = playedGames.size();
|
||||
this.nbWin = getNbWin();
|
||||
this.winRate = getWinRate();
|
||||
this.nbClicks = getNbClicks();
|
||||
this.nbRightClicks = getNbRightClicks();
|
||||
this.rightClickPercentRate = getRightClickPercentRate();
|
||||
this.nbRapidClicks = getNbRapidClicks();
|
||||
this.rapidClickPercentRate = getRapidClickPercentRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash le mot de passe en SHA-256
|
||||
*
|
||||
* @param password le mot de passe à hasher
|
||||
* @return le mot de passe hashé
|
||||
*/
|
||||
public static String hashPassword(String password) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
byte[] encodedhash = digest.digest(password.getBytes());
|
||||
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte b : encodedhash) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) hexString.append('0');
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, username, email, password, birth, gender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return l'identifiant de l'utilisateur
|
||||
*/
|
||||
public BigDecimal getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le pseudonyme de l'utilisateur
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le pseudonyme de l'utilisateur
|
||||
*
|
||||
* @param username le nouveau pseudonyme
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return l'adresse email de l'utilisateur
|
||||
*/
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie l'adresse email de l'utilisateur
|
||||
*
|
||||
* @param email la nouvelle adresse email
|
||||
*/
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le mot de passe hashé de l'utilisateur
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le mot de passe de l'utilisateur
|
||||
* Le mot de passe est hashé avant d'être stocké
|
||||
*
|
||||
* @param password le nouveau mot de passe
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = hashPassword(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return la date de naissance de l'utilisateur
|
||||
*/
|
||||
public Date getBirth() {
|
||||
return birth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie la date de naissance de l'utilisateur
|
||||
*
|
||||
* @param birth la nouvelle date de naissance
|
||||
*/
|
||||
public void setBirth(Date birth) {
|
||||
this.birth = birth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return le genre de l'utilisateur
|
||||
*/
|
||||
public Gender getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le genre de l'utilisateur
|
||||
*/
|
||||
public void setGender(Gender gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prédicat qui vérifie si le mot de passe fourni est correct
|
||||
*
|
||||
* @param password le mot de passe à vérifier
|
||||
* @return true si le prédicat est vérifié, false sinon
|
||||
*/
|
||||
public boolean verifyPassword(String password) {
|
||||
String hashedPassword = hashPassword(password);
|
||||
return hashedPassword != null && hashedPassword.equals(this.password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la liste des parties jouées par l'utilisateur
|
||||
*
|
||||
* @return la liste des parties jouées
|
||||
*/
|
||||
public List<Player> getPlayedGames() {
|
||||
return playedGames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une partie dans la liste des parties jouées
|
||||
*
|
||||
* @param player la nouvelle partie jouée
|
||||
*/
|
||||
public void addPlayedGame(Player player){
|
||||
playedGames.add(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nombre de parties jouées
|
||||
*
|
||||
* @return le nombre de parties jouées
|
||||
*/
|
||||
public int getNbPlayedGame() {
|
||||
return playedGames.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nombre de parties gagnées
|
||||
*
|
||||
* @return le nombre de parties gagnées
|
||||
*/
|
||||
public int getNbWin(){
|
||||
int nbWin = 0;
|
||||
for (Player p : playedGames) {
|
||||
if (p.isWinner()) nbWin++;
|
||||
}
|
||||
return nbWin;
|
||||
}
|
||||
|
||||
public double getScoreRate(){
|
||||
if (getNbPlayedGame() == 0) return 0;
|
||||
int maxScore = 0;
|
||||
int totalScore = 0;
|
||||
for (Player p : playedGames) {
|
||||
maxScore += p.getScoreMax();
|
||||
totalScore += p.getScore();
|
||||
}
|
||||
return (double) Math.abs(totalScore * 100 / maxScore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le pourcentage de victoire
|
||||
*
|
||||
* @return le pourcentage de victoire
|
||||
*/
|
||||
public double getWinRate(){
|
||||
if (getNbPlayedGame() == 0 || getNbWin() == 0) return 0;
|
||||
return (double) Math.abs(getNbWin() * 10000 / getNbPlayedGame()) /100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nombre total de clics toute partie confondue
|
||||
*
|
||||
* @return le nombre total de clics
|
||||
*/
|
||||
public int getNbClicks(){
|
||||
int nbClicks = 0;
|
||||
for (Player p : playedGames) {
|
||||
nbClicks += p.getClickCount();
|
||||
}
|
||||
return nbClicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nombre total de clics réussi toute partie confondue
|
||||
*
|
||||
* @return le nombre total de clics réussi
|
||||
*/
|
||||
public int getNbRightClicks(){
|
||||
int nbRightClicks = 0;
|
||||
for (Player p : playedGames) {
|
||||
nbRightClicks += p.getRightClickCount();
|
||||
}
|
||||
return nbRightClicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le pourcentage de clics réussi
|
||||
*
|
||||
* @return le pourcentage de clics réussi
|
||||
*/
|
||||
public double getRightClickPercentRate(){
|
||||
if (getNbClicks() == 0 || getNbRightClicks() == 0) return 0;
|
||||
return (double) Math.abs(getNbRightClicks() * 10000 / getNbClicks())/100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nombre total de clics les plus rapides toute partie confondue
|
||||
*
|
||||
* @return le nombre total de clics les plus rapides
|
||||
*/
|
||||
public int getNbRapidClicks(){
|
||||
int nbRapidClicks = 0;
|
||||
for (Player p : playedGames) {
|
||||
nbRapidClicks += p.getRapidClickCount();
|
||||
}
|
||||
return nbRapidClicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le pourcentage de clics les plus rapides
|
||||
*
|
||||
* @return le pourcentage de clics les plus rapides
|
||||
*/
|
||||
public double getRapidClickPercentRate(){
|
||||
if (getNbClicks() == 0 || getNbRapidClicks() == 0) return 0;
|
||||
return (double) Math.abs(getNbRapidClicks() * 10000 / getNbClicks())/100;
|
||||
}
|
||||
|
||||
public boolean isValidBirthDate(Date birthdate){
|
||||
Date currentDate = new Date();
|
||||
return birthdate.before(currentDate) || birthdate.equals(currentDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"User{id='%s', username=%s, email=%s, birth='%s', gender='%s'}",
|
||||
id != null ? id.toString() : "null",
|
||||
username != null ? username : "null",
|
||||
email != null ? email : "null",
|
||||
birth != null ? birth.toString() : "null",
|
||||
gender != null ? gender.toString() : "null"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof User)) return false;
|
||||
User user = (User) o;
|
||||
return Objects.equals(id, user.id)
|
||||
&& Objects.equals(username, user.username)
|
||||
&& Objects.equals(email, user.email)
|
||||
&& Objects.equals(password, user.password)
|
||||
&& Objects.equals(birth, user.birth)
|
||||
&& gender == user.gender
|
||||
&& Objects.equals(playedGames, user.playedGames)
|
||||
&& Objects.equals(recoveryPasswordTokens, user.recoveryPasswordTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumération des genres possibles
|
||||
*/
|
||||
public enum Gender {MALE, FEMALE, OTHER}
|
||||
|
||||
public static Gender getGender(String value) throws IllegalArgumentException{
|
||||
if (value.equals("MALE")) return Gender.MALE;
|
||||
if (value.equals("FEMALE")) return Gender.FEMALE;
|
||||
if (value.equals("OTHER")) return Gender.OTHER;
|
||||
throw new IllegalArgumentException("Le genre selectionné n'existe pas");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* HttpResponse.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.json;
|
||||
|
||||
/**
|
||||
* Classe représentant une réponse HTTP
|
||||
*
|
||||
* @author Kevin Mitresse
|
||||
* @author Lucàs Vabre
|
||||
*/
|
||||
public class HttpResponse {
|
||||
|
||||
/**
|
||||
* Défini si la réponse est un succès
|
||||
*/
|
||||
protected final int code;
|
||||
|
||||
/**
|
||||
* Message de la réponse
|
||||
*/
|
||||
protected final String message;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
*
|
||||
* @param code code HTTP de l'erreur
|
||||
* @param message message d'erreur
|
||||
*/
|
||||
public HttpResponse(HttpResponseCode code, String message) {
|
||||
this.code = code.getCode();
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package uppa.project.json;
|
||||
|
||||
public enum HttpResponseCode {
|
||||
OK(200),
|
||||
CREATED(201),
|
||||
NO_CONTENT(204),
|
||||
BAD_REQUEST(400),
|
||||
UNAUTHORIZED(401),
|
||||
FORBIDDEN(403),
|
||||
NOT_FOUND(404),
|
||||
CONFLICT(409),
|
||||
INTERNAL_SERVER_ERROR(500);
|
||||
|
||||
private final int code;
|
||||
|
||||
HttpResponseCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package uppa.project.json.websocket;
|
||||
|
||||
public enum ClickChoice {
|
||||
COLOR_VALUE,
|
||||
COLOR,
|
||||
VALUE,
|
||||
NONE,
|
||||
TIMER_END
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package uppa.project.json.websocket;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class Message {
|
||||
private final static Gson gson = new Gson();
|
||||
|
||||
private final String type;
|
||||
private final String data;
|
||||
|
||||
public Message(String type, String data) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
return gson.toJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Message{" + "type=" + type + ", data=" + data + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package uppa.project.json.websocket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import uppa.project.database.pojo.Card;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.database.pojo.Player;
|
||||
|
||||
public class SimpleGame {
|
||||
|
||||
private final int id;
|
||||
private final ArrayList<SimplePlayer> players;
|
||||
private final Card currentCard;
|
||||
private final int currentRound;
|
||||
|
||||
public SimpleGame(Game game, ArrayList<Player> playerArrayList) {
|
||||
this.id = game.getId().intValue();
|
||||
this.players = new ArrayList<>();
|
||||
for (Player p : playerArrayList) players.add(new SimplePlayer(p, game.getCurrentRound()));
|
||||
this.currentCard = game.getDeck().getCards().get(game.getCurrentRound() % game.getDeck().getCards().size());
|
||||
this.currentRound = game.getCurrentRound();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public ArrayList<SimplePlayer> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
public Card getCurrentCard() {
|
||||
return currentCard;
|
||||
}
|
||||
|
||||
public int getCurrentRound() {
|
||||
return currentRound;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package uppa.project.json.websocket;
|
||||
|
||||
public class SimpleInvitation {
|
||||
|
||||
private final SimpleUser from;
|
||||
|
||||
private final SimpleUser to;
|
||||
|
||||
private final int game_id;
|
||||
|
||||
public SimpleInvitation(SimpleUser from, SimpleUser to, int game_id) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.game_id = game_id;
|
||||
}
|
||||
|
||||
public SimpleUser getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public SimpleUser getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public int getGameId() {
|
||||
return game_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package uppa.project.json.websocket;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import uppa.project.database.pojo.Card;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
public class SimplePlayer {
|
||||
|
||||
private final SimpleUser user;
|
||||
private final int gameId;
|
||||
private final int score;
|
||||
private final boolean winner;
|
||||
private final String winnerUsername;
|
||||
private final String createdDate;
|
||||
private final int clickCount;
|
||||
private final int rightClickCount;
|
||||
private final int partialRightClickCount;
|
||||
private final int rapidClickCount;
|
||||
private final Card currentCard;
|
||||
|
||||
public SimplePlayer(Player player, int currentRound) {
|
||||
this.user = new SimpleUser(player.getUser());
|
||||
this.score = player.getScore();
|
||||
this.winner = player.isWinner();
|
||||
this.winnerUsername = "";
|
||||
this.clickCount = player.getClickCount();
|
||||
this.rightClickCount = player.getRightClickCount();
|
||||
this.rapidClickCount = player.getRapidClickCount();
|
||||
this.partialRightClickCount = player.getPartialRightClickCount();
|
||||
this.currentCard = player.getDeck().getCards().get((partialRightClickCount+rightClickCount) % player.getDeck().getCards().size());
|
||||
this.createdDate = "";
|
||||
this.gameId = -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructeur pour la pagination
|
||||
*
|
||||
* @param player le joueur
|
||||
* @param translator le traducteur
|
||||
*/
|
||||
public SimplePlayer(Player player, Translator translator) {
|
||||
this.user = new SimpleUser(player.getUser());
|
||||
this.gameId = player.getGame().getId().intValue();
|
||||
this.score = player.getScore();
|
||||
this.winner = player.isWinner();
|
||||
this.winnerUsername = player.getGame().getWinner().getUser().getUsername();
|
||||
this.clickCount = player.getClickCount();
|
||||
this.rightClickCount = player.getRightClickCount();
|
||||
this.rapidClickCount = player.getRapidClickCount();
|
||||
this.partialRightClickCount = player.getPartialRightClickCount();
|
||||
this.currentCard = null;
|
||||
Date date = player.getGame().getCreatedAt();
|
||||
String language = translator.getLanguage();
|
||||
SimpleDateFormat sdfDay;
|
||||
SimpleDateFormat sdfHour;
|
||||
if (translator.getLanguage().equals("EN")) {
|
||||
sdfDay = new SimpleDateFormat("MM/dd/yyyy");
|
||||
sdfHour = new SimpleDateFormat("HH:mm");
|
||||
} else {
|
||||
sdfDay = new SimpleDateFormat("dd/MM/yyyy");
|
||||
sdfHour = new SimpleDateFormat("HH:mm");
|
||||
}
|
||||
String day = sdfDay.format(date);
|
||||
String hour = sdfHour.format(date);
|
||||
this.createdDate = day + ',' + hour ;
|
||||
}
|
||||
|
||||
public SimplePlayer(Player player) {
|
||||
this.user = new SimpleUser(player.getUser());
|
||||
this.score = player.getScore();
|
||||
this.winner = player.isWinner();
|
||||
this.clickCount = player.getClickCount();
|
||||
this.rightClickCount = player.getRightClickCount();
|
||||
this.partialRightClickCount = player.getPartialRightClickCount();
|
||||
this.rapidClickCount = player.getRapidClickCount();
|
||||
this.currentCard = null;
|
||||
this.winnerUsername = "";
|
||||
this.createdDate = "" ;
|
||||
this.gameId = -1;
|
||||
|
||||
}
|
||||
|
||||
public Card getCurrentCard() {
|
||||
return currentCard;
|
||||
}
|
||||
|
||||
public SimpleUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public boolean isWinner() {
|
||||
return winner;
|
||||
}
|
||||
|
||||
public int getClickCount() {
|
||||
return clickCount;
|
||||
}
|
||||
|
||||
public int getPartialRightClickCount() {
|
||||
return partialRightClickCount;
|
||||
}
|
||||
|
||||
public int getRightClickCount() {
|
||||
return rightClickCount;
|
||||
}
|
||||
|
||||
public int getRapidClickCount() {
|
||||
return rapidClickCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package uppa.project.json.websocket;
|
||||
|
||||
import uppa.project.database.pojo.User;
|
||||
|
||||
public class SimpleUser {
|
||||
private final int id;
|
||||
private final String username;
|
||||
|
||||
private final int nbPlayedGames;
|
||||
private final int nbWin;
|
||||
private final double winRate;
|
||||
private final double scoreRate;
|
||||
|
||||
private final double rigthClickPercentRate;
|
||||
private final double rapidClickPercentRate;
|
||||
|
||||
public SimpleUser(User user) {
|
||||
this.id = user.getId().intValue();
|
||||
this.username = user.getUsername();
|
||||
this.nbPlayedGames = user.getNbPlayedGame();
|
||||
this.nbWin = user.getNbWin();
|
||||
this.winRate = user.getWinRate();
|
||||
this.scoreRate = user.getScoreRate();
|
||||
this.rigthClickPercentRate = user.getRightClickPercentRate();
|
||||
this.rapidClickPercentRate = user.getRapidClickPercentRate();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public int getNbPlayedGames() {
|
||||
return nbPlayedGames;
|
||||
}
|
||||
|
||||
public int getNbWin() {
|
||||
return nbWin;
|
||||
}
|
||||
|
||||
public double getWinRate() {
|
||||
return winRate;
|
||||
}
|
||||
|
||||
public double getScoreRate() {
|
||||
return scoreRate;
|
||||
}
|
||||
|
||||
public double getRigthClickPercentRate() {
|
||||
return rigthClickPercentRate;
|
||||
}
|
||||
|
||||
public double getRapidClickPercentRate() {
|
||||
return rapidClickPercentRate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package uppa.project.web.filter;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AlreadyLoggedFilter implements Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
HttpSession session = httpRequest.getSession(false);
|
||||
|
||||
// Vérifier si l'utilisateur est connecté en vérifiant la présence d'une session
|
||||
boolean isLoggedIn = (session != null && session.getAttribute("user") != null);
|
||||
|
||||
// Si l'utilisateur n'est pas connecté, laisser passer la requête
|
||||
if (!isLoggedIn) {
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
// Sinon, rediriger vers la page du menu principal
|
||||
httpResponse.sendRedirect(httpRequest.getContextPath() + "/lobby");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package uppa.project.web.filter;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.User;
|
||||
|
||||
public class AuthenticationFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
HttpSession session = httpRequest.getSession(true);
|
||||
|
||||
// Vérifier si l'utilisateur est connecté en vérifiant la présence d'une session
|
||||
boolean isLoggedIn = (session != null && session.getAttribute("user") != null);
|
||||
|
||||
// Si l'utilisateur est connecté, laisser passer la requête
|
||||
if (isLoggedIn) {
|
||||
User currentUser = (User) session.getAttribute("user");
|
||||
try {
|
||||
// Met à jour l'utilisateur en session
|
||||
DAO<User> userDAO = new Game_JPA_DAO_Factory().getDAOUser();
|
||||
session.removeAttribute("user");
|
||||
EntityManager em = EntityManagerProvider.getInstance();
|
||||
|
||||
em.getTransaction().begin();
|
||||
session.setAttribute("user", userDAO.findById(currentUser.getId().intValue()));
|
||||
em.getTransaction().commit();
|
||||
|
||||
// Passe la requête au filtre suivant
|
||||
chain.doFilter(request, response);
|
||||
} catch (DAOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
// Sinon, rediriger vers la page de connexion
|
||||
httpResponse.sendRedirect(httpRequest.getContextPath() + "/login");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* ForgottenPasswordServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import uppa.project.bean.ForgottenPasswordBean;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "forgottenPasswordServlet", value = "/forgotten-password")
|
||||
public class ForgottenPasswordServlet extends HttpServlet {
|
||||
final static EntityManager em = EntityManagerProvider.getInstance();
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de réinitialisation de mot de passe
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
request.setAttribute("current", "forgotten-password");
|
||||
request.getRequestDispatcher("/WEB-INF/pages/forgotten-password.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestion de la réinitialisation de mot de passe
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
*/
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
Translator translator = (Translator) request.getSession().getAttribute("translator");
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
ForgottenPasswordBean forgottenPasswordBean = new ForgottenPasswordBean()
|
||||
.setEmail(request.getParameter("email"))
|
||||
.setTranslator((Translator) request.getSession().getAttribute("translator"));
|
||||
|
||||
Gson gson = new Gson();
|
||||
HttpResponse httpResponse;
|
||||
String url = request.getRequestURL().toString();
|
||||
String uri = url.substring(0, url.lastIndexOf("/"));
|
||||
if (forgottenPasswordBean.validate(uri)) {
|
||||
httpResponse = new HttpResponse(HttpResponseCode.OK, "Mail sent");
|
||||
} else {
|
||||
httpResponse = new HttpResponse(HttpResponseCode.NOT_FOUND, translator.translate("forgotten_error_email"));
|
||||
}
|
||||
|
||||
out.println(gson.toJson(httpResponse));
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Création d'un token de réinitialisation de mot de passe
|
||||
*
|
||||
* @param token le token
|
||||
*/
|
||||
public static void CreateToken(RecoveryPasswordToken token){
|
||||
Game_JPA_DAO_Factory jpaDaoFactory = new Game_JPA_DAO_Factory();
|
||||
em.getTransaction().begin();
|
||||
try {
|
||||
DAO<RecoveryPasswordToken> daoJpaRecoveryPasswordToken = jpaDaoFactory.getDAORecoveryPasswordToken();
|
||||
daoJpaRecoveryPasswordToken.create(token);
|
||||
em.getTransaction().commit();
|
||||
} catch (DAOException e) {
|
||||
em.getTransaction().rollback();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* MainMenuServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "gameServlet", value = "/game")
|
||||
public class GameServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de jeu
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
try {
|
||||
DAO<Game> gameDAO = new Game_JPA_DAO_Factory().getDAOGame();
|
||||
Game game = gameDAO.findById(Integer.parseInt(request.getParameter("id")));
|
||||
request.setAttribute("game", game);
|
||||
|
||||
request.getRequestDispatcher("/WEB-INF/pages/game.jsp").forward(request, response);
|
||||
} catch (DAOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "game-statistics", value = "/game-statistics")
|
||||
public class GameStatisticsServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de statistiques de jeu
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
Game game;
|
||||
try {
|
||||
DAO<Game> gameDAO = new Game_JPA_DAO_Factory().getDAOGame();
|
||||
game = gameDAO.findById(Integer.parseInt(request.getParameter("id")));
|
||||
ArrayList<Player> players = new ArrayList<>(game.getPlayers());
|
||||
request.setAttribute("players", players);
|
||||
request.setAttribute("game", game);
|
||||
request.getRequestDispatcher("/WEB-INF/pages/game-statistics.jsp").forward(request, response);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* LoginServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "indexServlet", value = {"/index"})
|
||||
public class IndexServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page d'accueil
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
request.getRequestDispatcher("/WEB-INF/pages/index.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* MainMenuServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "lobbyServlet", value = "/lobby")
|
||||
public class LobbyServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de lobby
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
request.getRequestDispatcher("/WEB-INF/pages/lobby.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* LoginServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import uppa.project.bean.LoginBean;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "loginServlet", value = "/login")
|
||||
public class LoginServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de connexion
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
request.setAttribute("current", "login");
|
||||
request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestion de la connexion
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
*/
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
Translator translator = (Translator) request.getSession().getAttribute("translator");
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
LoginBean loginBean = new LoginBean()
|
||||
.setUsername(request.getParameter("username"))
|
||||
.setPassword(request.getParameter("password"))
|
||||
.setTranslator(translator)
|
||||
;
|
||||
|
||||
Gson gson = new Gson();
|
||||
HttpResponse httpResponse;
|
||||
if (loginBean.validate()) {
|
||||
request.getSession().setAttribute("user", loginBean.getUser());
|
||||
|
||||
httpResponse = new HttpResponse(HttpResponseCode.OK, "Login success");
|
||||
} else {
|
||||
httpResponse = loginBean.getError();
|
||||
}
|
||||
out.println(gson.toJson(httpResponse));
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* LogoutServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@WebServlet(name = "logoutServlet", value = "/logout")
|
||||
public class LogoutServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Déconnexion de l'utilisateur
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
request.getSession().removeAttribute("user");
|
||||
response.sendRedirect(request.getContextPath() + "/login");
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* MainMenuServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import uppa.project.bean.NewGameBean;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "newGameServlet", value = "/new")
|
||||
public class NewGameServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de création de partie
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
request.getRequestDispatcher("/WEB-INF/pages/new-game.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Création d'une nouvelle partie
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
*/
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
NewGameBean newGameBean = new NewGameBean()
|
||||
.setDifficulty(request.getParameter("difficulty"))
|
||||
.setNbRounds(request.getParameter("nbRounds"))
|
||||
.setTimer(request.getParameter("timer"))
|
||||
.setNbValues(request.getParameter("nbValues"))
|
||||
.setNbColors(request.getParameter("nbColors"))
|
||||
;
|
||||
|
||||
HttpResponse httpResponse;
|
||||
if (newGameBean.validate()) {
|
||||
Game game = newGameBean.getGame();
|
||||
httpResponse = new HttpResponse(HttpResponseCode.OK, game.getId().toString());
|
||||
} else {
|
||||
httpResponse = newGameBean.getError();
|
||||
}
|
||||
|
||||
out.println(gson.toJson(httpResponse));
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* LoginServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import uppa.project.bean.ProfileBean;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.json.websocket.SimplePlayer;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "profileServlet", value = "/profile")
|
||||
public class ProfileServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de profil
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
User usersession = (User) request.getSession().getAttribute("user");
|
||||
DAO<User> userDAO;
|
||||
try {
|
||||
userDAO = new Game_JPA_DAO_Factory().getDAOUser();
|
||||
User user = userDAO.findById(usersession.getId().intValue());
|
||||
request.getSession().setAttribute("user", user);
|
||||
request.getRequestDispatcher("/WEB-INF/pages/profile.jsp").forward(request, response);
|
||||
} catch (DAOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
response.sendRedirect(request.getContextPath() + "/lobby");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestion de la modification de profil
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
*/
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
Translator translator = (Translator) request.getSession().getAttribute("translator");
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
ProfileBean profileBean = new ProfileBean()
|
||||
.setTranslator(translator)
|
||||
.setUsername(request.getParameter("username"))
|
||||
.setOldEmail(request.getParameter("oldEmail"))
|
||||
.setEmail(request.getParameter("email"))
|
||||
.setOldPassword(request.getParameter("oldPassword"))
|
||||
.setNewPassword(request.getParameter("password"))
|
||||
.setConfirmPassword(request.getParameter("repassword"))
|
||||
.setGender(request.getParameter("gender"))
|
||||
;
|
||||
|
||||
Gson gson = new Gson();
|
||||
HttpResponse httpResponse;
|
||||
if (profileBean.validate()) {
|
||||
request.getSession().setAttribute("user", profileBean.getUser());
|
||||
httpResponse = new HttpResponse(
|
||||
HttpResponseCode.OK,
|
||||
"Register success"
|
||||
);
|
||||
} else {
|
||||
httpResponse = profileBean.getError();
|
||||
}
|
||||
out.println(gson.toJson(httpResponse));
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
Translator translator = (Translator) request.getSession().getAttribute("translator");
|
||||
int userID =Integer.parseInt(request.getParameter("userId"));
|
||||
int firstData = Integer.parseInt(request.getParameter("pageNumber")) * 5;
|
||||
try {
|
||||
DAO<Player> playerDAO = new Game_JPA_DAO_Factory().getDAOPlayer();
|
||||
Player[] players = playerDAO.findPlayerForPagination(userID, firstData);
|
||||
SimplePlayer[] simplePlayers = new SimplePlayer[players.length];
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
simplePlayers[i] = new SimplePlayer(players[i], translator);
|
||||
}
|
||||
Gson gson = new Gson();
|
||||
String jsonPlayers = gson.toJson(simplePlayers);
|
||||
|
||||
// Configurer la réponse
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
|
||||
// Envoyer la réponse JSON
|
||||
PrintWriter out = response.getWriter();
|
||||
out.println(jsonPlayers);
|
||||
out.flush();
|
||||
|
||||
} catch (DAOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* RegisterServlet.java, 20/03/2024
|
||||
* UPPA M1 TI 2023-2024
|
||||
* Pas de copyright, aucun droits
|
||||
*/
|
||||
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import uppa.project.bean.RegisterBean;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "registerServlet", value = "/register")
|
||||
public class RegisterServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page d'inscription
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
request.setAttribute("current", "register");
|
||||
request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestion de l'inscription
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
*/
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
|
||||
Translator translator = (Translator) request.getSession().getAttribute("translator");
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
|
||||
RegisterBean registerBean = new RegisterBean()
|
||||
.setTranslator(translator)
|
||||
.setUsername(request.getParameter("username"))
|
||||
.setEmail(request.getParameter("email"))
|
||||
.setPassword(request.getParameter("password"))
|
||||
.setConfirmPassword(request.getParameter("repassword"))
|
||||
.setBirth(request.getParameter("birth"))
|
||||
.setGender(request.getParameter("gender"))
|
||||
;
|
||||
|
||||
Gson gson = new Gson();
|
||||
HttpResponse httpResponse;
|
||||
if (registerBean.validate()) {
|
||||
httpResponse = new HttpResponse(
|
||||
HttpResponseCode.OK,
|
||||
"Register success"
|
||||
);
|
||||
} else {
|
||||
httpResponse = registerBean.getError();
|
||||
}
|
||||
|
||||
out.println(gson.toJson(httpResponse));
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import uppa.project.bean.ResetPasswordBean;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.jpa.DAO_JPA_RecoveryPasswordToken;
|
||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||
import uppa.project.json.HttpResponse;
|
||||
import uppa.project.json.HttpResponseCode;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "resetPasswordServlet", value = "/reset-password")
|
||||
public class ResetPasswordServlet extends HttpServlet {
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page de réinitialisation de mot de passe
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
RecoveryPasswordToken token = findRecoveryToken(request.getParameter("token"));
|
||||
if (token == null) {
|
||||
request.getRequestDispatcher("/WEB-INF/pages/errors/invalid-token-password.jsp").forward(request, response);
|
||||
return;
|
||||
}
|
||||
if (token.getExpirationDate().compareTo(new java.util.Date()) < 0){
|
||||
request.getRequestDispatcher("/WEB-INF/pages/errors/expired-token-password.jsp").forward(request, response);
|
||||
return;
|
||||
}
|
||||
request.setAttribute("current", "reset-password");
|
||||
request.getRequestDispatcher("/WEB-INF/pages/reset-password.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestion de la réinitialisation de mot de passe
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
*/
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
Translator translator = (Translator) request.getSession().getAttribute("translator");
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
ResetPasswordBean resetPasswordBean = new ResetPasswordBean()
|
||||
.setTranslator(translator)
|
||||
.setToken(request.getParameter("token"))
|
||||
.setPassword(request.getParameter("password"))
|
||||
.setConfirmPassword(request.getParameter("repassword"))
|
||||
;
|
||||
|
||||
Gson gson = new Gson();
|
||||
HttpResponse httpResponse;
|
||||
if (resetPasswordBean.validate()) {
|
||||
httpResponse = new HttpResponse(
|
||||
HttpResponseCode.OK,
|
||||
"Register success"
|
||||
);
|
||||
} else {
|
||||
httpResponse = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR, resetPasswordBean.getErrorMessage());
|
||||
}
|
||||
|
||||
out.println(gson.toJson(httpResponse));
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recherche d'un token de réinitialisation de mot de passe
|
||||
*
|
||||
* @param token le token
|
||||
* @return le token de réinitialisation de mot de passe
|
||||
*/
|
||||
public static RecoveryPasswordToken findRecoveryToken(String token) {
|
||||
try {
|
||||
DAO_JPA_RecoveryPasswordToken daoJpaRecoveryPasswordToken = new DAO_JPA_RecoveryPasswordToken();
|
||||
RecoveryPasswordToken[] recoveryPasswordTokens = daoJpaRecoveryPasswordToken.findByField("token",token);
|
||||
if (recoveryPasswordTokens.length == 0) {
|
||||
return null;
|
||||
}
|
||||
return recoveryPasswordTokens[0];
|
||||
} catch (DAOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "rulesServlet", value = "/rules")
|
||||
public class RulesServlet extends HttpServlet {
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Affichage de la page des règles
|
||||
*
|
||||
* @param request la requête
|
||||
* @param response la réponse
|
||||
* @throws IOException si une erreur d'entrée/sortie survient
|
||||
* @throws ServletException si une erreur de servlet survient
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
if (request.getSession().getAttribute("translator") == null) {
|
||||
request.getSession().setAttribute("language", "FR");
|
||||
request.getSession().setAttribute("translator", Translator.generateTranslator(request.getSession(), request.getServletContext()));
|
||||
}
|
||||
request.getRequestDispatcher("/WEB-INF/pages/rules.jsp").forward(request, response);
|
||||
}
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package uppa.project.web.servlet;
|
||||
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import uppa.project.web.translation.Translator;
|
||||
|
||||
@WebServlet(name = "translationServlet", value = "/translate")
|
||||
public class TranslationServlet extends HttpServlet {
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
if (request.getParameter("language") != null) {
|
||||
String language = request.getParameter("language");
|
||||
request.getSession().setAttribute("language", language);
|
||||
Translator translator = Translator.generateTranslator(request.getSession(), request.getServletContext());
|
||||
request.getSession().setAttribute("translator", translator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package uppa.project.web.translation;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class Translator {
|
||||
|
||||
private final String language;
|
||||
|
||||
private final JsonParser parser;
|
||||
|
||||
private JsonObject translations;
|
||||
|
||||
public enum Language {EN, FR}
|
||||
|
||||
public Translator(Language language) {
|
||||
this.language = language.name();
|
||||
this.parser = new JsonParser();
|
||||
}
|
||||
|
||||
public static Translator generateTranslator(HttpSession session , ServletContext context) {
|
||||
Translator translator;
|
||||
if (session.getAttribute("language") != null && session.getAttribute("language").equals(Translator.Language.EN.name())) {
|
||||
translator = new Translator(Translator.Language.EN);
|
||||
} else {
|
||||
translator = new Translator(Translator.Language.FR);
|
||||
}
|
||||
translator.setJsonContent(context);
|
||||
return translator;
|
||||
}
|
||||
|
||||
public void setJsonContent(ServletContext context) {
|
||||
InputStream is = context.getResourceAsStream("/WEB-INF/translations.json");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
|
||||
//Parse the File as a JSON Object
|
||||
JsonElement fileElement = parser.parse(reader);
|
||||
this.translations = fileElement.getAsJsonObject();
|
||||
}
|
||||
|
||||
public String translate(String text) {
|
||||
return this.translations.get(text).getAsJsonObject().get(this.language).getAsString();
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package uppa.project.web.websocket;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.websocket.OnClose;
|
||||
import jakarta.websocket.OnError;
|
||||
import jakarta.websocket.OnMessage;
|
||||
import jakarta.websocket.OnOpen;
|
||||
import jakarta.websocket.Session;
|
||||
import jakarta.websocket.server.PathParam;
|
||||
import jakarta.websocket.server.ServerEndpoint;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.json.websocket.Message;
|
||||
import uppa.project.json.websocket.SimpleInvitation;
|
||||
import uppa.project.json.websocket.SimpleUser;
|
||||
|
||||
@ServerEndpoint(value = "/ws/users/{user_id}")
|
||||
public class ConnectedUsersWS {
|
||||
|
||||
public static final HashMap<Session, User> users = new HashMap<>();
|
||||
public static final ArrayList<Session> anonymousUsers = new ArrayList<>();
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
private static void broadcast(String message) {
|
||||
// Send the message to all anonymous users
|
||||
for (Session session : anonymousUsers) {
|
||||
try {
|
||||
session.getBasicRemote().sendText(message);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Send the message to all connected users
|
||||
for (Session session : users.keySet()) {
|
||||
try {
|
||||
session.getBasicRemote().sendText(message);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam("user_id") String userId) throws DAOException {
|
||||
Message message;
|
||||
int id = Integer.parseInt(userId);
|
||||
|
||||
if (id == 0) {
|
||||
anonymousUsers.add(session);
|
||||
} else {
|
||||
// Get the new user
|
||||
final DAO<User> userDAO = new Game_JPA_DAO_Factory().getDAOUser();
|
||||
|
||||
User user = userDAO.findById(id);
|
||||
|
||||
// Send the new user to all connected users
|
||||
message = new Message("addUser", gson.toJson(new SimpleUser(user)));
|
||||
broadcast(message.toJson());
|
||||
|
||||
// Send all connected users to the new user
|
||||
users.put(session, user);
|
||||
}
|
||||
|
||||
ArrayList<SimpleUser> connectedUsers = new ArrayList<>();
|
||||
for (User u : users.values()) connectedUsers.add(new SimpleUser(u));
|
||||
message = new Message("init", gson.toJson(connectedUsers));
|
||||
session.getAsyncRemote().sendText(message.toJson());
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(Session session, @PathParam("user_id") String userId) {
|
||||
int id = Integer.parseInt(userId);
|
||||
|
||||
if (id == 0) {
|
||||
anonymousUsers.remove(session);
|
||||
} else {
|
||||
Message message = new Message("removeUser", gson.toJson(new SimpleUser(users.get(session))));
|
||||
users.remove(session);
|
||||
broadcast(message.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
@OnError
|
||||
public void onError(Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String rawMessage, Session session) {
|
||||
Message message = gson.fromJson(rawMessage, Message.class);
|
||||
|
||||
if (message.getType().equals("invite")) {
|
||||
SimpleInvitation invitation = gson.fromJson(message.getData(), SimpleInvitation.class);
|
||||
|
||||
// Récupérer la session de l'utilisateur invité
|
||||
for (Session s : users.keySet()) {
|
||||
if (users.get(s).getId().intValue() == invitation.getTo().getId()) {
|
||||
try {
|
||||
s.getBasicRemote().sendText(message.toJson());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
package uppa.project.web.websocket;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.websocket.OnClose;
|
||||
import jakarta.websocket.OnError;
|
||||
import jakarta.websocket.OnMessage;
|
||||
import jakarta.websocket.OnOpen;
|
||||
import jakarta.websocket.Session;
|
||||
import jakarta.websocket.server.PathParam;
|
||||
import jakarta.websocket.server.ServerEndpoint;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import uppa.project.bean.PlayerBean;
|
||||
import uppa.project.database.dao.DAO;
|
||||
import uppa.project.database.dao.DAOException;
|
||||
import uppa.project.database.dao.EntityManagerProvider;
|
||||
import uppa.project.database.dao.jpa.DAO_JPA_User;
|
||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||
import uppa.project.database.pojo.Card;
|
||||
import uppa.project.database.pojo.Game;
|
||||
import uppa.project.database.pojo.Player;
|
||||
import uppa.project.database.pojo.User;
|
||||
import uppa.project.json.websocket.ClickChoice;
|
||||
import uppa.project.json.websocket.Message;
|
||||
import uppa.project.json.websocket.SimpleGame;
|
||||
import uppa.project.json.websocket.SimplePlayer;
|
||||
import uppa.project.json.websocket.SimpleUser;
|
||||
|
||||
@ServerEndpoint(value = "/ws/game/{game_id}")
|
||||
public class GameWS {
|
||||
|
||||
private static final HashMap<Game, ArrayList<Player>> games = new HashMap<>();
|
||||
private static final HashMap<Game, Timer> timers = new HashMap<>();
|
||||
Gson gson = new Gson();
|
||||
private Game game;
|
||||
private Player player;
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam("game_id") String gameId) throws DAOException {
|
||||
DAO<Game> gameDAO = new Game_JPA_DAO_Factory().getDAOGame();
|
||||
this.game = gameDAO.findById(Integer.parseInt(gameId));
|
||||
if (!games.containsKey(game)) games.put(game, new ArrayList<>());
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(Session session, @PathParam("game_id") String gameId) throws DAOException {
|
||||
games.get(game).remove(this.player);
|
||||
|
||||
// Broadcast the new player
|
||||
ArrayList<SimplePlayer> simplePlayerList = new ArrayList<>();
|
||||
for (Player player : games.get(game)) simplePlayerList.add(new SimplePlayer(player));
|
||||
|
||||
broadcast(new Message("updatePlayerList", gson.toJson(simplePlayerList)).toJson());
|
||||
}
|
||||
|
||||
@OnError
|
||||
public void onError(Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String rawMessage, Session session, @PathParam("game_id") String gameId) throws DAOException {
|
||||
DAO<User> userDAO = new DAO_JPA_User();
|
||||
|
||||
Message message = gson.fromJson(rawMessage, Message.class);
|
||||
|
||||
if (message.getType().equals("connection")) {
|
||||
SimpleUser simpleUser = gson.fromJson(message.getData(), SimpleUser.class);
|
||||
|
||||
// find the user
|
||||
User user = userDAO.findById(simpleUser.getId());
|
||||
|
||||
this.player = new Player(game, user, session);
|
||||
games.get(game).add(this.player);
|
||||
|
||||
ArrayList<SimplePlayer> simplePlayerList = new ArrayList<>();
|
||||
for (Player p : games.get(game)) simplePlayerList.add(new SimplePlayer(p));
|
||||
|
||||
// Diffusion de la nouvelle liste de joueurs
|
||||
broadcast(new Message("updatePlayerList", gson.toJson(simplePlayerList)).toJson());
|
||||
}
|
||||
|
||||
if (message.getType().equals("start")) {
|
||||
game.setGameState(Game.GameState.STARTED);
|
||||
broadcast(new Message("start", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||
|
||||
Timer timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Fin du timer
|
||||
broadcast(new Message("timerEnd", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||
timer.cancel();
|
||||
}
|
||||
}, game.getTimer() * 1000L);
|
||||
timers.put(game, timer);
|
||||
}
|
||||
|
||||
ArrayList<Card> playersCurrentCards = new ArrayList<>(games.get(game).size());
|
||||
for (Player player : games.get(game)) {
|
||||
playersCurrentCards.add(player.getDeck().getCards().get((player.getPartialRightClickCount()+player.getRightClickCount()) % player.getDeck().getCards().size()));
|
||||
}
|
||||
|
||||
|
||||
if (message.getType().equals("click")) {
|
||||
ClickChoice choice = gson.fromJson(message.getData(), ClickChoice.class);
|
||||
|
||||
int playerScore = player.getScore();
|
||||
Card gameCard = game.getDeck().getCards().get(game.getCurrentRound());
|
||||
Card playerCard = player.getDeck().getCards().get((player.getPartialRightClickCount()+player.getRightClickCount()) % player.getDeck().getCards().size());
|
||||
|
||||
player.setCurrentClick(choice);
|
||||
|
||||
// Récupérer le nombre de joueurs ayant cliqué
|
||||
int gameClickCount = 0;
|
||||
for (Player player : games.get(game)) {
|
||||
if (player.getCurrentClick() != null) gameClickCount++;
|
||||
}
|
||||
|
||||
// Compteur de clics
|
||||
player.incrementClickCount();
|
||||
|
||||
boolean isRapid = false;
|
||||
// Compteur de clics rapides
|
||||
if (gameClickCount == 1 && choice != ClickChoice.TIMER_END) {
|
||||
isRapid = true;
|
||||
};
|
||||
|
||||
// Vérifier le choix du joueur et attribuer les points
|
||||
if (game.getDifficulty().equals(Game.Difficulty.EASY)) {
|
||||
switch (choice) {
|
||||
case COLOR_VALUE -> {
|
||||
if (gameCard.equals(playerCard)) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case COLOR -> {
|
||||
if (gameCard.getColor().equals(playerCard.getColor())) {
|
||||
if (!gameCard.equals(playerCard)) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.incrementPartialRightClickCount();
|
||||
player.setScore(playerScore + 1);
|
||||
}
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case VALUE -> {
|
||||
if (gameCard.getValue() == playerCard.getValue()) {
|
||||
if (!gameCard.equals(playerCard)) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.incrementPartialRightClickCount();
|
||||
player.setScore(playerScore + 1);
|
||||
}
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case NONE -> {
|
||||
if (!gameCard.getColor().equals(playerCard.getColor()) && gameCard.getValue() != playerCard.getValue()) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case TIMER_END -> {}
|
||||
}
|
||||
} else {
|
||||
int nbSameCard = countSameCard(gameCard, playersCurrentCards);
|
||||
int nbSameColor = countSameColor(gameCard, playersCurrentCards);
|
||||
int nbSameValue = countSameValue(gameCard, playersCurrentCards);
|
||||
int nbNone = countNone(gameCard, playersCurrentCards);
|
||||
|
||||
switch (choice) {
|
||||
case COLOR_VALUE -> {
|
||||
if ((nbSameCard >= nbSameColor) && (nbSameCard >= nbSameValue) && (nbSameCard >= nbNone)) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementTmpRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case COLOR -> {
|
||||
if ((nbSameCard >= nbSameColor) && (nbSameCard >= nbSameValue) && (nbSameCard >= nbNone)) {
|
||||
player.incrementTmpPartialRightClickCount();
|
||||
player.setScore(playerScore + 1);
|
||||
} else if ((nbSameColor > nbSameCard) && (nbSameColor >= nbSameValue) && (nbSameColor >= nbNone)) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementTmpRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case VALUE -> {
|
||||
if ((nbSameCard >= nbSameColor) && (nbSameCard >= nbSameValue) && (nbSameCard >= nbNone)) {
|
||||
player.incrementTmpPartialRightClickCount();
|
||||
player.setScore(playerScore + 1);
|
||||
} else if ((nbSameValue > nbSameCard) && (nbSameValue > nbSameColor) && (nbSameValue >= nbNone)) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementTmpRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case NONE -> {
|
||||
if ((nbNone > nbSameCard) && (nbNone >= nbSameColor) && (nbNone > nbSameValue)) {
|
||||
if (isRapid) {
|
||||
player.incrementRapidClickCount();
|
||||
playerScore++;
|
||||
}
|
||||
player.incrementTmpRightClickCount();
|
||||
player.setScore(playerScore + 2);
|
||||
} else {
|
||||
player.setScore(playerScore - 1);
|
||||
}
|
||||
}
|
||||
case TIMER_END -> {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Diffuser le score du joueur
|
||||
broadcast(new Message("updatePlayer", gson.toJson(new SimplePlayer(player))).toJson());
|
||||
|
||||
// Si tous les joueurs ont cliqué
|
||||
if (gameClickCount >= games.get(game).size()) {
|
||||
// Stopper le timer
|
||||
timers.get(game).cancel();
|
||||
|
||||
// Réinitialiser les clics courrants
|
||||
for (Player p : games.get(game)) {
|
||||
p.setRightClickCount(p.getTmpRightClickCount());
|
||||
p.setPartialRightClickCount(p.getTmpPartialRightClickCount());
|
||||
p.setCurrentClick(null);
|
||||
}
|
||||
|
||||
List<Player> players = games.get(game);
|
||||
players.sort((p1, p2) -> {
|
||||
if (p1.getScore() == p2.getScore()) {
|
||||
return p2.getRapidClickCount() - p1.getRapidClickCount();
|
||||
}
|
||||
return p2.getScore() - p1.getScore();
|
||||
});
|
||||
|
||||
Player theoricWinner = players.get(0);
|
||||
Player second = players.get(1);
|
||||
|
||||
// Vérifier si la partie est terminée
|
||||
if (game.nextRound() || (second.getScore() == theoricWinner.getScore() && second.getRapidClickCount() == theoricWinner.getRapidClickCount())) {
|
||||
broadcast(new Message("nextRound", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||
Timer timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Diffuser la fin du timer
|
||||
broadcast(new Message("timerEnd", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||
timer.cancel();
|
||||
}
|
||||
}, game.getTimer() * 1000L);
|
||||
timers.put(game, timer);
|
||||
} else {
|
||||
theoricWinner.setWinner();
|
||||
|
||||
EntityManager em = EntityManagerProvider.getFactory().createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
for (Player p : games.get(game)) {
|
||||
PlayerBean playerBean = new PlayerBean(p);
|
||||
if (playerBean.validate()) System.out.println("Player " + p.getUser().getUsername() + " sauvegardé en base de données");
|
||||
}
|
||||
em.getTransaction().commit();
|
||||
|
||||
// Diffusion de la fin de la partie
|
||||
broadcast(new Message("end", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le nombre de joueurs avec une carte identique à celle du plateau
|
||||
*
|
||||
* @param gameCard carte du plateau
|
||||
* @param currentCards liste des cartes des joueurs
|
||||
* @return nombre de cartes identiques à celle du plateau
|
||||
*/
|
||||
private int countSameCard(Card gameCard, List<Card> currentCards) {
|
||||
int counter = 0;
|
||||
for (Card card : currentCards) {
|
||||
if (gameCard.equals(card)) {
|
||||
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le nombre de joueurs avec une carte avec seulement la couleur correspondante à celle du plateau
|
||||
*
|
||||
* @param gameCard carte du plateau
|
||||
* @param currentCards liste des cartes des joueurs
|
||||
* @return nombre de couleurs identiques à celle du plateau
|
||||
*/
|
||||
private int countSameColor(Card gameCard, List<Card> currentCards) {
|
||||
int counter = 0;
|
||||
for (Card card : currentCards) {
|
||||
if (gameCard.getColor().equals(card.getColor()) && !gameCard.getValue().equals(card.getValue())) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le nombre de joueurs avec une carte avec seulement la valeur correspondante à celle du plateau
|
||||
*
|
||||
* @param gameCard carte du plateau
|
||||
* @param currentCards liste des cartes des joueurs
|
||||
* @return nombre de valeurs identiques à celle du plateau
|
||||
*/
|
||||
private int countSameValue(Card gameCard, List<Card> currentCards) {
|
||||
int counter = 0;
|
||||
for (Card card : currentCards) {
|
||||
if (gameCard.getValue().equals(card.getValue()) && !gameCard.getColor().equals(card.getColor())) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le nombre de joueurs avec une carte totalement différente de celle du plateau
|
||||
*
|
||||
* @param gameCard carte du plateau
|
||||
* @param currentCards liste des cartes des joueurs
|
||||
* @return nombre de cartes totalement différentes de celle du plateau
|
||||
*/
|
||||
private int countNone(Card gameCard, List<Card> currentCards) {
|
||||
int counter = 0;
|
||||
for (Card card : currentCards) {
|
||||
if (!gameCard.getColor().equals(card.getColor()) && !gameCard.getValue().equals(card.getValue())) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private void broadcast(String message) {
|
||||
for (Player player : games.get(game)) {
|
||||
try {
|
||||
player.getSession().getBasicRemote().sendText(message);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user